@@ -542,7 +542,7 @@ discard block |
||
542 | 542 | /** |
543 | 543 | * @initiate session |
544 | 544 | * @access private |
545 | - * @return TRUE on success, FALSE on fail |
|
545 | + * @return boolean on success, FALSE on fail |
|
546 | 546 | * @throws EE_Error |
547 | 547 | * @throws InvalidArgumentException |
548 | 548 | * @throws InvalidDataTypeException |
@@ -778,7 +778,7 @@ discard block |
||
778 | 778 | * @update session data prior to saving to the db |
779 | 779 | * @access public |
780 | 780 | * @param bool $new_session |
781 | - * @return TRUE on success, FALSE on fail |
|
781 | + * @return boolean on success, FALSE on fail |
|
782 | 782 | * @throws EE_Error |
783 | 783 | * @throws InvalidArgumentException |
784 | 784 | * @throws InvalidDataTypeException |
@@ -879,7 +879,7 @@ discard block |
||
879 | 879 | * _save_session_to_db |
880 | 880 | * |
881 | 881 | * @param bool $clear_session |
882 | - * @return string |
|
882 | + * @return boolean |
|
883 | 883 | * @throws EE_Error |
884 | 884 | * @throws InvalidArgumentException |
885 | 885 | * @throws InvalidDataTypeException |
@@ -24,1328 +24,1328 @@ discard block |
||
24 | 24 | class EE_Session implements SessionIdentifierInterface |
25 | 25 | { |
26 | 26 | |
27 | - const session_id_prefix = 'ee_ssn_'; |
|
28 | - |
|
29 | - const hash_check_prefix = 'ee_shc_'; |
|
30 | - |
|
31 | - const OPTION_NAME_SETTINGS = 'ee_session_settings'; |
|
32 | - |
|
33 | - const STATUS_CLOSED = 0; |
|
34 | - |
|
35 | - const STATUS_OPEN = 1; |
|
36 | - |
|
37 | - const SAVE_STATE_CLEAN = 'clean'; |
|
38 | - const SAVE_STATE_DIRTY = 'dirty'; |
|
39 | - |
|
40 | - |
|
41 | - /** |
|
42 | - * instance of the EE_Session object |
|
43 | - * |
|
44 | - * @var EE_Session |
|
45 | - */ |
|
46 | - private static $_instance; |
|
47 | - |
|
48 | - /** |
|
49 | - * @var CacheStorageInterface $cache_storage |
|
50 | - */ |
|
51 | - protected $cache_storage; |
|
52 | - |
|
53 | - /** |
|
54 | - * @var EE_Encryption $encryption |
|
55 | - */ |
|
56 | - protected $encryption; |
|
57 | - |
|
58 | - /** |
|
59 | - * @var SessionStartHandler $session_start_handler |
|
60 | - */ |
|
61 | - protected $session_start_handler; |
|
62 | - |
|
63 | - /** |
|
64 | - * the session id |
|
65 | - * |
|
66 | - * @var string |
|
67 | - */ |
|
68 | - private $_sid; |
|
69 | - |
|
70 | - /** |
|
71 | - * session id salt |
|
72 | - * |
|
73 | - * @var string |
|
74 | - */ |
|
75 | - private $_sid_salt; |
|
76 | - |
|
77 | - /** |
|
78 | - * session data |
|
79 | - * |
|
80 | - * @var array |
|
81 | - */ |
|
82 | - private $_session_data = array(); |
|
83 | - |
|
84 | - /** |
|
85 | - * how long an EE session lasts |
|
86 | - * default session lifespan of 1 hour (for not so instant IPNs) |
|
87 | - * |
|
88 | - * @var SessionLifespan $session_lifespan |
|
89 | - */ |
|
90 | - private $session_lifespan; |
|
91 | - |
|
92 | - /** |
|
93 | - * session expiration time as Unix timestamp in GMT |
|
94 | - * |
|
95 | - * @var int |
|
96 | - */ |
|
97 | - private $_expiration; |
|
98 | - |
|
99 | - /** |
|
100 | - * whether or not session has expired at some point |
|
101 | - * |
|
102 | - * @var boolean |
|
103 | - */ |
|
104 | - private $_expired = false; |
|
105 | - |
|
106 | - /** |
|
107 | - * current time as Unix timestamp in GMT |
|
108 | - * |
|
109 | - * @var int |
|
110 | - */ |
|
111 | - private $_time; |
|
112 | - |
|
113 | - /** |
|
114 | - * whether to encrypt session data |
|
115 | - * |
|
116 | - * @var bool |
|
117 | - */ |
|
118 | - private $_use_encryption; |
|
119 | - |
|
120 | - /** |
|
121 | - * well... according to the server... |
|
122 | - * |
|
123 | - * @var null |
|
124 | - */ |
|
125 | - private $_user_agent; |
|
126 | - |
|
127 | - /** |
|
128 | - * do you really trust the server ? |
|
129 | - * |
|
130 | - * @var null |
|
131 | - */ |
|
132 | - private $_ip_address; |
|
133 | - |
|
134 | - /** |
|
135 | - * current WP user_id |
|
136 | - * |
|
137 | - * @var null |
|
138 | - */ |
|
139 | - private $_wp_user_id; |
|
140 | - |
|
141 | - /** |
|
142 | - * array for defining default session vars |
|
143 | - * |
|
144 | - * @var array |
|
145 | - */ |
|
146 | - private $_default_session_vars = array( |
|
147 | - 'id' => null, |
|
148 | - 'user_id' => null, |
|
149 | - 'ip_address' => null, |
|
150 | - 'user_agent' => null, |
|
151 | - 'init_access' => null, |
|
152 | - 'last_access' => null, |
|
153 | - 'expiration' => null, |
|
154 | - 'pages_visited' => array(), |
|
155 | - ); |
|
156 | - |
|
157 | - /** |
|
158 | - * timestamp for when last garbage collection cycle was performed |
|
159 | - * |
|
160 | - * @var int $_last_gc |
|
161 | - */ |
|
162 | - private $_last_gc; |
|
163 | - |
|
164 | - /** |
|
165 | - * @var RequestInterface $request |
|
166 | - */ |
|
167 | - protected $request; |
|
168 | - |
|
169 | - /** |
|
170 | - * whether session is active or not |
|
171 | - * |
|
172 | - * @var int $status |
|
173 | - */ |
|
174 | - private $status = EE_Session::STATUS_CLOSED; |
|
175 | - |
|
176 | - /** |
|
177 | - * whether session data has changed therefore requiring a session save |
|
178 | - * |
|
179 | - * @var string $save_state |
|
180 | - */ |
|
181 | - private $save_state = EE_Session::SAVE_STATE_CLEAN; |
|
182 | - |
|
183 | - |
|
184 | - /** |
|
185 | - * @singleton method used to instantiate class object |
|
186 | - * @param CacheStorageInterface $cache_storage |
|
187 | - * @param SessionLifespan|null $lifespan |
|
188 | - * @param RequestInterface $request |
|
189 | - * @param SessionStartHandler $session_start_handler |
|
190 | - * @param EE_Encryption $encryption |
|
191 | - * @return EE_Session |
|
192 | - * @throws InvalidArgumentException |
|
193 | - * @throws InvalidDataTypeException |
|
194 | - * @throws InvalidInterfaceException |
|
195 | - */ |
|
196 | - public static function instance( |
|
197 | - CacheStorageInterface $cache_storage = null, |
|
198 | - SessionLifespan $lifespan = null, |
|
199 | - RequestInterface $request = null, |
|
200 | - SessionStartHandler $session_start_handler = null, |
|
201 | - EE_Encryption $encryption = null |
|
202 | - ) { |
|
203 | - // check if class object is instantiated |
|
204 | - // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via: |
|
205 | - // add_filter( 'FHEE_load_EE_Session', '__return_false' ); |
|
206 | - if ( |
|
207 | - ! self::$_instance instanceof EE_Session |
|
208 | - && $cache_storage instanceof CacheStorageInterface |
|
209 | - && $lifespan instanceof SessionLifespan |
|
210 | - && $request instanceof RequestInterface |
|
211 | - && $session_start_handler instanceof SessionStartHandler |
|
212 | - && apply_filters('FHEE_load_EE_Session', true) |
|
213 | - ) { |
|
214 | - self::$_instance = new self( |
|
215 | - $cache_storage, |
|
216 | - $lifespan, |
|
217 | - $request, |
|
218 | - $session_start_handler, |
|
219 | - $encryption |
|
220 | - ); |
|
221 | - } |
|
222 | - return self::$_instance; |
|
223 | - } |
|
224 | - |
|
225 | - |
|
226 | - /** |
|
227 | - * protected constructor to prevent direct creation |
|
228 | - * |
|
229 | - * @param CacheStorageInterface $cache_storage |
|
230 | - * @param SessionLifespan $lifespan |
|
231 | - * @param RequestInterface $request |
|
232 | - * @param SessionStartHandler $session_start_handler |
|
233 | - * @param EE_Encryption $encryption |
|
234 | - * @throws InvalidArgumentException |
|
235 | - * @throws InvalidDataTypeException |
|
236 | - * @throws InvalidInterfaceException |
|
237 | - */ |
|
238 | - protected function __construct( |
|
239 | - CacheStorageInterface $cache_storage, |
|
240 | - SessionLifespan $lifespan, |
|
241 | - RequestInterface $request, |
|
242 | - SessionStartHandler $session_start_handler, |
|
243 | - EE_Encryption $encryption = null |
|
244 | - ) { |
|
245 | - // session loading is turned ON by default, |
|
246 | - // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook |
|
247 | - // (which currently fires on the init hook at priority 9), |
|
248 | - // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' ); |
|
249 | - if (! apply_filters('FHEE_load_EE_Session', true)) { |
|
250 | - return; |
|
251 | - } |
|
252 | - $this->session_start_handler = $session_start_handler; |
|
253 | - $this->session_lifespan = $lifespan; |
|
254 | - $this->request = $request; |
|
255 | - if (! defined('ESPRESSO_SESSION')) { |
|
256 | - define('ESPRESSO_SESSION', true); |
|
257 | - } |
|
258 | - // retrieve session options from db |
|
259 | - $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array()); |
|
260 | - if (! empty($session_settings)) { |
|
261 | - // cycle though existing session options |
|
262 | - foreach ($session_settings as $var_name => $session_setting) { |
|
263 | - // set values for class properties |
|
264 | - $var_name = '_' . $var_name; |
|
265 | - $this->{$var_name} = $session_setting; |
|
266 | - } |
|
267 | - } |
|
268 | - $this->cache_storage = $cache_storage; |
|
269 | - // are we using encryption? |
|
270 | - $this->_use_encryption = $encryption instanceof EE_Encryption |
|
271 | - && EE_Registry::instance()->CFG->admin->encode_session_data(); |
|
272 | - // encrypt data via: $this->encryption->encrypt(); |
|
273 | - $this->encryption = $encryption; |
|
274 | - // filter hook allows outside functions/classes/plugins to change default empty cart |
|
275 | - $extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array()); |
|
276 | - array_merge($this->_default_session_vars, $extra_default_session_vars); |
|
277 | - // apply default session vars |
|
278 | - $this->_set_defaults(); |
|
279 | - add_action('AHEE__EE_System__initialize', array($this, 'open_session')); |
|
280 | - // check request for 'clear_session' param |
|
281 | - add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded')); |
|
282 | - // once everything is all said and done, |
|
283 | - add_action('shutdown', array($this, 'update'), 100); |
|
284 | - add_action('shutdown', array($this, 'garbageCollection'), 1000); |
|
285 | - $this->configure_garbage_collection_filters(); |
|
286 | - } |
|
287 | - |
|
288 | - |
|
289 | - /** |
|
290 | - * @return bool |
|
291 | - * @throws InvalidArgumentException |
|
292 | - * @throws InvalidDataTypeException |
|
293 | - * @throws InvalidInterfaceException |
|
294 | - */ |
|
295 | - public static function isLoadedAndActive() |
|
296 | - { |
|
297 | - return did_action('AHEE__EE_System__core_loaded_and_ready') |
|
298 | - && EE_Session::instance() instanceof EE_Session |
|
299 | - && EE_Session::instance()->isActive(); |
|
300 | - } |
|
301 | - |
|
302 | - |
|
303 | - /** |
|
304 | - * @return bool |
|
305 | - */ |
|
306 | - public function isActive() |
|
307 | - { |
|
308 | - return $this->status === EE_Session::STATUS_OPEN; |
|
309 | - } |
|
310 | - |
|
311 | - |
|
312 | - /** |
|
313 | - * @return void |
|
314 | - * @throws EE_Error |
|
315 | - * @throws InvalidArgumentException |
|
316 | - * @throws InvalidDataTypeException |
|
317 | - * @throws InvalidInterfaceException |
|
318 | - * @throws InvalidSessionDataException |
|
319 | - * @throws RuntimeException |
|
320 | - * @throws ReflectionException |
|
321 | - */ |
|
322 | - public function open_session() |
|
323 | - { |
|
324 | - // check for existing session and retrieve it from db |
|
325 | - if (! $this->_espresso_session()) { |
|
326 | - // or just start a new one |
|
327 | - $this->_create_espresso_session(); |
|
328 | - } |
|
329 | - } |
|
330 | - |
|
331 | - |
|
332 | - /** |
|
333 | - * @return bool |
|
334 | - */ |
|
335 | - public function expired() |
|
336 | - { |
|
337 | - return $this->_expired; |
|
338 | - } |
|
339 | - |
|
340 | - |
|
341 | - /** |
|
342 | - * @return void |
|
343 | - */ |
|
344 | - public function reset_expired() |
|
345 | - { |
|
346 | - $this->_expired = false; |
|
347 | - } |
|
348 | - |
|
349 | - |
|
350 | - /** |
|
351 | - * @return int |
|
352 | - */ |
|
353 | - public function expiration() |
|
354 | - { |
|
355 | - return $this->_expiration; |
|
356 | - } |
|
357 | - |
|
358 | - |
|
359 | - /** |
|
360 | - * @return int |
|
361 | - */ |
|
362 | - public function extension() |
|
363 | - { |
|
364 | - return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS); |
|
365 | - } |
|
366 | - |
|
367 | - |
|
368 | - /** |
|
369 | - * @param int $time number of seconds to add to session expiration |
|
370 | - */ |
|
371 | - public function extend_expiration($time = 0) |
|
372 | - { |
|
373 | - $time = $time ? $time : $this->extension(); |
|
374 | - $this->_expiration += absint($time); |
|
375 | - } |
|
376 | - |
|
377 | - |
|
378 | - /** |
|
379 | - * @return int |
|
380 | - */ |
|
381 | - public function lifespan() |
|
382 | - { |
|
383 | - return $this->session_lifespan->inSeconds(); |
|
384 | - } |
|
385 | - |
|
386 | - |
|
387 | - /** |
|
388 | - * Marks whether the session data has been updated or not. |
|
389 | - * Valid options are: |
|
390 | - * EE_Session::SAVE_STATE_CLEAN - session data remains unchanged and updating is not necessary |
|
391 | - * EE_Session::SAVE_STATE_DIRTY - session data has changed since last save and needs to be updated |
|
392 | - * default value is EE_Session::SAVE_STATE_DIRTY |
|
393 | - * |
|
394 | - * @param string $save_state |
|
395 | - */ |
|
396 | - public function setSaveState($save_state = EE_Session::SAVE_STATE_DIRTY) |
|
397 | - { |
|
398 | - $valid_save_states = [ |
|
399 | - EE_Session::SAVE_STATE_CLEAN, |
|
400 | - EE_Session::SAVE_STATE_DIRTY, |
|
401 | - ]; |
|
402 | - if (! in_array($save_state, $valid_save_states, true)) { |
|
403 | - $save_state = EE_Session::SAVE_STATE_DIRTY; |
|
404 | - } |
|
405 | - $this->save_state = $save_state; |
|
406 | - } |
|
407 | - |
|
408 | - |
|
409 | - |
|
410 | - /** |
|
411 | - * This just sets some defaults for the _session data property |
|
412 | - * |
|
413 | - * @access private |
|
414 | - * @return void |
|
415 | - */ |
|
416 | - private function _set_defaults() |
|
417 | - { |
|
418 | - // set some defaults |
|
419 | - foreach ($this->_default_session_vars as $key => $default_var) { |
|
420 | - if (is_array($default_var)) { |
|
421 | - $this->_session_data[ $key ] = array(); |
|
422 | - } else { |
|
423 | - $this->_session_data[ $key ] = ''; |
|
424 | - } |
|
425 | - } |
|
426 | - } |
|
427 | - |
|
428 | - |
|
429 | - /** |
|
430 | - * @retrieve session data |
|
431 | - * @access public |
|
432 | - * @return string |
|
433 | - */ |
|
434 | - public function id() |
|
435 | - { |
|
436 | - return $this->_sid; |
|
437 | - } |
|
438 | - |
|
439 | - |
|
440 | - /** |
|
441 | - * @param \EE_Cart $cart |
|
442 | - * @return bool |
|
443 | - */ |
|
444 | - public function set_cart(EE_Cart $cart) |
|
445 | - { |
|
446 | - $this->_session_data['cart'] = $cart; |
|
447 | - $this->setSaveState(); |
|
448 | - return true; |
|
449 | - } |
|
450 | - |
|
451 | - |
|
452 | - /** |
|
453 | - * reset_cart |
|
454 | - */ |
|
455 | - public function reset_cart() |
|
456 | - { |
|
457 | - do_action('AHEE__EE_Session__reset_cart__before_reset', $this); |
|
458 | - $this->_session_data['cart'] = null; |
|
459 | - $this->setSaveState(); |
|
460 | - } |
|
461 | - |
|
462 | - |
|
463 | - /** |
|
464 | - * @return \EE_Cart |
|
465 | - */ |
|
466 | - public function cart() |
|
467 | - { |
|
468 | - return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart |
|
469 | - ? $this->_session_data['cart'] |
|
470 | - : null; |
|
471 | - } |
|
472 | - |
|
473 | - |
|
474 | - /** |
|
475 | - * @param \EE_Checkout $checkout |
|
476 | - * @return bool |
|
477 | - */ |
|
478 | - public function set_checkout(EE_Checkout $checkout) |
|
479 | - { |
|
480 | - $this->_session_data['checkout'] = $checkout; |
|
481 | - $this->setSaveState(); |
|
482 | - return true; |
|
483 | - } |
|
484 | - |
|
485 | - |
|
486 | - /** |
|
487 | - * reset_checkout |
|
488 | - */ |
|
489 | - public function reset_checkout() |
|
490 | - { |
|
491 | - do_action('AHEE__EE_Session__reset_checkout__before_reset', $this); |
|
492 | - $this->_session_data['checkout'] = null; |
|
493 | - $this->setSaveState(); |
|
494 | - } |
|
495 | - |
|
496 | - |
|
497 | - /** |
|
498 | - * @return \EE_Checkout |
|
499 | - */ |
|
500 | - public function checkout() |
|
501 | - { |
|
502 | - return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout |
|
503 | - ? $this->_session_data['checkout'] |
|
504 | - : null; |
|
505 | - } |
|
506 | - |
|
507 | - |
|
508 | - /** |
|
509 | - * @param \EE_Transaction $transaction |
|
510 | - * @return bool |
|
511 | - * @throws EE_Error |
|
512 | - */ |
|
513 | - public function set_transaction(EE_Transaction $transaction) |
|
514 | - { |
|
515 | - // first remove the session from the transaction before we save the transaction in the session |
|
516 | - $transaction->set_txn_session_data(null); |
|
517 | - $this->_session_data['transaction'] = $transaction; |
|
518 | - $this->setSaveState(); |
|
519 | - return true; |
|
520 | - } |
|
521 | - |
|
522 | - |
|
523 | - /** |
|
524 | - * reset_transaction |
|
525 | - */ |
|
526 | - public function reset_transaction() |
|
527 | - { |
|
528 | - do_action('AHEE__EE_Session__reset_transaction__before_reset', $this); |
|
529 | - $this->_session_data['transaction'] = null; |
|
530 | - $this->setSaveState(); |
|
531 | - } |
|
532 | - |
|
533 | - |
|
534 | - /** |
|
535 | - * @return \EE_Transaction |
|
536 | - */ |
|
537 | - public function transaction() |
|
538 | - { |
|
539 | - return isset($this->_session_data['transaction']) |
|
540 | - && $this->_session_data['transaction'] instanceof EE_Transaction |
|
541 | - ? $this->_session_data['transaction'] |
|
542 | - : null; |
|
543 | - } |
|
544 | - |
|
545 | - |
|
546 | - /** |
|
547 | - * retrieve session data |
|
548 | - * |
|
549 | - * @param null $key |
|
550 | - * @param bool $reset_cache |
|
551 | - * @return array |
|
552 | - */ |
|
553 | - public function get_session_data($key = null, $reset_cache = false) |
|
554 | - { |
|
555 | - if ($reset_cache) { |
|
556 | - $this->reset_cart(); |
|
557 | - $this->reset_checkout(); |
|
558 | - $this->reset_transaction(); |
|
559 | - } |
|
560 | - if (! empty($key)) { |
|
561 | - return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null; |
|
562 | - } |
|
563 | - return $this->_session_data; |
|
564 | - } |
|
565 | - |
|
566 | - |
|
567 | - /** |
|
568 | - * Returns TRUE on success, FALSE on fail |
|
569 | - * |
|
570 | - * @param array $data |
|
571 | - * @return bool |
|
572 | - */ |
|
573 | - public function set_session_data($data) |
|
574 | - { |
|
575 | - // nothing ??? bad data ??? go home! |
|
576 | - if (empty($data) || ! is_array($data)) { |
|
577 | - EE_Error::add_error( |
|
578 | - esc_html__( |
|
579 | - 'No session data or invalid session data was provided.', |
|
580 | - 'event_espresso' |
|
581 | - ), |
|
582 | - __FILE__, |
|
583 | - __FUNCTION__, |
|
584 | - __LINE__ |
|
585 | - ); |
|
586 | - return false; |
|
587 | - } |
|
588 | - foreach ($data as $key => $value) { |
|
589 | - if (isset($this->_default_session_vars[ $key ])) { |
|
590 | - EE_Error::add_error( |
|
591 | - sprintf( |
|
592 | - esc_html__( |
|
593 | - 'Sorry! %s is a default session datum and can not be reset.', |
|
594 | - 'event_espresso' |
|
595 | - ), |
|
596 | - $key |
|
597 | - ), |
|
598 | - __FILE__, |
|
599 | - __FUNCTION__, |
|
600 | - __LINE__ |
|
601 | - ); |
|
602 | - return false; |
|
603 | - } |
|
604 | - $this->_session_data[ $key ] = $value; |
|
605 | - $this->setSaveState(); |
|
606 | - } |
|
607 | - return true; |
|
608 | - } |
|
609 | - |
|
610 | - |
|
611 | - /** |
|
612 | - * @initiate session |
|
613 | - * @access private |
|
614 | - * @return TRUE on success, FALSE on fail |
|
615 | - * @throws EE_Error |
|
616 | - * @throws InvalidArgumentException |
|
617 | - * @throws InvalidDataTypeException |
|
618 | - * @throws InvalidInterfaceException |
|
619 | - * @throws InvalidSessionDataException |
|
620 | - * @throws RuntimeException |
|
621 | - * @throws ReflectionException |
|
622 | - */ |
|
623 | - private function _espresso_session() |
|
624 | - { |
|
625 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
626 | - $this->session_start_handler->startSession(); |
|
627 | - $this->status = EE_Session::STATUS_OPEN; |
|
628 | - // get our modified session ID |
|
629 | - $this->_sid = $this->_generate_session_id(); |
|
630 | - // and the visitors IP |
|
631 | - $this->_ip_address = $this->request->ipAddress(); |
|
632 | - // set the "user agent" |
|
633 | - $this->_user_agent = $this->request->userAgent(); |
|
634 | - // now let's retrieve what's in the db |
|
635 | - $session_data = $this->_retrieve_session_data(); |
|
636 | - if (! empty($session_data)) { |
|
637 | - // get the current time in UTC |
|
638 | - $this->_time = $this->_time !== null ? $this->_time : time(); |
|
639 | - // and reset the session expiration |
|
640 | - $this->_expiration = isset($session_data['expiration']) |
|
641 | - ? $session_data['expiration'] |
|
642 | - : $this->_time + $this->session_lifespan->inSeconds(); |
|
643 | - } else { |
|
644 | - // set initial site access time and the session expiration |
|
645 | - $this->_set_init_access_and_expiration(); |
|
646 | - // set referer |
|
647 | - $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER']) |
|
648 | - ? esc_attr($_SERVER['HTTP_REFERER']) |
|
649 | - : ''; |
|
650 | - // no previous session = go back and create one (on top of the data above) |
|
651 | - return false; |
|
652 | - } |
|
653 | - // now the user agent |
|
654 | - if ($session_data['user_agent'] !== $this->_user_agent) { |
|
655 | - return false; |
|
656 | - } |
|
657 | - // wait a minute... how old are you? |
|
658 | - if ($this->_time > $this->_expiration) { |
|
659 | - // yer too old fer me! |
|
660 | - $this->_expired = true; |
|
661 | - // wipe out everything that isn't a default session datum |
|
662 | - $this->clear_session(__CLASS__, __FUNCTION__); |
|
663 | - } |
|
664 | - // make event espresso session data available to plugin |
|
665 | - $this->_session_data = array_merge($this->_session_data, $session_data); |
|
666 | - return true; |
|
667 | - } |
|
668 | - |
|
669 | - |
|
670 | - /** |
|
671 | - * _get_session_data |
|
672 | - * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup |
|
673 | - * databases |
|
674 | - * |
|
675 | - * @return array |
|
676 | - * @throws EE_Error |
|
677 | - * @throws InvalidArgumentException |
|
678 | - * @throws InvalidSessionDataException |
|
679 | - * @throws InvalidDataTypeException |
|
680 | - * @throws InvalidInterfaceException |
|
681 | - * @throws RuntimeException |
|
682 | - */ |
|
683 | - protected function _retrieve_session_data() |
|
684 | - { |
|
685 | - $ssn_key = EE_Session::session_id_prefix . $this->_sid; |
|
686 | - try { |
|
687 | - // we're using WP's Transient API to store session data using the PHP session ID as the option name |
|
688 | - $session_data = $this->cache_storage->get($ssn_key, false); |
|
689 | - if (empty($session_data)) { |
|
690 | - return array(); |
|
691 | - } |
|
692 | - if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
693 | - $hash_check = $this->cache_storage->get( |
|
694 | - EE_Session::hash_check_prefix . $this->_sid, |
|
695 | - false |
|
696 | - ); |
|
697 | - if ($hash_check && $hash_check !== md5($session_data)) { |
|
698 | - EE_Error::add_error( |
|
699 | - sprintf( |
|
700 | - __( |
|
701 | - 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.', |
|
702 | - 'event_espresso' |
|
703 | - ), |
|
704 | - EE_Session::session_id_prefix . $this->_sid |
|
705 | - ), |
|
706 | - __FILE__, |
|
707 | - __FUNCTION__, |
|
708 | - __LINE__ |
|
709 | - ); |
|
710 | - } |
|
711 | - } |
|
712 | - } catch (Exception $e) { |
|
713 | - // let's just eat that error for now and attempt to correct any corrupted data |
|
714 | - global $wpdb; |
|
715 | - $row = $wpdb->get_row( |
|
716 | - $wpdb->prepare( |
|
717 | - "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", |
|
718 | - '_transient_' . $ssn_key |
|
719 | - ) |
|
720 | - ); |
|
721 | - $session_data = is_object($row) ? $row->option_value : null; |
|
722 | - if ($session_data) { |
|
723 | - $session_data = preg_replace_callback( |
|
724 | - '!s:(d+):"(.*?)";!', |
|
725 | - function ($match) { |
|
726 | - return $match[1] === strlen($match[2]) |
|
727 | - ? $match[0] |
|
728 | - : 's:' . strlen($match[2]) . ':"' . $match[2] . '";'; |
|
729 | - }, |
|
730 | - $session_data |
|
731 | - ); |
|
732 | - } |
|
733 | - $session_data = maybe_unserialize($session_data); |
|
734 | - } |
|
735 | - // in case the data is encoded... try to decode it |
|
736 | - $session_data = $this->encryption instanceof EE_Encryption |
|
737 | - ? $this->encryption->base64_string_decode($session_data) |
|
738 | - : $session_data; |
|
739 | - if (! is_array($session_data)) { |
|
740 | - try { |
|
741 | - $session_data = maybe_unserialize($session_data); |
|
742 | - } catch (Exception $e) { |
|
743 | - $msg = esc_html__( |
|
744 | - 'An error occurred while attempting to unserialize the session data.', |
|
745 | - 'event_espresso' |
|
746 | - ); |
|
747 | - $msg .= WP_DEBUG |
|
748 | - ? '<br><pre>' |
|
749 | - . print_r($session_data, true) |
|
750 | - . '</pre><br>' |
|
751 | - . $this->find_serialize_error($session_data) |
|
752 | - : ''; |
|
753 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
754 | - throw new InvalidSessionDataException($msg, 0, $e); |
|
755 | - } |
|
756 | - } |
|
757 | - // just a check to make sure the session array is indeed an array |
|
758 | - if (! is_array($session_data)) { |
|
759 | - // no?!?! then something is wrong |
|
760 | - $msg = esc_html__( |
|
761 | - 'The session data is missing, invalid, or corrupted.', |
|
762 | - 'event_espresso' |
|
763 | - ); |
|
764 | - $msg .= WP_DEBUG |
|
765 | - ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data) |
|
766 | - : ''; |
|
767 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
768 | - throw new InvalidSessionDataException($msg); |
|
769 | - } |
|
770 | - if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) { |
|
771 | - $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID( |
|
772 | - $session_data['transaction'] |
|
773 | - ); |
|
774 | - } |
|
775 | - return $session_data; |
|
776 | - } |
|
777 | - |
|
778 | - |
|
779 | - /** |
|
780 | - * _generate_session_id |
|
781 | - * Retrieves the PHP session id either directly from the PHP session, |
|
782 | - * or from the $_REQUEST array if it was passed in from an AJAX request. |
|
783 | - * The session id is then salted and hashed (mmm sounds tasty) |
|
784 | - * so that it can be safely used as a $_REQUEST param |
|
785 | - * |
|
786 | - * @return string |
|
787 | - */ |
|
788 | - protected function _generate_session_id() |
|
789 | - { |
|
790 | - // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length |
|
791 | - if (isset($_REQUEST['EESID'])) { |
|
792 | - $session_id = sanitize_text_field($_REQUEST['EESID']); |
|
793 | - } else { |
|
794 | - $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt()); |
|
795 | - } |
|
796 | - return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id); |
|
797 | - } |
|
798 | - |
|
799 | - |
|
800 | - /** |
|
801 | - * _get_sid_salt |
|
802 | - * |
|
803 | - * @return string |
|
804 | - */ |
|
805 | - protected function _get_sid_salt() |
|
806 | - { |
|
807 | - // was session id salt already saved to db ? |
|
808 | - if (empty($this->_sid_salt)) { |
|
809 | - // no? then maybe use WP defined constant |
|
810 | - if (defined('AUTH_SALT')) { |
|
811 | - $this->_sid_salt = AUTH_SALT; |
|
812 | - } |
|
813 | - // if salt doesn't exist or is too short |
|
814 | - if (strlen($this->_sid_salt) < 32) { |
|
815 | - // create a new one |
|
816 | - $this->_sid_salt = wp_generate_password(64); |
|
817 | - } |
|
818 | - // and save it as a permanent session setting |
|
819 | - $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt)); |
|
820 | - } |
|
821 | - return $this->_sid_salt; |
|
822 | - } |
|
823 | - |
|
824 | - |
|
825 | - /** |
|
826 | - * _set_init_access_and_expiration |
|
827 | - * |
|
828 | - * @return void |
|
829 | - */ |
|
830 | - protected function _set_init_access_and_expiration() |
|
831 | - { |
|
832 | - $this->_time = time(); |
|
833 | - $this->_expiration = $this->_time + $this->session_lifespan->inSeconds(); |
|
834 | - // set initial site access time |
|
835 | - $this->_session_data['init_access'] = $this->_time; |
|
836 | - // and the session expiration |
|
837 | - $this->_session_data['expiration'] = $this->_expiration; |
|
838 | - } |
|
839 | - |
|
840 | - |
|
841 | - /** |
|
842 | - * @update session data prior to saving to the db |
|
843 | - * @access public |
|
844 | - * @param bool $new_session |
|
845 | - * @return TRUE on success, FALSE on fail |
|
846 | - * @throws EE_Error |
|
847 | - * @throws InvalidArgumentException |
|
848 | - * @throws InvalidDataTypeException |
|
849 | - * @throws InvalidInterfaceException |
|
850 | - * @throws ReflectionException |
|
851 | - */ |
|
852 | - public function update($new_session = false) |
|
853 | - { |
|
854 | - $this->_session_data = $this->_session_data !== null |
|
855 | - && is_array($this->_session_data) |
|
856 | - && isset($this->_session_data['id']) |
|
857 | - ? $this->_session_data |
|
858 | - : array(); |
|
859 | - if (empty($this->_session_data)) { |
|
860 | - $this->_set_defaults(); |
|
861 | - } |
|
862 | - $session_data = array(); |
|
863 | - foreach ($this->_session_data as $key => $value) { |
|
864 | - switch ($key) { |
|
865 | - case 'id': |
|
866 | - // session ID |
|
867 | - $session_data['id'] = $this->_sid; |
|
868 | - break; |
|
869 | - case 'ip_address': |
|
870 | - // visitor ip address |
|
871 | - $session_data['ip_address'] = $this->request->ipAddress(); |
|
872 | - break; |
|
873 | - case 'user_agent': |
|
874 | - // visitor user_agent |
|
875 | - $session_data['user_agent'] = $this->_user_agent; |
|
876 | - break; |
|
877 | - case 'init_access': |
|
878 | - $session_data['init_access'] = absint($value); |
|
879 | - break; |
|
880 | - case 'last_access': |
|
881 | - // current access time |
|
882 | - $session_data['last_access'] = $this->_time; |
|
883 | - break; |
|
884 | - case 'expiration': |
|
885 | - // when the session expires |
|
886 | - $session_data['expiration'] = ! empty($this->_expiration) |
|
887 | - ? $this->_expiration |
|
888 | - : $session_data['init_access'] + $this->session_lifespan->inSeconds(); |
|
889 | - break; |
|
890 | - case 'user_id': |
|
891 | - // current user if logged in |
|
892 | - $session_data['user_id'] = $this->_wp_user_id(); |
|
893 | - break; |
|
894 | - case 'pages_visited': |
|
895 | - $page_visit = $this->_get_page_visit(); |
|
896 | - if ($page_visit) { |
|
897 | - // set pages visited where the first will be the http referrer |
|
898 | - $this->_session_data['pages_visited'][ $this->_time ] = $page_visit; |
|
899 | - // we'll only save the last 10 page visits. |
|
900 | - $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10); |
|
901 | - } |
|
902 | - break; |
|
903 | - default: |
|
904 | - // carry any other data over |
|
905 | - $session_data[ $key ] = $this->_session_data[ $key ]; |
|
906 | - } |
|
907 | - } |
|
908 | - $this->_session_data = $session_data; |
|
909 | - // creating a new session does not require saving to the db just yet |
|
910 | - if (! $new_session) { |
|
911 | - // ready? let's save |
|
912 | - if ($this->_save_session_to_db()) { |
|
913 | - return true; |
|
914 | - } |
|
915 | - return false; |
|
916 | - } |
|
917 | - // meh, why not? |
|
918 | - return true; |
|
919 | - } |
|
920 | - |
|
921 | - |
|
922 | - /** |
|
923 | - * @create session data array |
|
924 | - * @access public |
|
925 | - * @return bool |
|
926 | - * @throws EE_Error |
|
927 | - * @throws InvalidArgumentException |
|
928 | - * @throws InvalidDataTypeException |
|
929 | - * @throws InvalidInterfaceException |
|
930 | - * @throws ReflectionException |
|
931 | - */ |
|
932 | - private function _create_espresso_session() |
|
933 | - { |
|
934 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, ''); |
|
935 | - // use the update function for now with $new_session arg set to TRUE |
|
936 | - return $this->update(true) ? true : false; |
|
937 | - } |
|
938 | - |
|
939 | - /** |
|
940 | - * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good |
|
941 | - * too). This is used when determining if we want to save the session or not. |
|
942 | - * @since 4.9.67.p |
|
943 | - * @return bool |
|
944 | - */ |
|
945 | - private function sessionHasStuffWorthSaving() |
|
946 | - { |
|
947 | - return $this->save_state === EE_Session::SAVE_STATE_DIRTY |
|
948 | - // we may want to eventually remove the following |
|
949 | - // on the assumption that the above check is enough |
|
950 | - || $this->cart() instanceof EE_Cart |
|
951 | - || ( |
|
952 | - isset($this->_session_data['ee_notices']) |
|
953 | - && ( |
|
954 | - ! empty($this->_session_data['ee_notices']['attention']) |
|
955 | - || ! empty($this->_session_data['ee_notices']['errors']) |
|
956 | - || ! empty($this->_session_data['ee_notices']['success']) |
|
957 | - ) |
|
958 | - ); |
|
959 | - } |
|
960 | - |
|
961 | - |
|
962 | - /** |
|
963 | - * _save_session_to_db |
|
964 | - * |
|
965 | - * @param bool $clear_session |
|
966 | - * @return string |
|
967 | - * @throws EE_Error |
|
968 | - * @throws InvalidArgumentException |
|
969 | - * @throws InvalidDataTypeException |
|
970 | - * @throws InvalidInterfaceException |
|
971 | - * @throws ReflectionException |
|
972 | - */ |
|
973 | - private function _save_session_to_db($clear_session = false) |
|
974 | - { |
|
975 | - // don't save sessions for crawlers |
|
976 | - // and unless we're deleting the session data, don't save anything if there isn't a cart |
|
977 | - if ( |
|
978 | - $this->request->isBot() |
|
979 | - || ( |
|
980 | - ! $clear_session |
|
981 | - && ! $this->sessionHasStuffWorthSaving() |
|
982 | - && apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true) |
|
983 | - ) |
|
984 | - ) { |
|
985 | - return false; |
|
986 | - } |
|
987 | - $transaction = $this->transaction(); |
|
988 | - if ($transaction instanceof EE_Transaction) { |
|
989 | - if (! $transaction->ID()) { |
|
990 | - $transaction->save(); |
|
991 | - } |
|
992 | - $this->_session_data['transaction'] = $transaction->ID(); |
|
993 | - } |
|
994 | - // then serialize all of our session data |
|
995 | - $session_data = serialize($this->_session_data); |
|
996 | - // do we need to also encode it to avoid corrupted data when saved to the db? |
|
997 | - $session_data = $this->_use_encryption |
|
998 | - ? $this->encryption->base64_string_encode($session_data) |
|
999 | - : $session_data; |
|
1000 | - // maybe save hash check |
|
1001 | - if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
1002 | - $this->cache_storage->add( |
|
1003 | - EE_Session::hash_check_prefix . $this->_sid, |
|
1004 | - md5($session_data), |
|
1005 | - $this->session_lifespan->inSeconds() |
|
1006 | - ); |
|
1007 | - } |
|
1008 | - // we're using the Transient API for storing session data, |
|
1009 | - $saved = $this->cache_storage->add( |
|
1010 | - EE_Session::session_id_prefix . $this->_sid, |
|
1011 | - $session_data, |
|
1012 | - $this->session_lifespan->inSeconds() |
|
1013 | - ); |
|
1014 | - $this->setSaveState(EE_Session::SAVE_STATE_CLEAN); |
|
1015 | - return $saved; |
|
1016 | - } |
|
1017 | - |
|
1018 | - |
|
1019 | - /** |
|
1020 | - * @get the full page request the visitor is accessing |
|
1021 | - * @access public |
|
1022 | - * @return string |
|
1023 | - */ |
|
1024 | - public function _get_page_visit() |
|
1025 | - { |
|
1026 | - $page_visit = home_url('/') . 'wp-admin/admin-ajax.php'; |
|
1027 | - // check for request url |
|
1028 | - if (isset($_SERVER['REQUEST_URI'])) { |
|
1029 | - $http_host = ''; |
|
1030 | - $page_id = '?'; |
|
1031 | - $e_reg = ''; |
|
1032 | - $request_uri = esc_url($_SERVER['REQUEST_URI']); |
|
1033 | - $ru_bits = explode('?', $request_uri); |
|
1034 | - $request_uri = $ru_bits[0]; |
|
1035 | - // check for and grab host as well |
|
1036 | - if (isset($_SERVER['HTTP_HOST'])) { |
|
1037 | - $http_host = esc_url($_SERVER['HTTP_HOST']); |
|
1038 | - } |
|
1039 | - // check for page_id in SERVER REQUEST |
|
1040 | - if (isset($_REQUEST['page_id'])) { |
|
1041 | - // rebuild $e_reg without any of the extra parameters |
|
1042 | - $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&'; |
|
1043 | - } |
|
1044 | - // check for $e_reg in SERVER REQUEST |
|
1045 | - if (isset($_REQUEST['ee'])) { |
|
1046 | - // rebuild $e_reg without any of the extra parameters |
|
1047 | - $e_reg = 'ee=' . esc_attr($_REQUEST['ee']); |
|
1048 | - } |
|
1049 | - $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?'); |
|
1050 | - } |
|
1051 | - return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : ''; |
|
1052 | - } |
|
1053 | - |
|
1054 | - |
|
1055 | - /** |
|
1056 | - * @the current wp user id |
|
1057 | - * @access public |
|
1058 | - * @return int |
|
1059 | - */ |
|
1060 | - public function _wp_user_id() |
|
1061 | - { |
|
1062 | - // if I need to explain the following lines of code, then you shouldn't be looking at this! |
|
1063 | - $this->_wp_user_id = get_current_user_id(); |
|
1064 | - return $this->_wp_user_id; |
|
1065 | - } |
|
1066 | - |
|
1067 | - |
|
1068 | - /** |
|
1069 | - * Clear EE_Session data |
|
1070 | - * |
|
1071 | - * @access public |
|
1072 | - * @param string $class |
|
1073 | - * @param string $function |
|
1074 | - * @return void |
|
1075 | - * @throws EE_Error |
|
1076 | - * @throws InvalidArgumentException |
|
1077 | - * @throws InvalidDataTypeException |
|
1078 | - * @throws InvalidInterfaceException |
|
1079 | - * @throws ReflectionException |
|
1080 | - */ |
|
1081 | - public function clear_session($class = '', $function = '') |
|
1082 | - { |
|
27 | + const session_id_prefix = 'ee_ssn_'; |
|
28 | + |
|
29 | + const hash_check_prefix = 'ee_shc_'; |
|
30 | + |
|
31 | + const OPTION_NAME_SETTINGS = 'ee_session_settings'; |
|
32 | + |
|
33 | + const STATUS_CLOSED = 0; |
|
34 | + |
|
35 | + const STATUS_OPEN = 1; |
|
36 | + |
|
37 | + const SAVE_STATE_CLEAN = 'clean'; |
|
38 | + const SAVE_STATE_DIRTY = 'dirty'; |
|
39 | + |
|
40 | + |
|
41 | + /** |
|
42 | + * instance of the EE_Session object |
|
43 | + * |
|
44 | + * @var EE_Session |
|
45 | + */ |
|
46 | + private static $_instance; |
|
47 | + |
|
48 | + /** |
|
49 | + * @var CacheStorageInterface $cache_storage |
|
50 | + */ |
|
51 | + protected $cache_storage; |
|
52 | + |
|
53 | + /** |
|
54 | + * @var EE_Encryption $encryption |
|
55 | + */ |
|
56 | + protected $encryption; |
|
57 | + |
|
58 | + /** |
|
59 | + * @var SessionStartHandler $session_start_handler |
|
60 | + */ |
|
61 | + protected $session_start_handler; |
|
62 | + |
|
63 | + /** |
|
64 | + * the session id |
|
65 | + * |
|
66 | + * @var string |
|
67 | + */ |
|
68 | + private $_sid; |
|
69 | + |
|
70 | + /** |
|
71 | + * session id salt |
|
72 | + * |
|
73 | + * @var string |
|
74 | + */ |
|
75 | + private $_sid_salt; |
|
76 | + |
|
77 | + /** |
|
78 | + * session data |
|
79 | + * |
|
80 | + * @var array |
|
81 | + */ |
|
82 | + private $_session_data = array(); |
|
83 | + |
|
84 | + /** |
|
85 | + * how long an EE session lasts |
|
86 | + * default session lifespan of 1 hour (for not so instant IPNs) |
|
87 | + * |
|
88 | + * @var SessionLifespan $session_lifespan |
|
89 | + */ |
|
90 | + private $session_lifespan; |
|
91 | + |
|
92 | + /** |
|
93 | + * session expiration time as Unix timestamp in GMT |
|
94 | + * |
|
95 | + * @var int |
|
96 | + */ |
|
97 | + private $_expiration; |
|
98 | + |
|
99 | + /** |
|
100 | + * whether or not session has expired at some point |
|
101 | + * |
|
102 | + * @var boolean |
|
103 | + */ |
|
104 | + private $_expired = false; |
|
105 | + |
|
106 | + /** |
|
107 | + * current time as Unix timestamp in GMT |
|
108 | + * |
|
109 | + * @var int |
|
110 | + */ |
|
111 | + private $_time; |
|
112 | + |
|
113 | + /** |
|
114 | + * whether to encrypt session data |
|
115 | + * |
|
116 | + * @var bool |
|
117 | + */ |
|
118 | + private $_use_encryption; |
|
119 | + |
|
120 | + /** |
|
121 | + * well... according to the server... |
|
122 | + * |
|
123 | + * @var null |
|
124 | + */ |
|
125 | + private $_user_agent; |
|
126 | + |
|
127 | + /** |
|
128 | + * do you really trust the server ? |
|
129 | + * |
|
130 | + * @var null |
|
131 | + */ |
|
132 | + private $_ip_address; |
|
133 | + |
|
134 | + /** |
|
135 | + * current WP user_id |
|
136 | + * |
|
137 | + * @var null |
|
138 | + */ |
|
139 | + private $_wp_user_id; |
|
140 | + |
|
141 | + /** |
|
142 | + * array for defining default session vars |
|
143 | + * |
|
144 | + * @var array |
|
145 | + */ |
|
146 | + private $_default_session_vars = array( |
|
147 | + 'id' => null, |
|
148 | + 'user_id' => null, |
|
149 | + 'ip_address' => null, |
|
150 | + 'user_agent' => null, |
|
151 | + 'init_access' => null, |
|
152 | + 'last_access' => null, |
|
153 | + 'expiration' => null, |
|
154 | + 'pages_visited' => array(), |
|
155 | + ); |
|
156 | + |
|
157 | + /** |
|
158 | + * timestamp for when last garbage collection cycle was performed |
|
159 | + * |
|
160 | + * @var int $_last_gc |
|
161 | + */ |
|
162 | + private $_last_gc; |
|
163 | + |
|
164 | + /** |
|
165 | + * @var RequestInterface $request |
|
166 | + */ |
|
167 | + protected $request; |
|
168 | + |
|
169 | + /** |
|
170 | + * whether session is active or not |
|
171 | + * |
|
172 | + * @var int $status |
|
173 | + */ |
|
174 | + private $status = EE_Session::STATUS_CLOSED; |
|
175 | + |
|
176 | + /** |
|
177 | + * whether session data has changed therefore requiring a session save |
|
178 | + * |
|
179 | + * @var string $save_state |
|
180 | + */ |
|
181 | + private $save_state = EE_Session::SAVE_STATE_CLEAN; |
|
182 | + |
|
183 | + |
|
184 | + /** |
|
185 | + * @singleton method used to instantiate class object |
|
186 | + * @param CacheStorageInterface $cache_storage |
|
187 | + * @param SessionLifespan|null $lifespan |
|
188 | + * @param RequestInterface $request |
|
189 | + * @param SessionStartHandler $session_start_handler |
|
190 | + * @param EE_Encryption $encryption |
|
191 | + * @return EE_Session |
|
192 | + * @throws InvalidArgumentException |
|
193 | + * @throws InvalidDataTypeException |
|
194 | + * @throws InvalidInterfaceException |
|
195 | + */ |
|
196 | + public static function instance( |
|
197 | + CacheStorageInterface $cache_storage = null, |
|
198 | + SessionLifespan $lifespan = null, |
|
199 | + RequestInterface $request = null, |
|
200 | + SessionStartHandler $session_start_handler = null, |
|
201 | + EE_Encryption $encryption = null |
|
202 | + ) { |
|
203 | + // check if class object is instantiated |
|
204 | + // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via: |
|
205 | + // add_filter( 'FHEE_load_EE_Session', '__return_false' ); |
|
206 | + if ( |
|
207 | + ! self::$_instance instanceof EE_Session |
|
208 | + && $cache_storage instanceof CacheStorageInterface |
|
209 | + && $lifespan instanceof SessionLifespan |
|
210 | + && $request instanceof RequestInterface |
|
211 | + && $session_start_handler instanceof SessionStartHandler |
|
212 | + && apply_filters('FHEE_load_EE_Session', true) |
|
213 | + ) { |
|
214 | + self::$_instance = new self( |
|
215 | + $cache_storage, |
|
216 | + $lifespan, |
|
217 | + $request, |
|
218 | + $session_start_handler, |
|
219 | + $encryption |
|
220 | + ); |
|
221 | + } |
|
222 | + return self::$_instance; |
|
223 | + } |
|
224 | + |
|
225 | + |
|
226 | + /** |
|
227 | + * protected constructor to prevent direct creation |
|
228 | + * |
|
229 | + * @param CacheStorageInterface $cache_storage |
|
230 | + * @param SessionLifespan $lifespan |
|
231 | + * @param RequestInterface $request |
|
232 | + * @param SessionStartHandler $session_start_handler |
|
233 | + * @param EE_Encryption $encryption |
|
234 | + * @throws InvalidArgumentException |
|
235 | + * @throws InvalidDataTypeException |
|
236 | + * @throws InvalidInterfaceException |
|
237 | + */ |
|
238 | + protected function __construct( |
|
239 | + CacheStorageInterface $cache_storage, |
|
240 | + SessionLifespan $lifespan, |
|
241 | + RequestInterface $request, |
|
242 | + SessionStartHandler $session_start_handler, |
|
243 | + EE_Encryption $encryption = null |
|
244 | + ) { |
|
245 | + // session loading is turned ON by default, |
|
246 | + // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook |
|
247 | + // (which currently fires on the init hook at priority 9), |
|
248 | + // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' ); |
|
249 | + if (! apply_filters('FHEE_load_EE_Session', true)) { |
|
250 | + return; |
|
251 | + } |
|
252 | + $this->session_start_handler = $session_start_handler; |
|
253 | + $this->session_lifespan = $lifespan; |
|
254 | + $this->request = $request; |
|
255 | + if (! defined('ESPRESSO_SESSION')) { |
|
256 | + define('ESPRESSO_SESSION', true); |
|
257 | + } |
|
258 | + // retrieve session options from db |
|
259 | + $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array()); |
|
260 | + if (! empty($session_settings)) { |
|
261 | + // cycle though existing session options |
|
262 | + foreach ($session_settings as $var_name => $session_setting) { |
|
263 | + // set values for class properties |
|
264 | + $var_name = '_' . $var_name; |
|
265 | + $this->{$var_name} = $session_setting; |
|
266 | + } |
|
267 | + } |
|
268 | + $this->cache_storage = $cache_storage; |
|
269 | + // are we using encryption? |
|
270 | + $this->_use_encryption = $encryption instanceof EE_Encryption |
|
271 | + && EE_Registry::instance()->CFG->admin->encode_session_data(); |
|
272 | + // encrypt data via: $this->encryption->encrypt(); |
|
273 | + $this->encryption = $encryption; |
|
274 | + // filter hook allows outside functions/classes/plugins to change default empty cart |
|
275 | + $extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array()); |
|
276 | + array_merge($this->_default_session_vars, $extra_default_session_vars); |
|
277 | + // apply default session vars |
|
278 | + $this->_set_defaults(); |
|
279 | + add_action('AHEE__EE_System__initialize', array($this, 'open_session')); |
|
280 | + // check request for 'clear_session' param |
|
281 | + add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded')); |
|
282 | + // once everything is all said and done, |
|
283 | + add_action('shutdown', array($this, 'update'), 100); |
|
284 | + add_action('shutdown', array($this, 'garbageCollection'), 1000); |
|
285 | + $this->configure_garbage_collection_filters(); |
|
286 | + } |
|
287 | + |
|
288 | + |
|
289 | + /** |
|
290 | + * @return bool |
|
291 | + * @throws InvalidArgumentException |
|
292 | + * @throws InvalidDataTypeException |
|
293 | + * @throws InvalidInterfaceException |
|
294 | + */ |
|
295 | + public static function isLoadedAndActive() |
|
296 | + { |
|
297 | + return did_action('AHEE__EE_System__core_loaded_and_ready') |
|
298 | + && EE_Session::instance() instanceof EE_Session |
|
299 | + && EE_Session::instance()->isActive(); |
|
300 | + } |
|
301 | + |
|
302 | + |
|
303 | + /** |
|
304 | + * @return bool |
|
305 | + */ |
|
306 | + public function isActive() |
|
307 | + { |
|
308 | + return $this->status === EE_Session::STATUS_OPEN; |
|
309 | + } |
|
310 | + |
|
311 | + |
|
312 | + /** |
|
313 | + * @return void |
|
314 | + * @throws EE_Error |
|
315 | + * @throws InvalidArgumentException |
|
316 | + * @throws InvalidDataTypeException |
|
317 | + * @throws InvalidInterfaceException |
|
318 | + * @throws InvalidSessionDataException |
|
319 | + * @throws RuntimeException |
|
320 | + * @throws ReflectionException |
|
321 | + */ |
|
322 | + public function open_session() |
|
323 | + { |
|
324 | + // check for existing session and retrieve it from db |
|
325 | + if (! $this->_espresso_session()) { |
|
326 | + // or just start a new one |
|
327 | + $this->_create_espresso_session(); |
|
328 | + } |
|
329 | + } |
|
330 | + |
|
331 | + |
|
332 | + /** |
|
333 | + * @return bool |
|
334 | + */ |
|
335 | + public function expired() |
|
336 | + { |
|
337 | + return $this->_expired; |
|
338 | + } |
|
339 | + |
|
340 | + |
|
341 | + /** |
|
342 | + * @return void |
|
343 | + */ |
|
344 | + public function reset_expired() |
|
345 | + { |
|
346 | + $this->_expired = false; |
|
347 | + } |
|
348 | + |
|
349 | + |
|
350 | + /** |
|
351 | + * @return int |
|
352 | + */ |
|
353 | + public function expiration() |
|
354 | + { |
|
355 | + return $this->_expiration; |
|
356 | + } |
|
357 | + |
|
358 | + |
|
359 | + /** |
|
360 | + * @return int |
|
361 | + */ |
|
362 | + public function extension() |
|
363 | + { |
|
364 | + return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS); |
|
365 | + } |
|
366 | + |
|
367 | + |
|
368 | + /** |
|
369 | + * @param int $time number of seconds to add to session expiration |
|
370 | + */ |
|
371 | + public function extend_expiration($time = 0) |
|
372 | + { |
|
373 | + $time = $time ? $time : $this->extension(); |
|
374 | + $this->_expiration += absint($time); |
|
375 | + } |
|
376 | + |
|
377 | + |
|
378 | + /** |
|
379 | + * @return int |
|
380 | + */ |
|
381 | + public function lifespan() |
|
382 | + { |
|
383 | + return $this->session_lifespan->inSeconds(); |
|
384 | + } |
|
385 | + |
|
386 | + |
|
387 | + /** |
|
388 | + * Marks whether the session data has been updated or not. |
|
389 | + * Valid options are: |
|
390 | + * EE_Session::SAVE_STATE_CLEAN - session data remains unchanged and updating is not necessary |
|
391 | + * EE_Session::SAVE_STATE_DIRTY - session data has changed since last save and needs to be updated |
|
392 | + * default value is EE_Session::SAVE_STATE_DIRTY |
|
393 | + * |
|
394 | + * @param string $save_state |
|
395 | + */ |
|
396 | + public function setSaveState($save_state = EE_Session::SAVE_STATE_DIRTY) |
|
397 | + { |
|
398 | + $valid_save_states = [ |
|
399 | + EE_Session::SAVE_STATE_CLEAN, |
|
400 | + EE_Session::SAVE_STATE_DIRTY, |
|
401 | + ]; |
|
402 | + if (! in_array($save_state, $valid_save_states, true)) { |
|
403 | + $save_state = EE_Session::SAVE_STATE_DIRTY; |
|
404 | + } |
|
405 | + $this->save_state = $save_state; |
|
406 | + } |
|
407 | + |
|
408 | + |
|
409 | + |
|
410 | + /** |
|
411 | + * This just sets some defaults for the _session data property |
|
412 | + * |
|
413 | + * @access private |
|
414 | + * @return void |
|
415 | + */ |
|
416 | + private function _set_defaults() |
|
417 | + { |
|
418 | + // set some defaults |
|
419 | + foreach ($this->_default_session_vars as $key => $default_var) { |
|
420 | + if (is_array($default_var)) { |
|
421 | + $this->_session_data[ $key ] = array(); |
|
422 | + } else { |
|
423 | + $this->_session_data[ $key ] = ''; |
|
424 | + } |
|
425 | + } |
|
426 | + } |
|
427 | + |
|
428 | + |
|
429 | + /** |
|
430 | + * @retrieve session data |
|
431 | + * @access public |
|
432 | + * @return string |
|
433 | + */ |
|
434 | + public function id() |
|
435 | + { |
|
436 | + return $this->_sid; |
|
437 | + } |
|
438 | + |
|
439 | + |
|
440 | + /** |
|
441 | + * @param \EE_Cart $cart |
|
442 | + * @return bool |
|
443 | + */ |
|
444 | + public function set_cart(EE_Cart $cart) |
|
445 | + { |
|
446 | + $this->_session_data['cart'] = $cart; |
|
447 | + $this->setSaveState(); |
|
448 | + return true; |
|
449 | + } |
|
450 | + |
|
451 | + |
|
452 | + /** |
|
453 | + * reset_cart |
|
454 | + */ |
|
455 | + public function reset_cart() |
|
456 | + { |
|
457 | + do_action('AHEE__EE_Session__reset_cart__before_reset', $this); |
|
458 | + $this->_session_data['cart'] = null; |
|
459 | + $this->setSaveState(); |
|
460 | + } |
|
461 | + |
|
462 | + |
|
463 | + /** |
|
464 | + * @return \EE_Cart |
|
465 | + */ |
|
466 | + public function cart() |
|
467 | + { |
|
468 | + return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart |
|
469 | + ? $this->_session_data['cart'] |
|
470 | + : null; |
|
471 | + } |
|
472 | + |
|
473 | + |
|
474 | + /** |
|
475 | + * @param \EE_Checkout $checkout |
|
476 | + * @return bool |
|
477 | + */ |
|
478 | + public function set_checkout(EE_Checkout $checkout) |
|
479 | + { |
|
480 | + $this->_session_data['checkout'] = $checkout; |
|
481 | + $this->setSaveState(); |
|
482 | + return true; |
|
483 | + } |
|
484 | + |
|
485 | + |
|
486 | + /** |
|
487 | + * reset_checkout |
|
488 | + */ |
|
489 | + public function reset_checkout() |
|
490 | + { |
|
491 | + do_action('AHEE__EE_Session__reset_checkout__before_reset', $this); |
|
492 | + $this->_session_data['checkout'] = null; |
|
493 | + $this->setSaveState(); |
|
494 | + } |
|
495 | + |
|
496 | + |
|
497 | + /** |
|
498 | + * @return \EE_Checkout |
|
499 | + */ |
|
500 | + public function checkout() |
|
501 | + { |
|
502 | + return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout |
|
503 | + ? $this->_session_data['checkout'] |
|
504 | + : null; |
|
505 | + } |
|
506 | + |
|
507 | + |
|
508 | + /** |
|
509 | + * @param \EE_Transaction $transaction |
|
510 | + * @return bool |
|
511 | + * @throws EE_Error |
|
512 | + */ |
|
513 | + public function set_transaction(EE_Transaction $transaction) |
|
514 | + { |
|
515 | + // first remove the session from the transaction before we save the transaction in the session |
|
516 | + $transaction->set_txn_session_data(null); |
|
517 | + $this->_session_data['transaction'] = $transaction; |
|
518 | + $this->setSaveState(); |
|
519 | + return true; |
|
520 | + } |
|
521 | + |
|
522 | + |
|
523 | + /** |
|
524 | + * reset_transaction |
|
525 | + */ |
|
526 | + public function reset_transaction() |
|
527 | + { |
|
528 | + do_action('AHEE__EE_Session__reset_transaction__before_reset', $this); |
|
529 | + $this->_session_data['transaction'] = null; |
|
530 | + $this->setSaveState(); |
|
531 | + } |
|
532 | + |
|
533 | + |
|
534 | + /** |
|
535 | + * @return \EE_Transaction |
|
536 | + */ |
|
537 | + public function transaction() |
|
538 | + { |
|
539 | + return isset($this->_session_data['transaction']) |
|
540 | + && $this->_session_data['transaction'] instanceof EE_Transaction |
|
541 | + ? $this->_session_data['transaction'] |
|
542 | + : null; |
|
543 | + } |
|
544 | + |
|
545 | + |
|
546 | + /** |
|
547 | + * retrieve session data |
|
548 | + * |
|
549 | + * @param null $key |
|
550 | + * @param bool $reset_cache |
|
551 | + * @return array |
|
552 | + */ |
|
553 | + public function get_session_data($key = null, $reset_cache = false) |
|
554 | + { |
|
555 | + if ($reset_cache) { |
|
556 | + $this->reset_cart(); |
|
557 | + $this->reset_checkout(); |
|
558 | + $this->reset_transaction(); |
|
559 | + } |
|
560 | + if (! empty($key)) { |
|
561 | + return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null; |
|
562 | + } |
|
563 | + return $this->_session_data; |
|
564 | + } |
|
565 | + |
|
566 | + |
|
567 | + /** |
|
568 | + * Returns TRUE on success, FALSE on fail |
|
569 | + * |
|
570 | + * @param array $data |
|
571 | + * @return bool |
|
572 | + */ |
|
573 | + public function set_session_data($data) |
|
574 | + { |
|
575 | + // nothing ??? bad data ??? go home! |
|
576 | + if (empty($data) || ! is_array($data)) { |
|
577 | + EE_Error::add_error( |
|
578 | + esc_html__( |
|
579 | + 'No session data or invalid session data was provided.', |
|
580 | + 'event_espresso' |
|
581 | + ), |
|
582 | + __FILE__, |
|
583 | + __FUNCTION__, |
|
584 | + __LINE__ |
|
585 | + ); |
|
586 | + return false; |
|
587 | + } |
|
588 | + foreach ($data as $key => $value) { |
|
589 | + if (isset($this->_default_session_vars[ $key ])) { |
|
590 | + EE_Error::add_error( |
|
591 | + sprintf( |
|
592 | + esc_html__( |
|
593 | + 'Sorry! %s is a default session datum and can not be reset.', |
|
594 | + 'event_espresso' |
|
595 | + ), |
|
596 | + $key |
|
597 | + ), |
|
598 | + __FILE__, |
|
599 | + __FUNCTION__, |
|
600 | + __LINE__ |
|
601 | + ); |
|
602 | + return false; |
|
603 | + } |
|
604 | + $this->_session_data[ $key ] = $value; |
|
605 | + $this->setSaveState(); |
|
606 | + } |
|
607 | + return true; |
|
608 | + } |
|
609 | + |
|
610 | + |
|
611 | + /** |
|
612 | + * @initiate session |
|
613 | + * @access private |
|
614 | + * @return TRUE on success, FALSE on fail |
|
615 | + * @throws EE_Error |
|
616 | + * @throws InvalidArgumentException |
|
617 | + * @throws InvalidDataTypeException |
|
618 | + * @throws InvalidInterfaceException |
|
619 | + * @throws InvalidSessionDataException |
|
620 | + * @throws RuntimeException |
|
621 | + * @throws ReflectionException |
|
622 | + */ |
|
623 | + private function _espresso_session() |
|
624 | + { |
|
625 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
626 | + $this->session_start_handler->startSession(); |
|
627 | + $this->status = EE_Session::STATUS_OPEN; |
|
628 | + // get our modified session ID |
|
629 | + $this->_sid = $this->_generate_session_id(); |
|
630 | + // and the visitors IP |
|
631 | + $this->_ip_address = $this->request->ipAddress(); |
|
632 | + // set the "user agent" |
|
633 | + $this->_user_agent = $this->request->userAgent(); |
|
634 | + // now let's retrieve what's in the db |
|
635 | + $session_data = $this->_retrieve_session_data(); |
|
636 | + if (! empty($session_data)) { |
|
637 | + // get the current time in UTC |
|
638 | + $this->_time = $this->_time !== null ? $this->_time : time(); |
|
639 | + // and reset the session expiration |
|
640 | + $this->_expiration = isset($session_data['expiration']) |
|
641 | + ? $session_data['expiration'] |
|
642 | + : $this->_time + $this->session_lifespan->inSeconds(); |
|
643 | + } else { |
|
644 | + // set initial site access time and the session expiration |
|
645 | + $this->_set_init_access_and_expiration(); |
|
646 | + // set referer |
|
647 | + $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER']) |
|
648 | + ? esc_attr($_SERVER['HTTP_REFERER']) |
|
649 | + : ''; |
|
650 | + // no previous session = go back and create one (on top of the data above) |
|
651 | + return false; |
|
652 | + } |
|
653 | + // now the user agent |
|
654 | + if ($session_data['user_agent'] !== $this->_user_agent) { |
|
655 | + return false; |
|
656 | + } |
|
657 | + // wait a minute... how old are you? |
|
658 | + if ($this->_time > $this->_expiration) { |
|
659 | + // yer too old fer me! |
|
660 | + $this->_expired = true; |
|
661 | + // wipe out everything that isn't a default session datum |
|
662 | + $this->clear_session(__CLASS__, __FUNCTION__); |
|
663 | + } |
|
664 | + // make event espresso session data available to plugin |
|
665 | + $this->_session_data = array_merge($this->_session_data, $session_data); |
|
666 | + return true; |
|
667 | + } |
|
668 | + |
|
669 | + |
|
670 | + /** |
|
671 | + * _get_session_data |
|
672 | + * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup |
|
673 | + * databases |
|
674 | + * |
|
675 | + * @return array |
|
676 | + * @throws EE_Error |
|
677 | + * @throws InvalidArgumentException |
|
678 | + * @throws InvalidSessionDataException |
|
679 | + * @throws InvalidDataTypeException |
|
680 | + * @throws InvalidInterfaceException |
|
681 | + * @throws RuntimeException |
|
682 | + */ |
|
683 | + protected function _retrieve_session_data() |
|
684 | + { |
|
685 | + $ssn_key = EE_Session::session_id_prefix . $this->_sid; |
|
686 | + try { |
|
687 | + // we're using WP's Transient API to store session data using the PHP session ID as the option name |
|
688 | + $session_data = $this->cache_storage->get($ssn_key, false); |
|
689 | + if (empty($session_data)) { |
|
690 | + return array(); |
|
691 | + } |
|
692 | + if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
693 | + $hash_check = $this->cache_storage->get( |
|
694 | + EE_Session::hash_check_prefix . $this->_sid, |
|
695 | + false |
|
696 | + ); |
|
697 | + if ($hash_check && $hash_check !== md5($session_data)) { |
|
698 | + EE_Error::add_error( |
|
699 | + sprintf( |
|
700 | + __( |
|
701 | + 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.', |
|
702 | + 'event_espresso' |
|
703 | + ), |
|
704 | + EE_Session::session_id_prefix . $this->_sid |
|
705 | + ), |
|
706 | + __FILE__, |
|
707 | + __FUNCTION__, |
|
708 | + __LINE__ |
|
709 | + ); |
|
710 | + } |
|
711 | + } |
|
712 | + } catch (Exception $e) { |
|
713 | + // let's just eat that error for now and attempt to correct any corrupted data |
|
714 | + global $wpdb; |
|
715 | + $row = $wpdb->get_row( |
|
716 | + $wpdb->prepare( |
|
717 | + "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", |
|
718 | + '_transient_' . $ssn_key |
|
719 | + ) |
|
720 | + ); |
|
721 | + $session_data = is_object($row) ? $row->option_value : null; |
|
722 | + if ($session_data) { |
|
723 | + $session_data = preg_replace_callback( |
|
724 | + '!s:(d+):"(.*?)";!', |
|
725 | + function ($match) { |
|
726 | + return $match[1] === strlen($match[2]) |
|
727 | + ? $match[0] |
|
728 | + : 's:' . strlen($match[2]) . ':"' . $match[2] . '";'; |
|
729 | + }, |
|
730 | + $session_data |
|
731 | + ); |
|
732 | + } |
|
733 | + $session_data = maybe_unserialize($session_data); |
|
734 | + } |
|
735 | + // in case the data is encoded... try to decode it |
|
736 | + $session_data = $this->encryption instanceof EE_Encryption |
|
737 | + ? $this->encryption->base64_string_decode($session_data) |
|
738 | + : $session_data; |
|
739 | + if (! is_array($session_data)) { |
|
740 | + try { |
|
741 | + $session_data = maybe_unserialize($session_data); |
|
742 | + } catch (Exception $e) { |
|
743 | + $msg = esc_html__( |
|
744 | + 'An error occurred while attempting to unserialize the session data.', |
|
745 | + 'event_espresso' |
|
746 | + ); |
|
747 | + $msg .= WP_DEBUG |
|
748 | + ? '<br><pre>' |
|
749 | + . print_r($session_data, true) |
|
750 | + . '</pre><br>' |
|
751 | + . $this->find_serialize_error($session_data) |
|
752 | + : ''; |
|
753 | + $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
754 | + throw new InvalidSessionDataException($msg, 0, $e); |
|
755 | + } |
|
756 | + } |
|
757 | + // just a check to make sure the session array is indeed an array |
|
758 | + if (! is_array($session_data)) { |
|
759 | + // no?!?! then something is wrong |
|
760 | + $msg = esc_html__( |
|
761 | + 'The session data is missing, invalid, or corrupted.', |
|
762 | + 'event_espresso' |
|
763 | + ); |
|
764 | + $msg .= WP_DEBUG |
|
765 | + ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data) |
|
766 | + : ''; |
|
767 | + $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
768 | + throw new InvalidSessionDataException($msg); |
|
769 | + } |
|
770 | + if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) { |
|
771 | + $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID( |
|
772 | + $session_data['transaction'] |
|
773 | + ); |
|
774 | + } |
|
775 | + return $session_data; |
|
776 | + } |
|
777 | + |
|
778 | + |
|
779 | + /** |
|
780 | + * _generate_session_id |
|
781 | + * Retrieves the PHP session id either directly from the PHP session, |
|
782 | + * or from the $_REQUEST array if it was passed in from an AJAX request. |
|
783 | + * The session id is then salted and hashed (mmm sounds tasty) |
|
784 | + * so that it can be safely used as a $_REQUEST param |
|
785 | + * |
|
786 | + * @return string |
|
787 | + */ |
|
788 | + protected function _generate_session_id() |
|
789 | + { |
|
790 | + // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length |
|
791 | + if (isset($_REQUEST['EESID'])) { |
|
792 | + $session_id = sanitize_text_field($_REQUEST['EESID']); |
|
793 | + } else { |
|
794 | + $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt()); |
|
795 | + } |
|
796 | + return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id); |
|
797 | + } |
|
798 | + |
|
799 | + |
|
800 | + /** |
|
801 | + * _get_sid_salt |
|
802 | + * |
|
803 | + * @return string |
|
804 | + */ |
|
805 | + protected function _get_sid_salt() |
|
806 | + { |
|
807 | + // was session id salt already saved to db ? |
|
808 | + if (empty($this->_sid_salt)) { |
|
809 | + // no? then maybe use WP defined constant |
|
810 | + if (defined('AUTH_SALT')) { |
|
811 | + $this->_sid_salt = AUTH_SALT; |
|
812 | + } |
|
813 | + // if salt doesn't exist or is too short |
|
814 | + if (strlen($this->_sid_salt) < 32) { |
|
815 | + // create a new one |
|
816 | + $this->_sid_salt = wp_generate_password(64); |
|
817 | + } |
|
818 | + // and save it as a permanent session setting |
|
819 | + $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt)); |
|
820 | + } |
|
821 | + return $this->_sid_salt; |
|
822 | + } |
|
823 | + |
|
824 | + |
|
825 | + /** |
|
826 | + * _set_init_access_and_expiration |
|
827 | + * |
|
828 | + * @return void |
|
829 | + */ |
|
830 | + protected function _set_init_access_and_expiration() |
|
831 | + { |
|
832 | + $this->_time = time(); |
|
833 | + $this->_expiration = $this->_time + $this->session_lifespan->inSeconds(); |
|
834 | + // set initial site access time |
|
835 | + $this->_session_data['init_access'] = $this->_time; |
|
836 | + // and the session expiration |
|
837 | + $this->_session_data['expiration'] = $this->_expiration; |
|
838 | + } |
|
839 | + |
|
840 | + |
|
841 | + /** |
|
842 | + * @update session data prior to saving to the db |
|
843 | + * @access public |
|
844 | + * @param bool $new_session |
|
845 | + * @return TRUE on success, FALSE on fail |
|
846 | + * @throws EE_Error |
|
847 | + * @throws InvalidArgumentException |
|
848 | + * @throws InvalidDataTypeException |
|
849 | + * @throws InvalidInterfaceException |
|
850 | + * @throws ReflectionException |
|
851 | + */ |
|
852 | + public function update($new_session = false) |
|
853 | + { |
|
854 | + $this->_session_data = $this->_session_data !== null |
|
855 | + && is_array($this->_session_data) |
|
856 | + && isset($this->_session_data['id']) |
|
857 | + ? $this->_session_data |
|
858 | + : array(); |
|
859 | + if (empty($this->_session_data)) { |
|
860 | + $this->_set_defaults(); |
|
861 | + } |
|
862 | + $session_data = array(); |
|
863 | + foreach ($this->_session_data as $key => $value) { |
|
864 | + switch ($key) { |
|
865 | + case 'id': |
|
866 | + // session ID |
|
867 | + $session_data['id'] = $this->_sid; |
|
868 | + break; |
|
869 | + case 'ip_address': |
|
870 | + // visitor ip address |
|
871 | + $session_data['ip_address'] = $this->request->ipAddress(); |
|
872 | + break; |
|
873 | + case 'user_agent': |
|
874 | + // visitor user_agent |
|
875 | + $session_data['user_agent'] = $this->_user_agent; |
|
876 | + break; |
|
877 | + case 'init_access': |
|
878 | + $session_data['init_access'] = absint($value); |
|
879 | + break; |
|
880 | + case 'last_access': |
|
881 | + // current access time |
|
882 | + $session_data['last_access'] = $this->_time; |
|
883 | + break; |
|
884 | + case 'expiration': |
|
885 | + // when the session expires |
|
886 | + $session_data['expiration'] = ! empty($this->_expiration) |
|
887 | + ? $this->_expiration |
|
888 | + : $session_data['init_access'] + $this->session_lifespan->inSeconds(); |
|
889 | + break; |
|
890 | + case 'user_id': |
|
891 | + // current user if logged in |
|
892 | + $session_data['user_id'] = $this->_wp_user_id(); |
|
893 | + break; |
|
894 | + case 'pages_visited': |
|
895 | + $page_visit = $this->_get_page_visit(); |
|
896 | + if ($page_visit) { |
|
897 | + // set pages visited where the first will be the http referrer |
|
898 | + $this->_session_data['pages_visited'][ $this->_time ] = $page_visit; |
|
899 | + // we'll only save the last 10 page visits. |
|
900 | + $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10); |
|
901 | + } |
|
902 | + break; |
|
903 | + default: |
|
904 | + // carry any other data over |
|
905 | + $session_data[ $key ] = $this->_session_data[ $key ]; |
|
906 | + } |
|
907 | + } |
|
908 | + $this->_session_data = $session_data; |
|
909 | + // creating a new session does not require saving to the db just yet |
|
910 | + if (! $new_session) { |
|
911 | + // ready? let's save |
|
912 | + if ($this->_save_session_to_db()) { |
|
913 | + return true; |
|
914 | + } |
|
915 | + return false; |
|
916 | + } |
|
917 | + // meh, why not? |
|
918 | + return true; |
|
919 | + } |
|
920 | + |
|
921 | + |
|
922 | + /** |
|
923 | + * @create session data array |
|
924 | + * @access public |
|
925 | + * @return bool |
|
926 | + * @throws EE_Error |
|
927 | + * @throws InvalidArgumentException |
|
928 | + * @throws InvalidDataTypeException |
|
929 | + * @throws InvalidInterfaceException |
|
930 | + * @throws ReflectionException |
|
931 | + */ |
|
932 | + private function _create_espresso_session() |
|
933 | + { |
|
934 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, ''); |
|
935 | + // use the update function for now with $new_session arg set to TRUE |
|
936 | + return $this->update(true) ? true : false; |
|
937 | + } |
|
938 | + |
|
939 | + /** |
|
940 | + * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good |
|
941 | + * too). This is used when determining if we want to save the session or not. |
|
942 | + * @since 4.9.67.p |
|
943 | + * @return bool |
|
944 | + */ |
|
945 | + private function sessionHasStuffWorthSaving() |
|
946 | + { |
|
947 | + return $this->save_state === EE_Session::SAVE_STATE_DIRTY |
|
948 | + // we may want to eventually remove the following |
|
949 | + // on the assumption that the above check is enough |
|
950 | + || $this->cart() instanceof EE_Cart |
|
951 | + || ( |
|
952 | + isset($this->_session_data['ee_notices']) |
|
953 | + && ( |
|
954 | + ! empty($this->_session_data['ee_notices']['attention']) |
|
955 | + || ! empty($this->_session_data['ee_notices']['errors']) |
|
956 | + || ! empty($this->_session_data['ee_notices']['success']) |
|
957 | + ) |
|
958 | + ); |
|
959 | + } |
|
960 | + |
|
961 | + |
|
962 | + /** |
|
963 | + * _save_session_to_db |
|
964 | + * |
|
965 | + * @param bool $clear_session |
|
966 | + * @return string |
|
967 | + * @throws EE_Error |
|
968 | + * @throws InvalidArgumentException |
|
969 | + * @throws InvalidDataTypeException |
|
970 | + * @throws InvalidInterfaceException |
|
971 | + * @throws ReflectionException |
|
972 | + */ |
|
973 | + private function _save_session_to_db($clear_session = false) |
|
974 | + { |
|
975 | + // don't save sessions for crawlers |
|
976 | + // and unless we're deleting the session data, don't save anything if there isn't a cart |
|
977 | + if ( |
|
978 | + $this->request->isBot() |
|
979 | + || ( |
|
980 | + ! $clear_session |
|
981 | + && ! $this->sessionHasStuffWorthSaving() |
|
982 | + && apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true) |
|
983 | + ) |
|
984 | + ) { |
|
985 | + return false; |
|
986 | + } |
|
987 | + $transaction = $this->transaction(); |
|
988 | + if ($transaction instanceof EE_Transaction) { |
|
989 | + if (! $transaction->ID()) { |
|
990 | + $transaction->save(); |
|
991 | + } |
|
992 | + $this->_session_data['transaction'] = $transaction->ID(); |
|
993 | + } |
|
994 | + // then serialize all of our session data |
|
995 | + $session_data = serialize($this->_session_data); |
|
996 | + // do we need to also encode it to avoid corrupted data when saved to the db? |
|
997 | + $session_data = $this->_use_encryption |
|
998 | + ? $this->encryption->base64_string_encode($session_data) |
|
999 | + : $session_data; |
|
1000 | + // maybe save hash check |
|
1001 | + if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
1002 | + $this->cache_storage->add( |
|
1003 | + EE_Session::hash_check_prefix . $this->_sid, |
|
1004 | + md5($session_data), |
|
1005 | + $this->session_lifespan->inSeconds() |
|
1006 | + ); |
|
1007 | + } |
|
1008 | + // we're using the Transient API for storing session data, |
|
1009 | + $saved = $this->cache_storage->add( |
|
1010 | + EE_Session::session_id_prefix . $this->_sid, |
|
1011 | + $session_data, |
|
1012 | + $this->session_lifespan->inSeconds() |
|
1013 | + ); |
|
1014 | + $this->setSaveState(EE_Session::SAVE_STATE_CLEAN); |
|
1015 | + return $saved; |
|
1016 | + } |
|
1017 | + |
|
1018 | + |
|
1019 | + /** |
|
1020 | + * @get the full page request the visitor is accessing |
|
1021 | + * @access public |
|
1022 | + * @return string |
|
1023 | + */ |
|
1024 | + public function _get_page_visit() |
|
1025 | + { |
|
1026 | + $page_visit = home_url('/') . 'wp-admin/admin-ajax.php'; |
|
1027 | + // check for request url |
|
1028 | + if (isset($_SERVER['REQUEST_URI'])) { |
|
1029 | + $http_host = ''; |
|
1030 | + $page_id = '?'; |
|
1031 | + $e_reg = ''; |
|
1032 | + $request_uri = esc_url($_SERVER['REQUEST_URI']); |
|
1033 | + $ru_bits = explode('?', $request_uri); |
|
1034 | + $request_uri = $ru_bits[0]; |
|
1035 | + // check for and grab host as well |
|
1036 | + if (isset($_SERVER['HTTP_HOST'])) { |
|
1037 | + $http_host = esc_url($_SERVER['HTTP_HOST']); |
|
1038 | + } |
|
1039 | + // check for page_id in SERVER REQUEST |
|
1040 | + if (isset($_REQUEST['page_id'])) { |
|
1041 | + // rebuild $e_reg without any of the extra parameters |
|
1042 | + $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&'; |
|
1043 | + } |
|
1044 | + // check for $e_reg in SERVER REQUEST |
|
1045 | + if (isset($_REQUEST['ee'])) { |
|
1046 | + // rebuild $e_reg without any of the extra parameters |
|
1047 | + $e_reg = 'ee=' . esc_attr($_REQUEST['ee']); |
|
1048 | + } |
|
1049 | + $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?'); |
|
1050 | + } |
|
1051 | + return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : ''; |
|
1052 | + } |
|
1053 | + |
|
1054 | + |
|
1055 | + /** |
|
1056 | + * @the current wp user id |
|
1057 | + * @access public |
|
1058 | + * @return int |
|
1059 | + */ |
|
1060 | + public function _wp_user_id() |
|
1061 | + { |
|
1062 | + // if I need to explain the following lines of code, then you shouldn't be looking at this! |
|
1063 | + $this->_wp_user_id = get_current_user_id(); |
|
1064 | + return $this->_wp_user_id; |
|
1065 | + } |
|
1066 | + |
|
1067 | + |
|
1068 | + /** |
|
1069 | + * Clear EE_Session data |
|
1070 | + * |
|
1071 | + * @access public |
|
1072 | + * @param string $class |
|
1073 | + * @param string $function |
|
1074 | + * @return void |
|
1075 | + * @throws EE_Error |
|
1076 | + * @throws InvalidArgumentException |
|
1077 | + * @throws InvalidDataTypeException |
|
1078 | + * @throws InvalidInterfaceException |
|
1079 | + * @throws ReflectionException |
|
1080 | + */ |
|
1081 | + public function clear_session($class = '', $function = '') |
|
1082 | + { |
|
1083 | 1083 | // echo ' |
1084 | 1084 | // <h3 style="color:#999;line-height:.9em;"> |
1085 | 1085 | // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/> |
1086 | 1086 | // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span> <b style="font-size:10px;"> ' . __LINE__ . ' </b> |
1087 | 1087 | // </h3>'; |
1088 | - do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()'); |
|
1089 | - $this->reset_cart(); |
|
1090 | - $this->reset_checkout(); |
|
1091 | - $this->reset_transaction(); |
|
1092 | - // wipe out everything that isn't a default session datum |
|
1093 | - $this->reset_data(array_keys($this->_session_data)); |
|
1094 | - // reset initial site access time and the session expiration |
|
1095 | - $this->_set_init_access_and_expiration(); |
|
1096 | - $this->setSaveState(); |
|
1097 | - $this->_save_session_to_db(true); |
|
1098 | - } |
|
1099 | - |
|
1100 | - |
|
1101 | - /** |
|
1102 | - * resets all non-default session vars. Returns TRUE on success, FALSE on fail |
|
1103 | - * |
|
1104 | - * @param array|mixed $data_to_reset |
|
1105 | - * @param bool $show_all_notices |
|
1106 | - * @return bool |
|
1107 | - */ |
|
1108 | - public function reset_data($data_to_reset = array(), $show_all_notices = false) |
|
1109 | - { |
|
1110 | - // if $data_to_reset is not in an array, then put it in one |
|
1111 | - if (! is_array($data_to_reset)) { |
|
1112 | - $data_to_reset = array($data_to_reset); |
|
1113 | - } |
|
1114 | - // nothing ??? go home! |
|
1115 | - if (empty($data_to_reset)) { |
|
1116 | - EE_Error::add_error( |
|
1117 | - __( |
|
1118 | - 'No session data could be reset, because no session var name was provided.', |
|
1119 | - 'event_espresso' |
|
1120 | - ), |
|
1121 | - __FILE__, |
|
1122 | - __FUNCTION__, |
|
1123 | - __LINE__ |
|
1124 | - ); |
|
1125 | - return false; |
|
1126 | - } |
|
1127 | - $return_value = true; |
|
1128 | - // since $data_to_reset is an array, cycle through the values |
|
1129 | - foreach ($data_to_reset as $reset) { |
|
1130 | - // first check to make sure it is a valid session var |
|
1131 | - if (isset($this->_session_data[ $reset ])) { |
|
1132 | - // then check to make sure it is not a default var |
|
1133 | - if (! array_key_exists($reset, $this->_default_session_vars)) { |
|
1134 | - // remove session var |
|
1135 | - unset($this->_session_data[ $reset ]); |
|
1136 | - $this->setSaveState(); |
|
1137 | - if ($show_all_notices) { |
|
1138 | - EE_Error::add_success( |
|
1139 | - sprintf( |
|
1140 | - __('The session variable %s was removed.', 'event_espresso'), |
|
1141 | - $reset |
|
1142 | - ), |
|
1143 | - __FILE__, |
|
1144 | - __FUNCTION__, |
|
1145 | - __LINE__ |
|
1146 | - ); |
|
1147 | - } |
|
1148 | - } else { |
|
1149 | - // yeeeeeeeeerrrrrrrrrrr OUT !!!! |
|
1150 | - if ($show_all_notices) { |
|
1151 | - EE_Error::add_error( |
|
1152 | - sprintf( |
|
1153 | - __( |
|
1154 | - 'Sorry! %s is a default session datum and can not be reset.', |
|
1155 | - 'event_espresso' |
|
1156 | - ), |
|
1157 | - $reset |
|
1158 | - ), |
|
1159 | - __FILE__, |
|
1160 | - __FUNCTION__, |
|
1161 | - __LINE__ |
|
1162 | - ); |
|
1163 | - } |
|
1164 | - $return_value = false; |
|
1165 | - } |
|
1166 | - } elseif ($show_all_notices) { |
|
1167 | - // oops! that session var does not exist! |
|
1168 | - EE_Error::add_error( |
|
1169 | - sprintf( |
|
1170 | - __( |
|
1171 | - 'The session item provided, %s, is invalid or does not exist.', |
|
1172 | - 'event_espresso' |
|
1173 | - ), |
|
1174 | - $reset |
|
1175 | - ), |
|
1176 | - __FILE__, |
|
1177 | - __FUNCTION__, |
|
1178 | - __LINE__ |
|
1179 | - ); |
|
1180 | - $return_value = false; |
|
1181 | - } |
|
1182 | - } // end of foreach |
|
1183 | - return $return_value; |
|
1184 | - } |
|
1185 | - |
|
1186 | - |
|
1187 | - /** |
|
1188 | - * wp_loaded |
|
1189 | - * |
|
1190 | - * @access public |
|
1191 | - * @throws EE_Error |
|
1192 | - * @throws InvalidDataTypeException |
|
1193 | - * @throws InvalidInterfaceException |
|
1194 | - * @throws InvalidArgumentException |
|
1195 | - * @throws ReflectionException |
|
1196 | - */ |
|
1197 | - public function wp_loaded() |
|
1198 | - { |
|
1199 | - if ($this->request->requestParamIsSet('clear_session')) { |
|
1200 | - $this->clear_session(__CLASS__, __FUNCTION__); |
|
1201 | - } |
|
1202 | - } |
|
1203 | - |
|
1204 | - |
|
1205 | - /** |
|
1206 | - * Used to reset the entire object (for tests). |
|
1207 | - * |
|
1208 | - * @since 4.3.0 |
|
1209 | - * @throws EE_Error |
|
1210 | - * @throws InvalidDataTypeException |
|
1211 | - * @throws InvalidInterfaceException |
|
1212 | - * @throws InvalidArgumentException |
|
1213 | - * @throws ReflectionException |
|
1214 | - */ |
|
1215 | - public function reset_instance() |
|
1216 | - { |
|
1217 | - $this->clear_session(); |
|
1218 | - self::$_instance = null; |
|
1219 | - } |
|
1220 | - |
|
1221 | - |
|
1222 | - public function configure_garbage_collection_filters() |
|
1223 | - { |
|
1224 | - // run old filter we had for controlling session cleanup |
|
1225 | - $expired_session_transient_delete_query_limit = absint( |
|
1226 | - apply_filters( |
|
1227 | - 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1228 | - 50 |
|
1229 | - ) |
|
1230 | - ); |
|
1231 | - // is there a value? or one that is different than the default 50 records? |
|
1232 | - if ($expired_session_transient_delete_query_limit === 0) { |
|
1233 | - // hook into TransientCacheStorage in case Session cleanup was turned off |
|
1234 | - add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero'); |
|
1235 | - } elseif ($expired_session_transient_delete_query_limit !== 50) { |
|
1236 | - // or use that for the new transient cleanup query limit |
|
1237 | - add_filter( |
|
1238 | - 'FHEE__TransientCacheStorage__clearExpiredTransients__limit', |
|
1239 | - function () use ($expired_session_transient_delete_query_limit) { |
|
1240 | - return $expired_session_transient_delete_query_limit; |
|
1241 | - } |
|
1242 | - ); |
|
1243 | - } |
|
1244 | - } |
|
1245 | - |
|
1246 | - |
|
1247 | - /** |
|
1248 | - * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996 |
|
1249 | - * @param $data1 |
|
1250 | - * @return string |
|
1251 | - */ |
|
1252 | - private function find_serialize_error($data1) |
|
1253 | - { |
|
1254 | - $error = '<pre>'; |
|
1255 | - $data2 = preg_replace_callback( |
|
1256 | - '!s:(\d+):"(.*?)";!', |
|
1257 | - function ($match) { |
|
1258 | - return ($match[1] === strlen($match[2])) |
|
1259 | - ? $match[0] |
|
1260 | - : 's:' |
|
1261 | - . strlen($match[2]) |
|
1262 | - . ':"' |
|
1263 | - . $match[2] |
|
1264 | - . '";'; |
|
1265 | - }, |
|
1266 | - $data1 |
|
1267 | - ); |
|
1268 | - $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2); |
|
1269 | - $error .= $data1 . PHP_EOL; |
|
1270 | - $error .= $data2 . PHP_EOL; |
|
1271 | - for ($i = 0; $i < $max; $i++) { |
|
1272 | - if (@$data1[ $i ] !== @$data2[ $i ]) { |
|
1273 | - $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL; |
|
1274 | - $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL; |
|
1275 | - $error .= "\t-> Line Number = $i" . PHP_EOL; |
|
1276 | - $start = ($i - 20); |
|
1277 | - $start = ($start < 0) ? 0 : $start; |
|
1278 | - $length = 40; |
|
1279 | - $point = $max - $i; |
|
1280 | - if ($point < 20) { |
|
1281 | - $rlength = 1; |
|
1282 | - $rpoint = -$point; |
|
1283 | - } else { |
|
1284 | - $rpoint = $length - 20; |
|
1285 | - $rlength = 1; |
|
1286 | - } |
|
1287 | - $error .= "\t-> Section Data1 = "; |
|
1288 | - $error .= substr_replace( |
|
1289 | - substr($data1, $start, $length), |
|
1290 | - "<b style=\"color:green\">{$data1[ $i ]}</b>", |
|
1291 | - $rpoint, |
|
1292 | - $rlength |
|
1293 | - ); |
|
1294 | - $error .= PHP_EOL; |
|
1295 | - $error .= "\t-> Section Data2 = "; |
|
1296 | - $error .= substr_replace( |
|
1297 | - substr($data2, $start, $length), |
|
1298 | - "<b style=\"color:red\">{$data2[ $i ]}</b>", |
|
1299 | - $rpoint, |
|
1300 | - $rlength |
|
1301 | - ); |
|
1302 | - $error .= PHP_EOL; |
|
1303 | - } |
|
1304 | - } |
|
1305 | - $error .= '</pre>'; |
|
1306 | - return $error; |
|
1307 | - } |
|
1308 | - |
|
1309 | - |
|
1310 | - /** |
|
1311 | - * Saves an array of settings used for configuring aspects of session behaviour |
|
1312 | - * |
|
1313 | - * @param array $updated_settings |
|
1314 | - */ |
|
1315 | - private function updateSessionSettings(array $updated_settings = array()) |
|
1316 | - { |
|
1317 | - // add existing settings, but only if not included in incoming $updated_settings array |
|
1318 | - $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array()); |
|
1319 | - update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings); |
|
1320 | - } |
|
1321 | - |
|
1322 | - |
|
1323 | - /** |
|
1324 | - * garbage_collection |
|
1325 | - */ |
|
1326 | - public function garbageCollection() |
|
1327 | - { |
|
1328 | - // only perform during regular requests if last garbage collection was over an hour ago |
|
1329 | - if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1330 | - $this->_last_gc = time(); |
|
1331 | - $this->updateSessionSettings(array('last_gc' => $this->_last_gc)); |
|
1332 | - /** @type WPDB $wpdb */ |
|
1333 | - global $wpdb; |
|
1334 | - // filter the query limit. Set to 0 to turn off garbage collection |
|
1335 | - $expired_session_transient_delete_query_limit = absint( |
|
1336 | - apply_filters( |
|
1337 | - 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1338 | - 50 |
|
1339 | - ) |
|
1340 | - ); |
|
1341 | - // non-zero LIMIT means take out the trash |
|
1342 | - if ($expired_session_transient_delete_query_limit) { |
|
1343 | - $session_key = str_replace('_', '\_', EE_Session::session_id_prefix); |
|
1344 | - $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix); |
|
1345 | - // since transient expiration timestamps are set in the future, we can compare against NOW |
|
1346 | - // but we only want to pick up any trash that's been around for more than a day |
|
1347 | - $expiration = time() - DAY_IN_SECONDS; |
|
1348 | - $SQL = " |
|
1088 | + do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()'); |
|
1089 | + $this->reset_cart(); |
|
1090 | + $this->reset_checkout(); |
|
1091 | + $this->reset_transaction(); |
|
1092 | + // wipe out everything that isn't a default session datum |
|
1093 | + $this->reset_data(array_keys($this->_session_data)); |
|
1094 | + // reset initial site access time and the session expiration |
|
1095 | + $this->_set_init_access_and_expiration(); |
|
1096 | + $this->setSaveState(); |
|
1097 | + $this->_save_session_to_db(true); |
|
1098 | + } |
|
1099 | + |
|
1100 | + |
|
1101 | + /** |
|
1102 | + * resets all non-default session vars. Returns TRUE on success, FALSE on fail |
|
1103 | + * |
|
1104 | + * @param array|mixed $data_to_reset |
|
1105 | + * @param bool $show_all_notices |
|
1106 | + * @return bool |
|
1107 | + */ |
|
1108 | + public function reset_data($data_to_reset = array(), $show_all_notices = false) |
|
1109 | + { |
|
1110 | + // if $data_to_reset is not in an array, then put it in one |
|
1111 | + if (! is_array($data_to_reset)) { |
|
1112 | + $data_to_reset = array($data_to_reset); |
|
1113 | + } |
|
1114 | + // nothing ??? go home! |
|
1115 | + if (empty($data_to_reset)) { |
|
1116 | + EE_Error::add_error( |
|
1117 | + __( |
|
1118 | + 'No session data could be reset, because no session var name was provided.', |
|
1119 | + 'event_espresso' |
|
1120 | + ), |
|
1121 | + __FILE__, |
|
1122 | + __FUNCTION__, |
|
1123 | + __LINE__ |
|
1124 | + ); |
|
1125 | + return false; |
|
1126 | + } |
|
1127 | + $return_value = true; |
|
1128 | + // since $data_to_reset is an array, cycle through the values |
|
1129 | + foreach ($data_to_reset as $reset) { |
|
1130 | + // first check to make sure it is a valid session var |
|
1131 | + if (isset($this->_session_data[ $reset ])) { |
|
1132 | + // then check to make sure it is not a default var |
|
1133 | + if (! array_key_exists($reset, $this->_default_session_vars)) { |
|
1134 | + // remove session var |
|
1135 | + unset($this->_session_data[ $reset ]); |
|
1136 | + $this->setSaveState(); |
|
1137 | + if ($show_all_notices) { |
|
1138 | + EE_Error::add_success( |
|
1139 | + sprintf( |
|
1140 | + __('The session variable %s was removed.', 'event_espresso'), |
|
1141 | + $reset |
|
1142 | + ), |
|
1143 | + __FILE__, |
|
1144 | + __FUNCTION__, |
|
1145 | + __LINE__ |
|
1146 | + ); |
|
1147 | + } |
|
1148 | + } else { |
|
1149 | + // yeeeeeeeeerrrrrrrrrrr OUT !!!! |
|
1150 | + if ($show_all_notices) { |
|
1151 | + EE_Error::add_error( |
|
1152 | + sprintf( |
|
1153 | + __( |
|
1154 | + 'Sorry! %s is a default session datum and can not be reset.', |
|
1155 | + 'event_espresso' |
|
1156 | + ), |
|
1157 | + $reset |
|
1158 | + ), |
|
1159 | + __FILE__, |
|
1160 | + __FUNCTION__, |
|
1161 | + __LINE__ |
|
1162 | + ); |
|
1163 | + } |
|
1164 | + $return_value = false; |
|
1165 | + } |
|
1166 | + } elseif ($show_all_notices) { |
|
1167 | + // oops! that session var does not exist! |
|
1168 | + EE_Error::add_error( |
|
1169 | + sprintf( |
|
1170 | + __( |
|
1171 | + 'The session item provided, %s, is invalid or does not exist.', |
|
1172 | + 'event_espresso' |
|
1173 | + ), |
|
1174 | + $reset |
|
1175 | + ), |
|
1176 | + __FILE__, |
|
1177 | + __FUNCTION__, |
|
1178 | + __LINE__ |
|
1179 | + ); |
|
1180 | + $return_value = false; |
|
1181 | + } |
|
1182 | + } // end of foreach |
|
1183 | + return $return_value; |
|
1184 | + } |
|
1185 | + |
|
1186 | + |
|
1187 | + /** |
|
1188 | + * wp_loaded |
|
1189 | + * |
|
1190 | + * @access public |
|
1191 | + * @throws EE_Error |
|
1192 | + * @throws InvalidDataTypeException |
|
1193 | + * @throws InvalidInterfaceException |
|
1194 | + * @throws InvalidArgumentException |
|
1195 | + * @throws ReflectionException |
|
1196 | + */ |
|
1197 | + public function wp_loaded() |
|
1198 | + { |
|
1199 | + if ($this->request->requestParamIsSet('clear_session')) { |
|
1200 | + $this->clear_session(__CLASS__, __FUNCTION__); |
|
1201 | + } |
|
1202 | + } |
|
1203 | + |
|
1204 | + |
|
1205 | + /** |
|
1206 | + * Used to reset the entire object (for tests). |
|
1207 | + * |
|
1208 | + * @since 4.3.0 |
|
1209 | + * @throws EE_Error |
|
1210 | + * @throws InvalidDataTypeException |
|
1211 | + * @throws InvalidInterfaceException |
|
1212 | + * @throws InvalidArgumentException |
|
1213 | + * @throws ReflectionException |
|
1214 | + */ |
|
1215 | + public function reset_instance() |
|
1216 | + { |
|
1217 | + $this->clear_session(); |
|
1218 | + self::$_instance = null; |
|
1219 | + } |
|
1220 | + |
|
1221 | + |
|
1222 | + public function configure_garbage_collection_filters() |
|
1223 | + { |
|
1224 | + // run old filter we had for controlling session cleanup |
|
1225 | + $expired_session_transient_delete_query_limit = absint( |
|
1226 | + apply_filters( |
|
1227 | + 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1228 | + 50 |
|
1229 | + ) |
|
1230 | + ); |
|
1231 | + // is there a value? or one that is different than the default 50 records? |
|
1232 | + if ($expired_session_transient_delete_query_limit === 0) { |
|
1233 | + // hook into TransientCacheStorage in case Session cleanup was turned off |
|
1234 | + add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero'); |
|
1235 | + } elseif ($expired_session_transient_delete_query_limit !== 50) { |
|
1236 | + // or use that for the new transient cleanup query limit |
|
1237 | + add_filter( |
|
1238 | + 'FHEE__TransientCacheStorage__clearExpiredTransients__limit', |
|
1239 | + function () use ($expired_session_transient_delete_query_limit) { |
|
1240 | + return $expired_session_transient_delete_query_limit; |
|
1241 | + } |
|
1242 | + ); |
|
1243 | + } |
|
1244 | + } |
|
1245 | + |
|
1246 | + |
|
1247 | + /** |
|
1248 | + * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996 |
|
1249 | + * @param $data1 |
|
1250 | + * @return string |
|
1251 | + */ |
|
1252 | + private function find_serialize_error($data1) |
|
1253 | + { |
|
1254 | + $error = '<pre>'; |
|
1255 | + $data2 = preg_replace_callback( |
|
1256 | + '!s:(\d+):"(.*?)";!', |
|
1257 | + function ($match) { |
|
1258 | + return ($match[1] === strlen($match[2])) |
|
1259 | + ? $match[0] |
|
1260 | + : 's:' |
|
1261 | + . strlen($match[2]) |
|
1262 | + . ':"' |
|
1263 | + . $match[2] |
|
1264 | + . '";'; |
|
1265 | + }, |
|
1266 | + $data1 |
|
1267 | + ); |
|
1268 | + $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2); |
|
1269 | + $error .= $data1 . PHP_EOL; |
|
1270 | + $error .= $data2 . PHP_EOL; |
|
1271 | + for ($i = 0; $i < $max; $i++) { |
|
1272 | + if (@$data1[ $i ] !== @$data2[ $i ]) { |
|
1273 | + $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL; |
|
1274 | + $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL; |
|
1275 | + $error .= "\t-> Line Number = $i" . PHP_EOL; |
|
1276 | + $start = ($i - 20); |
|
1277 | + $start = ($start < 0) ? 0 : $start; |
|
1278 | + $length = 40; |
|
1279 | + $point = $max - $i; |
|
1280 | + if ($point < 20) { |
|
1281 | + $rlength = 1; |
|
1282 | + $rpoint = -$point; |
|
1283 | + } else { |
|
1284 | + $rpoint = $length - 20; |
|
1285 | + $rlength = 1; |
|
1286 | + } |
|
1287 | + $error .= "\t-> Section Data1 = "; |
|
1288 | + $error .= substr_replace( |
|
1289 | + substr($data1, $start, $length), |
|
1290 | + "<b style=\"color:green\">{$data1[ $i ]}</b>", |
|
1291 | + $rpoint, |
|
1292 | + $rlength |
|
1293 | + ); |
|
1294 | + $error .= PHP_EOL; |
|
1295 | + $error .= "\t-> Section Data2 = "; |
|
1296 | + $error .= substr_replace( |
|
1297 | + substr($data2, $start, $length), |
|
1298 | + "<b style=\"color:red\">{$data2[ $i ]}</b>", |
|
1299 | + $rpoint, |
|
1300 | + $rlength |
|
1301 | + ); |
|
1302 | + $error .= PHP_EOL; |
|
1303 | + } |
|
1304 | + } |
|
1305 | + $error .= '</pre>'; |
|
1306 | + return $error; |
|
1307 | + } |
|
1308 | + |
|
1309 | + |
|
1310 | + /** |
|
1311 | + * Saves an array of settings used for configuring aspects of session behaviour |
|
1312 | + * |
|
1313 | + * @param array $updated_settings |
|
1314 | + */ |
|
1315 | + private function updateSessionSettings(array $updated_settings = array()) |
|
1316 | + { |
|
1317 | + // add existing settings, but only if not included in incoming $updated_settings array |
|
1318 | + $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array()); |
|
1319 | + update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings); |
|
1320 | + } |
|
1321 | + |
|
1322 | + |
|
1323 | + /** |
|
1324 | + * garbage_collection |
|
1325 | + */ |
|
1326 | + public function garbageCollection() |
|
1327 | + { |
|
1328 | + // only perform during regular requests if last garbage collection was over an hour ago |
|
1329 | + if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1330 | + $this->_last_gc = time(); |
|
1331 | + $this->updateSessionSettings(array('last_gc' => $this->_last_gc)); |
|
1332 | + /** @type WPDB $wpdb */ |
|
1333 | + global $wpdb; |
|
1334 | + // filter the query limit. Set to 0 to turn off garbage collection |
|
1335 | + $expired_session_transient_delete_query_limit = absint( |
|
1336 | + apply_filters( |
|
1337 | + 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1338 | + 50 |
|
1339 | + ) |
|
1340 | + ); |
|
1341 | + // non-zero LIMIT means take out the trash |
|
1342 | + if ($expired_session_transient_delete_query_limit) { |
|
1343 | + $session_key = str_replace('_', '\_', EE_Session::session_id_prefix); |
|
1344 | + $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix); |
|
1345 | + // since transient expiration timestamps are set in the future, we can compare against NOW |
|
1346 | + // but we only want to pick up any trash that's been around for more than a day |
|
1347 | + $expiration = time() - DAY_IN_SECONDS; |
|
1348 | + $SQL = " |
|
1349 | 1349 | SELECT option_name |
1350 | 1350 | FROM {$wpdb->options} |
1351 | 1351 | WHERE |
@@ -1354,17 +1354,17 @@ discard block |
||
1354 | 1354 | AND option_value < {$expiration} |
1355 | 1355 | LIMIT {$expired_session_transient_delete_query_limit} |
1356 | 1356 | "; |
1357 | - // produces something like: |
|
1358 | - // SELECT option_name FROM wp_options |
|
1359 | - // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%' |
|
1360 | - // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' ) |
|
1361 | - // AND option_value < 1508368198 LIMIT 50 |
|
1362 | - $expired_sessions = $wpdb->get_col($SQL); |
|
1363 | - // valid results? |
|
1364 | - if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1365 | - $this->cache_storage->deleteMany($expired_sessions, true); |
|
1366 | - } |
|
1367 | - } |
|
1368 | - } |
|
1369 | - } |
|
1357 | + // produces something like: |
|
1358 | + // SELECT option_name FROM wp_options |
|
1359 | + // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%' |
|
1360 | + // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' ) |
|
1361 | + // AND option_value < 1508368198 LIMIT 50 |
|
1362 | + $expired_sessions = $wpdb->get_col($SQL); |
|
1363 | + // valid results? |
|
1364 | + if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1365 | + $this->cache_storage->deleteMany($expired_sessions, true); |
|
1366 | + } |
|
1367 | + } |
|
1368 | + } |
|
1369 | + } |
|
1370 | 1370 | } |
@@ -246,22 +246,22 @@ discard block |
||
246 | 246 | // but prior to the 'AHEE__EE_System__core_loaded_and_ready' hook |
247 | 247 | // (which currently fires on the init hook at priority 9), |
248 | 248 | // can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' ); |
249 | - if (! apply_filters('FHEE_load_EE_Session', true)) { |
|
249 | + if ( ! apply_filters('FHEE_load_EE_Session', true)) { |
|
250 | 250 | return; |
251 | 251 | } |
252 | 252 | $this->session_start_handler = $session_start_handler; |
253 | 253 | $this->session_lifespan = $lifespan; |
254 | 254 | $this->request = $request; |
255 | - if (! defined('ESPRESSO_SESSION')) { |
|
255 | + if ( ! defined('ESPRESSO_SESSION')) { |
|
256 | 256 | define('ESPRESSO_SESSION', true); |
257 | 257 | } |
258 | 258 | // retrieve session options from db |
259 | 259 | $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array()); |
260 | - if (! empty($session_settings)) { |
|
260 | + if ( ! empty($session_settings)) { |
|
261 | 261 | // cycle though existing session options |
262 | 262 | foreach ($session_settings as $var_name => $session_setting) { |
263 | 263 | // set values for class properties |
264 | - $var_name = '_' . $var_name; |
|
264 | + $var_name = '_'.$var_name; |
|
265 | 265 | $this->{$var_name} = $session_setting; |
266 | 266 | } |
267 | 267 | } |
@@ -322,7 +322,7 @@ discard block |
||
322 | 322 | public function open_session() |
323 | 323 | { |
324 | 324 | // check for existing session and retrieve it from db |
325 | - if (! $this->_espresso_session()) { |
|
325 | + if ( ! $this->_espresso_session()) { |
|
326 | 326 | // or just start a new one |
327 | 327 | $this->_create_espresso_session(); |
328 | 328 | } |
@@ -399,7 +399,7 @@ discard block |
||
399 | 399 | EE_Session::SAVE_STATE_CLEAN, |
400 | 400 | EE_Session::SAVE_STATE_DIRTY, |
401 | 401 | ]; |
402 | - if (! in_array($save_state, $valid_save_states, true)) { |
|
402 | + if ( ! in_array($save_state, $valid_save_states, true)) { |
|
403 | 403 | $save_state = EE_Session::SAVE_STATE_DIRTY; |
404 | 404 | } |
405 | 405 | $this->save_state = $save_state; |
@@ -418,9 +418,9 @@ discard block |
||
418 | 418 | // set some defaults |
419 | 419 | foreach ($this->_default_session_vars as $key => $default_var) { |
420 | 420 | if (is_array($default_var)) { |
421 | - $this->_session_data[ $key ] = array(); |
|
421 | + $this->_session_data[$key] = array(); |
|
422 | 422 | } else { |
423 | - $this->_session_data[ $key ] = ''; |
|
423 | + $this->_session_data[$key] = ''; |
|
424 | 424 | } |
425 | 425 | } |
426 | 426 | } |
@@ -557,8 +557,8 @@ discard block |
||
557 | 557 | $this->reset_checkout(); |
558 | 558 | $this->reset_transaction(); |
559 | 559 | } |
560 | - if (! empty($key)) { |
|
561 | - return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null; |
|
560 | + if ( ! empty($key)) { |
|
561 | + return isset($this->_session_data[$key]) ? $this->_session_data[$key] : null; |
|
562 | 562 | } |
563 | 563 | return $this->_session_data; |
564 | 564 | } |
@@ -586,7 +586,7 @@ discard block |
||
586 | 586 | return false; |
587 | 587 | } |
588 | 588 | foreach ($data as $key => $value) { |
589 | - if (isset($this->_default_session_vars[ $key ])) { |
|
589 | + if (isset($this->_default_session_vars[$key])) { |
|
590 | 590 | EE_Error::add_error( |
591 | 591 | sprintf( |
592 | 592 | esc_html__( |
@@ -601,7 +601,7 @@ discard block |
||
601 | 601 | ); |
602 | 602 | return false; |
603 | 603 | } |
604 | - $this->_session_data[ $key ] = $value; |
|
604 | + $this->_session_data[$key] = $value; |
|
605 | 605 | $this->setSaveState(); |
606 | 606 | } |
607 | 607 | return true; |
@@ -633,7 +633,7 @@ discard block |
||
633 | 633 | $this->_user_agent = $this->request->userAgent(); |
634 | 634 | // now let's retrieve what's in the db |
635 | 635 | $session_data = $this->_retrieve_session_data(); |
636 | - if (! empty($session_data)) { |
|
636 | + if ( ! empty($session_data)) { |
|
637 | 637 | // get the current time in UTC |
638 | 638 | $this->_time = $this->_time !== null ? $this->_time : time(); |
639 | 639 | // and reset the session expiration |
@@ -644,7 +644,7 @@ discard block |
||
644 | 644 | // set initial site access time and the session expiration |
645 | 645 | $this->_set_init_access_and_expiration(); |
646 | 646 | // set referer |
647 | - $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER']) |
|
647 | + $this->_session_data['pages_visited'][$this->_session_data['init_access']] = isset($_SERVER['HTTP_REFERER']) |
|
648 | 648 | ? esc_attr($_SERVER['HTTP_REFERER']) |
649 | 649 | : ''; |
650 | 650 | // no previous session = go back and create one (on top of the data above) |
@@ -682,7 +682,7 @@ discard block |
||
682 | 682 | */ |
683 | 683 | protected function _retrieve_session_data() |
684 | 684 | { |
685 | - $ssn_key = EE_Session::session_id_prefix . $this->_sid; |
|
685 | + $ssn_key = EE_Session::session_id_prefix.$this->_sid; |
|
686 | 686 | try { |
687 | 687 | // we're using WP's Transient API to store session data using the PHP session ID as the option name |
688 | 688 | $session_data = $this->cache_storage->get($ssn_key, false); |
@@ -691,7 +691,7 @@ discard block |
||
691 | 691 | } |
692 | 692 | if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
693 | 693 | $hash_check = $this->cache_storage->get( |
694 | - EE_Session::hash_check_prefix . $this->_sid, |
|
694 | + EE_Session::hash_check_prefix.$this->_sid, |
|
695 | 695 | false |
696 | 696 | ); |
697 | 697 | if ($hash_check && $hash_check !== md5($session_data)) { |
@@ -701,7 +701,7 @@ discard block |
||
701 | 701 | 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.', |
702 | 702 | 'event_espresso' |
703 | 703 | ), |
704 | - EE_Session::session_id_prefix . $this->_sid |
|
704 | + EE_Session::session_id_prefix.$this->_sid |
|
705 | 705 | ), |
706 | 706 | __FILE__, |
707 | 707 | __FUNCTION__, |
@@ -715,17 +715,17 @@ discard block |
||
715 | 715 | $row = $wpdb->get_row( |
716 | 716 | $wpdb->prepare( |
717 | 717 | "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", |
718 | - '_transient_' . $ssn_key |
|
718 | + '_transient_'.$ssn_key |
|
719 | 719 | ) |
720 | 720 | ); |
721 | 721 | $session_data = is_object($row) ? $row->option_value : null; |
722 | 722 | if ($session_data) { |
723 | 723 | $session_data = preg_replace_callback( |
724 | 724 | '!s:(d+):"(.*?)";!', |
725 | - function ($match) { |
|
725 | + function($match) { |
|
726 | 726 | return $match[1] === strlen($match[2]) |
727 | 727 | ? $match[0] |
728 | - : 's:' . strlen($match[2]) . ':"' . $match[2] . '";'; |
|
728 | + : 's:'.strlen($match[2]).':"'.$match[2].'";'; |
|
729 | 729 | }, |
730 | 730 | $session_data |
731 | 731 | ); |
@@ -736,7 +736,7 @@ discard block |
||
736 | 736 | $session_data = $this->encryption instanceof EE_Encryption |
737 | 737 | ? $this->encryption->base64_string_decode($session_data) |
738 | 738 | : $session_data; |
739 | - if (! is_array($session_data)) { |
|
739 | + if ( ! is_array($session_data)) { |
|
740 | 740 | try { |
741 | 741 | $session_data = maybe_unserialize($session_data); |
742 | 742 | } catch (Exception $e) { |
@@ -750,21 +750,21 @@ discard block |
||
750 | 750 | . '</pre><br>' |
751 | 751 | . $this->find_serialize_error($session_data) |
752 | 752 | : ''; |
753 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
753 | + $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid); |
|
754 | 754 | throw new InvalidSessionDataException($msg, 0, $e); |
755 | 755 | } |
756 | 756 | } |
757 | 757 | // just a check to make sure the session array is indeed an array |
758 | - if (! is_array($session_data)) { |
|
758 | + if ( ! is_array($session_data)) { |
|
759 | 759 | // no?!?! then something is wrong |
760 | 760 | $msg = esc_html__( |
761 | 761 | 'The session data is missing, invalid, or corrupted.', |
762 | 762 | 'event_espresso' |
763 | 763 | ); |
764 | 764 | $msg .= WP_DEBUG |
765 | - ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data) |
|
765 | + ? '<br><pre>'.print_r($session_data, true).'</pre><br>'.$this->find_serialize_error($session_data) |
|
766 | 766 | : ''; |
767 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
767 | + $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid); |
|
768 | 768 | throw new InvalidSessionDataException($msg); |
769 | 769 | } |
770 | 770 | if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) { |
@@ -791,7 +791,7 @@ discard block |
||
791 | 791 | if (isset($_REQUEST['EESID'])) { |
792 | 792 | $session_id = sanitize_text_field($_REQUEST['EESID']); |
793 | 793 | } else { |
794 | - $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt()); |
|
794 | + $session_id = md5(session_id().get_current_blog_id().$this->_get_sid_salt()); |
|
795 | 795 | } |
796 | 796 | return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id); |
797 | 797 | } |
@@ -895,19 +895,19 @@ discard block |
||
895 | 895 | $page_visit = $this->_get_page_visit(); |
896 | 896 | if ($page_visit) { |
897 | 897 | // set pages visited where the first will be the http referrer |
898 | - $this->_session_data['pages_visited'][ $this->_time ] = $page_visit; |
|
898 | + $this->_session_data['pages_visited'][$this->_time] = $page_visit; |
|
899 | 899 | // we'll only save the last 10 page visits. |
900 | 900 | $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10); |
901 | 901 | } |
902 | 902 | break; |
903 | 903 | default: |
904 | 904 | // carry any other data over |
905 | - $session_data[ $key ] = $this->_session_data[ $key ]; |
|
905 | + $session_data[$key] = $this->_session_data[$key]; |
|
906 | 906 | } |
907 | 907 | } |
908 | 908 | $this->_session_data = $session_data; |
909 | 909 | // creating a new session does not require saving to the db just yet |
910 | - if (! $new_session) { |
|
910 | + if ( ! $new_session) { |
|
911 | 911 | // ready? let's save |
912 | 912 | if ($this->_save_session_to_db()) { |
913 | 913 | return true; |
@@ -986,7 +986,7 @@ discard block |
||
986 | 986 | } |
987 | 987 | $transaction = $this->transaction(); |
988 | 988 | if ($transaction instanceof EE_Transaction) { |
989 | - if (! $transaction->ID()) { |
|
989 | + if ( ! $transaction->ID()) { |
|
990 | 990 | $transaction->save(); |
991 | 991 | } |
992 | 992 | $this->_session_data['transaction'] = $transaction->ID(); |
@@ -1000,14 +1000,14 @@ discard block |
||
1000 | 1000 | // maybe save hash check |
1001 | 1001 | if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
1002 | 1002 | $this->cache_storage->add( |
1003 | - EE_Session::hash_check_prefix . $this->_sid, |
|
1003 | + EE_Session::hash_check_prefix.$this->_sid, |
|
1004 | 1004 | md5($session_data), |
1005 | 1005 | $this->session_lifespan->inSeconds() |
1006 | 1006 | ); |
1007 | 1007 | } |
1008 | 1008 | // we're using the Transient API for storing session data, |
1009 | 1009 | $saved = $this->cache_storage->add( |
1010 | - EE_Session::session_id_prefix . $this->_sid, |
|
1010 | + EE_Session::session_id_prefix.$this->_sid, |
|
1011 | 1011 | $session_data, |
1012 | 1012 | $this->session_lifespan->inSeconds() |
1013 | 1013 | ); |
@@ -1023,7 +1023,7 @@ discard block |
||
1023 | 1023 | */ |
1024 | 1024 | public function _get_page_visit() |
1025 | 1025 | { |
1026 | - $page_visit = home_url('/') . 'wp-admin/admin-ajax.php'; |
|
1026 | + $page_visit = home_url('/').'wp-admin/admin-ajax.php'; |
|
1027 | 1027 | // check for request url |
1028 | 1028 | if (isset($_SERVER['REQUEST_URI'])) { |
1029 | 1029 | $http_host = ''; |
@@ -1039,14 +1039,14 @@ discard block |
||
1039 | 1039 | // check for page_id in SERVER REQUEST |
1040 | 1040 | if (isset($_REQUEST['page_id'])) { |
1041 | 1041 | // rebuild $e_reg without any of the extra parameters |
1042 | - $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&'; |
|
1042 | + $page_id = '?page_id='.esc_attr($_REQUEST['page_id']).'&'; |
|
1043 | 1043 | } |
1044 | 1044 | // check for $e_reg in SERVER REQUEST |
1045 | 1045 | if (isset($_REQUEST['ee'])) { |
1046 | 1046 | // rebuild $e_reg without any of the extra parameters |
1047 | - $e_reg = 'ee=' . esc_attr($_REQUEST['ee']); |
|
1047 | + $e_reg = 'ee='.esc_attr($_REQUEST['ee']); |
|
1048 | 1048 | } |
1049 | - $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?'); |
|
1049 | + $page_visit = rtrim($http_host.$request_uri.$page_id.$e_reg, '?'); |
|
1050 | 1050 | } |
1051 | 1051 | return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : ''; |
1052 | 1052 | } |
@@ -1085,7 +1085,7 @@ discard block |
||
1085 | 1085 | // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/> |
1086 | 1086 | // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span> <b style="font-size:10px;"> ' . __LINE__ . ' </b> |
1087 | 1087 | // </h3>'; |
1088 | - do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()'); |
|
1088 | + do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : '.$class.'::'.$function.'()'); |
|
1089 | 1089 | $this->reset_cart(); |
1090 | 1090 | $this->reset_checkout(); |
1091 | 1091 | $this->reset_transaction(); |
@@ -1108,7 +1108,7 @@ discard block |
||
1108 | 1108 | public function reset_data($data_to_reset = array(), $show_all_notices = false) |
1109 | 1109 | { |
1110 | 1110 | // if $data_to_reset is not in an array, then put it in one |
1111 | - if (! is_array($data_to_reset)) { |
|
1111 | + if ( ! is_array($data_to_reset)) { |
|
1112 | 1112 | $data_to_reset = array($data_to_reset); |
1113 | 1113 | } |
1114 | 1114 | // nothing ??? go home! |
@@ -1128,11 +1128,11 @@ discard block |
||
1128 | 1128 | // since $data_to_reset is an array, cycle through the values |
1129 | 1129 | foreach ($data_to_reset as $reset) { |
1130 | 1130 | // first check to make sure it is a valid session var |
1131 | - if (isset($this->_session_data[ $reset ])) { |
|
1131 | + if (isset($this->_session_data[$reset])) { |
|
1132 | 1132 | // then check to make sure it is not a default var |
1133 | - if (! array_key_exists($reset, $this->_default_session_vars)) { |
|
1133 | + if ( ! array_key_exists($reset, $this->_default_session_vars)) { |
|
1134 | 1134 | // remove session var |
1135 | - unset($this->_session_data[ $reset ]); |
|
1135 | + unset($this->_session_data[$reset]); |
|
1136 | 1136 | $this->setSaveState(); |
1137 | 1137 | if ($show_all_notices) { |
1138 | 1138 | EE_Error::add_success( |
@@ -1236,7 +1236,7 @@ discard block |
||
1236 | 1236 | // or use that for the new transient cleanup query limit |
1237 | 1237 | add_filter( |
1238 | 1238 | 'FHEE__TransientCacheStorage__clearExpiredTransients__limit', |
1239 | - function () use ($expired_session_transient_delete_query_limit) { |
|
1239 | + function() use ($expired_session_transient_delete_query_limit) { |
|
1240 | 1240 | return $expired_session_transient_delete_query_limit; |
1241 | 1241 | } |
1242 | 1242 | ); |
@@ -1254,7 +1254,7 @@ discard block |
||
1254 | 1254 | $error = '<pre>'; |
1255 | 1255 | $data2 = preg_replace_callback( |
1256 | 1256 | '!s:(\d+):"(.*?)";!', |
1257 | - function ($match) { |
|
1257 | + function($match) { |
|
1258 | 1258 | return ($match[1] === strlen($match[2])) |
1259 | 1259 | ? $match[0] |
1260 | 1260 | : 's:' |
@@ -1266,13 +1266,13 @@ discard block |
||
1266 | 1266 | $data1 |
1267 | 1267 | ); |
1268 | 1268 | $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2); |
1269 | - $error .= $data1 . PHP_EOL; |
|
1270 | - $error .= $data2 . PHP_EOL; |
|
1269 | + $error .= $data1.PHP_EOL; |
|
1270 | + $error .= $data2.PHP_EOL; |
|
1271 | 1271 | for ($i = 0; $i < $max; $i++) { |
1272 | - if (@$data1[ $i ] !== @$data2[ $i ]) { |
|
1273 | - $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL; |
|
1274 | - $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL; |
|
1275 | - $error .= "\t-> Line Number = $i" . PHP_EOL; |
|
1272 | + if (@$data1[$i] !== @$data2[$i]) { |
|
1273 | + $error .= 'Difference '.@$data1[$i].' != '.@$data2[$i].PHP_EOL; |
|
1274 | + $error .= "\t-> ORD number ".ord(@$data1[$i]).' != '.ord(@$data2[$i]).PHP_EOL; |
|
1275 | + $error .= "\t-> Line Number = $i".PHP_EOL; |
|
1276 | 1276 | $start = ($i - 20); |
1277 | 1277 | $start = ($start < 0) ? 0 : $start; |
1278 | 1278 | $length = 40; |
@@ -1287,7 +1287,7 @@ discard block |
||
1287 | 1287 | $error .= "\t-> Section Data1 = "; |
1288 | 1288 | $error .= substr_replace( |
1289 | 1289 | substr($data1, $start, $length), |
1290 | - "<b style=\"color:green\">{$data1[ $i ]}</b>", |
|
1290 | + "<b style=\"color:green\">{$data1[$i]}</b>", |
|
1291 | 1291 | $rpoint, |
1292 | 1292 | $rlength |
1293 | 1293 | ); |
@@ -1295,7 +1295,7 @@ discard block |
||
1295 | 1295 | $error .= "\t-> Section Data2 = "; |
1296 | 1296 | $error .= substr_replace( |
1297 | 1297 | substr($data2, $start, $length), |
1298 | - "<b style=\"color:red\">{$data2[ $i ]}</b>", |
|
1298 | + "<b style=\"color:red\">{$data2[$i]}</b>", |
|
1299 | 1299 | $rpoint, |
1300 | 1300 | $rlength |
1301 | 1301 | ); |
@@ -1326,7 +1326,7 @@ discard block |
||
1326 | 1326 | public function garbageCollection() |
1327 | 1327 | { |
1328 | 1328 | // only perform during regular requests if last garbage collection was over an hour ago |
1329 | - if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1329 | + if ( ! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1330 | 1330 | $this->_last_gc = time(); |
1331 | 1331 | $this->updateSessionSettings(array('last_gc' => $this->_last_gc)); |
1332 | 1332 | /** @type WPDB $wpdb */ |
@@ -1361,7 +1361,7 @@ discard block |
||
1361 | 1361 | // AND option_value < 1508368198 LIMIT 50 |
1362 | 1362 | $expired_sessions = $wpdb->get_col($SQL); |
1363 | 1363 | // valid results? |
1364 | - if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1364 | + if ( ! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1365 | 1365 | $this->cache_storage->deleteMany($expired_sessions, true); |
1366 | 1366 | } |
1367 | 1367 | } |
@@ -14,28 +14,28 @@ |
||
14 | 14 | class EE_Detect_File_Editor_Request extends EE_Middleware |
15 | 15 | { |
16 | 16 | |
17 | - /** |
|
18 | - * @deprecated |
|
19 | - * @param EE_Request $request |
|
20 | - * @param EE_Response $response |
|
21 | - * @return EE_Response |
|
22 | - */ |
|
23 | - public function handle_request(EE_Request $request, EE_Response $response) |
|
24 | - { |
|
25 | - EE_Error::doing_it_wrong( |
|
26 | - __METHOD__, |
|
27 | - sprintf( |
|
28 | - esc_html__( |
|
29 | - 'This class is deprecated. Please use %1$s instead. All Event Espresso request stack classes have been moved to %2$s and are now under the %3$s namespace', |
|
30 | - 'event_espresso' |
|
31 | - ), |
|
32 | - 'EventEspresso\core\services\request\middleware\DetectFileEditorRequest', |
|
33 | - '\core\services\request', |
|
34 | - 'EventEspresso\core\services\request' |
|
35 | - ), |
|
36 | - '4.9.52' |
|
37 | - ); |
|
38 | - return $response; |
|
39 | - } |
|
17 | + /** |
|
18 | + * @deprecated |
|
19 | + * @param EE_Request $request |
|
20 | + * @param EE_Response $response |
|
21 | + * @return EE_Response |
|
22 | + */ |
|
23 | + public function handle_request(EE_Request $request, EE_Response $response) |
|
24 | + { |
|
25 | + EE_Error::doing_it_wrong( |
|
26 | + __METHOD__, |
|
27 | + sprintf( |
|
28 | + esc_html__( |
|
29 | + 'This class is deprecated. Please use %1$s instead. All Event Espresso request stack classes have been moved to %2$s and are now under the %3$s namespace', |
|
30 | + 'event_espresso' |
|
31 | + ), |
|
32 | + 'EventEspresso\core\services\request\middleware\DetectFileEditorRequest', |
|
33 | + '\core\services\request', |
|
34 | + 'EventEspresso\core\services\request' |
|
35 | + ), |
|
36 | + '4.9.52' |
|
37 | + ); |
|
38 | + return $response; |
|
39 | + } |
|
40 | 40 | |
41 | 41 | } |
@@ -101,7 +101,7 @@ |
||
101 | 101 | |
102 | 102 | |
103 | 103 | /** |
104 | - * @param FullyQualifiedName|string $fqcn |
|
104 | + * @param string $fqcn |
|
105 | 105 | * @param array $arguments |
106 | 106 | * @return mixed |
107 | 107 | */ |
@@ -15,116 +15,116 @@ |
||
15 | 15 | class Loader implements LoaderInterface |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * @var LoaderDecoratorInterface $new_loader |
|
20 | - */ |
|
21 | - private $new_loader; |
|
22 | - |
|
23 | - /** |
|
24 | - * @var LoaderDecoratorInterface $shared_loader |
|
25 | - */ |
|
26 | - private $shared_loader; |
|
27 | - |
|
28 | - /** |
|
29 | - * @var ClassInterfaceCache $class_cache |
|
30 | - */ |
|
31 | - private $class_cache; |
|
32 | - |
|
33 | - /** |
|
34 | - * Loader constructor. |
|
35 | - * |
|
36 | - * @param LoaderDecoratorInterface $new_loader |
|
37 | - * @param CachingLoaderDecoratorInterface $shared_loader |
|
38 | - * @param ClassInterfaceCache $class_cache |
|
39 | - */ |
|
40 | - public function __construct( |
|
41 | - LoaderDecoratorInterface $new_loader, |
|
42 | - CachingLoaderDecoratorInterface $shared_loader, |
|
43 | - ClassInterfaceCache $class_cache |
|
44 | - ) { |
|
45 | - $this->new_loader = $new_loader; |
|
46 | - $this->shared_loader = $shared_loader; |
|
47 | - $this->class_cache = $class_cache; |
|
48 | - } |
|
49 | - |
|
50 | - |
|
51 | - /** |
|
52 | - * @return LoaderDecoratorInterface |
|
53 | - */ |
|
54 | - public function getNewLoader() |
|
55 | - { |
|
56 | - return $this->new_loader; |
|
57 | - } |
|
58 | - |
|
59 | - |
|
60 | - /** |
|
61 | - * @return CachingLoaderDecoratorInterface |
|
62 | - */ |
|
63 | - public function getSharedLoader() |
|
64 | - { |
|
65 | - return $this->shared_loader; |
|
66 | - } |
|
67 | - |
|
68 | - |
|
69 | - /** |
|
70 | - * @param FullyQualifiedName|string $fqcn |
|
71 | - * @param array $arguments |
|
72 | - * @param bool $shared |
|
73 | - * @return mixed |
|
74 | - */ |
|
75 | - public function load($fqcn, array $arguments = array(), $shared = true) |
|
76 | - { |
|
77 | - $fqcn = $this->class_cache->getFqn($fqcn); |
|
78 | - if ($this->class_cache->hasInterface($fqcn, 'EventEspresso\core\interfaces\ReservedInstanceInterface')) { |
|
79 | - $shared = true; |
|
80 | - } |
|
81 | - return $shared |
|
82 | - ? $this->getSharedLoader()->load($fqcn, $arguments, $shared) |
|
83 | - : $this->getNewLoader()->load($fqcn, $arguments, $shared); |
|
84 | - } |
|
85 | - |
|
86 | - |
|
87 | - /** |
|
88 | - * @param FullyQualifiedName|string $fqcn |
|
89 | - * @param array $arguments |
|
90 | - * @return mixed |
|
91 | - */ |
|
92 | - public function getNew($fqcn, array $arguments = array()) |
|
93 | - { |
|
94 | - return $this->load($fqcn, $arguments, false); |
|
95 | - } |
|
96 | - |
|
97 | - |
|
98 | - /** |
|
99 | - * @param FullyQualifiedName|string $fqcn |
|
100 | - * @param array $arguments |
|
101 | - * @return mixed |
|
102 | - */ |
|
103 | - public function getShared($fqcn, array $arguments = array()) |
|
104 | - { |
|
105 | - return $this->load($fqcn, $arguments); |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * @param FullyQualifiedName|string $fqcn |
|
111 | - * @param mixed $object |
|
112 | - * @param array $arguments |
|
113 | - * @return bool |
|
114 | - * @throws InvalidArgumentException |
|
115 | - */ |
|
116 | - public function share($fqcn, $object, array $arguments = []) |
|
117 | - { |
|
118 | - $fqcn = $this->class_cache->getFqn($fqcn); |
|
119 | - return $this->getSharedLoader()->share($fqcn, $object, $arguments); |
|
120 | - } |
|
121 | - |
|
122 | - |
|
123 | - /** |
|
124 | - * calls reset() on loaders if that method exists |
|
125 | - */ |
|
126 | - public function reset() |
|
127 | - { |
|
128 | - $this->shared_loader->reset(); |
|
129 | - } |
|
18 | + /** |
|
19 | + * @var LoaderDecoratorInterface $new_loader |
|
20 | + */ |
|
21 | + private $new_loader; |
|
22 | + |
|
23 | + /** |
|
24 | + * @var LoaderDecoratorInterface $shared_loader |
|
25 | + */ |
|
26 | + private $shared_loader; |
|
27 | + |
|
28 | + /** |
|
29 | + * @var ClassInterfaceCache $class_cache |
|
30 | + */ |
|
31 | + private $class_cache; |
|
32 | + |
|
33 | + /** |
|
34 | + * Loader constructor. |
|
35 | + * |
|
36 | + * @param LoaderDecoratorInterface $new_loader |
|
37 | + * @param CachingLoaderDecoratorInterface $shared_loader |
|
38 | + * @param ClassInterfaceCache $class_cache |
|
39 | + */ |
|
40 | + public function __construct( |
|
41 | + LoaderDecoratorInterface $new_loader, |
|
42 | + CachingLoaderDecoratorInterface $shared_loader, |
|
43 | + ClassInterfaceCache $class_cache |
|
44 | + ) { |
|
45 | + $this->new_loader = $new_loader; |
|
46 | + $this->shared_loader = $shared_loader; |
|
47 | + $this->class_cache = $class_cache; |
|
48 | + } |
|
49 | + |
|
50 | + |
|
51 | + /** |
|
52 | + * @return LoaderDecoratorInterface |
|
53 | + */ |
|
54 | + public function getNewLoader() |
|
55 | + { |
|
56 | + return $this->new_loader; |
|
57 | + } |
|
58 | + |
|
59 | + |
|
60 | + /** |
|
61 | + * @return CachingLoaderDecoratorInterface |
|
62 | + */ |
|
63 | + public function getSharedLoader() |
|
64 | + { |
|
65 | + return $this->shared_loader; |
|
66 | + } |
|
67 | + |
|
68 | + |
|
69 | + /** |
|
70 | + * @param FullyQualifiedName|string $fqcn |
|
71 | + * @param array $arguments |
|
72 | + * @param bool $shared |
|
73 | + * @return mixed |
|
74 | + */ |
|
75 | + public function load($fqcn, array $arguments = array(), $shared = true) |
|
76 | + { |
|
77 | + $fqcn = $this->class_cache->getFqn($fqcn); |
|
78 | + if ($this->class_cache->hasInterface($fqcn, 'EventEspresso\core\interfaces\ReservedInstanceInterface')) { |
|
79 | + $shared = true; |
|
80 | + } |
|
81 | + return $shared |
|
82 | + ? $this->getSharedLoader()->load($fqcn, $arguments, $shared) |
|
83 | + : $this->getNewLoader()->load($fqcn, $arguments, $shared); |
|
84 | + } |
|
85 | + |
|
86 | + |
|
87 | + /** |
|
88 | + * @param FullyQualifiedName|string $fqcn |
|
89 | + * @param array $arguments |
|
90 | + * @return mixed |
|
91 | + */ |
|
92 | + public function getNew($fqcn, array $arguments = array()) |
|
93 | + { |
|
94 | + return $this->load($fqcn, $arguments, false); |
|
95 | + } |
|
96 | + |
|
97 | + |
|
98 | + /** |
|
99 | + * @param FullyQualifiedName|string $fqcn |
|
100 | + * @param array $arguments |
|
101 | + * @return mixed |
|
102 | + */ |
|
103 | + public function getShared($fqcn, array $arguments = array()) |
|
104 | + { |
|
105 | + return $this->load($fqcn, $arguments); |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * @param FullyQualifiedName|string $fqcn |
|
111 | + * @param mixed $object |
|
112 | + * @param array $arguments |
|
113 | + * @return bool |
|
114 | + * @throws InvalidArgumentException |
|
115 | + */ |
|
116 | + public function share($fqcn, $object, array $arguments = []) |
|
117 | + { |
|
118 | + $fqcn = $this->class_cache->getFqn($fqcn); |
|
119 | + return $this->getSharedLoader()->share($fqcn, $object, $arguments); |
|
120 | + } |
|
121 | + |
|
122 | + |
|
123 | + /** |
|
124 | + * calls reset() on loaders if that method exists |
|
125 | + */ |
|
126 | + public function reset() |
|
127 | + { |
|
128 | + $this->shared_loader->reset(); |
|
129 | + } |
|
130 | 130 | } |
@@ -78,13 +78,13 @@ |
||
78 | 78 | // EE_Dependency_Map: info about how to load classes required by other classes |
79 | 79 | espresso_load_required( |
80 | 80 | 'EE_Dependency_Map', |
81 | - EE_CORE . 'EE_Dependency_Map.core.php' |
|
81 | + EE_CORE.'EE_Dependency_Map.core.php' |
|
82 | 82 | ); |
83 | 83 | $this->dependency_map = EE_Dependency_Map::instance($this->class_cache); |
84 | 84 | // EE_Registry: central repository for classes (legacy) |
85 | 85 | espresso_load_required( |
86 | 86 | 'EE_Registry', |
87 | - EE_CORE . 'EE_Registry.core.php' |
|
87 | + EE_CORE.'EE_Registry.core.php' |
|
88 | 88 | ); |
89 | 89 | $this->registry = EE_Registry::instance( |
90 | 90 | $this->dependency_map, |
@@ -25,123 +25,123 @@ |
||
25 | 25 | class BootstrapDependencyInjectionContainer |
26 | 26 | { |
27 | 27 | |
28 | - /** |
|
29 | - * @var EE_Dependency_Map $dependency_map |
|
30 | - */ |
|
31 | - protected $dependency_map; |
|
32 | - |
|
33 | - /** |
|
34 | - * @type LoaderInterface $loader |
|
35 | - */ |
|
36 | - protected $loader; |
|
37 | - |
|
38 | - /** |
|
39 | - * @var EE_Registry $registry |
|
40 | - */ |
|
41 | - protected $registry; |
|
42 | - |
|
43 | - /** |
|
44 | - * @var ClassInterfaceCache $class_cache |
|
45 | - */ |
|
46 | - private $class_cache; |
|
47 | - |
|
48 | - /** |
|
49 | - * @var Mirror |
|
50 | - */ |
|
51 | - private $mirror; |
|
52 | - |
|
53 | - /** |
|
54 | - * @var ObjectIdentifier |
|
55 | - */ |
|
56 | - private $object_identifier; |
|
57 | - |
|
58 | - |
|
59 | - /** |
|
60 | - * Can't use this just yet until we exorcise some more of our singleton usage from core |
|
61 | - */ |
|
62 | - public function buildDependencyInjectionContainer() |
|
63 | - { |
|
64 | - // build DI container |
|
65 | - // $OpenCoffeeShop = new EventEspresso\core\services\container\OpenCoffeeShop(); |
|
66 | - // $OpenCoffeeShop->addRecipes(); |
|
67 | - // $CoffeeShop = $OpenCoffeeShop->CoffeeShop(); |
|
68 | - } |
|
69 | - |
|
70 | - |
|
71 | - /** |
|
72 | - * Setups EE_Registry and EE_Dependency_Map |
|
73 | - * |
|
74 | - * @throws EE_Error |
|
75 | - */ |
|
76 | - public function buildLegacyDependencyInjectionContainer() |
|
77 | - { |
|
78 | - $this->class_cache = new ClassInterfaceCache(); |
|
79 | - $this->object_identifier = new ObjectIdentifier($this->class_cache); |
|
80 | - $this->mirror = new Mirror(); |
|
81 | - // EE_Dependency_Map: info about how to load classes required by other classes |
|
82 | - espresso_load_required( |
|
83 | - 'EE_Dependency_Map', |
|
84 | - EE_CORE . 'EE_Dependency_Map.core.php' |
|
85 | - ); |
|
86 | - $this->dependency_map = EE_Dependency_Map::instance($this->class_cache); |
|
87 | - // EE_Registry: central repository for classes (legacy) |
|
88 | - espresso_load_required( |
|
89 | - 'EE_Registry', |
|
90 | - EE_CORE . 'EE_Registry.core.php' |
|
91 | - ); |
|
92 | - $this->registry = EE_Registry::instance( |
|
93 | - $this->dependency_map, |
|
94 | - $this->mirror, |
|
95 | - $this->class_cache, |
|
96 | - $this->object_identifier |
|
97 | - ); |
|
98 | - } |
|
99 | - |
|
100 | - |
|
101 | - /** |
|
102 | - * Performs initial setup for the generic Loader |
|
103 | - * |
|
104 | - * @throws InvalidDataTypeException |
|
105 | - * @throws InvalidInterfaceException |
|
106 | - * @throws InvalidArgumentException |
|
107 | - */ |
|
108 | - public function buildLoader() |
|
109 | - { |
|
110 | - $this->loader = LoaderFactory::getLoader( |
|
111 | - $this->registry, |
|
112 | - $this->class_cache, |
|
113 | - $this->object_identifier |
|
114 | - ); |
|
115 | - $this->loader->share('EventEspresso\core\services\loaders\ClassInterfaceCache', $this->class_cache); |
|
116 | - $this->loader->share('EventEspresso\core\services\loaders\ObjectIdentifier', $this->object_identifier); |
|
117 | - $this->loader->share('EventEspresso\core\services\container\Mirror', $this->mirror); |
|
118 | - $this->dependency_map->setLoader($this->loader); |
|
119 | - } |
|
120 | - |
|
121 | - |
|
122 | - /** |
|
123 | - * @return EE_Dependency_Map |
|
124 | - */ |
|
125 | - public function getDependencyMap() |
|
126 | - { |
|
127 | - return $this->dependency_map; |
|
128 | - } |
|
129 | - |
|
130 | - |
|
131 | - /** |
|
132 | - * @return EE_Registry |
|
133 | - */ |
|
134 | - public function getRegistry() |
|
135 | - { |
|
136 | - return $this->registry; |
|
137 | - } |
|
138 | - |
|
139 | - |
|
140 | - /** |
|
141 | - * @return LoaderInterface |
|
142 | - */ |
|
143 | - public function getLoader() |
|
144 | - { |
|
145 | - return $this->loader; |
|
146 | - } |
|
28 | + /** |
|
29 | + * @var EE_Dependency_Map $dependency_map |
|
30 | + */ |
|
31 | + protected $dependency_map; |
|
32 | + |
|
33 | + /** |
|
34 | + * @type LoaderInterface $loader |
|
35 | + */ |
|
36 | + protected $loader; |
|
37 | + |
|
38 | + /** |
|
39 | + * @var EE_Registry $registry |
|
40 | + */ |
|
41 | + protected $registry; |
|
42 | + |
|
43 | + /** |
|
44 | + * @var ClassInterfaceCache $class_cache |
|
45 | + */ |
|
46 | + private $class_cache; |
|
47 | + |
|
48 | + /** |
|
49 | + * @var Mirror |
|
50 | + */ |
|
51 | + private $mirror; |
|
52 | + |
|
53 | + /** |
|
54 | + * @var ObjectIdentifier |
|
55 | + */ |
|
56 | + private $object_identifier; |
|
57 | + |
|
58 | + |
|
59 | + /** |
|
60 | + * Can't use this just yet until we exorcise some more of our singleton usage from core |
|
61 | + */ |
|
62 | + public function buildDependencyInjectionContainer() |
|
63 | + { |
|
64 | + // build DI container |
|
65 | + // $OpenCoffeeShop = new EventEspresso\core\services\container\OpenCoffeeShop(); |
|
66 | + // $OpenCoffeeShop->addRecipes(); |
|
67 | + // $CoffeeShop = $OpenCoffeeShop->CoffeeShop(); |
|
68 | + } |
|
69 | + |
|
70 | + |
|
71 | + /** |
|
72 | + * Setups EE_Registry and EE_Dependency_Map |
|
73 | + * |
|
74 | + * @throws EE_Error |
|
75 | + */ |
|
76 | + public function buildLegacyDependencyInjectionContainer() |
|
77 | + { |
|
78 | + $this->class_cache = new ClassInterfaceCache(); |
|
79 | + $this->object_identifier = new ObjectIdentifier($this->class_cache); |
|
80 | + $this->mirror = new Mirror(); |
|
81 | + // EE_Dependency_Map: info about how to load classes required by other classes |
|
82 | + espresso_load_required( |
|
83 | + 'EE_Dependency_Map', |
|
84 | + EE_CORE . 'EE_Dependency_Map.core.php' |
|
85 | + ); |
|
86 | + $this->dependency_map = EE_Dependency_Map::instance($this->class_cache); |
|
87 | + // EE_Registry: central repository for classes (legacy) |
|
88 | + espresso_load_required( |
|
89 | + 'EE_Registry', |
|
90 | + EE_CORE . 'EE_Registry.core.php' |
|
91 | + ); |
|
92 | + $this->registry = EE_Registry::instance( |
|
93 | + $this->dependency_map, |
|
94 | + $this->mirror, |
|
95 | + $this->class_cache, |
|
96 | + $this->object_identifier |
|
97 | + ); |
|
98 | + } |
|
99 | + |
|
100 | + |
|
101 | + /** |
|
102 | + * Performs initial setup for the generic Loader |
|
103 | + * |
|
104 | + * @throws InvalidDataTypeException |
|
105 | + * @throws InvalidInterfaceException |
|
106 | + * @throws InvalidArgumentException |
|
107 | + */ |
|
108 | + public function buildLoader() |
|
109 | + { |
|
110 | + $this->loader = LoaderFactory::getLoader( |
|
111 | + $this->registry, |
|
112 | + $this->class_cache, |
|
113 | + $this->object_identifier |
|
114 | + ); |
|
115 | + $this->loader->share('EventEspresso\core\services\loaders\ClassInterfaceCache', $this->class_cache); |
|
116 | + $this->loader->share('EventEspresso\core\services\loaders\ObjectIdentifier', $this->object_identifier); |
|
117 | + $this->loader->share('EventEspresso\core\services\container\Mirror', $this->mirror); |
|
118 | + $this->dependency_map->setLoader($this->loader); |
|
119 | + } |
|
120 | + |
|
121 | + |
|
122 | + /** |
|
123 | + * @return EE_Dependency_Map |
|
124 | + */ |
|
125 | + public function getDependencyMap() |
|
126 | + { |
|
127 | + return $this->dependency_map; |
|
128 | + } |
|
129 | + |
|
130 | + |
|
131 | + /** |
|
132 | + * @return EE_Registry |
|
133 | + */ |
|
134 | + public function getRegistry() |
|
135 | + { |
|
136 | + return $this->registry; |
|
137 | + } |
|
138 | + |
|
139 | + |
|
140 | + /** |
|
141 | + * @return LoaderInterface |
|
142 | + */ |
|
143 | + public function getLoader() |
|
144 | + { |
|
145 | + return $this->loader; |
|
146 | + } |
|
147 | 147 | } |
@@ -64,13 +64,13 @@ discard block |
||
64 | 64 | */ |
65 | 65 | public function getReflectionClass($class_name) |
66 | 66 | { |
67 | - if (! is_string($class_name)) { |
|
67 | + if ( ! is_string($class_name)) { |
|
68 | 68 | throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)'); |
69 | 69 | } |
70 | - if (! isset($this->classes[ $class_name ])) { |
|
71 | - $this->classes[ $class_name ] = new ReflectionClass($class_name); |
|
70 | + if ( ! isset($this->classes[$class_name])) { |
|
71 | + $this->classes[$class_name] = new ReflectionClass($class_name); |
|
72 | 72 | } |
73 | - return $this->classes[ $class_name ]; |
|
73 | + return $this->classes[$class_name]; |
|
74 | 74 | } |
75 | 75 | |
76 | 76 | |
@@ -82,14 +82,14 @@ discard block |
||
82 | 82 | */ |
83 | 83 | public function getConstructor($class_name) |
84 | 84 | { |
85 | - if (! is_string($class_name)) { |
|
85 | + if ( ! is_string($class_name)) { |
|
86 | 86 | throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)'); |
87 | 87 | } |
88 | - if (! isset($this->constructors[ $class_name ])) { |
|
88 | + if ( ! isset($this->constructors[$class_name])) { |
|
89 | 89 | $reflection_class = $this->getReflectionClass($class_name); |
90 | - $this->constructors[ $class_name ] = $reflection_class->getConstructor(); |
|
90 | + $this->constructors[$class_name] = $reflection_class->getConstructor(); |
|
91 | 91 | } |
92 | - return $this->constructors[ $class_name ]; |
|
92 | + return $this->constructors[$class_name]; |
|
93 | 93 | } |
94 | 94 | |
95 | 95 | |
@@ -113,11 +113,11 @@ discard block |
||
113 | 113 | */ |
114 | 114 | public function getParameters($class_name) |
115 | 115 | { |
116 | - if (! isset($this->parameters[ $class_name ])) { |
|
116 | + if ( ! isset($this->parameters[$class_name])) { |
|
117 | 117 | $constructor = $this->getConstructor($class_name); |
118 | - $this->parameters[ $class_name ] = $constructor->getParameters(); |
|
118 | + $this->parameters[$class_name] = $constructor->getParameters(); |
|
119 | 119 | } |
120 | - return $this->parameters[ $class_name ]; |
|
120 | + return $this->parameters[$class_name]; |
|
121 | 121 | } |
122 | 122 | |
123 | 123 | |
@@ -153,19 +153,19 @@ discard block |
||
153 | 153 | */ |
154 | 154 | public function getParameterClassName(ReflectionParameter $param, $class_name, $index) |
155 | 155 | { |
156 | - if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_name'])) { |
|
157 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_name']; |
|
156 | + if (isset($this->parameter_classes[$class_name][$index]['param_class_name'])) { |
|
157 | + return $this->parameter_classes[$class_name][$index]['param_class_name']; |
|
158 | 158 | } |
159 | - if (! isset($this->parameter_classes[ $class_name ])) { |
|
160 | - $this->parameter_classes[ $class_name ] = array(); |
|
159 | + if ( ! isset($this->parameter_classes[$class_name])) { |
|
160 | + $this->parameter_classes[$class_name] = array(); |
|
161 | 161 | } |
162 | - if (! isset($this->parameter_classes[ $class_name ][ $index ])) { |
|
163 | - $this->parameter_classes[ $class_name ][ $index ] = array(); |
|
162 | + if ( ! isset($this->parameter_classes[$class_name][$index])) { |
|
163 | + $this->parameter_classes[$class_name][$index] = array(); |
|
164 | 164 | } |
165 | - $this->parameter_classes[ $class_name ][ $index ]['param_class_name'] = $param->getClass() |
|
165 | + $this->parameter_classes[$class_name][$index]['param_class_name'] = $param->getClass() |
|
166 | 166 | ? $param->getClass()->name |
167 | 167 | : null; |
168 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_name']; |
|
168 | + return $this->parameter_classes[$class_name][$index]['param_class_name']; |
|
169 | 169 | } |
170 | 170 | |
171 | 171 | |
@@ -177,19 +177,19 @@ discard block |
||
177 | 177 | */ |
178 | 178 | public function getParameterDefaultValue(ReflectionParameter $param, $class_name, $index) |
179 | 179 | { |
180 | - if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_default'])) { |
|
181 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_default']; |
|
180 | + if (isset($this->parameter_classes[$class_name][$index]['param_class_default'])) { |
|
181 | + return $this->parameter_classes[$class_name][$index]['param_class_default']; |
|
182 | 182 | } |
183 | - if (! isset($this->parameter_classes[ $class_name ])) { |
|
184 | - $this->parameter_classes[ $class_name ] = array(); |
|
183 | + if ( ! isset($this->parameter_classes[$class_name])) { |
|
184 | + $this->parameter_classes[$class_name] = array(); |
|
185 | 185 | } |
186 | - if (! isset($this->parameter_classes[ $class_name ][ $index ])) { |
|
187 | - $this->parameter_classes[ $class_name ][ $index ] = array(); |
|
186 | + if ( ! isset($this->parameter_classes[$class_name][$index])) { |
|
187 | + $this->parameter_classes[$class_name][$index] = array(); |
|
188 | 188 | } |
189 | - $this->parameter_classes[ $class_name ][ $index ]['param_class_default'] = $param->isDefaultValueAvailable() |
|
189 | + $this->parameter_classes[$class_name][$index]['param_class_default'] = $param->isDefaultValueAvailable() |
|
190 | 190 | ? $param->getDefaultValue() |
191 | 191 | : null; |
192 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_default']; |
|
192 | + return $this->parameter_classes[$class_name][$index]['param_class_default']; |
|
193 | 193 | } |
194 | 194 | |
195 | 195 | |
@@ -201,11 +201,11 @@ discard block |
||
201 | 201 | */ |
202 | 202 | public function getProperties($class_name) |
203 | 203 | { |
204 | - if (! isset($this->properties[ $class_name ])) { |
|
204 | + if ( ! isset($this->properties[$class_name])) { |
|
205 | 205 | $reflection_class = $this->getReflectionClass($class_name); |
206 | - $this->properties[ $class_name ] = $reflection_class->getProperties(); |
|
206 | + $this->properties[$class_name] = $reflection_class->getProperties(); |
|
207 | 207 | } |
208 | - return $this->properties[ $class_name ]; |
|
208 | + return $this->properties[$class_name]; |
|
209 | 209 | } |
210 | 210 | |
211 | 211 | |
@@ -229,11 +229,11 @@ discard block |
||
229 | 229 | */ |
230 | 230 | public function getMethods($class_name) |
231 | 231 | { |
232 | - if (! isset($this->methods[ $class_name ])) { |
|
232 | + if ( ! isset($this->methods[$class_name])) { |
|
233 | 233 | $reflection_class = $this->getReflectionClass($class_name); |
234 | - $this->methods[ $class_name ] = $reflection_class->getMethods(); |
|
234 | + $this->methods[$class_name] = $reflection_class->getMethods(); |
|
235 | 235 | } |
236 | - return $this->methods[ $class_name ]; |
|
236 | + return $this->methods[$class_name]; |
|
237 | 237 | } |
238 | 238 | |
239 | 239 |
@@ -21,247 +21,247 @@ |
||
21 | 21 | class Mirror |
22 | 22 | { |
23 | 23 | |
24 | - /** |
|
25 | - * @var ReflectionClass[] $classes |
|
26 | - */ |
|
27 | - private $classes = array(); |
|
28 | - |
|
29 | - /** |
|
30 | - * @var ReflectionMethod[] $constructors |
|
31 | - */ |
|
32 | - private $constructors = array(); |
|
33 | - |
|
34 | - /** |
|
35 | - * @var ReflectionParameter[][] $parameters |
|
36 | - */ |
|
37 | - private $parameters = array(); |
|
38 | - |
|
39 | - /** |
|
40 | - * @var ReflectionParameter[][] $parameters |
|
41 | - */ |
|
42 | - private $parameter_classes = array(); |
|
43 | - |
|
44 | - /** |
|
45 | - * @var ReflectionProperty[][] $properties |
|
46 | - */ |
|
47 | - private $properties = array(); |
|
48 | - |
|
49 | - /** |
|
50 | - * @var ReflectionMethod[][] $methods |
|
51 | - */ |
|
52 | - private $methods = array(); |
|
53 | - |
|
54 | - |
|
55 | - /** |
|
56 | - * @param string $class_name |
|
57 | - * @return ReflectionClass |
|
58 | - * @throws ReflectionException |
|
59 | - * @throws InvalidDataTypeException |
|
60 | - */ |
|
61 | - public function getReflectionClass($class_name) |
|
62 | - { |
|
63 | - if (! is_string($class_name)) { |
|
64 | - throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)'); |
|
65 | - } |
|
66 | - if (! isset($this->classes[ $class_name ])) { |
|
67 | - $this->classes[ $class_name ] = new ReflectionClass($class_name); |
|
68 | - } |
|
69 | - return $this->classes[ $class_name ]; |
|
70 | - } |
|
71 | - |
|
72 | - |
|
73 | - /** |
|
74 | - * @param string $class_name |
|
75 | - * @return ReflectionMethod |
|
76 | - * @throws InvalidDataTypeException |
|
77 | - * @throws ReflectionException |
|
78 | - */ |
|
79 | - public function getConstructor($class_name) |
|
80 | - { |
|
81 | - if (! is_string($class_name)) { |
|
82 | - throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)'); |
|
83 | - } |
|
84 | - if (! isset($this->constructors[ $class_name ])) { |
|
85 | - $reflection_class = $this->getReflectionClass($class_name); |
|
86 | - $this->constructors[ $class_name ] = $reflection_class->getConstructor(); |
|
87 | - } |
|
88 | - return $this->constructors[ $class_name ]; |
|
89 | - } |
|
90 | - |
|
91 | - |
|
92 | - /** |
|
93 | - * @param ReflectionClass $reflection_class |
|
94 | - * @return ReflectionMethod |
|
95 | - * @throws InvalidDataTypeException |
|
96 | - * @throws ReflectionException |
|
97 | - */ |
|
98 | - public function getConstructorFromReflection(ReflectionClass $reflection_class) |
|
99 | - { |
|
100 | - return $this->getConstructor($reflection_class->getName()); |
|
101 | - } |
|
102 | - |
|
103 | - |
|
104 | - /** |
|
105 | - * @param string $class_name |
|
106 | - * @return ReflectionParameter[] |
|
107 | - * @throws InvalidDataTypeException |
|
108 | - * @throws ReflectionException |
|
109 | - */ |
|
110 | - public function getParameters($class_name) |
|
111 | - { |
|
112 | - if (! isset($this->parameters[ $class_name ])) { |
|
113 | - $constructor = $this->getConstructor($class_name); |
|
114 | - $this->parameters[ $class_name ] = $constructor->getParameters(); |
|
115 | - } |
|
116 | - return $this->parameters[ $class_name ]; |
|
117 | - } |
|
118 | - |
|
119 | - |
|
120 | - /** |
|
121 | - * @param ReflectionClass $reflection_class |
|
122 | - * @return ReflectionParameter[] |
|
123 | - * @throws InvalidDataTypeException |
|
124 | - * @throws ReflectionException |
|
125 | - */ |
|
126 | - public function getParametersFromReflection(ReflectionClass $reflection_class) |
|
127 | - { |
|
128 | - return $this->getParameters($reflection_class->getName()); |
|
129 | - } |
|
130 | - |
|
131 | - |
|
132 | - /** |
|
133 | - * @param ReflectionMethod $constructor |
|
134 | - * @return ReflectionParameter[] |
|
135 | - * @throws InvalidDataTypeException |
|
136 | - * @throws ReflectionException |
|
137 | - */ |
|
138 | - public function getParametersFromReflectionConstructor(ReflectionMethod $constructor) |
|
139 | - { |
|
140 | - return $this->getParameters($constructor->getDeclaringClass()); |
|
141 | - } |
|
142 | - |
|
143 | - |
|
144 | - /** |
|
145 | - * returns array of ReflectionParameter objects for parameters that are NOT optional |
|
146 | - * |
|
147 | - * @param string $class_name |
|
148 | - * @return ReflectionParameter[] |
|
149 | - * @throws InvalidDataTypeException |
|
150 | - * @throws ReflectionException |
|
151 | - */ |
|
152 | - public function getRequiredParameters($class_name) |
|
153 | - { |
|
154 | - $required_parameters = []; |
|
155 | - $parameters = $this->getParameters($class_name); |
|
156 | - foreach ($parameters as $parameter) { |
|
157 | - if ($parameter instanceof ReflectionParameter && ! $parameter->isOptional()) { |
|
158 | - $required_parameters[] = $parameter; |
|
159 | - } |
|
160 | - } |
|
161 | - return $required_parameters; |
|
162 | - } |
|
163 | - |
|
164 | - |
|
165 | - /** |
|
166 | - * @param ReflectionParameter $param |
|
167 | - * @param string $class_name |
|
168 | - * @param string $index |
|
169 | - * @return string|null |
|
170 | - */ |
|
171 | - public function getParameterClassName(ReflectionParameter $param, $class_name, $index) |
|
172 | - { |
|
173 | - if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_name'])) { |
|
174 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_name']; |
|
175 | - } |
|
176 | - if (! isset($this->parameter_classes[ $class_name ])) { |
|
177 | - $this->parameter_classes[ $class_name ] = array(); |
|
178 | - } |
|
179 | - if (! isset($this->parameter_classes[ $class_name ][ $index ])) { |
|
180 | - $this->parameter_classes[ $class_name ][ $index ] = array(); |
|
181 | - } |
|
182 | - $this->parameter_classes[ $class_name ][ $index ]['param_class_name'] = $param->getClass() |
|
183 | - ? $param->getClass()->name |
|
184 | - : null; |
|
185 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_name']; |
|
186 | - } |
|
187 | - |
|
188 | - |
|
189 | - /** |
|
190 | - * @param ReflectionParameter $param |
|
191 | - * @param string $class_name |
|
192 | - * @param string $index |
|
193 | - * @return string|null |
|
194 | - */ |
|
195 | - public function getParameterDefaultValue(ReflectionParameter $param, $class_name, $index) |
|
196 | - { |
|
197 | - if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_default'])) { |
|
198 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_default']; |
|
199 | - } |
|
200 | - if (! isset($this->parameter_classes[ $class_name ])) { |
|
201 | - $this->parameter_classes[ $class_name ] = array(); |
|
202 | - } |
|
203 | - if (! isset($this->parameter_classes[ $class_name ][ $index ])) { |
|
204 | - $this->parameter_classes[ $class_name ][ $index ] = array(); |
|
205 | - } |
|
206 | - $this->parameter_classes[ $class_name ][ $index ]['param_class_default'] = $param->isDefaultValueAvailable() |
|
207 | - ? $param->getDefaultValue() |
|
208 | - : null; |
|
209 | - return $this->parameter_classes[ $class_name ][ $index ]['param_class_default']; |
|
210 | - } |
|
211 | - |
|
212 | - |
|
213 | - /** |
|
214 | - * @param string $class_name |
|
215 | - * @return ReflectionProperty[] |
|
216 | - * @throws InvalidDataTypeException |
|
217 | - * @throws ReflectionException |
|
218 | - */ |
|
219 | - public function getProperties($class_name) |
|
220 | - { |
|
221 | - if (! isset($this->properties[ $class_name ])) { |
|
222 | - $reflection_class = $this->getReflectionClass($class_name); |
|
223 | - $this->properties[ $class_name ] = $reflection_class->getProperties(); |
|
224 | - } |
|
225 | - return $this->properties[ $class_name ]; |
|
226 | - } |
|
227 | - |
|
228 | - |
|
229 | - /** |
|
230 | - * @param ReflectionClass $reflection_class |
|
231 | - * @return ReflectionProperty[] |
|
232 | - * @throws InvalidDataTypeException |
|
233 | - * @throws ReflectionException |
|
234 | - */ |
|
235 | - public function getPropertiesFromReflection(ReflectionClass $reflection_class) |
|
236 | - { |
|
237 | - return $this->getProperties($reflection_class->getName()); |
|
238 | - } |
|
239 | - |
|
240 | - |
|
241 | - /** |
|
242 | - * @param string $class_name |
|
243 | - * @return ReflectionMethod[] |
|
244 | - * @throws InvalidDataTypeException |
|
245 | - * @throws ReflectionException |
|
246 | - */ |
|
247 | - public function getMethods($class_name) |
|
248 | - { |
|
249 | - if (! isset($this->methods[ $class_name ])) { |
|
250 | - $reflection_class = $this->getReflectionClass($class_name); |
|
251 | - $this->methods[ $class_name ] = $reflection_class->getMethods(); |
|
252 | - } |
|
253 | - return $this->methods[ $class_name ]; |
|
254 | - } |
|
255 | - |
|
256 | - |
|
257 | - /** |
|
258 | - * @param ReflectionClass $reflection_class ) |
|
259 | - * @return ReflectionMethod[] |
|
260 | - * @throws InvalidDataTypeException |
|
261 | - * @throws ReflectionException |
|
262 | - */ |
|
263 | - public function getMethodsFromReflection(ReflectionClass $reflection_class) |
|
264 | - { |
|
265 | - return $this->getMethods($reflection_class->getName()); |
|
266 | - } |
|
24 | + /** |
|
25 | + * @var ReflectionClass[] $classes |
|
26 | + */ |
|
27 | + private $classes = array(); |
|
28 | + |
|
29 | + /** |
|
30 | + * @var ReflectionMethod[] $constructors |
|
31 | + */ |
|
32 | + private $constructors = array(); |
|
33 | + |
|
34 | + /** |
|
35 | + * @var ReflectionParameter[][] $parameters |
|
36 | + */ |
|
37 | + private $parameters = array(); |
|
38 | + |
|
39 | + /** |
|
40 | + * @var ReflectionParameter[][] $parameters |
|
41 | + */ |
|
42 | + private $parameter_classes = array(); |
|
43 | + |
|
44 | + /** |
|
45 | + * @var ReflectionProperty[][] $properties |
|
46 | + */ |
|
47 | + private $properties = array(); |
|
48 | + |
|
49 | + /** |
|
50 | + * @var ReflectionMethod[][] $methods |
|
51 | + */ |
|
52 | + private $methods = array(); |
|
53 | + |
|
54 | + |
|
55 | + /** |
|
56 | + * @param string $class_name |
|
57 | + * @return ReflectionClass |
|
58 | + * @throws ReflectionException |
|
59 | + * @throws InvalidDataTypeException |
|
60 | + */ |
|
61 | + public function getReflectionClass($class_name) |
|
62 | + { |
|
63 | + if (! is_string($class_name)) { |
|
64 | + throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)'); |
|
65 | + } |
|
66 | + if (! isset($this->classes[ $class_name ])) { |
|
67 | + $this->classes[ $class_name ] = new ReflectionClass($class_name); |
|
68 | + } |
|
69 | + return $this->classes[ $class_name ]; |
|
70 | + } |
|
71 | + |
|
72 | + |
|
73 | + /** |
|
74 | + * @param string $class_name |
|
75 | + * @return ReflectionMethod |
|
76 | + * @throws InvalidDataTypeException |
|
77 | + * @throws ReflectionException |
|
78 | + */ |
|
79 | + public function getConstructor($class_name) |
|
80 | + { |
|
81 | + if (! is_string($class_name)) { |
|
82 | + throw new InvalidDataTypeException($class_name, '$class_name', 'string (fully qualified class name)'); |
|
83 | + } |
|
84 | + if (! isset($this->constructors[ $class_name ])) { |
|
85 | + $reflection_class = $this->getReflectionClass($class_name); |
|
86 | + $this->constructors[ $class_name ] = $reflection_class->getConstructor(); |
|
87 | + } |
|
88 | + return $this->constructors[ $class_name ]; |
|
89 | + } |
|
90 | + |
|
91 | + |
|
92 | + /** |
|
93 | + * @param ReflectionClass $reflection_class |
|
94 | + * @return ReflectionMethod |
|
95 | + * @throws InvalidDataTypeException |
|
96 | + * @throws ReflectionException |
|
97 | + */ |
|
98 | + public function getConstructorFromReflection(ReflectionClass $reflection_class) |
|
99 | + { |
|
100 | + return $this->getConstructor($reflection_class->getName()); |
|
101 | + } |
|
102 | + |
|
103 | + |
|
104 | + /** |
|
105 | + * @param string $class_name |
|
106 | + * @return ReflectionParameter[] |
|
107 | + * @throws InvalidDataTypeException |
|
108 | + * @throws ReflectionException |
|
109 | + */ |
|
110 | + public function getParameters($class_name) |
|
111 | + { |
|
112 | + if (! isset($this->parameters[ $class_name ])) { |
|
113 | + $constructor = $this->getConstructor($class_name); |
|
114 | + $this->parameters[ $class_name ] = $constructor->getParameters(); |
|
115 | + } |
|
116 | + return $this->parameters[ $class_name ]; |
|
117 | + } |
|
118 | + |
|
119 | + |
|
120 | + /** |
|
121 | + * @param ReflectionClass $reflection_class |
|
122 | + * @return ReflectionParameter[] |
|
123 | + * @throws InvalidDataTypeException |
|
124 | + * @throws ReflectionException |
|
125 | + */ |
|
126 | + public function getParametersFromReflection(ReflectionClass $reflection_class) |
|
127 | + { |
|
128 | + return $this->getParameters($reflection_class->getName()); |
|
129 | + } |
|
130 | + |
|
131 | + |
|
132 | + /** |
|
133 | + * @param ReflectionMethod $constructor |
|
134 | + * @return ReflectionParameter[] |
|
135 | + * @throws InvalidDataTypeException |
|
136 | + * @throws ReflectionException |
|
137 | + */ |
|
138 | + public function getParametersFromReflectionConstructor(ReflectionMethod $constructor) |
|
139 | + { |
|
140 | + return $this->getParameters($constructor->getDeclaringClass()); |
|
141 | + } |
|
142 | + |
|
143 | + |
|
144 | + /** |
|
145 | + * returns array of ReflectionParameter objects for parameters that are NOT optional |
|
146 | + * |
|
147 | + * @param string $class_name |
|
148 | + * @return ReflectionParameter[] |
|
149 | + * @throws InvalidDataTypeException |
|
150 | + * @throws ReflectionException |
|
151 | + */ |
|
152 | + public function getRequiredParameters($class_name) |
|
153 | + { |
|
154 | + $required_parameters = []; |
|
155 | + $parameters = $this->getParameters($class_name); |
|
156 | + foreach ($parameters as $parameter) { |
|
157 | + if ($parameter instanceof ReflectionParameter && ! $parameter->isOptional()) { |
|
158 | + $required_parameters[] = $parameter; |
|
159 | + } |
|
160 | + } |
|
161 | + return $required_parameters; |
|
162 | + } |
|
163 | + |
|
164 | + |
|
165 | + /** |
|
166 | + * @param ReflectionParameter $param |
|
167 | + * @param string $class_name |
|
168 | + * @param string $index |
|
169 | + * @return string|null |
|
170 | + */ |
|
171 | + public function getParameterClassName(ReflectionParameter $param, $class_name, $index) |
|
172 | + { |
|
173 | + if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_name'])) { |
|
174 | + return $this->parameter_classes[ $class_name ][ $index ]['param_class_name']; |
|
175 | + } |
|
176 | + if (! isset($this->parameter_classes[ $class_name ])) { |
|
177 | + $this->parameter_classes[ $class_name ] = array(); |
|
178 | + } |
|
179 | + if (! isset($this->parameter_classes[ $class_name ][ $index ])) { |
|
180 | + $this->parameter_classes[ $class_name ][ $index ] = array(); |
|
181 | + } |
|
182 | + $this->parameter_classes[ $class_name ][ $index ]['param_class_name'] = $param->getClass() |
|
183 | + ? $param->getClass()->name |
|
184 | + : null; |
|
185 | + return $this->parameter_classes[ $class_name ][ $index ]['param_class_name']; |
|
186 | + } |
|
187 | + |
|
188 | + |
|
189 | + /** |
|
190 | + * @param ReflectionParameter $param |
|
191 | + * @param string $class_name |
|
192 | + * @param string $index |
|
193 | + * @return string|null |
|
194 | + */ |
|
195 | + public function getParameterDefaultValue(ReflectionParameter $param, $class_name, $index) |
|
196 | + { |
|
197 | + if (isset($this->parameter_classes[ $class_name ][ $index ]['param_class_default'])) { |
|
198 | + return $this->parameter_classes[ $class_name ][ $index ]['param_class_default']; |
|
199 | + } |
|
200 | + if (! isset($this->parameter_classes[ $class_name ])) { |
|
201 | + $this->parameter_classes[ $class_name ] = array(); |
|
202 | + } |
|
203 | + if (! isset($this->parameter_classes[ $class_name ][ $index ])) { |
|
204 | + $this->parameter_classes[ $class_name ][ $index ] = array(); |
|
205 | + } |
|
206 | + $this->parameter_classes[ $class_name ][ $index ]['param_class_default'] = $param->isDefaultValueAvailable() |
|
207 | + ? $param->getDefaultValue() |
|
208 | + : null; |
|
209 | + return $this->parameter_classes[ $class_name ][ $index ]['param_class_default']; |
|
210 | + } |
|
211 | + |
|
212 | + |
|
213 | + /** |
|
214 | + * @param string $class_name |
|
215 | + * @return ReflectionProperty[] |
|
216 | + * @throws InvalidDataTypeException |
|
217 | + * @throws ReflectionException |
|
218 | + */ |
|
219 | + public function getProperties($class_name) |
|
220 | + { |
|
221 | + if (! isset($this->properties[ $class_name ])) { |
|
222 | + $reflection_class = $this->getReflectionClass($class_name); |
|
223 | + $this->properties[ $class_name ] = $reflection_class->getProperties(); |
|
224 | + } |
|
225 | + return $this->properties[ $class_name ]; |
|
226 | + } |
|
227 | + |
|
228 | + |
|
229 | + /** |
|
230 | + * @param ReflectionClass $reflection_class |
|
231 | + * @return ReflectionProperty[] |
|
232 | + * @throws InvalidDataTypeException |
|
233 | + * @throws ReflectionException |
|
234 | + */ |
|
235 | + public function getPropertiesFromReflection(ReflectionClass $reflection_class) |
|
236 | + { |
|
237 | + return $this->getProperties($reflection_class->getName()); |
|
238 | + } |
|
239 | + |
|
240 | + |
|
241 | + /** |
|
242 | + * @param string $class_name |
|
243 | + * @return ReflectionMethod[] |
|
244 | + * @throws InvalidDataTypeException |
|
245 | + * @throws ReflectionException |
|
246 | + */ |
|
247 | + public function getMethods($class_name) |
|
248 | + { |
|
249 | + if (! isset($this->methods[ $class_name ])) { |
|
250 | + $reflection_class = $this->getReflectionClass($class_name); |
|
251 | + $this->methods[ $class_name ] = $reflection_class->getMethods(); |
|
252 | + } |
|
253 | + return $this->methods[ $class_name ]; |
|
254 | + } |
|
255 | + |
|
256 | + |
|
257 | + /** |
|
258 | + * @param ReflectionClass $reflection_class ) |
|
259 | + * @return ReflectionMethod[] |
|
260 | + * @throws InvalidDataTypeException |
|
261 | + * @throws ReflectionException |
|
262 | + */ |
|
263 | + public function getMethodsFromReflection(ReflectionClass $reflection_class) |
|
264 | + { |
|
265 | + return $this->getMethods($reflection_class->getName()); |
|
266 | + } |
|
267 | 267 | } |
@@ -416,7 +416,7 @@ |
||
416 | 416 | * If $expired is set to true, then only line items for expired sessions will be returned. |
417 | 417 | * If $expired is set to false, then only line items for active sessions will be returned. |
418 | 418 | * |
419 | - * @param null $expired |
|
419 | + * @param boolean $expired |
|
420 | 420 | * @return EE_Base_Class[]|EE_Line_Item[] |
421 | 421 | * @throws EE_Error |
422 | 422 | * @throws InvalidArgumentException |
@@ -324,8 +324,8 @@ discard block |
||
324 | 324 | ); |
325 | 325 | $query = $wpdb->prepare( |
326 | 326 | 'DELETE li |
327 | - FROM ' . $this->table() . ' li |
|
328 | - LEFT JOIN ' . EEM_Transaction::instance()->table() . ' t ON li.TXN_ID = t.TXN_ID |
|
327 | + FROM ' . $this->table().' li |
|
328 | + LEFT JOIN ' . EEM_Transaction::instance()->table().' t ON li.TXN_ID = t.TXN_ID |
|
329 | 329 | WHERE t.TXN_ID IS NULL AND li.LIN_timestamp < %s', |
330 | 330 | // use GMT time because that's what TXN_timestamps are in |
331 | 331 | date('Y-m-d H:i:s', time() - $time_to_leave_alone) |
@@ -598,7 +598,7 @@ discard block |
||
598 | 598 | */ |
599 | 599 | public function getTicketLineItemsForExpiredCarts($timestamp = 0) |
600 | 600 | { |
601 | - if (! absint($timestamp)) { |
|
601 | + if ( ! absint($timestamp)) { |
|
602 | 602 | /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
603 | 603 | $session_lifespan = LoaderFactory::getLoader()->getShared( |
604 | 604 | 'EventEspresso\core\domain\values\session\SessionLifespan' |
@@ -28,602 +28,602 @@ |
||
28 | 28 | class EEM_Line_Item extends EEM_Base |
29 | 29 | { |
30 | 30 | |
31 | - /** |
|
32 | - * Tax sub-total is just the total of all the taxes, which should be children |
|
33 | - * of this line item. There should only ever be one tax sub-total, and it should |
|
34 | - * be a direct child of. Its quantity and LIN_unit_price = 1. |
|
35 | - */ |
|
36 | - const type_tax_sub_total = 'tax-sub-total'; |
|
37 | - |
|
38 | - /** |
|
39 | - * Tax line items indicate a tax applied to all the taxable line items. |
|
40 | - * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal |
|
41 | - * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1. |
|
42 | - */ |
|
43 | - const type_tax = 'tax'; |
|
44 | - |
|
45 | - /** |
|
46 | - * Indicating individual items purchased, or discounts or surcharges. |
|
47 | - * The sum of all the regular line items plus the tax items should equal the grand total. |
|
48 | - * Possible children are sub-line-items and cancellations. |
|
49 | - * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children |
|
50 | - * LIN_totals. Its LIN_percent = 0. |
|
51 | - * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1). |
|
52 | - * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1. |
|
53 | - */ |
|
54 | - const type_line_item = 'line-item'; |
|
55 | - |
|
56 | - /** |
|
57 | - * Line item indicating all the factors that make a single line item. |
|
58 | - * Sub-line items should have NO children line items. |
|
59 | - * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's |
|
60 | - * contribution towards the price of ONE of their parent items, and its LIN_total should be |
|
61 | - * = LIN_quantity * LIN_unit_price. Its LIN_percent = 0. |
|
62 | - * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should |
|
63 | - * = LIN_percent / 100 * sum of lower-priority sibling line items.. |
|
64 | - */ |
|
65 | - const type_sub_line_item = 'sub-item'; |
|
66 | - |
|
67 | - /** |
|
68 | - * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal). |
|
69 | - * Direct children should be event subtotals. |
|
70 | - * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals. |
|
71 | - */ |
|
72 | - const type_sub_total = 'sub-total'; |
|
73 | - |
|
74 | - /** |
|
75 | - * Line item for the grand total of an order. |
|
76 | - * Its direct children should be tax subtotals and (pre-tax) subtotals, |
|
77 | - * and possibly a regular line item indicating a transaction-wide discount/surcharge. |
|
78 | - * Should have a quantity of 1, a LIN_total and LIN_unit_price of the entire order's amount. |
|
79 | - */ |
|
80 | - const type_total = 'total'; |
|
81 | - |
|
82 | - /** |
|
83 | - * When a line item is cancelled, a sub-line-item of type 'cancellation' |
|
84 | - * should be created, indicating the quantity that were cancelled |
|
85 | - * (because a line item could have a quantity of 1, and its cancellation item |
|
86 | - * could be for 3, indicating that originally 4 were purchased, but 3 have been |
|
87 | - * cancelled, and only one remains). |
|
88 | - * When items are refunded, a cancellation line item should be made, which points |
|
89 | - * to teh payment model object which actually refunded the payment. |
|
90 | - * Cancellations should NOT have any children line items; the should NOT affect |
|
91 | - * any calculations, and are only meant as a record that cancellations have occurred. |
|
92 | - * Their LIN_percent should be 0. |
|
93 | - */ |
|
94 | - const type_cancellation = 'cancellation'; |
|
95 | - |
|
96 | - // various line item object types |
|
97 | - const OBJ_TYPE_EVENT = 'Event'; |
|
98 | - |
|
99 | - const OBJ_TYPE_PRICE = 'Price'; |
|
100 | - |
|
101 | - const OBJ_TYPE_PROMOTION = 'Promotion'; |
|
102 | - |
|
103 | - const OBJ_TYPE_TICKET = 'Ticket'; |
|
104 | - |
|
105 | - const OBJ_TYPE_TRANSACTION = 'Transaction'; |
|
106 | - |
|
107 | - /** |
|
108 | - * @var EEM_Line_Item $_instance |
|
109 | - */ |
|
110 | - protected static $_instance; |
|
111 | - |
|
112 | - |
|
113 | - /** |
|
114 | - * private constructor to prevent direct creation |
|
115 | - * |
|
116 | - * @Constructor |
|
117 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
118 | - * (and any incoming timezone data that gets saved). |
|
119 | - * Note this just sends the timezone info to the date time model field objects. |
|
120 | - * Default is NULL |
|
121 | - * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
122 | - * @throws EE_Error |
|
123 | - * @throws InvalidArgumentException |
|
124 | - */ |
|
125 | - protected function __construct($timezone) |
|
126 | - { |
|
127 | - $this->singular_item = esc_html__('Line Item', 'event_espresso'); |
|
128 | - $this->plural_item = esc_html__('Line Items', 'event_espresso'); |
|
129 | - |
|
130 | - $this->_tables = array( |
|
131 | - 'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID'), |
|
132 | - ); |
|
133 | - $line_items_can_be_for = apply_filters( |
|
134 | - 'FHEE__EEM_Line_Item__line_items_can_be_for', |
|
135 | - array('Ticket', 'Price', 'Event') |
|
136 | - ); |
|
137 | - $this->_fields = array( |
|
138 | - 'Line_Item' => array( |
|
139 | - 'LIN_ID' => new EE_Primary_Key_Int_Field( |
|
140 | - 'LIN_ID', |
|
141 | - esc_html__('ID', 'event_espresso') |
|
142 | - ), |
|
143 | - 'LIN_code' => new EE_Slug_Field( |
|
144 | - 'LIN_code', |
|
145 | - esc_html__('Code for index into Cart', 'event_espresso'), |
|
146 | - true |
|
147 | - ), |
|
148 | - 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
149 | - 'TXN_ID', |
|
150 | - esc_html__('Transaction ID', 'event_espresso'), |
|
151 | - true, |
|
152 | - null, |
|
153 | - 'Transaction' |
|
154 | - ), |
|
155 | - 'LIN_name' => new EE_Full_HTML_Field( |
|
156 | - 'LIN_name', |
|
157 | - esc_html__('Line Item Name', 'event_espresso'), |
|
158 | - false, |
|
159 | - '' |
|
160 | - ), |
|
161 | - 'LIN_desc' => new EE_Full_HTML_Field( |
|
162 | - 'LIN_desc', |
|
163 | - esc_html__('Line Item Description', 'event_espresso'), |
|
164 | - true |
|
165 | - ), |
|
166 | - 'LIN_unit_price' => new EE_Money_Field( |
|
167 | - 'LIN_unit_price', |
|
168 | - esc_html__('Unit Price', 'event_espresso'), |
|
169 | - false, |
|
170 | - 0 |
|
171 | - ), |
|
172 | - 'LIN_percent' => new EE_Float_Field( |
|
173 | - 'LIN_percent', |
|
174 | - esc_html__('Percent', 'event_espresso'), |
|
175 | - false, |
|
176 | - 0 |
|
177 | - ), |
|
178 | - 'LIN_is_taxable' => new EE_Boolean_Field( |
|
179 | - 'LIN_is_taxable', |
|
180 | - esc_html__('Taxable', 'event_espresso'), |
|
181 | - false, |
|
182 | - false |
|
183 | - ), |
|
184 | - 'LIN_order' => new EE_Integer_Field( |
|
185 | - 'LIN_order', |
|
186 | - esc_html__('Order of Application towards total of parent', 'event_espresso'), |
|
187 | - false, |
|
188 | - 1 |
|
189 | - ), |
|
190 | - 'LIN_total' => new EE_Money_Field( |
|
191 | - 'LIN_total', |
|
192 | - esc_html__('Total (unit price x quantity)', 'event_espresso'), |
|
193 | - false, |
|
194 | - 0 |
|
195 | - ), |
|
196 | - 'LIN_quantity' => new EE_Integer_Field( |
|
197 | - 'LIN_quantity', |
|
198 | - esc_html__('Quantity', 'event_espresso'), |
|
199 | - true, |
|
200 | - 1 |
|
201 | - ), |
|
202 | - 'LIN_parent' => new EE_Integer_Field( |
|
203 | - 'LIN_parent', |
|
204 | - esc_html__("Parent ID (this item goes towards that Line Item's total)", 'event_espresso'), |
|
205 | - true, |
|
206 | - null |
|
207 | - ), |
|
208 | - 'LIN_type' => new EE_Enum_Text_Field( |
|
209 | - 'LIN_type', |
|
210 | - esc_html__('Type', 'event_espresso'), |
|
211 | - false, |
|
212 | - 'line-item', |
|
213 | - array( |
|
214 | - self::type_line_item => esc_html__('Line Item', 'event_espresso'), |
|
215 | - self::type_sub_line_item => esc_html__('Sub-Item', 'event_espresso'), |
|
216 | - self::type_sub_total => esc_html__('Subtotal', 'event_espresso'), |
|
217 | - self::type_tax_sub_total => esc_html__('Tax Subtotal', 'event_espresso'), |
|
218 | - self::type_tax => esc_html__('Tax', 'event_espresso'), |
|
219 | - self::type_total => esc_html__('Total', 'event_espresso'), |
|
220 | - self::type_cancellation => esc_html__('Cancellation', 'event_espresso'), |
|
221 | - ) |
|
222 | - ), |
|
223 | - 'OBJ_ID' => new EE_Foreign_Key_Int_Field( |
|
224 | - 'OBJ_ID', |
|
225 | - esc_html__('ID of Item purchased.', 'event_espresso'), |
|
226 | - true, |
|
227 | - null, |
|
228 | - $line_items_can_be_for |
|
229 | - ), |
|
230 | - 'OBJ_type' => new EE_Any_Foreign_Model_Name_Field( |
|
231 | - 'OBJ_type', |
|
232 | - esc_html__('Model Name this Line Item is for', 'event_espresso'), |
|
233 | - true, |
|
234 | - null, |
|
235 | - $line_items_can_be_for |
|
236 | - ), |
|
237 | - 'LIN_timestamp' => new EE_Datetime_Field( |
|
238 | - 'LIN_timestamp', |
|
239 | - esc_html__('When the line item was created', 'event_espresso'), |
|
240 | - false, |
|
241 | - EE_Datetime_Field::now, |
|
242 | - $timezone |
|
243 | - ), |
|
244 | - ), |
|
245 | - ); |
|
246 | - $this->_model_relations = array( |
|
247 | - 'Transaction' => new EE_Belongs_To_Relation(), |
|
248 | - 'Ticket' => new EE_Belongs_To_Any_Relation(), |
|
249 | - 'Price' => new EE_Belongs_To_Any_Relation(), |
|
250 | - 'Event' => new EE_Belongs_To_Any_Relation(), |
|
251 | - ); |
|
252 | - $this->_model_chain_to_wp_user = 'Transaction.Registration.Event'; |
|
253 | - $this->_caps_slug = 'transactions'; |
|
254 | - parent::__construct($timezone); |
|
255 | - } |
|
256 | - |
|
257 | - |
|
258 | - /** |
|
259 | - * Gets all the line items for this transaction of the given type |
|
260 | - * |
|
261 | - * @param string $line_item_type like one of EEM_Line_Item::type_* |
|
262 | - * @param EE_Transaction|int $transaction |
|
263 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
264 | - * @throws EE_Error |
|
265 | - * @throws InvalidArgumentException |
|
266 | - * @throws InvalidDataTypeException |
|
267 | - * @throws InvalidInterfaceException |
|
268 | - */ |
|
269 | - public function get_all_of_type_for_transaction($line_item_type, $transaction) |
|
270 | - { |
|
271 | - $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
272 | - return $this->get_all(array( |
|
273 | - array( |
|
274 | - 'LIN_type' => $line_item_type, |
|
275 | - 'TXN_ID' => $transaction, |
|
276 | - ), |
|
277 | - )); |
|
278 | - } |
|
279 | - |
|
280 | - |
|
281 | - /** |
|
282 | - * Gets all line items unrelated to tickets that are normal line items |
|
283 | - * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category) |
|
284 | - * |
|
285 | - * @param EE_Transaction|int $transaction |
|
286 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
287 | - * @throws EE_Error |
|
288 | - * @throws InvalidArgumentException |
|
289 | - * @throws InvalidDataTypeException |
|
290 | - * @throws InvalidInterfaceException |
|
291 | - */ |
|
292 | - public function get_all_non_ticket_line_items_for_transaction($transaction) |
|
293 | - { |
|
294 | - $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
295 | - return $this->get_all(array( |
|
296 | - array( |
|
297 | - 'LIN_type' => self::type_line_item, |
|
298 | - 'TXN_ID' => $transaction, |
|
299 | - 'OR' => array( |
|
300 | - 'OBJ_type*notticket' => array('!=', EEM_Line_Item::OBJ_TYPE_TICKET), |
|
301 | - 'OBJ_type*null' => array('IS_NULL'), |
|
302 | - ), |
|
303 | - ), |
|
304 | - )); |
|
305 | - } |
|
306 | - |
|
307 | - |
|
308 | - /** |
|
309 | - * Deletes line items with no transaction who have passed the transaction cutoff time. |
|
310 | - * This needs to be very efficient |
|
311 | - * because if there are spam bots afoot there will be LOTS of line items. Also MySQL doesn't allow a limit when |
|
312 | - * deleting and joining tables like this. |
|
313 | - * |
|
314 | - * @return int count of how many deleted |
|
315 | - * @throws EE_Error |
|
316 | - * @throws InvalidArgumentException |
|
317 | - * @throws InvalidDataTypeException |
|
318 | - * @throws InvalidInterfaceException |
|
319 | - */ |
|
320 | - public function delete_line_items_with_no_transaction() |
|
321 | - { |
|
322 | - /** @type WPDB $wpdb */ |
|
323 | - global $wpdb; |
|
324 | - $time_to_leave_alone = apply_filters( |
|
325 | - 'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', |
|
326 | - WEEK_IN_SECONDS |
|
327 | - ); |
|
328 | - $query = $wpdb->prepare( |
|
329 | - 'DELETE li |
|
31 | + /** |
|
32 | + * Tax sub-total is just the total of all the taxes, which should be children |
|
33 | + * of this line item. There should only ever be one tax sub-total, and it should |
|
34 | + * be a direct child of. Its quantity and LIN_unit_price = 1. |
|
35 | + */ |
|
36 | + const type_tax_sub_total = 'tax-sub-total'; |
|
37 | + |
|
38 | + /** |
|
39 | + * Tax line items indicate a tax applied to all the taxable line items. |
|
40 | + * Should not have any children line items. Its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal |
|
41 | + * (eg 10% tax = 10, not 0.1). Its LIN_total = LIN_unit_price * pre-tax-total. Quantity = 1. |
|
42 | + */ |
|
43 | + const type_tax = 'tax'; |
|
44 | + |
|
45 | + /** |
|
46 | + * Indicating individual items purchased, or discounts or surcharges. |
|
47 | + * The sum of all the regular line items plus the tax items should equal the grand total. |
|
48 | + * Possible children are sub-line-items and cancellations. |
|
49 | + * For flat items, LIN_unit_price * LIN_quantity = LIN_total. Its LIN_total is the sum of all the children |
|
50 | + * LIN_totals. Its LIN_percent = 0. |
|
51 | + * For percent items, its LIN_unit_price = 0. Its LIN_percent is a percent, not a decimal (eg 10% = 10, not 0.1). |
|
52 | + * Its LIN_total is LIN_percent / 100 * sum of lower-priority sibling line items. Quantity = 1. |
|
53 | + */ |
|
54 | + const type_line_item = 'line-item'; |
|
55 | + |
|
56 | + /** |
|
57 | + * Line item indicating all the factors that make a single line item. |
|
58 | + * Sub-line items should have NO children line items. |
|
59 | + * For flat sub-items, their quantity should match their parent item, their LIN_unit_price should be this sub-item's |
|
60 | + * contribution towards the price of ONE of their parent items, and its LIN_total should be |
|
61 | + * = LIN_quantity * LIN_unit_price. Its LIN_percent = 0. |
|
62 | + * For percent sub-items, the quantity should be 1, LIN_unit_price should be 0, and its LIN_total should |
|
63 | + * = LIN_percent / 100 * sum of lower-priority sibling line items.. |
|
64 | + */ |
|
65 | + const type_sub_line_item = 'sub-item'; |
|
66 | + |
|
67 | + /** |
|
68 | + * Line item indicating a sub-total (eg total for an event, or pre-tax subtotal). |
|
69 | + * Direct children should be event subtotals. |
|
70 | + * Should have quantity of 1, and a LIN_total and LIN_unit_price of the sum of all its sub-items' LIN_totals. |
|
71 | + */ |
|
72 | + const type_sub_total = 'sub-total'; |
|
73 | + |
|
74 | + /** |
|
75 | + * Line item for the grand total of an order. |
|
76 | + * Its direct children should be tax subtotals and (pre-tax) subtotals, |
|
77 | + * and possibly a regular line item indicating a transaction-wide discount/surcharge. |
|
78 | + * Should have a quantity of 1, a LIN_total and LIN_unit_price of the entire order's amount. |
|
79 | + */ |
|
80 | + const type_total = 'total'; |
|
81 | + |
|
82 | + /** |
|
83 | + * When a line item is cancelled, a sub-line-item of type 'cancellation' |
|
84 | + * should be created, indicating the quantity that were cancelled |
|
85 | + * (because a line item could have a quantity of 1, and its cancellation item |
|
86 | + * could be for 3, indicating that originally 4 were purchased, but 3 have been |
|
87 | + * cancelled, and only one remains). |
|
88 | + * When items are refunded, a cancellation line item should be made, which points |
|
89 | + * to teh payment model object which actually refunded the payment. |
|
90 | + * Cancellations should NOT have any children line items; the should NOT affect |
|
91 | + * any calculations, and are only meant as a record that cancellations have occurred. |
|
92 | + * Their LIN_percent should be 0. |
|
93 | + */ |
|
94 | + const type_cancellation = 'cancellation'; |
|
95 | + |
|
96 | + // various line item object types |
|
97 | + const OBJ_TYPE_EVENT = 'Event'; |
|
98 | + |
|
99 | + const OBJ_TYPE_PRICE = 'Price'; |
|
100 | + |
|
101 | + const OBJ_TYPE_PROMOTION = 'Promotion'; |
|
102 | + |
|
103 | + const OBJ_TYPE_TICKET = 'Ticket'; |
|
104 | + |
|
105 | + const OBJ_TYPE_TRANSACTION = 'Transaction'; |
|
106 | + |
|
107 | + /** |
|
108 | + * @var EEM_Line_Item $_instance |
|
109 | + */ |
|
110 | + protected static $_instance; |
|
111 | + |
|
112 | + |
|
113 | + /** |
|
114 | + * private constructor to prevent direct creation |
|
115 | + * |
|
116 | + * @Constructor |
|
117 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
118 | + * (and any incoming timezone data that gets saved). |
|
119 | + * Note this just sends the timezone info to the date time model field objects. |
|
120 | + * Default is NULL |
|
121 | + * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
122 | + * @throws EE_Error |
|
123 | + * @throws InvalidArgumentException |
|
124 | + */ |
|
125 | + protected function __construct($timezone) |
|
126 | + { |
|
127 | + $this->singular_item = esc_html__('Line Item', 'event_espresso'); |
|
128 | + $this->plural_item = esc_html__('Line Items', 'event_espresso'); |
|
129 | + |
|
130 | + $this->_tables = array( |
|
131 | + 'Line_Item' => new EE_Primary_Table('esp_line_item', 'LIN_ID'), |
|
132 | + ); |
|
133 | + $line_items_can_be_for = apply_filters( |
|
134 | + 'FHEE__EEM_Line_Item__line_items_can_be_for', |
|
135 | + array('Ticket', 'Price', 'Event') |
|
136 | + ); |
|
137 | + $this->_fields = array( |
|
138 | + 'Line_Item' => array( |
|
139 | + 'LIN_ID' => new EE_Primary_Key_Int_Field( |
|
140 | + 'LIN_ID', |
|
141 | + esc_html__('ID', 'event_espresso') |
|
142 | + ), |
|
143 | + 'LIN_code' => new EE_Slug_Field( |
|
144 | + 'LIN_code', |
|
145 | + esc_html__('Code for index into Cart', 'event_espresso'), |
|
146 | + true |
|
147 | + ), |
|
148 | + 'TXN_ID' => new EE_Foreign_Key_Int_Field( |
|
149 | + 'TXN_ID', |
|
150 | + esc_html__('Transaction ID', 'event_espresso'), |
|
151 | + true, |
|
152 | + null, |
|
153 | + 'Transaction' |
|
154 | + ), |
|
155 | + 'LIN_name' => new EE_Full_HTML_Field( |
|
156 | + 'LIN_name', |
|
157 | + esc_html__('Line Item Name', 'event_espresso'), |
|
158 | + false, |
|
159 | + '' |
|
160 | + ), |
|
161 | + 'LIN_desc' => new EE_Full_HTML_Field( |
|
162 | + 'LIN_desc', |
|
163 | + esc_html__('Line Item Description', 'event_espresso'), |
|
164 | + true |
|
165 | + ), |
|
166 | + 'LIN_unit_price' => new EE_Money_Field( |
|
167 | + 'LIN_unit_price', |
|
168 | + esc_html__('Unit Price', 'event_espresso'), |
|
169 | + false, |
|
170 | + 0 |
|
171 | + ), |
|
172 | + 'LIN_percent' => new EE_Float_Field( |
|
173 | + 'LIN_percent', |
|
174 | + esc_html__('Percent', 'event_espresso'), |
|
175 | + false, |
|
176 | + 0 |
|
177 | + ), |
|
178 | + 'LIN_is_taxable' => new EE_Boolean_Field( |
|
179 | + 'LIN_is_taxable', |
|
180 | + esc_html__('Taxable', 'event_espresso'), |
|
181 | + false, |
|
182 | + false |
|
183 | + ), |
|
184 | + 'LIN_order' => new EE_Integer_Field( |
|
185 | + 'LIN_order', |
|
186 | + esc_html__('Order of Application towards total of parent', 'event_espresso'), |
|
187 | + false, |
|
188 | + 1 |
|
189 | + ), |
|
190 | + 'LIN_total' => new EE_Money_Field( |
|
191 | + 'LIN_total', |
|
192 | + esc_html__('Total (unit price x quantity)', 'event_espresso'), |
|
193 | + false, |
|
194 | + 0 |
|
195 | + ), |
|
196 | + 'LIN_quantity' => new EE_Integer_Field( |
|
197 | + 'LIN_quantity', |
|
198 | + esc_html__('Quantity', 'event_espresso'), |
|
199 | + true, |
|
200 | + 1 |
|
201 | + ), |
|
202 | + 'LIN_parent' => new EE_Integer_Field( |
|
203 | + 'LIN_parent', |
|
204 | + esc_html__("Parent ID (this item goes towards that Line Item's total)", 'event_espresso'), |
|
205 | + true, |
|
206 | + null |
|
207 | + ), |
|
208 | + 'LIN_type' => new EE_Enum_Text_Field( |
|
209 | + 'LIN_type', |
|
210 | + esc_html__('Type', 'event_espresso'), |
|
211 | + false, |
|
212 | + 'line-item', |
|
213 | + array( |
|
214 | + self::type_line_item => esc_html__('Line Item', 'event_espresso'), |
|
215 | + self::type_sub_line_item => esc_html__('Sub-Item', 'event_espresso'), |
|
216 | + self::type_sub_total => esc_html__('Subtotal', 'event_espresso'), |
|
217 | + self::type_tax_sub_total => esc_html__('Tax Subtotal', 'event_espresso'), |
|
218 | + self::type_tax => esc_html__('Tax', 'event_espresso'), |
|
219 | + self::type_total => esc_html__('Total', 'event_espresso'), |
|
220 | + self::type_cancellation => esc_html__('Cancellation', 'event_espresso'), |
|
221 | + ) |
|
222 | + ), |
|
223 | + 'OBJ_ID' => new EE_Foreign_Key_Int_Field( |
|
224 | + 'OBJ_ID', |
|
225 | + esc_html__('ID of Item purchased.', 'event_espresso'), |
|
226 | + true, |
|
227 | + null, |
|
228 | + $line_items_can_be_for |
|
229 | + ), |
|
230 | + 'OBJ_type' => new EE_Any_Foreign_Model_Name_Field( |
|
231 | + 'OBJ_type', |
|
232 | + esc_html__('Model Name this Line Item is for', 'event_espresso'), |
|
233 | + true, |
|
234 | + null, |
|
235 | + $line_items_can_be_for |
|
236 | + ), |
|
237 | + 'LIN_timestamp' => new EE_Datetime_Field( |
|
238 | + 'LIN_timestamp', |
|
239 | + esc_html__('When the line item was created', 'event_espresso'), |
|
240 | + false, |
|
241 | + EE_Datetime_Field::now, |
|
242 | + $timezone |
|
243 | + ), |
|
244 | + ), |
|
245 | + ); |
|
246 | + $this->_model_relations = array( |
|
247 | + 'Transaction' => new EE_Belongs_To_Relation(), |
|
248 | + 'Ticket' => new EE_Belongs_To_Any_Relation(), |
|
249 | + 'Price' => new EE_Belongs_To_Any_Relation(), |
|
250 | + 'Event' => new EE_Belongs_To_Any_Relation(), |
|
251 | + ); |
|
252 | + $this->_model_chain_to_wp_user = 'Transaction.Registration.Event'; |
|
253 | + $this->_caps_slug = 'transactions'; |
|
254 | + parent::__construct($timezone); |
|
255 | + } |
|
256 | + |
|
257 | + |
|
258 | + /** |
|
259 | + * Gets all the line items for this transaction of the given type |
|
260 | + * |
|
261 | + * @param string $line_item_type like one of EEM_Line_Item::type_* |
|
262 | + * @param EE_Transaction|int $transaction |
|
263 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
264 | + * @throws EE_Error |
|
265 | + * @throws InvalidArgumentException |
|
266 | + * @throws InvalidDataTypeException |
|
267 | + * @throws InvalidInterfaceException |
|
268 | + */ |
|
269 | + public function get_all_of_type_for_transaction($line_item_type, $transaction) |
|
270 | + { |
|
271 | + $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
272 | + return $this->get_all(array( |
|
273 | + array( |
|
274 | + 'LIN_type' => $line_item_type, |
|
275 | + 'TXN_ID' => $transaction, |
|
276 | + ), |
|
277 | + )); |
|
278 | + } |
|
279 | + |
|
280 | + |
|
281 | + /** |
|
282 | + * Gets all line items unrelated to tickets that are normal line items |
|
283 | + * (eg shipping, promotions, and miscellaneous other stuff should probably fit in this category) |
|
284 | + * |
|
285 | + * @param EE_Transaction|int $transaction |
|
286 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
287 | + * @throws EE_Error |
|
288 | + * @throws InvalidArgumentException |
|
289 | + * @throws InvalidDataTypeException |
|
290 | + * @throws InvalidInterfaceException |
|
291 | + */ |
|
292 | + public function get_all_non_ticket_line_items_for_transaction($transaction) |
|
293 | + { |
|
294 | + $transaction = EEM_Transaction::instance()->ensure_is_ID($transaction); |
|
295 | + return $this->get_all(array( |
|
296 | + array( |
|
297 | + 'LIN_type' => self::type_line_item, |
|
298 | + 'TXN_ID' => $transaction, |
|
299 | + 'OR' => array( |
|
300 | + 'OBJ_type*notticket' => array('!=', EEM_Line_Item::OBJ_TYPE_TICKET), |
|
301 | + 'OBJ_type*null' => array('IS_NULL'), |
|
302 | + ), |
|
303 | + ), |
|
304 | + )); |
|
305 | + } |
|
306 | + |
|
307 | + |
|
308 | + /** |
|
309 | + * Deletes line items with no transaction who have passed the transaction cutoff time. |
|
310 | + * This needs to be very efficient |
|
311 | + * because if there are spam bots afoot there will be LOTS of line items. Also MySQL doesn't allow a limit when |
|
312 | + * deleting and joining tables like this. |
|
313 | + * |
|
314 | + * @return int count of how many deleted |
|
315 | + * @throws EE_Error |
|
316 | + * @throws InvalidArgumentException |
|
317 | + * @throws InvalidDataTypeException |
|
318 | + * @throws InvalidInterfaceException |
|
319 | + */ |
|
320 | + public function delete_line_items_with_no_transaction() |
|
321 | + { |
|
322 | + /** @type WPDB $wpdb */ |
|
323 | + global $wpdb; |
|
324 | + $time_to_leave_alone = apply_filters( |
|
325 | + 'FHEE__EEM_Line_Item__delete_line_items_with_no_transaction__time_to_leave_alone', |
|
326 | + WEEK_IN_SECONDS |
|
327 | + ); |
|
328 | + $query = $wpdb->prepare( |
|
329 | + 'DELETE li |
|
330 | 330 | FROM ' . $this->table() . ' li |
331 | 331 | LEFT JOIN ' . EEM_Transaction::instance()->table() . ' t ON li.TXN_ID = t.TXN_ID |
332 | 332 | WHERE t.TXN_ID IS NULL AND li.LIN_timestamp < %s', |
333 | - // use GMT time because that's what TXN_timestamps are in |
|
334 | - date('Y-m-d H:i:s', time() - $time_to_leave_alone) |
|
335 | - ); |
|
336 | - return $wpdb->query($query); |
|
337 | - } |
|
338 | - |
|
339 | - |
|
340 | - /** |
|
341 | - * get_line_item_for_transaction_object |
|
342 | - * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket |
|
343 | - * |
|
344 | - * @param int $TXN_ID |
|
345 | - * @param EE_Base_Class $object |
|
346 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
347 | - * @throws EE_Error |
|
348 | - * @throws InvalidArgumentException |
|
349 | - * @throws InvalidDataTypeException |
|
350 | - * @throws InvalidInterfaceException |
|
351 | - * @throws ReflectionException |
|
352 | - */ |
|
353 | - public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object) |
|
354 | - { |
|
355 | - return $this->get_all(array( |
|
356 | - array( |
|
357 | - 'TXN_ID' => $TXN_ID, |
|
358 | - 'OBJ_type' => str_replace('EE_', '', get_class($object)), |
|
359 | - 'OBJ_ID' => $object->ID(), |
|
360 | - ), |
|
361 | - )); |
|
362 | - } |
|
363 | - |
|
364 | - |
|
365 | - /** |
|
366 | - * get_object_line_items_for_transaction |
|
367 | - * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs |
|
368 | - * |
|
369 | - * @param int $TXN_ID |
|
370 | - * @param string $OBJ_type |
|
371 | - * @param array $OBJ_IDs |
|
372 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
373 | - * @throws EE_Error |
|
374 | - */ |
|
375 | - public function get_object_line_items_for_transaction( |
|
376 | - $TXN_ID, |
|
377 | - $OBJ_type = EEM_Line_Item::OBJ_TYPE_EVENT, |
|
378 | - $OBJ_IDs = array() |
|
379 | - ) { |
|
380 | - $query_params = array( |
|
381 | - 'OBJ_type' => $OBJ_type, |
|
382 | - // if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query |
|
383 | - 'OBJ_ID' => is_array($OBJ_IDs) && ! isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs, |
|
384 | - ); |
|
385 | - if ($TXN_ID) { |
|
386 | - $query_params['TXN_ID'] = $TXN_ID; |
|
387 | - } |
|
388 | - return $this->get_all(array($query_params)); |
|
389 | - } |
|
390 | - |
|
391 | - |
|
392 | - /** |
|
393 | - * get_all_ticket_line_items_for_transaction |
|
394 | - * |
|
395 | - * @param EE_Transaction $transaction |
|
396 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
397 | - * @throws EE_Error |
|
398 | - * @throws InvalidArgumentException |
|
399 | - * @throws InvalidDataTypeException |
|
400 | - * @throws InvalidInterfaceException |
|
401 | - * @throws ReflectionException |
|
402 | - */ |
|
403 | - public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction) |
|
404 | - { |
|
405 | - return $this->get_all(array( |
|
406 | - array( |
|
407 | - 'TXN_ID' => $transaction->ID(), |
|
408 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
409 | - ), |
|
410 | - )); |
|
411 | - } |
|
412 | - |
|
413 | - |
|
414 | - /** |
|
415 | - * get_ticket_line_item_for_transaction |
|
416 | - * |
|
417 | - * @param int $TXN_ID |
|
418 | - * @param int $TKT_ID |
|
419 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
420 | - * @throws EE_Error |
|
421 | - * @throws InvalidArgumentException |
|
422 | - * @throws InvalidDataTypeException |
|
423 | - * @throws InvalidInterfaceException |
|
424 | - */ |
|
425 | - public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID) |
|
426 | - { |
|
427 | - return $this->get_one(array( |
|
428 | - array( |
|
429 | - 'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID), |
|
430 | - 'OBJ_ID' => $TKT_ID, |
|
431 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
432 | - ), |
|
433 | - )); |
|
434 | - } |
|
435 | - |
|
436 | - |
|
437 | - /** |
|
438 | - * get_existing_promotion_line_item |
|
439 | - * searches the cart for existing line items for the specified promotion |
|
440 | - * |
|
441 | - * @since 1.0.0 |
|
442 | - * @param EE_Line_Item $parent_line_item |
|
443 | - * @param EE_Promotion $promotion |
|
444 | - * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
445 | - * @throws EE_Error |
|
446 | - * @throws InvalidArgumentException |
|
447 | - * @throws InvalidDataTypeException |
|
448 | - * @throws InvalidInterfaceException |
|
449 | - * @throws ReflectionException |
|
450 | - */ |
|
451 | - public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion) |
|
452 | - { |
|
453 | - return $this->get_one(array( |
|
454 | - array( |
|
455 | - 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
456 | - 'LIN_parent' => $parent_line_item->ID(), |
|
457 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
458 | - 'OBJ_ID' => $promotion->ID(), |
|
459 | - ), |
|
460 | - )); |
|
461 | - } |
|
462 | - |
|
463 | - |
|
464 | - /** |
|
465 | - * get_all_promotion_line_items |
|
466 | - * searches the cart for any and all existing promotion line items |
|
467 | - * |
|
468 | - * @since 1.0.0 |
|
469 | - * @param EE_Line_Item $parent_line_item |
|
470 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
471 | - * @throws EE_Error |
|
472 | - * @throws InvalidArgumentException |
|
473 | - * @throws InvalidDataTypeException |
|
474 | - * @throws InvalidInterfaceException |
|
475 | - * @throws ReflectionException |
|
476 | - */ |
|
477 | - public function get_all_promotion_line_items(EE_Line_Item $parent_line_item) |
|
478 | - { |
|
479 | - return $this->get_all(array( |
|
480 | - array( |
|
481 | - 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
482 | - 'LIN_parent' => $parent_line_item->ID(), |
|
483 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
484 | - ), |
|
485 | - )); |
|
486 | - } |
|
487 | - |
|
488 | - |
|
489 | - /** |
|
490 | - * Gets the registration's corresponding line item. |
|
491 | - * Note: basically does NOT support having multiple line items for a single ticket, |
|
492 | - * which would happen if some of the registrations had a price modifier while others didn't. |
|
493 | - * In order to support that, we'd probably need a LIN_ID on registrations or something. |
|
494 | - * |
|
495 | - * @param EE_Registration $registration |
|
496 | - * @return EE_Base_Class|EE_Line_ITem|EE_Soft_Delete_Base_Class|NULL |
|
497 | - * @throws EE_Error |
|
498 | - */ |
|
499 | - public function get_line_item_for_registration(EE_Registration $registration) |
|
500 | - { |
|
501 | - return $this->get_one($this->line_item_for_registration_query_params($registration)); |
|
502 | - } |
|
503 | - |
|
504 | - |
|
505 | - /** |
|
506 | - * Gets the query params used to retrieve a specific line item for the given registration |
|
507 | - * |
|
508 | - * @param EE_Registration $registration |
|
509 | - * @param array $original_query_params any extra query params you'd like to be merged with |
|
510 | - * @return array @see |
|
511 | - * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
512 | - * @throws EE_Error |
|
513 | - */ |
|
514 | - public function line_item_for_registration_query_params( |
|
515 | - EE_Registration $registration, |
|
516 | - $original_query_params = array() |
|
517 | - ) { |
|
518 | - return array_replace_recursive($original_query_params, array( |
|
519 | - array( |
|
520 | - 'OBJ_ID' => $registration->ticket_ID(), |
|
521 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
522 | - 'TXN_ID' => $registration->transaction_ID(), |
|
523 | - ), |
|
524 | - )); |
|
525 | - } |
|
526 | - |
|
527 | - |
|
528 | - /** |
|
529 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
530 | - * @throws InvalidInterfaceException |
|
531 | - * @throws InvalidDataTypeException |
|
532 | - * @throws EE_Error |
|
533 | - * @throws InvalidArgumentException |
|
534 | - */ |
|
535 | - public function get_total_line_items_with_no_transaction() |
|
536 | - { |
|
537 | - return $this->get_total_line_items_for_carts(); |
|
538 | - } |
|
539 | - |
|
540 | - |
|
541 | - /** |
|
542 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
543 | - * @throws InvalidInterfaceException |
|
544 | - * @throws InvalidDataTypeException |
|
545 | - * @throws EE_Error |
|
546 | - * @throws InvalidArgumentException |
|
547 | - */ |
|
548 | - public function get_total_line_items_for_active_carts() |
|
549 | - { |
|
550 | - return $this->get_total_line_items_for_carts(false); |
|
551 | - } |
|
552 | - |
|
553 | - |
|
554 | - /** |
|
555 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
556 | - * @throws InvalidInterfaceException |
|
557 | - * @throws InvalidDataTypeException |
|
558 | - * @throws EE_Error |
|
559 | - * @throws InvalidArgumentException |
|
560 | - */ |
|
561 | - public function get_total_line_items_for_expired_carts() |
|
562 | - { |
|
563 | - return $this->get_total_line_items_for_carts(true); |
|
564 | - } |
|
565 | - |
|
566 | - |
|
567 | - /** |
|
568 | - * Returns an array of grand total line items where the TXN_ID is 0. |
|
569 | - * If $expired is set to true, then only line items for expired sessions will be returned. |
|
570 | - * If $expired is set to false, then only line items for active sessions will be returned. |
|
571 | - * |
|
572 | - * @param null $expired |
|
573 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
574 | - * @throws EE_Error |
|
575 | - * @throws InvalidArgumentException |
|
576 | - * @throws InvalidDataTypeException |
|
577 | - * @throws InvalidInterfaceException |
|
578 | - */ |
|
579 | - private function get_total_line_items_for_carts($expired = null) |
|
580 | - { |
|
581 | - $where_params = array( |
|
582 | - 'TXN_ID' => 0, |
|
583 | - 'LIN_type' => 'total', |
|
584 | - ); |
|
585 | - if ($expired !== null) { |
|
586 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
587 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
588 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
589 | - ); |
|
590 | - $where_params['LIN_timestamp'] = array( |
|
591 | - $expired ? '<=' : '>', |
|
592 | - $session_lifespan->expiration(), |
|
593 | - ); |
|
594 | - } |
|
595 | - return $this->get_all(array($where_params)); |
|
596 | - } |
|
597 | - |
|
598 | - |
|
599 | - /** |
|
600 | - * Returns an array of ticket total line items where the TXN_ID is 0 |
|
601 | - * AND the timestamp is older than the session lifespan. |
|
602 | - * |
|
603 | - * @param int $timestamp |
|
604 | - * @return EE_Base_Class[]|EE_Line_Item[] |
|
605 | - * @throws EE_Error |
|
606 | - * @throws InvalidArgumentException |
|
607 | - * @throws InvalidDataTypeException |
|
608 | - * @throws InvalidInterfaceException |
|
609 | - */ |
|
610 | - public function getTicketLineItemsForExpiredCarts($timestamp = 0) |
|
611 | - { |
|
612 | - if (! absint($timestamp)) { |
|
613 | - /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
614 | - $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
615 | - 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
616 | - ); |
|
617 | - $timestamp = $session_lifespan->expiration(); |
|
618 | - } |
|
619 | - return $this->get_all( |
|
620 | - array( |
|
621 | - array( |
|
622 | - 'TXN_ID' => 0, |
|
623 | - 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
624 | - 'LIN_timestamp' => array('<=', $timestamp), |
|
625 | - ), |
|
626 | - ) |
|
627 | - ); |
|
628 | - } |
|
333 | + // use GMT time because that's what TXN_timestamps are in |
|
334 | + date('Y-m-d H:i:s', time() - $time_to_leave_alone) |
|
335 | + ); |
|
336 | + return $wpdb->query($query); |
|
337 | + } |
|
338 | + |
|
339 | + |
|
340 | + /** |
|
341 | + * get_line_item_for_transaction_object |
|
342 | + * Gets a transaction's line item record for a specific object such as a EE_Event or EE_Ticket |
|
343 | + * |
|
344 | + * @param int $TXN_ID |
|
345 | + * @param EE_Base_Class $object |
|
346 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
347 | + * @throws EE_Error |
|
348 | + * @throws InvalidArgumentException |
|
349 | + * @throws InvalidDataTypeException |
|
350 | + * @throws InvalidInterfaceException |
|
351 | + * @throws ReflectionException |
|
352 | + */ |
|
353 | + public function get_line_item_for_transaction_object($TXN_ID, EE_Base_Class $object) |
|
354 | + { |
|
355 | + return $this->get_all(array( |
|
356 | + array( |
|
357 | + 'TXN_ID' => $TXN_ID, |
|
358 | + 'OBJ_type' => str_replace('EE_', '', get_class($object)), |
|
359 | + 'OBJ_ID' => $object->ID(), |
|
360 | + ), |
|
361 | + )); |
|
362 | + } |
|
363 | + |
|
364 | + |
|
365 | + /** |
|
366 | + * get_object_line_items_for_transaction |
|
367 | + * Gets all of the the object line items for a transaction, based on an object type plus an array of object IDs |
|
368 | + * |
|
369 | + * @param int $TXN_ID |
|
370 | + * @param string $OBJ_type |
|
371 | + * @param array $OBJ_IDs |
|
372 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
373 | + * @throws EE_Error |
|
374 | + */ |
|
375 | + public function get_object_line_items_for_transaction( |
|
376 | + $TXN_ID, |
|
377 | + $OBJ_type = EEM_Line_Item::OBJ_TYPE_EVENT, |
|
378 | + $OBJ_IDs = array() |
|
379 | + ) { |
|
380 | + $query_params = array( |
|
381 | + 'OBJ_type' => $OBJ_type, |
|
382 | + // if incoming $OBJ_IDs is an array, then make sure it is formatted correctly for the query |
|
383 | + 'OBJ_ID' => is_array($OBJ_IDs) && ! isset($OBJ_IDs['IN']) ? array('IN', $OBJ_IDs) : $OBJ_IDs, |
|
384 | + ); |
|
385 | + if ($TXN_ID) { |
|
386 | + $query_params['TXN_ID'] = $TXN_ID; |
|
387 | + } |
|
388 | + return $this->get_all(array($query_params)); |
|
389 | + } |
|
390 | + |
|
391 | + |
|
392 | + /** |
|
393 | + * get_all_ticket_line_items_for_transaction |
|
394 | + * |
|
395 | + * @param EE_Transaction $transaction |
|
396 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
397 | + * @throws EE_Error |
|
398 | + * @throws InvalidArgumentException |
|
399 | + * @throws InvalidDataTypeException |
|
400 | + * @throws InvalidInterfaceException |
|
401 | + * @throws ReflectionException |
|
402 | + */ |
|
403 | + public function get_all_ticket_line_items_for_transaction(EE_Transaction $transaction) |
|
404 | + { |
|
405 | + return $this->get_all(array( |
|
406 | + array( |
|
407 | + 'TXN_ID' => $transaction->ID(), |
|
408 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
409 | + ), |
|
410 | + )); |
|
411 | + } |
|
412 | + |
|
413 | + |
|
414 | + /** |
|
415 | + * get_ticket_line_item_for_transaction |
|
416 | + * |
|
417 | + * @param int $TXN_ID |
|
418 | + * @param int $TKT_ID |
|
419 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
420 | + * @throws EE_Error |
|
421 | + * @throws InvalidArgumentException |
|
422 | + * @throws InvalidDataTypeException |
|
423 | + * @throws InvalidInterfaceException |
|
424 | + */ |
|
425 | + public function get_ticket_line_item_for_transaction($TXN_ID, $TKT_ID) |
|
426 | + { |
|
427 | + return $this->get_one(array( |
|
428 | + array( |
|
429 | + 'TXN_ID' => EEM_Transaction::instance()->ensure_is_ID($TXN_ID), |
|
430 | + 'OBJ_ID' => $TKT_ID, |
|
431 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
432 | + ), |
|
433 | + )); |
|
434 | + } |
|
435 | + |
|
436 | + |
|
437 | + /** |
|
438 | + * get_existing_promotion_line_item |
|
439 | + * searches the cart for existing line items for the specified promotion |
|
440 | + * |
|
441 | + * @since 1.0.0 |
|
442 | + * @param EE_Line_Item $parent_line_item |
|
443 | + * @param EE_Promotion $promotion |
|
444 | + * @return EE_Base_Class|EE_Line_Item|EE_Soft_Delete_Base_Class|NULL |
|
445 | + * @throws EE_Error |
|
446 | + * @throws InvalidArgumentException |
|
447 | + * @throws InvalidDataTypeException |
|
448 | + * @throws InvalidInterfaceException |
|
449 | + * @throws ReflectionException |
|
450 | + */ |
|
451 | + public function get_existing_promotion_line_item(EE_Line_Item $parent_line_item, EE_Promotion $promotion) |
|
452 | + { |
|
453 | + return $this->get_one(array( |
|
454 | + array( |
|
455 | + 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
456 | + 'LIN_parent' => $parent_line_item->ID(), |
|
457 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
458 | + 'OBJ_ID' => $promotion->ID(), |
|
459 | + ), |
|
460 | + )); |
|
461 | + } |
|
462 | + |
|
463 | + |
|
464 | + /** |
|
465 | + * get_all_promotion_line_items |
|
466 | + * searches the cart for any and all existing promotion line items |
|
467 | + * |
|
468 | + * @since 1.0.0 |
|
469 | + * @param EE_Line_Item $parent_line_item |
|
470 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
471 | + * @throws EE_Error |
|
472 | + * @throws InvalidArgumentException |
|
473 | + * @throws InvalidDataTypeException |
|
474 | + * @throws InvalidInterfaceException |
|
475 | + * @throws ReflectionException |
|
476 | + */ |
|
477 | + public function get_all_promotion_line_items(EE_Line_Item $parent_line_item) |
|
478 | + { |
|
479 | + return $this->get_all(array( |
|
480 | + array( |
|
481 | + 'TXN_ID' => $parent_line_item->TXN_ID(), |
|
482 | + 'LIN_parent' => $parent_line_item->ID(), |
|
483 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_PROMOTION, |
|
484 | + ), |
|
485 | + )); |
|
486 | + } |
|
487 | + |
|
488 | + |
|
489 | + /** |
|
490 | + * Gets the registration's corresponding line item. |
|
491 | + * Note: basically does NOT support having multiple line items for a single ticket, |
|
492 | + * which would happen if some of the registrations had a price modifier while others didn't. |
|
493 | + * In order to support that, we'd probably need a LIN_ID on registrations or something. |
|
494 | + * |
|
495 | + * @param EE_Registration $registration |
|
496 | + * @return EE_Base_Class|EE_Line_ITem|EE_Soft_Delete_Base_Class|NULL |
|
497 | + * @throws EE_Error |
|
498 | + */ |
|
499 | + public function get_line_item_for_registration(EE_Registration $registration) |
|
500 | + { |
|
501 | + return $this->get_one($this->line_item_for_registration_query_params($registration)); |
|
502 | + } |
|
503 | + |
|
504 | + |
|
505 | + /** |
|
506 | + * Gets the query params used to retrieve a specific line item for the given registration |
|
507 | + * |
|
508 | + * @param EE_Registration $registration |
|
509 | + * @param array $original_query_params any extra query params you'd like to be merged with |
|
510 | + * @return array @see |
|
511 | + * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
512 | + * @throws EE_Error |
|
513 | + */ |
|
514 | + public function line_item_for_registration_query_params( |
|
515 | + EE_Registration $registration, |
|
516 | + $original_query_params = array() |
|
517 | + ) { |
|
518 | + return array_replace_recursive($original_query_params, array( |
|
519 | + array( |
|
520 | + 'OBJ_ID' => $registration->ticket_ID(), |
|
521 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
522 | + 'TXN_ID' => $registration->transaction_ID(), |
|
523 | + ), |
|
524 | + )); |
|
525 | + } |
|
526 | + |
|
527 | + |
|
528 | + /** |
|
529 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
530 | + * @throws InvalidInterfaceException |
|
531 | + * @throws InvalidDataTypeException |
|
532 | + * @throws EE_Error |
|
533 | + * @throws InvalidArgumentException |
|
534 | + */ |
|
535 | + public function get_total_line_items_with_no_transaction() |
|
536 | + { |
|
537 | + return $this->get_total_line_items_for_carts(); |
|
538 | + } |
|
539 | + |
|
540 | + |
|
541 | + /** |
|
542 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
543 | + * @throws InvalidInterfaceException |
|
544 | + * @throws InvalidDataTypeException |
|
545 | + * @throws EE_Error |
|
546 | + * @throws InvalidArgumentException |
|
547 | + */ |
|
548 | + public function get_total_line_items_for_active_carts() |
|
549 | + { |
|
550 | + return $this->get_total_line_items_for_carts(false); |
|
551 | + } |
|
552 | + |
|
553 | + |
|
554 | + /** |
|
555 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
556 | + * @throws InvalidInterfaceException |
|
557 | + * @throws InvalidDataTypeException |
|
558 | + * @throws EE_Error |
|
559 | + * @throws InvalidArgumentException |
|
560 | + */ |
|
561 | + public function get_total_line_items_for_expired_carts() |
|
562 | + { |
|
563 | + return $this->get_total_line_items_for_carts(true); |
|
564 | + } |
|
565 | + |
|
566 | + |
|
567 | + /** |
|
568 | + * Returns an array of grand total line items where the TXN_ID is 0. |
|
569 | + * If $expired is set to true, then only line items for expired sessions will be returned. |
|
570 | + * If $expired is set to false, then only line items for active sessions will be returned. |
|
571 | + * |
|
572 | + * @param null $expired |
|
573 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
574 | + * @throws EE_Error |
|
575 | + * @throws InvalidArgumentException |
|
576 | + * @throws InvalidDataTypeException |
|
577 | + * @throws InvalidInterfaceException |
|
578 | + */ |
|
579 | + private function get_total_line_items_for_carts($expired = null) |
|
580 | + { |
|
581 | + $where_params = array( |
|
582 | + 'TXN_ID' => 0, |
|
583 | + 'LIN_type' => 'total', |
|
584 | + ); |
|
585 | + if ($expired !== null) { |
|
586 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
587 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
588 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
589 | + ); |
|
590 | + $where_params['LIN_timestamp'] = array( |
|
591 | + $expired ? '<=' : '>', |
|
592 | + $session_lifespan->expiration(), |
|
593 | + ); |
|
594 | + } |
|
595 | + return $this->get_all(array($where_params)); |
|
596 | + } |
|
597 | + |
|
598 | + |
|
599 | + /** |
|
600 | + * Returns an array of ticket total line items where the TXN_ID is 0 |
|
601 | + * AND the timestamp is older than the session lifespan. |
|
602 | + * |
|
603 | + * @param int $timestamp |
|
604 | + * @return EE_Base_Class[]|EE_Line_Item[] |
|
605 | + * @throws EE_Error |
|
606 | + * @throws InvalidArgumentException |
|
607 | + * @throws InvalidDataTypeException |
|
608 | + * @throws InvalidInterfaceException |
|
609 | + */ |
|
610 | + public function getTicketLineItemsForExpiredCarts($timestamp = 0) |
|
611 | + { |
|
612 | + if (! absint($timestamp)) { |
|
613 | + /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */ |
|
614 | + $session_lifespan = LoaderFactory::getLoader()->getShared( |
|
615 | + 'EventEspresso\core\domain\values\session\SessionLifespan' |
|
616 | + ); |
|
617 | + $timestamp = $session_lifespan->expiration(); |
|
618 | + } |
|
619 | + return $this->get_all( |
|
620 | + array( |
|
621 | + array( |
|
622 | + 'TXN_ID' => 0, |
|
623 | + 'OBJ_type' => EEM_Line_Item::OBJ_TYPE_TICKET, |
|
624 | + 'LIN_timestamp' => array('<=', $timestamp), |
|
625 | + ), |
|
626 | + ) |
|
627 | + ); |
|
628 | + } |
|
629 | 629 | } |
@@ -241,7 +241,7 @@ |
||
241 | 241 | |
242 | 242 | |
243 | 243 | /** |
244 | - * @return string |
|
244 | + * @return boolean |
|
245 | 245 | * @throws InvalidArgumentException |
246 | 246 | * @throws InvalidInterfaceException |
247 | 247 | * @throws InvalidDataTypeException |
@@ -17,445 +17,445 @@ |
||
17 | 17 | class EED_Ticket_Selector extends EED_Module |
18 | 18 | { |
19 | 19 | |
20 | - /** |
|
21 | - * @var DisplayTicketSelector $ticket_selector |
|
22 | - */ |
|
23 | - private static $ticket_selector; |
|
24 | - |
|
25 | - /** |
|
26 | - * @var TicketSelectorIframeEmbedButton $iframe_embed_button |
|
27 | - */ |
|
28 | - private static $iframe_embed_button; |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * @return EED_Module|EED_Ticket_Selector |
|
33 | - */ |
|
34 | - public static function instance() |
|
35 | - { |
|
36 | - return parent::get_instance(__CLASS__); |
|
37 | - } |
|
38 | - |
|
39 | - |
|
40 | - /** |
|
41 | - * @return void |
|
42 | - */ |
|
43 | - protected function set_config() |
|
44 | - { |
|
45 | - $this->set_config_section('template_settings'); |
|
46 | - $this->set_config_class('EE_Ticket_Selector_Config'); |
|
47 | - $this->set_config_name('EED_Ticket_Selector'); |
|
48 | - } |
|
49 | - |
|
50 | - |
|
51 | - /** |
|
52 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
53 | - * |
|
54 | - * @return void |
|
55 | - */ |
|
56 | - public static function set_hooks() |
|
57 | - { |
|
58 | - // routing |
|
59 | - EE_Config::register_route( |
|
60 | - 'iframe', |
|
61 | - 'EED_Ticket_Selector', |
|
62 | - 'ticket_selector_iframe', |
|
63 | - 'ticket_selector' |
|
64 | - ); |
|
65 | - EE_Config::register_route( |
|
66 | - 'process_ticket_selections', |
|
67 | - 'EED_Ticket_Selector', |
|
68 | - 'process_ticket_selections' |
|
69 | - ); |
|
70 | - EE_Config::register_route( |
|
71 | - 'cancel_ticket_selections', |
|
72 | - 'EED_Ticket_Selector', |
|
73 | - 'cancel_ticket_selections' |
|
74 | - ); |
|
75 | - add_action('wp_loaded', array('EED_Ticket_Selector', 'set_definitions'), 2); |
|
76 | - add_action('AHEE_event_details_header_bottom', array('EED_Ticket_Selector', 'display_ticket_selector'), 10, 1); |
|
77 | - add_action('wp_enqueue_scripts', array('EED_Ticket_Selector', 'translate_js_strings'), 0); |
|
78 | - add_action('wp_enqueue_scripts', array('EED_Ticket_Selector', 'load_tckt_slctr_assets'), 10); |
|
79 | - EED_Ticket_Selector::loadIframeAssets(); |
|
80 | - } |
|
81 | - |
|
82 | - |
|
83 | - /** |
|
84 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
85 | - * |
|
86 | - * @return void |
|
87 | - */ |
|
88 | - public static function set_hooks_admin() |
|
89 | - { |
|
90 | - // hook into the end of the \EE_Admin_Page::_load_page_dependencies() |
|
91 | - // to load assets for "espresso_events" page on the "edit" route (action) |
|
92 | - add_action( |
|
93 | - 'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_events__edit', |
|
94 | - array('EED_Ticket_Selector', 'ticket_selector_iframe_embed_button'), |
|
95 | - 10 |
|
96 | - ); |
|
97 | - /** |
|
98 | - * Make sure assets for the ticket selector are loaded on the espresso registrations route so admin side |
|
99 | - * registrations work. |
|
100 | - */ |
|
101 | - add_action( |
|
102 | - 'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_registrations__new_registration', |
|
103 | - array('EED_Ticket_Selector', 'set_definitions'), |
|
104 | - 10 |
|
105 | - ); |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * set_definitions |
|
111 | - * |
|
112 | - * @return void |
|
113 | - * @throws InvalidArgumentException |
|
114 | - * @throws InvalidDataTypeException |
|
115 | - * @throws InvalidInterfaceException |
|
116 | - */ |
|
117 | - public static function set_definitions() |
|
118 | - { |
|
119 | - // don't do this twice |
|
120 | - if (defined('TICKET_SELECTOR_ASSETS_URL')) { |
|
121 | - return; |
|
122 | - } |
|
123 | - define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
124 | - define( |
|
125 | - 'TICKET_SELECTOR_TEMPLATES_PATH', |
|
126 | - str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/' |
|
127 | - ); |
|
128 | - // if config is not set, initialize |
|
129 | - if ( |
|
130 | - ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
131 | - ) { |
|
132 | - EED_Ticket_Selector::instance()->set_config(); |
|
133 | - EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector = EED_Ticket_Selector::instance( |
|
134 | - )->config(); |
|
135 | - } |
|
136 | - } |
|
137 | - |
|
138 | - |
|
139 | - /** |
|
140 | - * @return DisplayTicketSelector |
|
141 | - */ |
|
142 | - public static function ticketSelector() |
|
143 | - { |
|
144 | - if (! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) { |
|
145 | - EED_Ticket_Selector::$ticket_selector = new DisplayTicketSelector(EED_Events_Archive::is_iframe()); |
|
146 | - } |
|
147 | - return EED_Ticket_Selector::$ticket_selector; |
|
148 | - } |
|
149 | - |
|
150 | - |
|
151 | - /** |
|
152 | - * gets the ball rolling |
|
153 | - * |
|
154 | - * @param WP $WP |
|
155 | - * @return void |
|
156 | - */ |
|
157 | - public function run($WP) |
|
158 | - { |
|
159 | - } |
|
160 | - |
|
161 | - |
|
162 | - /** |
|
163 | - * @return TicketSelectorIframeEmbedButton |
|
164 | - */ |
|
165 | - public static function getIframeEmbedButton() |
|
166 | - { |
|
167 | - if (! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) { |
|
168 | - self::$iframe_embed_button = new TicketSelectorIframeEmbedButton(); |
|
169 | - } |
|
170 | - return self::$iframe_embed_button; |
|
171 | - } |
|
172 | - |
|
173 | - |
|
174 | - /** |
|
175 | - * ticket_selector_iframe_embed_button |
|
176 | - * |
|
177 | - * @return void |
|
178 | - * @throws EE_Error |
|
179 | - */ |
|
180 | - public static function ticket_selector_iframe_embed_button() |
|
181 | - { |
|
182 | - $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton(); |
|
183 | - $iframe_embed_button->addEventEditorIframeEmbedButton(); |
|
184 | - } |
|
185 | - |
|
186 | - |
|
187 | - /** |
|
188 | - * ticket_selector_iframe |
|
189 | - * |
|
190 | - * @return void |
|
191 | - * @throws DomainException |
|
192 | - * @throws EE_Error |
|
193 | - */ |
|
194 | - public function ticket_selector_iframe() |
|
195 | - { |
|
196 | - $ticket_selector_iframe = new TicketSelectorIframe(); |
|
197 | - $ticket_selector_iframe->display(); |
|
198 | - } |
|
199 | - |
|
200 | - |
|
201 | - /** |
|
202 | - * creates buttons for selecting number of attendees for an event |
|
203 | - * |
|
204 | - * @param WP_Post|int $event |
|
205 | - * @param bool $view_details |
|
206 | - * @return string |
|
207 | - * @throws EE_Error |
|
208 | - */ |
|
209 | - public static function display_ticket_selector($event = null, $view_details = false) |
|
210 | - { |
|
211 | - return EED_Ticket_Selector::ticketSelector()->display($event, $view_details); |
|
212 | - } |
|
213 | - |
|
214 | - |
|
215 | - /** |
|
216 | - * @return array or FALSE |
|
217 | - * @throws \ReflectionException |
|
218 | - * @throws \EE_Error |
|
219 | - * @throws InvalidArgumentException |
|
220 | - * @throws InvalidInterfaceException |
|
221 | - * @throws InvalidDataTypeException |
|
222 | - */ |
|
223 | - public function process_ticket_selections() |
|
224 | - { |
|
225 | - /** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */ |
|
226 | - $form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector'); |
|
227 | - return $form->processTicketSelections(); |
|
228 | - } |
|
229 | - |
|
230 | - |
|
231 | - /** |
|
232 | - * @return string |
|
233 | - * @throws InvalidArgumentException |
|
234 | - * @throws InvalidInterfaceException |
|
235 | - * @throws InvalidDataTypeException |
|
236 | - * @throws EE_Error |
|
237 | - */ |
|
238 | - public static function cancel_ticket_selections() |
|
239 | - { |
|
240 | - /** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */ |
|
241 | - $form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector'); |
|
242 | - return $form->cancelTicketSelections(); |
|
243 | - } |
|
244 | - |
|
245 | - |
|
246 | - /** |
|
247 | - * @return void |
|
248 | - */ |
|
249 | - public static function translate_js_strings() |
|
250 | - { |
|
251 | - EE_Registry::$i18n_js_strings['please_select_date_filter_notice'] = esc_html__( |
|
252 | - 'please select a datetime', |
|
253 | - 'event_espresso' |
|
254 | - ); |
|
255 | - } |
|
256 | - |
|
257 | - |
|
258 | - /** |
|
259 | - * @return void |
|
260 | - */ |
|
261 | - public static function load_tckt_slctr_assets() |
|
262 | - { |
|
263 | - if (apply_filters('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', false)) { |
|
264 | - // add some style |
|
265 | - wp_register_style( |
|
266 | - 'ticket_selector', |
|
267 | - TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css', |
|
268 | - array(), |
|
269 | - EVENT_ESPRESSO_VERSION |
|
270 | - ); |
|
271 | - wp_enqueue_style('ticket_selector'); |
|
272 | - // make it dance |
|
273 | - wp_register_script( |
|
274 | - 'ticket_selector', |
|
275 | - TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js', |
|
276 | - array('espresso_core'), |
|
277 | - EVENT_ESPRESSO_VERSION, |
|
278 | - true |
|
279 | - ); |
|
280 | - wp_enqueue_script('ticket_selector'); |
|
281 | - require_once EE_LIBRARIES |
|
282 | - . 'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php'; |
|
283 | - \EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts(); |
|
284 | - } |
|
285 | - } |
|
286 | - |
|
287 | - |
|
288 | - /** |
|
289 | - * @return void |
|
290 | - */ |
|
291 | - public static function loadIframeAssets() |
|
292 | - { |
|
293 | - // for event lists |
|
294 | - add_filter( |
|
295 | - 'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__css', |
|
296 | - array('EED_Ticket_Selector', 'iframeCss') |
|
297 | - ); |
|
298 | - add_filter( |
|
299 | - 'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js', |
|
300 | - array('EED_Ticket_Selector', 'iframeJs') |
|
301 | - ); |
|
302 | - // for ticket selectors |
|
303 | - add_filter( |
|
304 | - 'FHEE__EED_Ticket_Selector__ticket_selector_iframe__css', |
|
305 | - array('EED_Ticket_Selector', 'iframeCss') |
|
306 | - ); |
|
307 | - add_filter( |
|
308 | - 'FHEE__EED_Ticket_Selector__ticket_selector_iframe__js', |
|
309 | - array('EED_Ticket_Selector', 'iframeJs') |
|
310 | - ); |
|
311 | - } |
|
312 | - |
|
313 | - |
|
314 | - /** |
|
315 | - * Informs the rest of the forms system what CSS and JS is needed to display the input |
|
316 | - * |
|
317 | - * @param array $iframe_css |
|
318 | - * @return array |
|
319 | - */ |
|
320 | - public static function iframeCss(array $iframe_css) |
|
321 | - { |
|
322 | - $iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css'; |
|
323 | - return $iframe_css; |
|
324 | - } |
|
325 | - |
|
326 | - |
|
327 | - /** |
|
328 | - * Informs the rest of the forms system what CSS and JS is needed to display the input |
|
329 | - * |
|
330 | - * @param array $iframe_js |
|
331 | - * @return array |
|
332 | - */ |
|
333 | - public static function iframeJs(array $iframe_js) |
|
334 | - { |
|
335 | - $iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js'; |
|
336 | - return $iframe_js; |
|
337 | - } |
|
338 | - |
|
339 | - |
|
340 | - /****************************** DEPRECATED ******************************/ |
|
341 | - |
|
342 | - |
|
343 | - /** |
|
344 | - * @deprecated |
|
345 | - * @return string |
|
346 | - * @throws EE_Error |
|
347 | - */ |
|
348 | - public static function display_view_details_btn() |
|
349 | - { |
|
350 | - // todo add doing_it_wrong() notice during next major version |
|
351 | - return EED_Ticket_Selector::ticketSelector()->displayViewDetailsButton(); |
|
352 | - } |
|
353 | - |
|
354 | - |
|
355 | - /** |
|
356 | - * @deprecated |
|
357 | - * @return string |
|
358 | - * @throws EE_Error |
|
359 | - */ |
|
360 | - public static function display_ticket_selector_submit() |
|
361 | - { |
|
362 | - // todo add doing_it_wrong() notice during next major version |
|
363 | - return EED_Ticket_Selector::ticketSelector()->displaySubmitButton(); |
|
364 | - } |
|
365 | - |
|
366 | - |
|
367 | - /** |
|
368 | - * @deprecated |
|
369 | - * @param string $permalink_string |
|
370 | - * @param int $id |
|
371 | - * @param string $new_title |
|
372 | - * @param string $new_slug |
|
373 | - * @return string |
|
374 | - * @throws InvalidArgumentException |
|
375 | - * @throws InvalidDataTypeException |
|
376 | - * @throws InvalidInterfaceException |
|
377 | - */ |
|
378 | - public static function iframe_code_button($permalink_string, $id, $new_title = '', $new_slug = '') |
|
379 | - { |
|
380 | - // todo add doing_it_wrong() notice during next major version |
|
381 | - if ( |
|
382 | - EE_Registry::instance()->REQ->get('page') === 'espresso_events' |
|
383 | - && EE_Registry::instance()->REQ->get('action') === 'edit' |
|
384 | - ) { |
|
385 | - $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton(); |
|
386 | - $iframe_embed_button->addEventEditorIframeEmbedButton(); |
|
387 | - } |
|
388 | - return ''; |
|
389 | - } |
|
390 | - |
|
391 | - |
|
392 | - /** |
|
393 | - * @deprecated |
|
394 | - * @param int $ID |
|
395 | - * @param string $external_url |
|
396 | - * @return string |
|
397 | - */ |
|
398 | - public static function ticket_selector_form_open($ID = 0, $external_url = '') |
|
399 | - { |
|
400 | - // todo add doing_it_wrong() notice during next major version |
|
401 | - return EED_Ticket_Selector::ticketSelector()->formOpen($ID, $external_url); |
|
402 | - } |
|
403 | - |
|
404 | - |
|
405 | - /** |
|
406 | - * @deprecated |
|
407 | - * @return string |
|
408 | - */ |
|
409 | - public static function ticket_selector_form_close() |
|
410 | - { |
|
411 | - // todo add doing_it_wrong() notice during next major version |
|
412 | - return EED_Ticket_Selector::ticketSelector()->formClose(); |
|
413 | - } |
|
414 | - |
|
415 | - |
|
416 | - /** |
|
417 | - * @deprecated |
|
418 | - * @return string |
|
419 | - */ |
|
420 | - public static function no_tkt_slctr_end_dv() |
|
421 | - { |
|
422 | - // todo add doing_it_wrong() notice during next major version |
|
423 | - return EED_Ticket_Selector::ticketSelector()->ticketSelectorEndDiv(); |
|
424 | - } |
|
425 | - |
|
426 | - |
|
427 | - /** |
|
428 | - * @deprecated 4.9.13 |
|
429 | - * @return string |
|
430 | - */ |
|
431 | - public static function tkt_slctr_end_dv() |
|
432 | - { |
|
433 | - return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
434 | - } |
|
435 | - |
|
436 | - |
|
437 | - /** |
|
438 | - * @deprecated |
|
439 | - * @return string |
|
440 | - */ |
|
441 | - public static function clear_tkt_slctr() |
|
442 | - { |
|
443 | - return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
444 | - } |
|
445 | - |
|
446 | - |
|
447 | - /** |
|
448 | - * @deprecated |
|
449 | - */ |
|
450 | - public static function load_tckt_slctr_assets_admin() |
|
451 | - { |
|
452 | - // todo add doing_it_wrong() notice during next major version |
|
453 | - if ( |
|
454 | - EE_Registry::instance()->REQ->get('page') === 'espresso_events' |
|
455 | - && EE_Registry::instance()->REQ->get('action') === 'edit' |
|
456 | - ) { |
|
457 | - $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton(); |
|
458 | - $iframe_embed_button->embedButtonAssets(); |
|
459 | - } |
|
460 | - } |
|
20 | + /** |
|
21 | + * @var DisplayTicketSelector $ticket_selector |
|
22 | + */ |
|
23 | + private static $ticket_selector; |
|
24 | + |
|
25 | + /** |
|
26 | + * @var TicketSelectorIframeEmbedButton $iframe_embed_button |
|
27 | + */ |
|
28 | + private static $iframe_embed_button; |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * @return EED_Module|EED_Ticket_Selector |
|
33 | + */ |
|
34 | + public static function instance() |
|
35 | + { |
|
36 | + return parent::get_instance(__CLASS__); |
|
37 | + } |
|
38 | + |
|
39 | + |
|
40 | + /** |
|
41 | + * @return void |
|
42 | + */ |
|
43 | + protected function set_config() |
|
44 | + { |
|
45 | + $this->set_config_section('template_settings'); |
|
46 | + $this->set_config_class('EE_Ticket_Selector_Config'); |
|
47 | + $this->set_config_name('EED_Ticket_Selector'); |
|
48 | + } |
|
49 | + |
|
50 | + |
|
51 | + /** |
|
52 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
53 | + * |
|
54 | + * @return void |
|
55 | + */ |
|
56 | + public static function set_hooks() |
|
57 | + { |
|
58 | + // routing |
|
59 | + EE_Config::register_route( |
|
60 | + 'iframe', |
|
61 | + 'EED_Ticket_Selector', |
|
62 | + 'ticket_selector_iframe', |
|
63 | + 'ticket_selector' |
|
64 | + ); |
|
65 | + EE_Config::register_route( |
|
66 | + 'process_ticket_selections', |
|
67 | + 'EED_Ticket_Selector', |
|
68 | + 'process_ticket_selections' |
|
69 | + ); |
|
70 | + EE_Config::register_route( |
|
71 | + 'cancel_ticket_selections', |
|
72 | + 'EED_Ticket_Selector', |
|
73 | + 'cancel_ticket_selections' |
|
74 | + ); |
|
75 | + add_action('wp_loaded', array('EED_Ticket_Selector', 'set_definitions'), 2); |
|
76 | + add_action('AHEE_event_details_header_bottom', array('EED_Ticket_Selector', 'display_ticket_selector'), 10, 1); |
|
77 | + add_action('wp_enqueue_scripts', array('EED_Ticket_Selector', 'translate_js_strings'), 0); |
|
78 | + add_action('wp_enqueue_scripts', array('EED_Ticket_Selector', 'load_tckt_slctr_assets'), 10); |
|
79 | + EED_Ticket_Selector::loadIframeAssets(); |
|
80 | + } |
|
81 | + |
|
82 | + |
|
83 | + /** |
|
84 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
85 | + * |
|
86 | + * @return void |
|
87 | + */ |
|
88 | + public static function set_hooks_admin() |
|
89 | + { |
|
90 | + // hook into the end of the \EE_Admin_Page::_load_page_dependencies() |
|
91 | + // to load assets for "espresso_events" page on the "edit" route (action) |
|
92 | + add_action( |
|
93 | + 'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_events__edit', |
|
94 | + array('EED_Ticket_Selector', 'ticket_selector_iframe_embed_button'), |
|
95 | + 10 |
|
96 | + ); |
|
97 | + /** |
|
98 | + * Make sure assets for the ticket selector are loaded on the espresso registrations route so admin side |
|
99 | + * registrations work. |
|
100 | + */ |
|
101 | + add_action( |
|
102 | + 'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_registrations__new_registration', |
|
103 | + array('EED_Ticket_Selector', 'set_definitions'), |
|
104 | + 10 |
|
105 | + ); |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * set_definitions |
|
111 | + * |
|
112 | + * @return void |
|
113 | + * @throws InvalidArgumentException |
|
114 | + * @throws InvalidDataTypeException |
|
115 | + * @throws InvalidInterfaceException |
|
116 | + */ |
|
117 | + public static function set_definitions() |
|
118 | + { |
|
119 | + // don't do this twice |
|
120 | + if (defined('TICKET_SELECTOR_ASSETS_URL')) { |
|
121 | + return; |
|
122 | + } |
|
123 | + define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
124 | + define( |
|
125 | + 'TICKET_SELECTOR_TEMPLATES_PATH', |
|
126 | + str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/' |
|
127 | + ); |
|
128 | + // if config is not set, initialize |
|
129 | + if ( |
|
130 | + ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config |
|
131 | + ) { |
|
132 | + EED_Ticket_Selector::instance()->set_config(); |
|
133 | + EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector = EED_Ticket_Selector::instance( |
|
134 | + )->config(); |
|
135 | + } |
|
136 | + } |
|
137 | + |
|
138 | + |
|
139 | + /** |
|
140 | + * @return DisplayTicketSelector |
|
141 | + */ |
|
142 | + public static function ticketSelector() |
|
143 | + { |
|
144 | + if (! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) { |
|
145 | + EED_Ticket_Selector::$ticket_selector = new DisplayTicketSelector(EED_Events_Archive::is_iframe()); |
|
146 | + } |
|
147 | + return EED_Ticket_Selector::$ticket_selector; |
|
148 | + } |
|
149 | + |
|
150 | + |
|
151 | + /** |
|
152 | + * gets the ball rolling |
|
153 | + * |
|
154 | + * @param WP $WP |
|
155 | + * @return void |
|
156 | + */ |
|
157 | + public function run($WP) |
|
158 | + { |
|
159 | + } |
|
160 | + |
|
161 | + |
|
162 | + /** |
|
163 | + * @return TicketSelectorIframeEmbedButton |
|
164 | + */ |
|
165 | + public static function getIframeEmbedButton() |
|
166 | + { |
|
167 | + if (! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) { |
|
168 | + self::$iframe_embed_button = new TicketSelectorIframeEmbedButton(); |
|
169 | + } |
|
170 | + return self::$iframe_embed_button; |
|
171 | + } |
|
172 | + |
|
173 | + |
|
174 | + /** |
|
175 | + * ticket_selector_iframe_embed_button |
|
176 | + * |
|
177 | + * @return void |
|
178 | + * @throws EE_Error |
|
179 | + */ |
|
180 | + public static function ticket_selector_iframe_embed_button() |
|
181 | + { |
|
182 | + $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton(); |
|
183 | + $iframe_embed_button->addEventEditorIframeEmbedButton(); |
|
184 | + } |
|
185 | + |
|
186 | + |
|
187 | + /** |
|
188 | + * ticket_selector_iframe |
|
189 | + * |
|
190 | + * @return void |
|
191 | + * @throws DomainException |
|
192 | + * @throws EE_Error |
|
193 | + */ |
|
194 | + public function ticket_selector_iframe() |
|
195 | + { |
|
196 | + $ticket_selector_iframe = new TicketSelectorIframe(); |
|
197 | + $ticket_selector_iframe->display(); |
|
198 | + } |
|
199 | + |
|
200 | + |
|
201 | + /** |
|
202 | + * creates buttons for selecting number of attendees for an event |
|
203 | + * |
|
204 | + * @param WP_Post|int $event |
|
205 | + * @param bool $view_details |
|
206 | + * @return string |
|
207 | + * @throws EE_Error |
|
208 | + */ |
|
209 | + public static function display_ticket_selector($event = null, $view_details = false) |
|
210 | + { |
|
211 | + return EED_Ticket_Selector::ticketSelector()->display($event, $view_details); |
|
212 | + } |
|
213 | + |
|
214 | + |
|
215 | + /** |
|
216 | + * @return array or FALSE |
|
217 | + * @throws \ReflectionException |
|
218 | + * @throws \EE_Error |
|
219 | + * @throws InvalidArgumentException |
|
220 | + * @throws InvalidInterfaceException |
|
221 | + * @throws InvalidDataTypeException |
|
222 | + */ |
|
223 | + public function process_ticket_selections() |
|
224 | + { |
|
225 | + /** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */ |
|
226 | + $form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector'); |
|
227 | + return $form->processTicketSelections(); |
|
228 | + } |
|
229 | + |
|
230 | + |
|
231 | + /** |
|
232 | + * @return string |
|
233 | + * @throws InvalidArgumentException |
|
234 | + * @throws InvalidInterfaceException |
|
235 | + * @throws InvalidDataTypeException |
|
236 | + * @throws EE_Error |
|
237 | + */ |
|
238 | + public static function cancel_ticket_selections() |
|
239 | + { |
|
240 | + /** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */ |
|
241 | + $form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector'); |
|
242 | + return $form->cancelTicketSelections(); |
|
243 | + } |
|
244 | + |
|
245 | + |
|
246 | + /** |
|
247 | + * @return void |
|
248 | + */ |
|
249 | + public static function translate_js_strings() |
|
250 | + { |
|
251 | + EE_Registry::$i18n_js_strings['please_select_date_filter_notice'] = esc_html__( |
|
252 | + 'please select a datetime', |
|
253 | + 'event_espresso' |
|
254 | + ); |
|
255 | + } |
|
256 | + |
|
257 | + |
|
258 | + /** |
|
259 | + * @return void |
|
260 | + */ |
|
261 | + public static function load_tckt_slctr_assets() |
|
262 | + { |
|
263 | + if (apply_filters('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', false)) { |
|
264 | + // add some style |
|
265 | + wp_register_style( |
|
266 | + 'ticket_selector', |
|
267 | + TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css', |
|
268 | + array(), |
|
269 | + EVENT_ESPRESSO_VERSION |
|
270 | + ); |
|
271 | + wp_enqueue_style('ticket_selector'); |
|
272 | + // make it dance |
|
273 | + wp_register_script( |
|
274 | + 'ticket_selector', |
|
275 | + TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js', |
|
276 | + array('espresso_core'), |
|
277 | + EVENT_ESPRESSO_VERSION, |
|
278 | + true |
|
279 | + ); |
|
280 | + wp_enqueue_script('ticket_selector'); |
|
281 | + require_once EE_LIBRARIES |
|
282 | + . 'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php'; |
|
283 | + \EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts(); |
|
284 | + } |
|
285 | + } |
|
286 | + |
|
287 | + |
|
288 | + /** |
|
289 | + * @return void |
|
290 | + */ |
|
291 | + public static function loadIframeAssets() |
|
292 | + { |
|
293 | + // for event lists |
|
294 | + add_filter( |
|
295 | + 'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__css', |
|
296 | + array('EED_Ticket_Selector', 'iframeCss') |
|
297 | + ); |
|
298 | + add_filter( |
|
299 | + 'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js', |
|
300 | + array('EED_Ticket_Selector', 'iframeJs') |
|
301 | + ); |
|
302 | + // for ticket selectors |
|
303 | + add_filter( |
|
304 | + 'FHEE__EED_Ticket_Selector__ticket_selector_iframe__css', |
|
305 | + array('EED_Ticket_Selector', 'iframeCss') |
|
306 | + ); |
|
307 | + add_filter( |
|
308 | + 'FHEE__EED_Ticket_Selector__ticket_selector_iframe__js', |
|
309 | + array('EED_Ticket_Selector', 'iframeJs') |
|
310 | + ); |
|
311 | + } |
|
312 | + |
|
313 | + |
|
314 | + /** |
|
315 | + * Informs the rest of the forms system what CSS and JS is needed to display the input |
|
316 | + * |
|
317 | + * @param array $iframe_css |
|
318 | + * @return array |
|
319 | + */ |
|
320 | + public static function iframeCss(array $iframe_css) |
|
321 | + { |
|
322 | + $iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css'; |
|
323 | + return $iframe_css; |
|
324 | + } |
|
325 | + |
|
326 | + |
|
327 | + /** |
|
328 | + * Informs the rest of the forms system what CSS and JS is needed to display the input |
|
329 | + * |
|
330 | + * @param array $iframe_js |
|
331 | + * @return array |
|
332 | + */ |
|
333 | + public static function iframeJs(array $iframe_js) |
|
334 | + { |
|
335 | + $iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js'; |
|
336 | + return $iframe_js; |
|
337 | + } |
|
338 | + |
|
339 | + |
|
340 | + /****************************** DEPRECATED ******************************/ |
|
341 | + |
|
342 | + |
|
343 | + /** |
|
344 | + * @deprecated |
|
345 | + * @return string |
|
346 | + * @throws EE_Error |
|
347 | + */ |
|
348 | + public static function display_view_details_btn() |
|
349 | + { |
|
350 | + // todo add doing_it_wrong() notice during next major version |
|
351 | + return EED_Ticket_Selector::ticketSelector()->displayViewDetailsButton(); |
|
352 | + } |
|
353 | + |
|
354 | + |
|
355 | + /** |
|
356 | + * @deprecated |
|
357 | + * @return string |
|
358 | + * @throws EE_Error |
|
359 | + */ |
|
360 | + public static function display_ticket_selector_submit() |
|
361 | + { |
|
362 | + // todo add doing_it_wrong() notice during next major version |
|
363 | + return EED_Ticket_Selector::ticketSelector()->displaySubmitButton(); |
|
364 | + } |
|
365 | + |
|
366 | + |
|
367 | + /** |
|
368 | + * @deprecated |
|
369 | + * @param string $permalink_string |
|
370 | + * @param int $id |
|
371 | + * @param string $new_title |
|
372 | + * @param string $new_slug |
|
373 | + * @return string |
|
374 | + * @throws InvalidArgumentException |
|
375 | + * @throws InvalidDataTypeException |
|
376 | + * @throws InvalidInterfaceException |
|
377 | + */ |
|
378 | + public static function iframe_code_button($permalink_string, $id, $new_title = '', $new_slug = '') |
|
379 | + { |
|
380 | + // todo add doing_it_wrong() notice during next major version |
|
381 | + if ( |
|
382 | + EE_Registry::instance()->REQ->get('page') === 'espresso_events' |
|
383 | + && EE_Registry::instance()->REQ->get('action') === 'edit' |
|
384 | + ) { |
|
385 | + $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton(); |
|
386 | + $iframe_embed_button->addEventEditorIframeEmbedButton(); |
|
387 | + } |
|
388 | + return ''; |
|
389 | + } |
|
390 | + |
|
391 | + |
|
392 | + /** |
|
393 | + * @deprecated |
|
394 | + * @param int $ID |
|
395 | + * @param string $external_url |
|
396 | + * @return string |
|
397 | + */ |
|
398 | + public static function ticket_selector_form_open($ID = 0, $external_url = '') |
|
399 | + { |
|
400 | + // todo add doing_it_wrong() notice during next major version |
|
401 | + return EED_Ticket_Selector::ticketSelector()->formOpen($ID, $external_url); |
|
402 | + } |
|
403 | + |
|
404 | + |
|
405 | + /** |
|
406 | + * @deprecated |
|
407 | + * @return string |
|
408 | + */ |
|
409 | + public static function ticket_selector_form_close() |
|
410 | + { |
|
411 | + // todo add doing_it_wrong() notice during next major version |
|
412 | + return EED_Ticket_Selector::ticketSelector()->formClose(); |
|
413 | + } |
|
414 | + |
|
415 | + |
|
416 | + /** |
|
417 | + * @deprecated |
|
418 | + * @return string |
|
419 | + */ |
|
420 | + public static function no_tkt_slctr_end_dv() |
|
421 | + { |
|
422 | + // todo add doing_it_wrong() notice during next major version |
|
423 | + return EED_Ticket_Selector::ticketSelector()->ticketSelectorEndDiv(); |
|
424 | + } |
|
425 | + |
|
426 | + |
|
427 | + /** |
|
428 | + * @deprecated 4.9.13 |
|
429 | + * @return string |
|
430 | + */ |
|
431 | + public static function tkt_slctr_end_dv() |
|
432 | + { |
|
433 | + return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
434 | + } |
|
435 | + |
|
436 | + |
|
437 | + /** |
|
438 | + * @deprecated |
|
439 | + * @return string |
|
440 | + */ |
|
441 | + public static function clear_tkt_slctr() |
|
442 | + { |
|
443 | + return EED_Ticket_Selector::ticketSelector()->clearTicketSelector(); |
|
444 | + } |
|
445 | + |
|
446 | + |
|
447 | + /** |
|
448 | + * @deprecated |
|
449 | + */ |
|
450 | + public static function load_tckt_slctr_assets_admin() |
|
451 | + { |
|
452 | + // todo add doing_it_wrong() notice during next major version |
|
453 | + if ( |
|
454 | + EE_Registry::instance()->REQ->get('page') === 'espresso_events' |
|
455 | + && EE_Registry::instance()->REQ->get('action') === 'edit' |
|
456 | + ) { |
|
457 | + $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton(); |
|
458 | + $iframe_embed_button->embedButtonAssets(); |
|
459 | + } |
|
460 | + } |
|
461 | 461 | } |
@@ -120,10 +120,10 @@ discard block |
||
120 | 120 | if (defined('TICKET_SELECTOR_ASSETS_URL')) { |
121 | 121 | return; |
122 | 122 | } |
123 | - define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
123 | + define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__).'assets/'); |
|
124 | 124 | define( |
125 | 125 | 'TICKET_SELECTOR_TEMPLATES_PATH', |
126 | - str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/' |
|
126 | + str_replace('\\', '/', plugin_dir_path(__FILE__)).'templates/' |
|
127 | 127 | ); |
128 | 128 | // if config is not set, initialize |
129 | 129 | if ( |
@@ -141,7 +141,7 @@ discard block |
||
141 | 141 | */ |
142 | 142 | public static function ticketSelector() |
143 | 143 | { |
144 | - if (! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) { |
|
144 | + if ( ! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) { |
|
145 | 145 | EED_Ticket_Selector::$ticket_selector = new DisplayTicketSelector(EED_Events_Archive::is_iframe()); |
146 | 146 | } |
147 | 147 | return EED_Ticket_Selector::$ticket_selector; |
@@ -164,7 +164,7 @@ discard block |
||
164 | 164 | */ |
165 | 165 | public static function getIframeEmbedButton() |
166 | 166 | { |
167 | - if (! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) { |
|
167 | + if ( ! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) { |
|
168 | 168 | self::$iframe_embed_button = new TicketSelectorIframeEmbedButton(); |
169 | 169 | } |
170 | 170 | return self::$iframe_embed_button; |
@@ -264,7 +264,7 @@ discard block |
||
264 | 264 | // add some style |
265 | 265 | wp_register_style( |
266 | 266 | 'ticket_selector', |
267 | - TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css', |
|
267 | + TICKET_SELECTOR_ASSETS_URL.'ticket_selector.css', |
|
268 | 268 | array(), |
269 | 269 | EVENT_ESPRESSO_VERSION |
270 | 270 | ); |
@@ -272,7 +272,7 @@ discard block |
||
272 | 272 | // make it dance |
273 | 273 | wp_register_script( |
274 | 274 | 'ticket_selector', |
275 | - TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js', |
|
275 | + TICKET_SELECTOR_ASSETS_URL.'ticket_selector.js', |
|
276 | 276 | array('espresso_core'), |
277 | 277 | EVENT_ESPRESSO_VERSION, |
278 | 278 | true |
@@ -319,7 +319,7 @@ discard block |
||
319 | 319 | */ |
320 | 320 | public static function iframeCss(array $iframe_css) |
321 | 321 | { |
322 | - $iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css'; |
|
322 | + $iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL.'ticket_selector.css'; |
|
323 | 323 | return $iframe_css; |
324 | 324 | } |
325 | 325 | |
@@ -332,7 +332,7 @@ discard block |
||
332 | 332 | */ |
333 | 333 | public static function iframeJs(array $iframe_js) |
334 | 334 | { |
335 | - $iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js'; |
|
335 | + $iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL.'ticket_selector.js'; |
|
336 | 336 | return $iframe_js; |
337 | 337 | } |
338 | 338 |
@@ -65,7 +65,7 @@ |
||
65 | 65 | */ |
66 | 66 | public function registerCustomTaxonomyTerm($taxonomy, $term_slug, array $cpt_slugs = array()) |
67 | 67 | { |
68 | - $this->custom_taxonomy_terms[][ $term_slug ] = new CustomTaxonomyTerm( |
|
68 | + $this->custom_taxonomy_terms[][$term_slug] = new CustomTaxonomyTerm( |
|
69 | 69 | $taxonomy, |
70 | 70 | $term_slug, |
71 | 71 | $cpt_slugs |
@@ -16,181 +16,181 @@ |
||
16 | 16 | class RegisterCustomTaxonomyTerms |
17 | 17 | { |
18 | 18 | |
19 | - /** |
|
20 | - * @var array[] $custom_taxonomy_terms |
|
21 | - */ |
|
22 | - public $custom_taxonomy_terms = array(); |
|
23 | - |
|
24 | - |
|
25 | - /** |
|
26 | - * RegisterCustomTaxonomyTerms constructor. |
|
27 | - */ |
|
28 | - public function __construct() |
|
29 | - { |
|
30 | - // hook into save_post so that we can make sure that the default terms get saved on publish of registered cpts |
|
31 | - // IF they don't have a term for that taxonomy set. |
|
32 | - add_action('save_post', array($this, 'saveDefaultTerm'), 100, 2); |
|
33 | - do_action( |
|
34 | - 'AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end', |
|
35 | - $this |
|
36 | - ); |
|
37 | - } |
|
38 | - |
|
39 | - |
|
40 | - public function registerCustomTaxonomyTerms() |
|
41 | - { |
|
42 | - // setup default terms in any of our taxonomies (but only if we're in admin). |
|
43 | - // Why not added via register_activation_hook? |
|
44 | - // Because it's possible that in future iterations of EE we may add new defaults for specialized taxonomies |
|
45 | - // (think event_types) and register_activation_hook only reliably runs when a user manually activates the plugin. |
|
46 | - // Keep in mind that this will READ these terms if they are deleted by the user. Hence MUST use terms. |
|
47 | - // if ( is_admin() ) { |
|
48 | - // $this->set_must_use_event_types(); |
|
49 | - // } |
|
50 | - // set default terms |
|
51 | - $this->registerCustomTaxonomyTerm( |
|
52 | - 'espresso_event_type', |
|
53 | - 'single-event', |
|
54 | - array('espresso_events') |
|
55 | - ); |
|
56 | - } |
|
57 | - |
|
58 | - |
|
59 | - /** |
|
60 | - * Allows us to set what the default will be for terms when a cpt is PUBLISHED. |
|
61 | - * |
|
62 | - * @param string $taxonomy The taxonomy we're using for the default term |
|
63 | - * @param string $term_slug The slug of the term that will be the default. |
|
64 | - * @param array $cpt_slugs An array of custom post types we want the default assigned to |
|
65 | - */ |
|
66 | - public function registerCustomTaxonomyTerm($taxonomy, $term_slug, array $cpt_slugs = array()) |
|
67 | - { |
|
68 | - $this->custom_taxonomy_terms[][ $term_slug ] = new CustomTaxonomyTerm( |
|
69 | - $taxonomy, |
|
70 | - $term_slug, |
|
71 | - $cpt_slugs |
|
72 | - ); |
|
73 | - } |
|
74 | - |
|
75 | - |
|
76 | - /** |
|
77 | - * hooked into the wp 'save_post' action hook for setting our default terms found in the $_default_terms property |
|
78 | - * |
|
79 | - * @param int $post_id ID of CPT being saved |
|
80 | - * @param WP_Post $post Post object |
|
81 | - * @return void |
|
82 | - */ |
|
83 | - public function saveDefaultTerm($post_id, WP_Post $post) |
|
84 | - { |
|
85 | - if (empty($this->custom_taxonomy_terms)) { |
|
86 | - return; |
|
87 | - } |
|
88 | - // no default terms set so lets just exit. |
|
89 | - foreach ($this->custom_taxonomy_terms as $custom_taxonomy_terms) { |
|
90 | - foreach ($custom_taxonomy_terms as $custom_taxonomy_term) { |
|
91 | - if ( |
|
92 | - $post->post_status === 'publish' |
|
93 | - && $custom_taxonomy_term instanceof CustomTaxonomyTerm |
|
94 | - && in_array($post->post_type, $custom_taxonomy_term->customPostTypeSlugs(), true) |
|
95 | - ) { |
|
96 | - // note some error proofing going on here to save unnecessary db queries |
|
97 | - $taxonomies = get_object_taxonomies($post->post_type); |
|
98 | - foreach ($taxonomies as $taxonomy) { |
|
99 | - $terms = wp_get_post_terms($post_id, $taxonomy); |
|
100 | - if (empty($terms) && $taxonomy === $custom_taxonomy_term->taxonomySlug()) { |
|
101 | - wp_set_object_terms( |
|
102 | - $post_id, |
|
103 | - array($custom_taxonomy_term->termSlug()), |
|
104 | - $taxonomy |
|
105 | - ); |
|
106 | - } |
|
107 | - } |
|
108 | - } |
|
109 | - } |
|
110 | - } |
|
111 | - } |
|
112 | - |
|
113 | - |
|
114 | - /** |
|
115 | - * @return void |
|
116 | - */ |
|
117 | - public function setMustUseEventTypes() |
|
118 | - { |
|
119 | - $term_details = array( |
|
120 | - // Attendee's register for the first date-time only |
|
121 | - 'single-event' => array( |
|
122 | - 'term' => esc_html__('Single Event', 'event_espresso'), |
|
123 | - 'desc' => esc_html__( |
|
124 | - 'A single event that spans one or more consecutive days.', |
|
125 | - 'event_espresso' |
|
126 | - ), |
|
127 | - ), |
|
128 | - // example: a party or two-day long workshop |
|
129 | - // Attendee's can register for any of the date-times |
|
130 | - 'multi-event' => array( |
|
131 | - 'term' => esc_html__('Multi Event', 'event_espresso'), |
|
132 | - 'desc' => esc_html__( |
|
133 | - 'Multiple, separate, but related events that occur on consecutive days.', |
|
134 | - 'event_espresso' |
|
135 | - ), |
|
136 | - ), |
|
137 | - // example: a three day music festival or week long conference |
|
138 | - // Attendee's register for the first date-time only |
|
139 | - 'event-series' => array( |
|
140 | - 'term' => esc_html__('Event Series', 'event_espresso'), |
|
141 | - 'desc' => esc_html__( |
|
142 | - ' Multiple events that occur over multiple non-consecutive days.', |
|
143 | - 'event_espresso' |
|
144 | - ), |
|
145 | - ), |
|
146 | - // example: an 8 week introduction to basket weaving course |
|
147 | - // Attendee's can register for any of the date-times. |
|
148 | - 'recurring-event' => array( |
|
149 | - 'term' => esc_html__('Recurring Event', 'event_espresso'), |
|
150 | - 'desc' => esc_html__( |
|
151 | - 'Multiple events that occur over multiple non-consecutive days.', |
|
152 | - 'event_espresso' |
|
153 | - ), |
|
154 | - ), |
|
155 | - // example: a yoga class |
|
156 | - 'ongoing' => array( |
|
157 | - 'term' => esc_html__('Ongoing Event', 'event_espresso'), |
|
158 | - 'desc' => esc_html__( |
|
159 | - 'An "event" that people can purchase tickets to gain access for anytime for this event regardless of date times on the event', |
|
160 | - 'event_espresso' |
|
161 | - ), |
|
162 | - ) |
|
163 | - // example: access to a museum |
|
164 | - // 'walk-in' => array( esc_html__('Walk In', 'event_espresso'), esc_html__('Single datetime and single entry recurring events. Attendees register for one or multiple datetimes individually.', 'event_espresso') ), |
|
165 | - // 'reservation' => array( esc_html__('Reservation', 'event_espresso'), esc_html__('Reservations are created by specifying available datetimes and quantities. Attendees choose from the available datetimes and specify the quantity available (if the maximum is greater than 1)') ), //@TODO to avoid confusion we'll implement this in a later iteration > EE4.1 |
|
166 | - // 'multiple-session' => array( esc_html__('Multiple Session', 'event_espresso'), esc_html__('Multiple event, multiple datetime, hierarchically organized, custom entry events. Attendees may be required to register for a parent event before being allowed to register for child events. Attendees can register for any combination of child events as long as the datetimes do not conflict. Parent and child events may have additional fees or registration questions.') ), //@TODO to avoid confusion we'll implement this in a later iteration > EE4.1 |
|
167 | - // 'appointment' => array( esc_html__('Appointments', 'event_espresso'), esc_html__('Time slotted events where datetimes are generally in hours or minutes. For example, attendees can register for a single 15 minute or 1 hour time slot and this type of availability frequently reoccurs.', 'event_espresso') ) |
|
168 | - ); |
|
169 | - $this->setMustUseTerms('espresso_event_type', $term_details); |
|
170 | - } |
|
171 | - |
|
172 | - |
|
173 | - /** |
|
174 | - * wrapper method for handling the setting up of initial terms in the db (if they don't already exist). |
|
175 | - * Note this should ONLY be used for terms that always must be present. Be aware that if an initial term is |
|
176 | - * deleted then it WILL be recreated. |
|
177 | - * |
|
178 | - * @param string $taxonomy The name of the taxonomy |
|
179 | - * @param array $term_details An array of term details indexed by slug and containing Name of term, and |
|
180 | - * description as the elements in the array |
|
181 | - * @return void |
|
182 | - */ |
|
183 | - public function setMustUseTerms($taxonomy, $term_details) |
|
184 | - { |
|
185 | - $term_details = (array) $term_details; |
|
186 | - foreach ($term_details as $slug => $details) { |
|
187 | - if (isset($details['term'], $details['desc']) && ! term_exists($slug, $taxonomy)) { |
|
188 | - $insert_arr = array( |
|
189 | - 'slug' => $slug, |
|
190 | - 'description' => $details['desc'], |
|
191 | - ); |
|
192 | - wp_insert_term($details['term'], $taxonomy, $insert_arr); |
|
193 | - } |
|
194 | - } |
|
195 | - } |
|
19 | + /** |
|
20 | + * @var array[] $custom_taxonomy_terms |
|
21 | + */ |
|
22 | + public $custom_taxonomy_terms = array(); |
|
23 | + |
|
24 | + |
|
25 | + /** |
|
26 | + * RegisterCustomTaxonomyTerms constructor. |
|
27 | + */ |
|
28 | + public function __construct() |
|
29 | + { |
|
30 | + // hook into save_post so that we can make sure that the default terms get saved on publish of registered cpts |
|
31 | + // IF they don't have a term for that taxonomy set. |
|
32 | + add_action('save_post', array($this, 'saveDefaultTerm'), 100, 2); |
|
33 | + do_action( |
|
34 | + 'AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end', |
|
35 | + $this |
|
36 | + ); |
|
37 | + } |
|
38 | + |
|
39 | + |
|
40 | + public function registerCustomTaxonomyTerms() |
|
41 | + { |
|
42 | + // setup default terms in any of our taxonomies (but only if we're in admin). |
|
43 | + // Why not added via register_activation_hook? |
|
44 | + // Because it's possible that in future iterations of EE we may add new defaults for specialized taxonomies |
|
45 | + // (think event_types) and register_activation_hook only reliably runs when a user manually activates the plugin. |
|
46 | + // Keep in mind that this will READ these terms if they are deleted by the user. Hence MUST use terms. |
|
47 | + // if ( is_admin() ) { |
|
48 | + // $this->set_must_use_event_types(); |
|
49 | + // } |
|
50 | + // set default terms |
|
51 | + $this->registerCustomTaxonomyTerm( |
|
52 | + 'espresso_event_type', |
|
53 | + 'single-event', |
|
54 | + array('espresso_events') |
|
55 | + ); |
|
56 | + } |
|
57 | + |
|
58 | + |
|
59 | + /** |
|
60 | + * Allows us to set what the default will be for terms when a cpt is PUBLISHED. |
|
61 | + * |
|
62 | + * @param string $taxonomy The taxonomy we're using for the default term |
|
63 | + * @param string $term_slug The slug of the term that will be the default. |
|
64 | + * @param array $cpt_slugs An array of custom post types we want the default assigned to |
|
65 | + */ |
|
66 | + public function registerCustomTaxonomyTerm($taxonomy, $term_slug, array $cpt_slugs = array()) |
|
67 | + { |
|
68 | + $this->custom_taxonomy_terms[][ $term_slug ] = new CustomTaxonomyTerm( |
|
69 | + $taxonomy, |
|
70 | + $term_slug, |
|
71 | + $cpt_slugs |
|
72 | + ); |
|
73 | + } |
|
74 | + |
|
75 | + |
|
76 | + /** |
|
77 | + * hooked into the wp 'save_post' action hook for setting our default terms found in the $_default_terms property |
|
78 | + * |
|
79 | + * @param int $post_id ID of CPT being saved |
|
80 | + * @param WP_Post $post Post object |
|
81 | + * @return void |
|
82 | + */ |
|
83 | + public function saveDefaultTerm($post_id, WP_Post $post) |
|
84 | + { |
|
85 | + if (empty($this->custom_taxonomy_terms)) { |
|
86 | + return; |
|
87 | + } |
|
88 | + // no default terms set so lets just exit. |
|
89 | + foreach ($this->custom_taxonomy_terms as $custom_taxonomy_terms) { |
|
90 | + foreach ($custom_taxonomy_terms as $custom_taxonomy_term) { |
|
91 | + if ( |
|
92 | + $post->post_status === 'publish' |
|
93 | + && $custom_taxonomy_term instanceof CustomTaxonomyTerm |
|
94 | + && in_array($post->post_type, $custom_taxonomy_term->customPostTypeSlugs(), true) |
|
95 | + ) { |
|
96 | + // note some error proofing going on here to save unnecessary db queries |
|
97 | + $taxonomies = get_object_taxonomies($post->post_type); |
|
98 | + foreach ($taxonomies as $taxonomy) { |
|
99 | + $terms = wp_get_post_terms($post_id, $taxonomy); |
|
100 | + if (empty($terms) && $taxonomy === $custom_taxonomy_term->taxonomySlug()) { |
|
101 | + wp_set_object_terms( |
|
102 | + $post_id, |
|
103 | + array($custom_taxonomy_term->termSlug()), |
|
104 | + $taxonomy |
|
105 | + ); |
|
106 | + } |
|
107 | + } |
|
108 | + } |
|
109 | + } |
|
110 | + } |
|
111 | + } |
|
112 | + |
|
113 | + |
|
114 | + /** |
|
115 | + * @return void |
|
116 | + */ |
|
117 | + public function setMustUseEventTypes() |
|
118 | + { |
|
119 | + $term_details = array( |
|
120 | + // Attendee's register for the first date-time only |
|
121 | + 'single-event' => array( |
|
122 | + 'term' => esc_html__('Single Event', 'event_espresso'), |
|
123 | + 'desc' => esc_html__( |
|
124 | + 'A single event that spans one or more consecutive days.', |
|
125 | + 'event_espresso' |
|
126 | + ), |
|
127 | + ), |
|
128 | + // example: a party or two-day long workshop |
|
129 | + // Attendee's can register for any of the date-times |
|
130 | + 'multi-event' => array( |
|
131 | + 'term' => esc_html__('Multi Event', 'event_espresso'), |
|
132 | + 'desc' => esc_html__( |
|
133 | + 'Multiple, separate, but related events that occur on consecutive days.', |
|
134 | + 'event_espresso' |
|
135 | + ), |
|
136 | + ), |
|
137 | + // example: a three day music festival or week long conference |
|
138 | + // Attendee's register for the first date-time only |
|
139 | + 'event-series' => array( |
|
140 | + 'term' => esc_html__('Event Series', 'event_espresso'), |
|
141 | + 'desc' => esc_html__( |
|
142 | + ' Multiple events that occur over multiple non-consecutive days.', |
|
143 | + 'event_espresso' |
|
144 | + ), |
|
145 | + ), |
|
146 | + // example: an 8 week introduction to basket weaving course |
|
147 | + // Attendee's can register for any of the date-times. |
|
148 | + 'recurring-event' => array( |
|
149 | + 'term' => esc_html__('Recurring Event', 'event_espresso'), |
|
150 | + 'desc' => esc_html__( |
|
151 | + 'Multiple events that occur over multiple non-consecutive days.', |
|
152 | + 'event_espresso' |
|
153 | + ), |
|
154 | + ), |
|
155 | + // example: a yoga class |
|
156 | + 'ongoing' => array( |
|
157 | + 'term' => esc_html__('Ongoing Event', 'event_espresso'), |
|
158 | + 'desc' => esc_html__( |
|
159 | + 'An "event" that people can purchase tickets to gain access for anytime for this event regardless of date times on the event', |
|
160 | + 'event_espresso' |
|
161 | + ), |
|
162 | + ) |
|
163 | + // example: access to a museum |
|
164 | + // 'walk-in' => array( esc_html__('Walk In', 'event_espresso'), esc_html__('Single datetime and single entry recurring events. Attendees register for one or multiple datetimes individually.', 'event_espresso') ), |
|
165 | + // 'reservation' => array( esc_html__('Reservation', 'event_espresso'), esc_html__('Reservations are created by specifying available datetimes and quantities. Attendees choose from the available datetimes and specify the quantity available (if the maximum is greater than 1)') ), //@TODO to avoid confusion we'll implement this in a later iteration > EE4.1 |
|
166 | + // 'multiple-session' => array( esc_html__('Multiple Session', 'event_espresso'), esc_html__('Multiple event, multiple datetime, hierarchically organized, custom entry events. Attendees may be required to register for a parent event before being allowed to register for child events. Attendees can register for any combination of child events as long as the datetimes do not conflict. Parent and child events may have additional fees or registration questions.') ), //@TODO to avoid confusion we'll implement this in a later iteration > EE4.1 |
|
167 | + // 'appointment' => array( esc_html__('Appointments', 'event_espresso'), esc_html__('Time slotted events where datetimes are generally in hours or minutes. For example, attendees can register for a single 15 minute or 1 hour time slot and this type of availability frequently reoccurs.', 'event_espresso') ) |
|
168 | + ); |
|
169 | + $this->setMustUseTerms('espresso_event_type', $term_details); |
|
170 | + } |
|
171 | + |
|
172 | + |
|
173 | + /** |
|
174 | + * wrapper method for handling the setting up of initial terms in the db (if they don't already exist). |
|
175 | + * Note this should ONLY be used for terms that always must be present. Be aware that if an initial term is |
|
176 | + * deleted then it WILL be recreated. |
|
177 | + * |
|
178 | + * @param string $taxonomy The name of the taxonomy |
|
179 | + * @param array $term_details An array of term details indexed by slug and containing Name of term, and |
|
180 | + * description as the elements in the array |
|
181 | + * @return void |
|
182 | + */ |
|
183 | + public function setMustUseTerms($taxonomy, $term_details) |
|
184 | + { |
|
185 | + $term_details = (array) $term_details; |
|
186 | + foreach ($term_details as $slug => $details) { |
|
187 | + if (isset($details['term'], $details['desc']) && ! term_exists($slug, $taxonomy)) { |
|
188 | + $insert_arr = array( |
|
189 | + 'slug' => $slug, |
|
190 | + 'description' => $details['desc'], |
|
191 | + ); |
|
192 | + wp_insert_term($details['term'], $taxonomy, $insert_arr); |
|
193 | + } |
|
194 | + } |
|
195 | + } |
|
196 | 196 | } |
@@ -47,7 +47,7 @@ |
||
47 | 47 | */ |
48 | 48 | public function __construct($generator) |
49 | 49 | { |
50 | - if (! ($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) { |
|
50 | + if ( ! ($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) { |
|
51 | 51 | throw new InvalidArgumentException( |
52 | 52 | esc_html__( |
53 | 53 | 'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.', |
@@ -29,108 +29,108 @@ |
||
29 | 29 | class CoreLoader implements LoaderDecoratorInterface |
30 | 30 | { |
31 | 31 | |
32 | - /** |
|
33 | - * @var EE_Registry|CoffeeShop $generator |
|
34 | - */ |
|
35 | - private $generator; |
|
32 | + /** |
|
33 | + * @var EE_Registry|CoffeeShop $generator |
|
34 | + */ |
|
35 | + private $generator; |
|
36 | 36 | |
37 | 37 | |
38 | - /** |
|
39 | - * CoreLoader constructor. |
|
40 | - * |
|
41 | - * @param EE_Registry|CoffeeShop $generator |
|
42 | - * @throws InvalidArgumentException |
|
43 | - */ |
|
44 | - public function __construct($generator) |
|
45 | - { |
|
46 | - if (! ($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) { |
|
47 | - throw new InvalidArgumentException( |
|
48 | - esc_html__( |
|
49 | - 'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.', |
|
50 | - 'event_espresso' |
|
51 | - ) |
|
52 | - ); |
|
53 | - } |
|
54 | - $this->generator = $generator; |
|
55 | - } |
|
38 | + /** |
|
39 | + * CoreLoader constructor. |
|
40 | + * |
|
41 | + * @param EE_Registry|CoffeeShop $generator |
|
42 | + * @throws InvalidArgumentException |
|
43 | + */ |
|
44 | + public function __construct($generator) |
|
45 | + { |
|
46 | + if (! ($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) { |
|
47 | + throw new InvalidArgumentException( |
|
48 | + esc_html__( |
|
49 | + 'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.', |
|
50 | + 'event_espresso' |
|
51 | + ) |
|
52 | + ); |
|
53 | + } |
|
54 | + $this->generator = $generator; |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | - /** |
|
59 | - * Calls the appropriate loading method from the installed generator; |
|
60 | - * If EE_Registry is being used, then the additional parameters for the EE_Registry::create() method |
|
61 | - * can be added to the $arguments array and they will be extracted and passed to EE_Registry::create(), |
|
62 | - * but NOT to the class being instantiated. |
|
63 | - * This is done by adding the parameters to the $arguments array as follows: |
|
64 | - * array( |
|
65 | - * 'EE_Registry::create(from_db)' => true, // boolean value, default = false |
|
66 | - * 'EE_Registry::create(load_only)' => true, // boolean value, default = false |
|
67 | - * 'EE_Registry::create(addon)' => true, // boolean value, default = false |
|
68 | - * ) |
|
69 | - * |
|
70 | - * @param string $fqcn |
|
71 | - * @param array $arguments |
|
72 | - * @param bool $shared |
|
73 | - * @return mixed |
|
74 | - * @throws OutOfBoundsException |
|
75 | - * @throws ServiceExistsException |
|
76 | - * @throws InstantiationException |
|
77 | - * @throws InvalidIdentifierException |
|
78 | - * @throws InvalidDataTypeException |
|
79 | - * @throws InvalidClassException |
|
80 | - * @throws EE_Error |
|
81 | - * @throws ServiceNotFoundException |
|
82 | - * @throws ReflectionException |
|
83 | - * @throws InvalidInterfaceException |
|
84 | - * @throws InvalidArgumentException |
|
85 | - */ |
|
86 | - public function load($fqcn, $arguments = array(), $shared = true) |
|
87 | - { |
|
88 | - $shared = filter_var($shared, FILTER_VALIDATE_BOOLEAN); |
|
89 | - if ($this->generator instanceof EE_Registry) { |
|
90 | - // check if additional EE_Registry::create() arguments have been passed |
|
91 | - // from_db |
|
92 | - $from_db = isset($arguments['EE_Registry::create(from_db)']) |
|
93 | - ? filter_var($arguments['EE_Registry::create(from_db)'], FILTER_VALIDATE_BOOLEAN) |
|
94 | - : false; |
|
95 | - // load_only |
|
96 | - $load_only = isset($arguments['EE_Registry::create(load_only)']) |
|
97 | - ? filter_var($arguments['EE_Registry::create(load_only)'], FILTER_VALIDATE_BOOLEAN) |
|
98 | - : false; |
|
99 | - // addon |
|
100 | - $addon = isset($arguments['EE_Registry::create(addon)']) |
|
101 | - ? filter_var($arguments['EE_Registry::create(addon)'], FILTER_VALIDATE_BOOLEAN) |
|
102 | - : false; |
|
103 | - unset( |
|
104 | - $arguments['EE_Registry::create(from_db)'], |
|
105 | - $arguments['EE_Registry::create(load_only)'], |
|
106 | - $arguments['EE_Registry::create(addon)'] |
|
107 | - ); |
|
108 | - // addons need to be cached on EE_Registry |
|
109 | - $shared = $addon ? true : $shared; |
|
110 | - return $this->generator->create( |
|
111 | - $fqcn, |
|
112 | - $arguments, |
|
113 | - $shared, |
|
114 | - $from_db, |
|
115 | - $load_only, |
|
116 | - $addon |
|
117 | - ); |
|
118 | - } |
|
119 | - return $this->generator->brew( |
|
120 | - $fqcn, |
|
121 | - $arguments, |
|
122 | - $shared ? CoffeeMaker::BREW_SHARED : CoffeeMaker::BREW_NEW |
|
123 | - ); |
|
124 | - } |
|
58 | + /** |
|
59 | + * Calls the appropriate loading method from the installed generator; |
|
60 | + * If EE_Registry is being used, then the additional parameters for the EE_Registry::create() method |
|
61 | + * can be added to the $arguments array and they will be extracted and passed to EE_Registry::create(), |
|
62 | + * but NOT to the class being instantiated. |
|
63 | + * This is done by adding the parameters to the $arguments array as follows: |
|
64 | + * array( |
|
65 | + * 'EE_Registry::create(from_db)' => true, // boolean value, default = false |
|
66 | + * 'EE_Registry::create(load_only)' => true, // boolean value, default = false |
|
67 | + * 'EE_Registry::create(addon)' => true, // boolean value, default = false |
|
68 | + * ) |
|
69 | + * |
|
70 | + * @param string $fqcn |
|
71 | + * @param array $arguments |
|
72 | + * @param bool $shared |
|
73 | + * @return mixed |
|
74 | + * @throws OutOfBoundsException |
|
75 | + * @throws ServiceExistsException |
|
76 | + * @throws InstantiationException |
|
77 | + * @throws InvalidIdentifierException |
|
78 | + * @throws InvalidDataTypeException |
|
79 | + * @throws InvalidClassException |
|
80 | + * @throws EE_Error |
|
81 | + * @throws ServiceNotFoundException |
|
82 | + * @throws ReflectionException |
|
83 | + * @throws InvalidInterfaceException |
|
84 | + * @throws InvalidArgumentException |
|
85 | + */ |
|
86 | + public function load($fqcn, $arguments = array(), $shared = true) |
|
87 | + { |
|
88 | + $shared = filter_var($shared, FILTER_VALIDATE_BOOLEAN); |
|
89 | + if ($this->generator instanceof EE_Registry) { |
|
90 | + // check if additional EE_Registry::create() arguments have been passed |
|
91 | + // from_db |
|
92 | + $from_db = isset($arguments['EE_Registry::create(from_db)']) |
|
93 | + ? filter_var($arguments['EE_Registry::create(from_db)'], FILTER_VALIDATE_BOOLEAN) |
|
94 | + : false; |
|
95 | + // load_only |
|
96 | + $load_only = isset($arguments['EE_Registry::create(load_only)']) |
|
97 | + ? filter_var($arguments['EE_Registry::create(load_only)'], FILTER_VALIDATE_BOOLEAN) |
|
98 | + : false; |
|
99 | + // addon |
|
100 | + $addon = isset($arguments['EE_Registry::create(addon)']) |
|
101 | + ? filter_var($arguments['EE_Registry::create(addon)'], FILTER_VALIDATE_BOOLEAN) |
|
102 | + : false; |
|
103 | + unset( |
|
104 | + $arguments['EE_Registry::create(from_db)'], |
|
105 | + $arguments['EE_Registry::create(load_only)'], |
|
106 | + $arguments['EE_Registry::create(addon)'] |
|
107 | + ); |
|
108 | + // addons need to be cached on EE_Registry |
|
109 | + $shared = $addon ? true : $shared; |
|
110 | + return $this->generator->create( |
|
111 | + $fqcn, |
|
112 | + $arguments, |
|
113 | + $shared, |
|
114 | + $from_db, |
|
115 | + $load_only, |
|
116 | + $addon |
|
117 | + ); |
|
118 | + } |
|
119 | + return $this->generator->brew( |
|
120 | + $fqcn, |
|
121 | + $arguments, |
|
122 | + $shared ? CoffeeMaker::BREW_SHARED : CoffeeMaker::BREW_NEW |
|
123 | + ); |
|
124 | + } |
|
125 | 125 | |
126 | 126 | |
127 | - /** |
|
128 | - * calls reset() on generator if method exists |
|
129 | - */ |
|
130 | - public function reset() |
|
131 | - { |
|
132 | - if ($this->generator instanceof ResettableInterface) { |
|
133 | - $this->generator->reset(); |
|
134 | - } |
|
135 | - } |
|
127 | + /** |
|
128 | + * calls reset() on generator if method exists |
|
129 | + */ |
|
130 | + public function reset() |
|
131 | + { |
|
132 | + if ($this->generator instanceof ResettableInterface) { |
|
133 | + $this->generator->reset(); |
|
134 | + } |
|
135 | + } |
|
136 | 136 | } |