@@ -21,172 +21,172 @@ |
||
21 | 21 | class EventAttendees extends Block |
22 | 22 | { |
23 | 23 | |
24 | - const BLOCK_TYPE = 'event-attendees'; |
|
24 | + const BLOCK_TYPE = 'event-attendees'; |
|
25 | 25 | |
26 | - /** |
|
27 | - * @var EventAttendeesBlockRenderer $renderer |
|
28 | - */ |
|
29 | - protected $renderer; |
|
26 | + /** |
|
27 | + * @var EventAttendeesBlockRenderer $renderer |
|
28 | + */ |
|
29 | + protected $renderer; |
|
30 | 30 | |
31 | 31 | |
32 | - /** |
|
33 | - * EventAttendees constructor. |
|
34 | - * |
|
35 | - * @param CoreBlocksAssetManager $block_asset_manager |
|
36 | - * @param RequestInterface $request |
|
37 | - * @param EventAttendeesBlockRenderer $renderer |
|
38 | - */ |
|
39 | - public function __construct( |
|
40 | - CoreBlocksAssetManager $block_asset_manager, |
|
41 | - RequestInterface $request, |
|
42 | - EventAttendeesBlockRenderer $renderer |
|
43 | - ) { |
|
44 | - parent::__construct($block_asset_manager, $request); |
|
45 | - $this->renderer = $renderer; |
|
46 | - } |
|
32 | + /** |
|
33 | + * EventAttendees constructor. |
|
34 | + * |
|
35 | + * @param CoreBlocksAssetManager $block_asset_manager |
|
36 | + * @param RequestInterface $request |
|
37 | + * @param EventAttendeesBlockRenderer $renderer |
|
38 | + */ |
|
39 | + public function __construct( |
|
40 | + CoreBlocksAssetManager $block_asset_manager, |
|
41 | + RequestInterface $request, |
|
42 | + EventAttendeesBlockRenderer $renderer |
|
43 | + ) { |
|
44 | + parent::__construct($block_asset_manager, $request); |
|
45 | + $this->renderer = $renderer; |
|
46 | + } |
|
47 | 47 | |
48 | 48 | |
49 | - /** |
|
50 | - * Perform any early setup required by the block |
|
51 | - * including setting the block type and supported post types |
|
52 | - * |
|
53 | - * @return void |
|
54 | - */ |
|
55 | - public function initialize() |
|
56 | - { |
|
57 | - $this->setBlockType(self::BLOCK_TYPE); |
|
58 | - $this->setSupportedRoutes( |
|
59 | - array( |
|
60 | - 'EventEspresso\core\domain\entities\route_match\specifications\admin\EspressoStandardPostTypeEditor', |
|
61 | - 'EventEspresso\core\domain\entities\route_match\specifications\admin\WordPressPostTypeEditor', |
|
62 | - 'EventEspresso\core\domain\entities\route_match\specifications\frontend\EspressoBlockRenderer', |
|
63 | - 'EventEspresso\core\domain\entities\route_match\specifications\frontend\AnyFrontendRequest' |
|
64 | - ) |
|
65 | - ); |
|
66 | - $EVT_ID = $this->request->getRequestParam('page') === 'espresso_events' |
|
67 | - ? $this->request->getRequestParam('post', 0, 'int') |
|
68 | - : 0; |
|
69 | - $this->setAttributes( |
|
70 | - array( |
|
71 | - 'eventId' => array( |
|
72 | - 'type' => 'number', |
|
73 | - 'default' => $EVT_ID, |
|
74 | - ), |
|
75 | - 'datetimeId' => array( |
|
76 | - 'type' => 'number', |
|
77 | - 'default' => 0, |
|
78 | - ), |
|
79 | - 'ticketId' => array( |
|
80 | - 'type' => 'number', |
|
81 | - 'default' => 0, |
|
82 | - ), |
|
83 | - 'status' => array( |
|
84 | - 'type' => 'string', |
|
85 | - 'default' => EEM_Registration::status_id_approved, |
|
86 | - ), |
|
87 | - 'limit' => array( |
|
88 | - 'type' => 'number', |
|
89 | - 'default' => 100, |
|
90 | - ), |
|
91 | - 'order' => array( |
|
92 | - 'type' => 'string', |
|
93 | - 'default' => 'ASC' |
|
94 | - ), |
|
95 | - 'orderBy' => array( |
|
96 | - 'type' => 'string', |
|
97 | - 'default' => 'lastThenFirstName', |
|
98 | - ), |
|
99 | - 'showGravatar' => array( |
|
100 | - 'type' => 'boolean', |
|
101 | - 'default' => false, |
|
102 | - ), |
|
103 | - 'avatarClass' => array( |
|
104 | - 'type' => 'string', |
|
105 | - 'default' => 'contact', |
|
106 | - ), |
|
107 | - 'avatarSize' => array( |
|
108 | - 'type' => 'number', |
|
109 | - 'default' => 24, |
|
110 | - ), |
|
111 | - 'displayOnArchives' => array( |
|
112 | - 'type' => 'boolean', |
|
113 | - 'default' => false, |
|
114 | - ), |
|
115 | - ) |
|
116 | - ); |
|
117 | - $this->setDynamic(); |
|
118 | - } |
|
49 | + /** |
|
50 | + * Perform any early setup required by the block |
|
51 | + * including setting the block type and supported post types |
|
52 | + * |
|
53 | + * @return void |
|
54 | + */ |
|
55 | + public function initialize() |
|
56 | + { |
|
57 | + $this->setBlockType(self::BLOCK_TYPE); |
|
58 | + $this->setSupportedRoutes( |
|
59 | + array( |
|
60 | + 'EventEspresso\core\domain\entities\route_match\specifications\admin\EspressoStandardPostTypeEditor', |
|
61 | + 'EventEspresso\core\domain\entities\route_match\specifications\admin\WordPressPostTypeEditor', |
|
62 | + 'EventEspresso\core\domain\entities\route_match\specifications\frontend\EspressoBlockRenderer', |
|
63 | + 'EventEspresso\core\domain\entities\route_match\specifications\frontend\AnyFrontendRequest' |
|
64 | + ) |
|
65 | + ); |
|
66 | + $EVT_ID = $this->request->getRequestParam('page') === 'espresso_events' |
|
67 | + ? $this->request->getRequestParam('post', 0, 'int') |
|
68 | + : 0; |
|
69 | + $this->setAttributes( |
|
70 | + array( |
|
71 | + 'eventId' => array( |
|
72 | + 'type' => 'number', |
|
73 | + 'default' => $EVT_ID, |
|
74 | + ), |
|
75 | + 'datetimeId' => array( |
|
76 | + 'type' => 'number', |
|
77 | + 'default' => 0, |
|
78 | + ), |
|
79 | + 'ticketId' => array( |
|
80 | + 'type' => 'number', |
|
81 | + 'default' => 0, |
|
82 | + ), |
|
83 | + 'status' => array( |
|
84 | + 'type' => 'string', |
|
85 | + 'default' => EEM_Registration::status_id_approved, |
|
86 | + ), |
|
87 | + 'limit' => array( |
|
88 | + 'type' => 'number', |
|
89 | + 'default' => 100, |
|
90 | + ), |
|
91 | + 'order' => array( |
|
92 | + 'type' => 'string', |
|
93 | + 'default' => 'ASC' |
|
94 | + ), |
|
95 | + 'orderBy' => array( |
|
96 | + 'type' => 'string', |
|
97 | + 'default' => 'lastThenFirstName', |
|
98 | + ), |
|
99 | + 'showGravatar' => array( |
|
100 | + 'type' => 'boolean', |
|
101 | + 'default' => false, |
|
102 | + ), |
|
103 | + 'avatarClass' => array( |
|
104 | + 'type' => 'string', |
|
105 | + 'default' => 'contact', |
|
106 | + ), |
|
107 | + 'avatarSize' => array( |
|
108 | + 'type' => 'number', |
|
109 | + 'default' => 24, |
|
110 | + ), |
|
111 | + 'displayOnArchives' => array( |
|
112 | + 'type' => 'boolean', |
|
113 | + 'default' => false, |
|
114 | + ), |
|
115 | + ) |
|
116 | + ); |
|
117 | + $this->setDynamic(); |
|
118 | + } |
|
119 | 119 | |
120 | 120 | |
121 | - /** |
|
122 | - * Returns an array where the key corresponds to the incoming attribute name from the WP block |
|
123 | - * and the value corresponds to the attribute name for the existing EspressoEventAttendees shortcode |
|
124 | - * |
|
125 | - * @since 4.9.71.p |
|
126 | - * @return array |
|
127 | - */ |
|
128 | - private function getAttributesMap() |
|
129 | - { |
|
130 | - return array( |
|
131 | - 'eventId' => 'absint', |
|
132 | - 'datetimeId' => 'absint', |
|
133 | - 'ticketId' => 'absint', |
|
134 | - 'status' => 'sanitize_text_field', |
|
135 | - 'limit' => 'intval', |
|
136 | - 'showGravatar' => 'bool', |
|
137 | - 'avatarClass' => 'sanitize_text_field', |
|
138 | - 'avatarSize' => 'absint', |
|
139 | - 'displayOnArchives' => 'bool', |
|
140 | - 'order' => 'sanitize_text_field', |
|
141 | - 'orderBy' => 'sanitize_text_field', |
|
142 | - ); |
|
143 | - } |
|
121 | + /** |
|
122 | + * Returns an array where the key corresponds to the incoming attribute name from the WP block |
|
123 | + * and the value corresponds to the attribute name for the existing EspressoEventAttendees shortcode |
|
124 | + * |
|
125 | + * @since 4.9.71.p |
|
126 | + * @return array |
|
127 | + */ |
|
128 | + private function getAttributesMap() |
|
129 | + { |
|
130 | + return array( |
|
131 | + 'eventId' => 'absint', |
|
132 | + 'datetimeId' => 'absint', |
|
133 | + 'ticketId' => 'absint', |
|
134 | + 'status' => 'sanitize_text_field', |
|
135 | + 'limit' => 'intval', |
|
136 | + 'showGravatar' => 'bool', |
|
137 | + 'avatarClass' => 'sanitize_text_field', |
|
138 | + 'avatarSize' => 'absint', |
|
139 | + 'displayOnArchives' => 'bool', |
|
140 | + 'order' => 'sanitize_text_field', |
|
141 | + 'orderBy' => 'sanitize_text_field', |
|
142 | + ); |
|
143 | + } |
|
144 | 144 | |
145 | 145 | |
146 | - /** |
|
147 | - * Sanitizes attributes. |
|
148 | - * |
|
149 | - * @param array $attributes |
|
150 | - * @return array |
|
151 | - */ |
|
152 | - private function sanitizeAttributes(array $attributes) |
|
153 | - { |
|
154 | - $sanitized_attributes = array(); |
|
155 | - foreach ($attributes as $attribute => $value) { |
|
156 | - $convert = $this->getAttributesMap(); |
|
157 | - if (isset($convert[ $attribute ])) { |
|
158 | - $sanitize = $convert[ $attribute ]; |
|
159 | - if ($sanitize === 'bool') { |
|
160 | - $sanitized_attributes[ $attribute ] = filter_var( |
|
161 | - $value, |
|
162 | - FILTER_VALIDATE_BOOLEAN |
|
163 | - ); |
|
164 | - } else { |
|
165 | - $sanitized_attributes[ $attribute ] = $sanitize($value); |
|
166 | - } |
|
167 | - // don't pass along attributes with a 0 value |
|
168 | - if ($sanitized_attributes[ $attribute ] === 0) { |
|
169 | - unset($sanitized_attributes[ $attribute ]); |
|
170 | - } |
|
171 | - } |
|
172 | - } |
|
173 | - return $attributes; |
|
174 | - } |
|
146 | + /** |
|
147 | + * Sanitizes attributes. |
|
148 | + * |
|
149 | + * @param array $attributes |
|
150 | + * @return array |
|
151 | + */ |
|
152 | + private function sanitizeAttributes(array $attributes) |
|
153 | + { |
|
154 | + $sanitized_attributes = array(); |
|
155 | + foreach ($attributes as $attribute => $value) { |
|
156 | + $convert = $this->getAttributesMap(); |
|
157 | + if (isset($convert[ $attribute ])) { |
|
158 | + $sanitize = $convert[ $attribute ]; |
|
159 | + if ($sanitize === 'bool') { |
|
160 | + $sanitized_attributes[ $attribute ] = filter_var( |
|
161 | + $value, |
|
162 | + FILTER_VALIDATE_BOOLEAN |
|
163 | + ); |
|
164 | + } else { |
|
165 | + $sanitized_attributes[ $attribute ] = $sanitize($value); |
|
166 | + } |
|
167 | + // don't pass along attributes with a 0 value |
|
168 | + if ($sanitized_attributes[ $attribute ] === 0) { |
|
169 | + unset($sanitized_attributes[ $attribute ]); |
|
170 | + } |
|
171 | + } |
|
172 | + } |
|
173 | + return $attributes; |
|
174 | + } |
|
175 | 175 | |
176 | 176 | |
177 | - /** |
|
178 | - * Returns the rendered HTML for the block |
|
179 | - * |
|
180 | - * @param array $attributes |
|
181 | - * @return string |
|
182 | - * @throws DomainException |
|
183 | - * @throws EE_Error |
|
184 | - */ |
|
185 | - public function renderBlock(array $attributes = array()) |
|
186 | - { |
|
187 | - $attributes = $this->sanitizeAttributes($attributes); |
|
188 | - return (is_archive() || is_front_page() || is_home()) && ! $attributes['displayOnArchives'] |
|
189 | - ? '' |
|
190 | - : $this->renderer->render($attributes); |
|
191 | - } |
|
177 | + /** |
|
178 | + * Returns the rendered HTML for the block |
|
179 | + * |
|
180 | + * @param array $attributes |
|
181 | + * @return string |
|
182 | + * @throws DomainException |
|
183 | + * @throws EE_Error |
|
184 | + */ |
|
185 | + public function renderBlock(array $attributes = array()) |
|
186 | + { |
|
187 | + $attributes = $this->sanitizeAttributes($attributes); |
|
188 | + return (is_archive() || is_front_page() || is_home()) && ! $attributes['displayOnArchives'] |
|
189 | + ? '' |
|
190 | + : $this->renderer->render($attributes); |
|
191 | + } |
|
192 | 192 | } |
@@ -154,19 +154,19 @@ |
||
154 | 154 | $sanitized_attributes = array(); |
155 | 155 | foreach ($attributes as $attribute => $value) { |
156 | 156 | $convert = $this->getAttributesMap(); |
157 | - if (isset($convert[ $attribute ])) { |
|
158 | - $sanitize = $convert[ $attribute ]; |
|
157 | + if (isset($convert[$attribute])) { |
|
158 | + $sanitize = $convert[$attribute]; |
|
159 | 159 | if ($sanitize === 'bool') { |
160 | - $sanitized_attributes[ $attribute ] = filter_var( |
|
160 | + $sanitized_attributes[$attribute] = filter_var( |
|
161 | 161 | $value, |
162 | 162 | FILTER_VALIDATE_BOOLEAN |
163 | 163 | ); |
164 | 164 | } else { |
165 | - $sanitized_attributes[ $attribute ] = $sanitize($value); |
|
165 | + $sanitized_attributes[$attribute] = $sanitize($value); |
|
166 | 166 | } |
167 | 167 | // don't pass along attributes with a 0 value |
168 | - if ($sanitized_attributes[ $attribute ] === 0) { |
|
169 | - unset($sanitized_attributes[ $attribute ]); |
|
168 | + if ($sanitized_attributes[$attribute] === 0) { |
|
169 | + unset($sanitized_attributes[$attribute]); |
|
170 | 170 | } |
171 | 171 | } |
172 | 172 | } |
@@ -26,92 +26,92 @@ |
||
26 | 26 | { |
27 | 27 | |
28 | 28 | |
29 | - /** |
|
30 | - * the actual shortcode tag that gets registered with WordPress |
|
31 | - * |
|
32 | - * @return string |
|
33 | - */ |
|
34 | - public function getTag() |
|
35 | - { |
|
36 | - return 'ESPRESSO_TXN_PAGE'; |
|
37 | - } |
|
29 | + /** |
|
30 | + * the actual shortcode tag that gets registered with WordPress |
|
31 | + * |
|
32 | + * @return string |
|
33 | + */ |
|
34 | + public function getTag() |
|
35 | + { |
|
36 | + return 'ESPRESSO_TXN_PAGE'; |
|
37 | + } |
|
38 | 38 | |
39 | 39 | |
40 | - /** |
|
41 | - * the time in seconds to cache the results of the processShortcode() method |
|
42 | - * 0 means the processShortcode() results will NOT be cached at all |
|
43 | - * |
|
44 | - * @return int |
|
45 | - */ |
|
46 | - public function cacheExpiration() |
|
47 | - { |
|
48 | - return 0; |
|
49 | - } |
|
40 | + /** |
|
41 | + * the time in seconds to cache the results of the processShortcode() method |
|
42 | + * 0 means the processShortcode() results will NOT be cached at all |
|
43 | + * |
|
44 | + * @return int |
|
45 | + */ |
|
46 | + public function cacheExpiration() |
|
47 | + { |
|
48 | + return 0; |
|
49 | + } |
|
50 | 50 | |
51 | 51 | |
52 | - /** |
|
53 | - * a place for adding any initialization code that needs to run prior to wp_header(). |
|
54 | - * this may be required for shortcodes that utilize a corresponding module, |
|
55 | - * and need to enqueue assets for that module |
|
56 | - * |
|
57 | - * @return void |
|
58 | - * @throws Exception |
|
59 | - * @throws EE_Error |
|
60 | - */ |
|
61 | - public function initializeShortcode() |
|
62 | - { |
|
63 | - $transaction = null; |
|
64 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
65 | - $reg_url_link = $request->getRequestParam('e_reg_url_link'); |
|
66 | - if ($reg_url_link) { |
|
67 | - /** @var EEM_Transaction $EEM_Transaction */ |
|
68 | - $EEM_Transaction = EE_Registry::instance()->load_model('Transaction'); |
|
69 | - $transaction = $EEM_Transaction->get_transaction_from_reg_url_link($reg_url_link); |
|
70 | - } |
|
71 | - if ($transaction instanceof EE_Transaction) { |
|
72 | - $payment_method = null; |
|
73 | - $payment_method_slug = $request->getRequestParam('ee_payment_method'); |
|
74 | - if ($payment_method_slug) { |
|
75 | - $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($payment_method_slug); |
|
76 | - } |
|
77 | - if ($payment_method instanceof EE_Payment_Method && $payment_method->is_off_site()) { |
|
78 | - $gateway = $payment_method->type_obj()->get_gateway(); |
|
79 | - if ( |
|
80 | - $gateway instanceof EE_Offsite_Gateway |
|
81 | - && $gateway->handle_IPN_in_this_request( |
|
82 | - $request->requestParams(), |
|
83 | - true |
|
84 | - ) |
|
85 | - ) { |
|
86 | - /** @type EE_Payment_Processor $payment_processor */ |
|
87 | - $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); |
|
88 | - /** @var RequestInterface $request */ |
|
89 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
90 | - $payment_processor->process_ipn($request->requestParams(), $transaction, $payment_method); |
|
91 | - } |
|
92 | - } |
|
93 | - // allow gateways to add a filter to stop rendering the page |
|
94 | - if (apply_filters('FHEE__EES_Espresso_Txn_Page__run__exit', false)) { |
|
95 | - exit; |
|
96 | - } |
|
97 | - } |
|
98 | - $this->shortcodeHasBeenInitialized(); |
|
99 | - } |
|
52 | + /** |
|
53 | + * a place for adding any initialization code that needs to run prior to wp_header(). |
|
54 | + * this may be required for shortcodes that utilize a corresponding module, |
|
55 | + * and need to enqueue assets for that module |
|
56 | + * |
|
57 | + * @return void |
|
58 | + * @throws Exception |
|
59 | + * @throws EE_Error |
|
60 | + */ |
|
61 | + public function initializeShortcode() |
|
62 | + { |
|
63 | + $transaction = null; |
|
64 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
65 | + $reg_url_link = $request->getRequestParam('e_reg_url_link'); |
|
66 | + if ($reg_url_link) { |
|
67 | + /** @var EEM_Transaction $EEM_Transaction */ |
|
68 | + $EEM_Transaction = EE_Registry::instance()->load_model('Transaction'); |
|
69 | + $transaction = $EEM_Transaction->get_transaction_from_reg_url_link($reg_url_link); |
|
70 | + } |
|
71 | + if ($transaction instanceof EE_Transaction) { |
|
72 | + $payment_method = null; |
|
73 | + $payment_method_slug = $request->getRequestParam('ee_payment_method'); |
|
74 | + if ($payment_method_slug) { |
|
75 | + $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($payment_method_slug); |
|
76 | + } |
|
77 | + if ($payment_method instanceof EE_Payment_Method && $payment_method->is_off_site()) { |
|
78 | + $gateway = $payment_method->type_obj()->get_gateway(); |
|
79 | + if ( |
|
80 | + $gateway instanceof EE_Offsite_Gateway |
|
81 | + && $gateway->handle_IPN_in_this_request( |
|
82 | + $request->requestParams(), |
|
83 | + true |
|
84 | + ) |
|
85 | + ) { |
|
86 | + /** @type EE_Payment_Processor $payment_processor */ |
|
87 | + $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); |
|
88 | + /** @var RequestInterface $request */ |
|
89 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
90 | + $payment_processor->process_ipn($request->requestParams(), $transaction, $payment_method); |
|
91 | + } |
|
92 | + } |
|
93 | + // allow gateways to add a filter to stop rendering the page |
|
94 | + if (apply_filters('FHEE__EES_Espresso_Txn_Page__run__exit', false)) { |
|
95 | + exit; |
|
96 | + } |
|
97 | + } |
|
98 | + $this->shortcodeHasBeenInitialized(); |
|
99 | + } |
|
100 | 100 | |
101 | 101 | |
102 | - /** |
|
103 | - * callback that runs when the shortcode is encountered in post content. |
|
104 | - * IMPORTANT !!! |
|
105 | - * remember that shortcode content should be RETURNED and NOT echoed out |
|
106 | - * |
|
107 | - * @param array $attributes |
|
108 | - * @return string |
|
109 | - */ |
|
110 | - public function processShortcode($attributes = array()) |
|
111 | - { |
|
112 | - return esc_html__( |
|
113 | - 'This is the Event Espresso Transactions page. This page receives instant payment notification (IPN) requests and should have a status of published, but should not be easily accessible by site visitors. Do not add it to your website\'s navigation menu or link to it from another page. Also, do not delete it or change its status to private.', |
|
114 | - 'event_espresso' |
|
115 | - ); |
|
116 | - } |
|
102 | + /** |
|
103 | + * callback that runs when the shortcode is encountered in post content. |
|
104 | + * IMPORTANT !!! |
|
105 | + * remember that shortcode content should be RETURNED and NOT echoed out |
|
106 | + * |
|
107 | + * @param array $attributes |
|
108 | + * @return string |
|
109 | + */ |
|
110 | + public function processShortcode($attributes = array()) |
|
111 | + { |
|
112 | + return esc_html__( |
|
113 | + 'This is the Event Espresso Transactions page. This page receives instant payment notification (IPN) requests and should have a status of published, but should not be easily accessible by site visitors. Do not add it to your website\'s navigation menu or link to it from another page. Also, do not delete it or change its status to private.', |
|
114 | + 'event_espresso' |
|
115 | + ); |
|
116 | + } |
|
117 | 117 | } |
@@ -17,288 +17,288 @@ |
||
17 | 17 | class CustomPostTypeDefinitions |
18 | 18 | { |
19 | 19 | |
20 | - /** |
|
21 | - * @var EE_Core_Config |
|
22 | - */ |
|
23 | - public $core_config; |
|
20 | + /** |
|
21 | + * @var EE_Core_Config |
|
22 | + */ |
|
23 | + public $core_config; |
|
24 | 24 | |
25 | - /** |
|
26 | - * @var array $custom_post_types |
|
27 | - */ |
|
28 | - private $custom_post_types; |
|
25 | + /** |
|
26 | + * @var array $custom_post_types |
|
27 | + */ |
|
28 | + private $custom_post_types; |
|
29 | 29 | |
30 | - /** |
|
31 | - * @var LoaderInterface $loader |
|
32 | - */ |
|
33 | - private $loader; |
|
30 | + /** |
|
31 | + * @var LoaderInterface $loader |
|
32 | + */ |
|
33 | + private $loader; |
|
34 | 34 | |
35 | 35 | |
36 | - /** |
|
37 | - * EspressoCustomPostTypeDefinitions constructor. |
|
38 | - * |
|
39 | - * @param EE_Core_Config $core_config |
|
40 | - * @param LoaderInterface $loader |
|
41 | - */ |
|
42 | - public function __construct(EE_Core_Config $core_config, LoaderInterface $loader) |
|
43 | - { |
|
44 | - $this->core_config = $core_config; |
|
45 | - $this->loader = $loader; |
|
46 | - $this->setDefinitions(); |
|
47 | - } |
|
36 | + /** |
|
37 | + * EspressoCustomPostTypeDefinitions constructor. |
|
38 | + * |
|
39 | + * @param EE_Core_Config $core_config |
|
40 | + * @param LoaderInterface $loader |
|
41 | + */ |
|
42 | + public function __construct(EE_Core_Config $core_config, LoaderInterface $loader) |
|
43 | + { |
|
44 | + $this->core_config = $core_config; |
|
45 | + $this->loader = $loader; |
|
46 | + $this->setDefinitions(); |
|
47 | + } |
|
48 | 48 | |
49 | 49 | |
50 | - /** |
|
51 | - * defines Espresso Custom Post Types |
|
52 | - * NOTE the ['args']['page_templates'] array index is something specific to our CPTs |
|
53 | - * and not part of the WP custom post type api. |
|
54 | - * |
|
55 | - * @return void |
|
56 | - */ |
|
57 | - private function setDefinitions() |
|
58 | - { |
|
59 | - $this->custom_post_types = array( |
|
60 | - 'espresso_events' => array( |
|
61 | - 'singular_name' => esc_html__('Event', 'event_espresso'), |
|
62 | - 'plural_name' => esc_html__('Events', 'event_espresso'), |
|
63 | - 'singular_slug' => esc_html__('event', 'event_espresso'), |
|
64 | - 'plural_slug' => $this->core_config->event_cpt_slug, |
|
65 | - 'class_name' => 'EE_Event', |
|
66 | - 'model_name' => 'EEM_Event', |
|
67 | - 'args' => array( |
|
68 | - 'public' => true, |
|
69 | - 'show_in_nav_menus' => true, |
|
70 | - 'capability_type' => 'event', |
|
71 | - 'capabilities' => array( |
|
72 | - 'edit_post' => 'ee_edit_event', |
|
73 | - 'read_post' => 'ee_read_event', |
|
74 | - 'delete_post' => 'ee_delete_event', |
|
75 | - 'edit_posts' => 'ee_edit_events', |
|
76 | - 'edit_others_posts' => 'ee_edit_others_events', |
|
77 | - 'publish_posts' => 'ee_publish_events', |
|
78 | - 'read_private_posts' => 'ee_read_private_events', |
|
79 | - 'delete_posts' => 'ee_delete_events', |
|
80 | - 'delete_private_posts' => 'ee_delete_private_events', |
|
81 | - 'delete_published_posts' => 'ee_delete_published_events', |
|
82 | - 'delete_others_posts' => 'ee_delete_others_events', |
|
83 | - 'edit_private_posts' => 'ee_edit_private_events', |
|
84 | - 'edit_published_posts' => 'ee_edit_published_events', |
|
85 | - ), |
|
86 | - 'taxonomies' => array( |
|
87 | - 'espresso_event_categories', |
|
88 | - 'espresso_event_type', |
|
89 | - 'post_tag', |
|
90 | - ), |
|
91 | - 'page_templates' => true, |
|
92 | - ), |
|
93 | - ), |
|
94 | - 'espresso_venues' => array( |
|
95 | - 'singular_name' => esc_html__('Venue', 'event_espresso'), |
|
96 | - 'plural_name' => esc_html__('Venues', 'event_espresso'), |
|
97 | - 'singular_slug' => esc_html__('venue', 'event_espresso'), |
|
98 | - 'plural_slug' => esc_html__('venues', 'event_espresso'), |
|
99 | - 'class_name' => 'EE_Venue', |
|
100 | - 'model_name' => 'EEM_Venue', |
|
101 | - 'args' => array( |
|
102 | - 'public' => true, |
|
103 | - 'show_in_nav_menus' => false, // by default this doesn't show for decaf, |
|
104 | - 'capability_type' => 'venue', |
|
105 | - 'capabilities' => array( |
|
106 | - 'edit_post' => 'ee_edit_venue', |
|
107 | - 'read_post' => 'ee_read_venue', |
|
108 | - 'delete_post' => 'ee_delete_venue', |
|
109 | - 'edit_posts' => 'ee_edit_venues', |
|
110 | - 'edit_others_posts' => 'ee_edit_others_venues', |
|
111 | - 'publish_posts' => 'ee_publish_venues', |
|
112 | - 'read_private_posts' => 'ee_read_private_venues', |
|
113 | - 'delete_posts' => 'ee_delete_venues', |
|
114 | - 'delete_private_posts' => 'ee_delete_private_venues', |
|
115 | - 'delete_published_posts' => 'ee_delete_published_venues', |
|
116 | - 'delete_others_posts' => 'ee_edit_others_venues', |
|
117 | - 'edit_private_posts' => 'ee_edit_private_venues', |
|
118 | - 'edit_published_posts' => 'ee_edit_published_venues', |
|
119 | - ), |
|
120 | - 'taxonomies' => array( |
|
121 | - 'espresso_venue_categories', |
|
122 | - 'post_tag', |
|
123 | - ), |
|
124 | - 'page_templates' => true, |
|
125 | - ), |
|
126 | - ), |
|
127 | - 'espresso_attendees' => array( |
|
128 | - 'singular_name' => esc_html__('Contact', 'event_espresso'), |
|
129 | - 'plural_name' => esc_html__('Contacts', 'event_espresso'), |
|
130 | - 'singular_slug' => esc_html__('contact', 'event_espresso'), |
|
131 | - 'plural_slug' => esc_html__('contacts', 'event_espresso'), |
|
132 | - 'class_name' => 'EE_Attendee', |
|
133 | - 'model_name' => 'EEM_Attendee', |
|
134 | - 'args' => array( |
|
135 | - 'public' => false, |
|
136 | - 'publicly_queryable' => false, |
|
137 | - 'hierarchical' => false, |
|
138 | - 'has_archive' => false, |
|
139 | - 'supports' => array( |
|
140 | - 'editor', |
|
141 | - 'thumbnail', |
|
142 | - 'excerpt', |
|
143 | - 'custom-fields', |
|
144 | - 'comments', |
|
145 | - ), |
|
146 | - 'taxonomies' => array('post_tag'), |
|
147 | - 'capability_type' => 'contact', |
|
148 | - 'capabilities' => array( |
|
149 | - 'edit_post' => 'ee_edit_contact', |
|
150 | - 'read_post' => 'ee_read_contact', |
|
151 | - 'delete_post' => 'ee_delete_contact', |
|
152 | - 'edit_posts' => 'ee_edit_contacts', |
|
153 | - 'edit_others_posts' => 'ee_edit_contacts', |
|
154 | - 'publish_posts' => 'ee_edit_contacts', |
|
155 | - 'read_private_posts' => 'ee_edit_contacts', |
|
156 | - 'delete_posts' => 'ee_delete_contacts', |
|
157 | - 'delete_private_posts' => 'ee_delete_contacts', |
|
158 | - 'delete_published_posts' => 'ee_delete_contacts', |
|
159 | - 'delete_others_posts' => 'ee_delete_contacts', |
|
160 | - 'edit_private_posts' => 'ee_edit_contacts', |
|
161 | - 'edit_published_posts' => 'ee_edit_contacts', |
|
162 | - ), |
|
163 | - ), |
|
164 | - ), |
|
165 | - ); |
|
166 | - } |
|
50 | + /** |
|
51 | + * defines Espresso Custom Post Types |
|
52 | + * NOTE the ['args']['page_templates'] array index is something specific to our CPTs |
|
53 | + * and not part of the WP custom post type api. |
|
54 | + * |
|
55 | + * @return void |
|
56 | + */ |
|
57 | + private function setDefinitions() |
|
58 | + { |
|
59 | + $this->custom_post_types = array( |
|
60 | + 'espresso_events' => array( |
|
61 | + 'singular_name' => esc_html__('Event', 'event_espresso'), |
|
62 | + 'plural_name' => esc_html__('Events', 'event_espresso'), |
|
63 | + 'singular_slug' => esc_html__('event', 'event_espresso'), |
|
64 | + 'plural_slug' => $this->core_config->event_cpt_slug, |
|
65 | + 'class_name' => 'EE_Event', |
|
66 | + 'model_name' => 'EEM_Event', |
|
67 | + 'args' => array( |
|
68 | + 'public' => true, |
|
69 | + 'show_in_nav_menus' => true, |
|
70 | + 'capability_type' => 'event', |
|
71 | + 'capabilities' => array( |
|
72 | + 'edit_post' => 'ee_edit_event', |
|
73 | + 'read_post' => 'ee_read_event', |
|
74 | + 'delete_post' => 'ee_delete_event', |
|
75 | + 'edit_posts' => 'ee_edit_events', |
|
76 | + 'edit_others_posts' => 'ee_edit_others_events', |
|
77 | + 'publish_posts' => 'ee_publish_events', |
|
78 | + 'read_private_posts' => 'ee_read_private_events', |
|
79 | + 'delete_posts' => 'ee_delete_events', |
|
80 | + 'delete_private_posts' => 'ee_delete_private_events', |
|
81 | + 'delete_published_posts' => 'ee_delete_published_events', |
|
82 | + 'delete_others_posts' => 'ee_delete_others_events', |
|
83 | + 'edit_private_posts' => 'ee_edit_private_events', |
|
84 | + 'edit_published_posts' => 'ee_edit_published_events', |
|
85 | + ), |
|
86 | + 'taxonomies' => array( |
|
87 | + 'espresso_event_categories', |
|
88 | + 'espresso_event_type', |
|
89 | + 'post_tag', |
|
90 | + ), |
|
91 | + 'page_templates' => true, |
|
92 | + ), |
|
93 | + ), |
|
94 | + 'espresso_venues' => array( |
|
95 | + 'singular_name' => esc_html__('Venue', 'event_espresso'), |
|
96 | + 'plural_name' => esc_html__('Venues', 'event_espresso'), |
|
97 | + 'singular_slug' => esc_html__('venue', 'event_espresso'), |
|
98 | + 'plural_slug' => esc_html__('venues', 'event_espresso'), |
|
99 | + 'class_name' => 'EE_Venue', |
|
100 | + 'model_name' => 'EEM_Venue', |
|
101 | + 'args' => array( |
|
102 | + 'public' => true, |
|
103 | + 'show_in_nav_menus' => false, // by default this doesn't show for decaf, |
|
104 | + 'capability_type' => 'venue', |
|
105 | + 'capabilities' => array( |
|
106 | + 'edit_post' => 'ee_edit_venue', |
|
107 | + 'read_post' => 'ee_read_venue', |
|
108 | + 'delete_post' => 'ee_delete_venue', |
|
109 | + 'edit_posts' => 'ee_edit_venues', |
|
110 | + 'edit_others_posts' => 'ee_edit_others_venues', |
|
111 | + 'publish_posts' => 'ee_publish_venues', |
|
112 | + 'read_private_posts' => 'ee_read_private_venues', |
|
113 | + 'delete_posts' => 'ee_delete_venues', |
|
114 | + 'delete_private_posts' => 'ee_delete_private_venues', |
|
115 | + 'delete_published_posts' => 'ee_delete_published_venues', |
|
116 | + 'delete_others_posts' => 'ee_edit_others_venues', |
|
117 | + 'edit_private_posts' => 'ee_edit_private_venues', |
|
118 | + 'edit_published_posts' => 'ee_edit_published_venues', |
|
119 | + ), |
|
120 | + 'taxonomies' => array( |
|
121 | + 'espresso_venue_categories', |
|
122 | + 'post_tag', |
|
123 | + ), |
|
124 | + 'page_templates' => true, |
|
125 | + ), |
|
126 | + ), |
|
127 | + 'espresso_attendees' => array( |
|
128 | + 'singular_name' => esc_html__('Contact', 'event_espresso'), |
|
129 | + 'plural_name' => esc_html__('Contacts', 'event_espresso'), |
|
130 | + 'singular_slug' => esc_html__('contact', 'event_espresso'), |
|
131 | + 'plural_slug' => esc_html__('contacts', 'event_espresso'), |
|
132 | + 'class_name' => 'EE_Attendee', |
|
133 | + 'model_name' => 'EEM_Attendee', |
|
134 | + 'args' => array( |
|
135 | + 'public' => false, |
|
136 | + 'publicly_queryable' => false, |
|
137 | + 'hierarchical' => false, |
|
138 | + 'has_archive' => false, |
|
139 | + 'supports' => array( |
|
140 | + 'editor', |
|
141 | + 'thumbnail', |
|
142 | + 'excerpt', |
|
143 | + 'custom-fields', |
|
144 | + 'comments', |
|
145 | + ), |
|
146 | + 'taxonomies' => array('post_tag'), |
|
147 | + 'capability_type' => 'contact', |
|
148 | + 'capabilities' => array( |
|
149 | + 'edit_post' => 'ee_edit_contact', |
|
150 | + 'read_post' => 'ee_read_contact', |
|
151 | + 'delete_post' => 'ee_delete_contact', |
|
152 | + 'edit_posts' => 'ee_edit_contacts', |
|
153 | + 'edit_others_posts' => 'ee_edit_contacts', |
|
154 | + 'publish_posts' => 'ee_edit_contacts', |
|
155 | + 'read_private_posts' => 'ee_edit_contacts', |
|
156 | + 'delete_posts' => 'ee_delete_contacts', |
|
157 | + 'delete_private_posts' => 'ee_delete_contacts', |
|
158 | + 'delete_published_posts' => 'ee_delete_contacts', |
|
159 | + 'delete_others_posts' => 'ee_delete_contacts', |
|
160 | + 'edit_private_posts' => 'ee_edit_contacts', |
|
161 | + 'edit_published_posts' => 'ee_edit_contacts', |
|
162 | + ), |
|
163 | + ), |
|
164 | + ), |
|
165 | + ); |
|
166 | + } |
|
167 | 167 | |
168 | 168 | |
169 | - /** |
|
170 | - * @return array |
|
171 | - */ |
|
172 | - public function getDefinitions() |
|
173 | - { |
|
174 | - return (array) apply_filters( |
|
175 | - 'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes', |
|
176 | - // legacy filter applied for now, |
|
177 | - // later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice |
|
178 | - apply_filters( |
|
179 | - 'FHEE__EE_Register_CPTs__get_CPTs__cpts', |
|
180 | - $this->custom_post_types |
|
181 | - ) |
|
182 | - ); |
|
183 | - } |
|
169 | + /** |
|
170 | + * @return array |
|
171 | + */ |
|
172 | + public function getDefinitions() |
|
173 | + { |
|
174 | + return (array) apply_filters( |
|
175 | + 'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes', |
|
176 | + // legacy filter applied for now, |
|
177 | + // later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice |
|
178 | + apply_filters( |
|
179 | + 'FHEE__EE_Register_CPTs__get_CPTs__cpts', |
|
180 | + $this->custom_post_types |
|
181 | + ) |
|
182 | + ); |
|
183 | + } |
|
184 | 184 | |
185 | 185 | |
186 | - /** |
|
187 | - * @return array |
|
188 | - */ |
|
189 | - public function getCustomPostTypeSlugs() |
|
190 | - { |
|
191 | - return array_keys($this->getDefinitions()); |
|
192 | - } |
|
186 | + /** |
|
187 | + * @return array |
|
188 | + */ |
|
189 | + public function getCustomPostTypeSlugs() |
|
190 | + { |
|
191 | + return array_keys($this->getDefinitions()); |
|
192 | + } |
|
193 | 193 | |
194 | 194 | |
195 | - /** |
|
196 | - * This basically goes through the CPT array and returns only CPT's |
|
197 | - * that have the ['args']['public'] option set as false |
|
198 | - * |
|
199 | - * @return array |
|
200 | - */ |
|
201 | - public function getPrivateCustomPostTypes() |
|
202 | - { |
|
203 | - $private_CPTs = array(); |
|
204 | - foreach ($this->getDefinitions() as $CPT => $details) { |
|
205 | - if (empty($details['args']['public'])) { |
|
206 | - $private_CPTs[ $CPT ] = $details; |
|
207 | - } |
|
208 | - } |
|
209 | - return $private_CPTs; |
|
210 | - } |
|
195 | + /** |
|
196 | + * This basically goes through the CPT array and returns only CPT's |
|
197 | + * that have the ['args']['public'] option set as false |
|
198 | + * |
|
199 | + * @return array |
|
200 | + */ |
|
201 | + public function getPrivateCustomPostTypes() |
|
202 | + { |
|
203 | + $private_CPTs = array(); |
|
204 | + foreach ($this->getDefinitions() as $CPT => $details) { |
|
205 | + if (empty($details['args']['public'])) { |
|
206 | + $private_CPTs[ $CPT ] = $details; |
|
207 | + } |
|
208 | + } |
|
209 | + return $private_CPTs; |
|
210 | + } |
|
211 | 211 | |
212 | 212 | |
213 | - /** |
|
214 | - * This returns the corresponding model name for cpts registered by EE. |
|
215 | - * |
|
216 | - * @param string $post_type_slug If a slug is included, then attempt to retrieve |
|
217 | - * the model name for the given cpt slug. |
|
218 | - * Otherwise if empty, then we'll return |
|
219 | - * all cpt model names for cpts registered in EE. |
|
220 | - * @return array Empty array if no matching model names for the given slug |
|
221 | - * or an array of model names indexed by post type slug. |
|
222 | - */ |
|
223 | - public function getCustomPostTypeModelNames($post_type_slug = '') |
|
224 | - { |
|
225 | - $cpts = $this->getDefinitions(); |
|
226 | - // first if slug passed in... |
|
227 | - if (! empty($post_type_slug)) { |
|
228 | - // check that slug and cpt match |
|
229 | - if (! isset($cpts[ $post_type_slug ])) { |
|
230 | - return array(); |
|
231 | - } |
|
232 | - if ( |
|
233 | - empty($cpts[ $post_type_slug ]['class_name']) |
|
234 | - && empty($cpts[ $post_type_slug ]['model_name']) |
|
235 | - ) { |
|
236 | - return array(); |
|
237 | - } |
|
238 | - // k let's get the model name for this cpt. |
|
239 | - return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]); |
|
240 | - } |
|
241 | - // if we made it here then we're returning an array of cpt model names indexed by post_type_slug. |
|
242 | - $cpt_models = array(); |
|
243 | - foreach ($cpts as $slug => $args) { |
|
244 | - $model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]); |
|
245 | - if (! empty($model)) { |
|
246 | - $cpt_models[ $slug ] = $model; |
|
247 | - } |
|
248 | - } |
|
249 | - return $cpt_models; |
|
250 | - } |
|
213 | + /** |
|
214 | + * This returns the corresponding model name for cpts registered by EE. |
|
215 | + * |
|
216 | + * @param string $post_type_slug If a slug is included, then attempt to retrieve |
|
217 | + * the model name for the given cpt slug. |
|
218 | + * Otherwise if empty, then we'll return |
|
219 | + * all cpt model names for cpts registered in EE. |
|
220 | + * @return array Empty array if no matching model names for the given slug |
|
221 | + * or an array of model names indexed by post type slug. |
|
222 | + */ |
|
223 | + public function getCustomPostTypeModelNames($post_type_slug = '') |
|
224 | + { |
|
225 | + $cpts = $this->getDefinitions(); |
|
226 | + // first if slug passed in... |
|
227 | + if (! empty($post_type_slug)) { |
|
228 | + // check that slug and cpt match |
|
229 | + if (! isset($cpts[ $post_type_slug ])) { |
|
230 | + return array(); |
|
231 | + } |
|
232 | + if ( |
|
233 | + empty($cpts[ $post_type_slug ]['class_name']) |
|
234 | + && empty($cpts[ $post_type_slug ]['model_name']) |
|
235 | + ) { |
|
236 | + return array(); |
|
237 | + } |
|
238 | + // k let's get the model name for this cpt. |
|
239 | + return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]); |
|
240 | + } |
|
241 | + // if we made it here then we're returning an array of cpt model names indexed by post_type_slug. |
|
242 | + $cpt_models = array(); |
|
243 | + foreach ($cpts as $slug => $args) { |
|
244 | + $model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]); |
|
245 | + if (! empty($model)) { |
|
246 | + $cpt_models[ $slug ] = $model; |
|
247 | + } |
|
248 | + } |
|
249 | + return $cpt_models; |
|
250 | + } |
|
251 | 251 | |
252 | 252 | |
253 | - /** |
|
254 | - * @param $post_type_slug |
|
255 | - * @param array $cpt |
|
256 | - * @return array |
|
257 | - */ |
|
258 | - private function getCustomPostTypeModelName($post_type_slug, array $cpt) |
|
259 | - { |
|
260 | - if (! empty($cpt['model_name'])) { |
|
261 | - return array($post_type_slug => $cpt['model_name']); |
|
262 | - } |
|
263 | - if (! empty($cpt['class_name'])) { |
|
264 | - return array( |
|
265 | - $post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']), |
|
266 | - ); |
|
267 | - } |
|
268 | - return array(); |
|
269 | - } |
|
253 | + /** |
|
254 | + * @param $post_type_slug |
|
255 | + * @param array $cpt |
|
256 | + * @return array |
|
257 | + */ |
|
258 | + private function getCustomPostTypeModelName($post_type_slug, array $cpt) |
|
259 | + { |
|
260 | + if (! empty($cpt['model_name'])) { |
|
261 | + return array($post_type_slug => $cpt['model_name']); |
|
262 | + } |
|
263 | + if (! empty($cpt['class_name'])) { |
|
264 | + return array( |
|
265 | + $post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']), |
|
266 | + ); |
|
267 | + } |
|
268 | + return array(); |
|
269 | + } |
|
270 | 270 | |
271 | 271 | |
272 | - /** |
|
273 | - * @param string $class_name |
|
274 | - * @return string |
|
275 | - */ |
|
276 | - private function deriveCptModelNameFromClassName($class_name) |
|
277 | - { |
|
278 | - return str_replace('EE', 'EEM', $class_name); |
|
279 | - } |
|
272 | + /** |
|
273 | + * @param string $class_name |
|
274 | + * @return string |
|
275 | + */ |
|
276 | + private function deriveCptModelNameFromClassName($class_name) |
|
277 | + { |
|
278 | + return str_replace('EE', 'EEM', $class_name); |
|
279 | + } |
|
280 | 280 | |
281 | 281 | |
282 | - /** |
|
283 | - * This instantiates cpt models related to the cpts registered via EE. |
|
284 | - * |
|
285 | - * @since 4.6.16.rc.000 |
|
286 | - * @param string $post_type_slug If valid slug is provided, then will instantiate the model only for |
|
287 | - * the cpt matching the given slug. Otherwise all cpt models will be |
|
288 | - * instantiated (if possible). |
|
289 | - * @return EEM_CPT_Base[] successful instantiation will return an array of successfully instantiated |
|
290 | - * EEM models indexed by post slug. |
|
291 | - */ |
|
292 | - public function getCustomPostTypeModels($post_type_slug = '') |
|
293 | - { |
|
294 | - $cpt_model_names = $this->getCustomPostTypeModelNames($post_type_slug); |
|
295 | - $instantiated = array(); |
|
296 | - foreach ($cpt_model_names as $slug => $model_name) { |
|
297 | - $model = $this->loader->getShared($model_name); |
|
298 | - if ($model instanceof EEM_CPT_Base) { |
|
299 | - $instantiated[ $slug ] = $model; |
|
300 | - } |
|
301 | - } |
|
302 | - return $instantiated; |
|
303 | - } |
|
282 | + /** |
|
283 | + * This instantiates cpt models related to the cpts registered via EE. |
|
284 | + * |
|
285 | + * @since 4.6.16.rc.000 |
|
286 | + * @param string $post_type_slug If valid slug is provided, then will instantiate the model only for |
|
287 | + * the cpt matching the given slug. Otherwise all cpt models will be |
|
288 | + * instantiated (if possible). |
|
289 | + * @return EEM_CPT_Base[] successful instantiation will return an array of successfully instantiated |
|
290 | + * EEM models indexed by post slug. |
|
291 | + */ |
|
292 | + public function getCustomPostTypeModels($post_type_slug = '') |
|
293 | + { |
|
294 | + $cpt_model_names = $this->getCustomPostTypeModelNames($post_type_slug); |
|
295 | + $instantiated = array(); |
|
296 | + foreach ($cpt_model_names as $slug => $model_name) { |
|
297 | + $model = $this->loader->getShared($model_name); |
|
298 | + if ($model instanceof EEM_CPT_Base) { |
|
299 | + $instantiated[ $slug ] = $model; |
|
300 | + } |
|
301 | + } |
|
302 | + return $instantiated; |
|
303 | + } |
|
304 | 304 | } |
@@ -203,7 +203,7 @@ discard block |
||
203 | 203 | $private_CPTs = array(); |
204 | 204 | foreach ($this->getDefinitions() as $CPT => $details) { |
205 | 205 | if (empty($details['args']['public'])) { |
206 | - $private_CPTs[ $CPT ] = $details; |
|
206 | + $private_CPTs[$CPT] = $details; |
|
207 | 207 | } |
208 | 208 | } |
209 | 209 | return $private_CPTs; |
@@ -224,26 +224,26 @@ discard block |
||
224 | 224 | { |
225 | 225 | $cpts = $this->getDefinitions(); |
226 | 226 | // first if slug passed in... |
227 | - if (! empty($post_type_slug)) { |
|
227 | + if ( ! empty($post_type_slug)) { |
|
228 | 228 | // check that slug and cpt match |
229 | - if (! isset($cpts[ $post_type_slug ])) { |
|
229 | + if ( ! isset($cpts[$post_type_slug])) { |
|
230 | 230 | return array(); |
231 | 231 | } |
232 | 232 | if ( |
233 | - empty($cpts[ $post_type_slug ]['class_name']) |
|
234 | - && empty($cpts[ $post_type_slug ]['model_name']) |
|
233 | + empty($cpts[$post_type_slug]['class_name']) |
|
234 | + && empty($cpts[$post_type_slug]['model_name']) |
|
235 | 235 | ) { |
236 | 236 | return array(); |
237 | 237 | } |
238 | 238 | // k let's get the model name for this cpt. |
239 | - return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]); |
|
239 | + return $this->getCustomPostTypeModelName($post_type_slug, $cpts[$post_type_slug]); |
|
240 | 240 | } |
241 | 241 | // if we made it here then we're returning an array of cpt model names indexed by post_type_slug. |
242 | 242 | $cpt_models = array(); |
243 | 243 | foreach ($cpts as $slug => $args) { |
244 | - $model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]); |
|
245 | - if (! empty($model)) { |
|
246 | - $cpt_models[ $slug ] = $model; |
|
244 | + $model = $this->getCustomPostTypeModelName($post_type_slug, $cpts[$post_type_slug]); |
|
245 | + if ( ! empty($model)) { |
|
246 | + $cpt_models[$slug] = $model; |
|
247 | 247 | } |
248 | 248 | } |
249 | 249 | return $cpt_models; |
@@ -257,10 +257,10 @@ discard block |
||
257 | 257 | */ |
258 | 258 | private function getCustomPostTypeModelName($post_type_slug, array $cpt) |
259 | 259 | { |
260 | - if (! empty($cpt['model_name'])) { |
|
260 | + if ( ! empty($cpt['model_name'])) { |
|
261 | 261 | return array($post_type_slug => $cpt['model_name']); |
262 | 262 | } |
263 | - if (! empty($cpt['class_name'])) { |
|
263 | + if ( ! empty($cpt['class_name'])) { |
|
264 | 264 | return array( |
265 | 265 | $post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']), |
266 | 266 | ); |
@@ -296,7 +296,7 @@ discard block |
||
296 | 296 | foreach ($cpt_model_names as $slug => $model_name) { |
297 | 297 | $model = $this->loader->getShared($model_name); |
298 | 298 | if ($model instanceof EEM_CPT_Base) { |
299 | - $instantiated[ $slug ] = $model; |
|
299 | + $instantiated[$slug] = $model; |
|
300 | 300 | } |
301 | 301 | } |
302 | 302 | return $instantiated; |
@@ -17,85 +17,85 @@ |
||
17 | 17 | */ |
18 | 18 | class EE_Restriction_Generator_Default_Protected extends EE_Restriction_Generator_Base |
19 | 19 | { |
20 | - /** |
|
21 | - * Name of the field on this model (or a related model, including the model chain to it) |
|
22 | - * that is a boolean indicating whether or not a model object is considered "Default" or not |
|
23 | - * @var string |
|
24 | - */ |
|
25 | - protected $_default_field_name; |
|
20 | + /** |
|
21 | + * Name of the field on this model (or a related model, including the model chain to it) |
|
22 | + * that is a boolean indicating whether or not a model object is considered "Default" or not |
|
23 | + * @var string |
|
24 | + */ |
|
25 | + protected $_default_field_name; |
|
26 | 26 | |
27 | - /** |
|
28 | - * The model chain to follow to get to the event model, including the event model itself. |
|
29 | - * Eg 'Ticket.Datetime.Event' |
|
30 | - * @var string |
|
31 | - */ |
|
32 | - protected $_path_to_event_model; |
|
33 | - /** |
|
34 | - * |
|
35 | - * @param string $default_field_name the name of the field Name of the field on this model (or a related model, including the model chain to it) |
|
36 | - * that is a boolean indicating whether or not a model object is considered "Default" or not |
|
37 | - * @param string $path_to_event_model The model chain to follow to get to the event model, including the event model itself. |
|
38 | - * Eg 'Ticket.Datetime.Event' |
|
39 | - */ |
|
40 | - public function __construct($default_field_name, $path_to_event_model) |
|
41 | - { |
|
42 | - $this->_default_field_name = $default_field_name; |
|
43 | - if (substr($path_to_event_model, -1, 1) != '.') { |
|
44 | - $path_to_event_model .= '.'; |
|
45 | - } |
|
46 | - $this->_path_to_event_model = $path_to_event_model; |
|
47 | - } |
|
27 | + /** |
|
28 | + * The model chain to follow to get to the event model, including the event model itself. |
|
29 | + * Eg 'Ticket.Datetime.Event' |
|
30 | + * @var string |
|
31 | + */ |
|
32 | + protected $_path_to_event_model; |
|
33 | + /** |
|
34 | + * |
|
35 | + * @param string $default_field_name the name of the field Name of the field on this model (or a related model, including the model chain to it) |
|
36 | + * that is a boolean indicating whether or not a model object is considered "Default" or not |
|
37 | + * @param string $path_to_event_model The model chain to follow to get to the event model, including the event model itself. |
|
38 | + * Eg 'Ticket.Datetime.Event' |
|
39 | + */ |
|
40 | + public function __construct($default_field_name, $path_to_event_model) |
|
41 | + { |
|
42 | + $this->_default_field_name = $default_field_name; |
|
43 | + if (substr($path_to_event_model, -1, 1) != '.') { |
|
44 | + $path_to_event_model .= '.'; |
|
45 | + } |
|
46 | + $this->_path_to_event_model = $path_to_event_model; |
|
47 | + } |
|
48 | 48 | |
49 | 49 | |
50 | 50 | |
51 | - /** |
|
52 | - * |
|
53 | - * @return \EE_Default_Where_Conditions |
|
54 | - */ |
|
55 | - protected function _generate_restrictions() |
|
56 | - { |
|
57 | - // if there are no standard caps for this model, then for now all we know is |
|
58 | - // if they need the default cap to access this |
|
59 | - if (! $this->model()->cap_slug()) { |
|
60 | - return array( |
|
61 | - self::get_default_restrictions_cap() => new EE_Return_None_Where_Conditions() |
|
62 | - ); |
|
63 | - } |
|
51 | + /** |
|
52 | + * |
|
53 | + * @return \EE_Default_Where_Conditions |
|
54 | + */ |
|
55 | + protected function _generate_restrictions() |
|
56 | + { |
|
57 | + // if there are no standard caps for this model, then for now all we know is |
|
58 | + // if they need the default cap to access this |
|
59 | + if (! $this->model()->cap_slug()) { |
|
60 | + return array( |
|
61 | + self::get_default_restrictions_cap() => new EE_Return_None_Where_Conditions() |
|
62 | + ); |
|
63 | + } |
|
64 | 64 | |
65 | - $event_model = EEM_Event::instance(); |
|
65 | + $event_model = EEM_Event::instance(); |
|
66 | 66 | |
67 | - $restrictions = array( |
|
68 | - // first: basically access to non-defaults is essentially controlled by which events are accessible |
|
69 | - // if they don't have the basic event cap, they can't access ANY non-default items |
|
70 | - EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action()) => new EE_Default_Where_Conditions(array( $this->_default_field_name => true )), |
|
71 | - // if they don't have the others event cap, they can't access others' non-default items |
|
72 | - EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_others') => new EE_Default_Where_Conditions(array( |
|
73 | - 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_others') => array( |
|
74 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder ), |
|
75 | - $this->_default_field_name => true )), |
|
76 | - // if they have basic and others, but not private, they can't access others' private non-default items |
|
77 | - EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_private') => new EE_Default_Where_Conditions(array( |
|
78 | - 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_private') => array( |
|
79 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
80 | - $this->_path_to_event_model . 'status' => array( '!=', 'private' ), |
|
81 | - $this->_default_field_name => true ) )), |
|
82 | - // second: access to defaults is controlled by the defaulty capabilities |
|
83 | - // if they don't have the default capability, restrict access to only non-default items |
|
84 | - EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_default') => new EE_Default_Where_Conditions(array( $this->_default_field_name => false )), |
|
85 | - // if they don't have the "others" default capability, restrict access to only their default ones, and non-default ones |
|
86 | - ); |
|
87 | - if (EE_Restriction_Generator_Base::is_cap($this->model(), $this->action() . '_others_default')) { |
|
88 | - $restrictions[ EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_others_default') ] = new EE_Default_Where_Conditions(array( |
|
89 | - // if they don't have the others default cap, they can't access others default items (but they can access |
|
90 | - // their own default items, and non-default items) |
|
91 | - 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_others_default') => array( |
|
92 | - 'AND' => array( |
|
93 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
94 | - $this->_default_field_name => true |
|
95 | - ), |
|
96 | - $this->_default_field_name => false |
|
97 | - ) )); |
|
98 | - } |
|
99 | - return $restrictions; |
|
100 | - } |
|
67 | + $restrictions = array( |
|
68 | + // first: basically access to non-defaults is essentially controlled by which events are accessible |
|
69 | + // if they don't have the basic event cap, they can't access ANY non-default items |
|
70 | + EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action()) => new EE_Default_Where_Conditions(array( $this->_default_field_name => true )), |
|
71 | + // if they don't have the others event cap, they can't access others' non-default items |
|
72 | + EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_others') => new EE_Default_Where_Conditions(array( |
|
73 | + 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_others') => array( |
|
74 | + $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder ), |
|
75 | + $this->_default_field_name => true )), |
|
76 | + // if they have basic and others, but not private, they can't access others' private non-default items |
|
77 | + EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_private') => new EE_Default_Where_Conditions(array( |
|
78 | + 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_private') => array( |
|
79 | + $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
80 | + $this->_path_to_event_model . 'status' => array( '!=', 'private' ), |
|
81 | + $this->_default_field_name => true ) )), |
|
82 | + // second: access to defaults is controlled by the defaulty capabilities |
|
83 | + // if they don't have the default capability, restrict access to only non-default items |
|
84 | + EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_default') => new EE_Default_Where_Conditions(array( $this->_default_field_name => false )), |
|
85 | + // if they don't have the "others" default capability, restrict access to only their default ones, and non-default ones |
|
86 | + ); |
|
87 | + if (EE_Restriction_Generator_Base::is_cap($this->model(), $this->action() . '_others_default')) { |
|
88 | + $restrictions[ EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_others_default') ] = new EE_Default_Where_Conditions(array( |
|
89 | + // if they don't have the others default cap, they can't access others default items (but they can access |
|
90 | + // their own default items, and non-default items) |
|
91 | + 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_others_default') => array( |
|
92 | + 'AND' => array( |
|
93 | + $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
94 | + $this->_default_field_name => true |
|
95 | + ), |
|
96 | + $this->_default_field_name => false |
|
97 | + ) )); |
|
98 | + } |
|
99 | + return $restrictions; |
|
100 | + } |
|
101 | 101 | } |
@@ -56,7 +56,7 @@ discard block |
||
56 | 56 | { |
57 | 57 | // if there are no standard caps for this model, then for now all we know is |
58 | 58 | // if they need the default cap to access this |
59 | - if (! $this->model()->cap_slug()) { |
|
59 | + if ( ! $this->model()->cap_slug()) { |
|
60 | 60 | return array( |
61 | 61 | self::get_default_restrictions_cap() => new EE_Return_None_Where_Conditions() |
62 | 62 | ); |
@@ -64,33 +64,33 @@ discard block |
||
64 | 64 | |
65 | 65 | $event_model = EEM_Event::instance(); |
66 | 66 | |
67 | - $restrictions = array( |
|
67 | + $restrictions = array( |
|
68 | 68 | // first: basically access to non-defaults is essentially controlled by which events are accessible |
69 | 69 | // if they don't have the basic event cap, they can't access ANY non-default items |
70 | - EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action()) => new EE_Default_Where_Conditions(array( $this->_default_field_name => true )), |
|
70 | + EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action()) => new EE_Default_Where_Conditions(array($this->_default_field_name => true)), |
|
71 | 71 | // if they don't have the others event cap, they can't access others' non-default items |
72 | - EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_others') => new EE_Default_Where_Conditions(array( |
|
73 | - 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_others') => array( |
|
74 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder ), |
|
72 | + EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action().'_others') => new EE_Default_Where_Conditions(array( |
|
73 | + 'OR*no_'.EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action().'_others') => array( |
|
74 | + $this->_path_to_event_model.'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder ), |
|
75 | 75 | $this->_default_field_name => true )), |
76 | 76 | // if they have basic and others, but not private, they can't access others' private non-default items |
77 | - EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_private') => new EE_Default_Where_Conditions(array( |
|
78 | - 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action() . '_private') => array( |
|
79 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
80 | - $this->_path_to_event_model . 'status' => array( '!=', 'private' ), |
|
77 | + EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action().'_private') => new EE_Default_Where_Conditions(array( |
|
78 | + 'OR*no_'.EE_Restriction_Generator_Base::get_cap_name($event_model, $this->action().'_private') => array( |
|
79 | + $this->_path_to_event_model.'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
80 | + $this->_path_to_event_model.'status' => array('!=', 'private'), |
|
81 | 81 | $this->_default_field_name => true ) )), |
82 | 82 | // second: access to defaults is controlled by the defaulty capabilities |
83 | 83 | // if they don't have the default capability, restrict access to only non-default items |
84 | - EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_default') => new EE_Default_Where_Conditions(array( $this->_default_field_name => false )), |
|
84 | + EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action().'_default') => new EE_Default_Where_Conditions(array($this->_default_field_name => false)), |
|
85 | 85 | // if they don't have the "others" default capability, restrict access to only their default ones, and non-default ones |
86 | 86 | ); |
87 | - if (EE_Restriction_Generator_Base::is_cap($this->model(), $this->action() . '_others_default')) { |
|
88 | - $restrictions[ EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_others_default') ] = new EE_Default_Where_Conditions(array( |
|
87 | + if (EE_Restriction_Generator_Base::is_cap($this->model(), $this->action().'_others_default')) { |
|
88 | + $restrictions[EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action().'_others_default')] = new EE_Default_Where_Conditions(array( |
|
89 | 89 | // if they don't have the others default cap, they can't access others default items (but they can access |
90 | 90 | // their own default items, and non-default items) |
91 | - 'OR*no_' . EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action() . '_others_default') => array( |
|
91 | + 'OR*no_'.EE_Restriction_Generator_Base::get_cap_name($this->model(), $this->action().'_others_default') => array( |
|
92 | 92 | 'AND' => array( |
93 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
93 | + $this->_path_to_event_model.'EVT_wp_user' => EE_Default_Where_Conditions::current_user_placeholder, |
|
94 | 94 | $this->_default_field_name => true |
95 | 95 | ), |
96 | 96 | $this->_default_field_name => false |
@@ -216,7 +216,7 @@ discard block |
||
216 | 216 | { |
217 | 217 | if (EEH_Event_Query::apply_query_filters($wp_query)) { |
218 | 218 | global $wpdb; |
219 | - $clauses['groupby'] = $wpdb->posts . '.ID '; |
|
219 | + $clauses['groupby'] = $wpdb->posts.'.ID '; |
|
220 | 220 | } |
221 | 221 | return $clauses; |
222 | 222 | } |
@@ -251,23 +251,23 @@ discard block |
||
251 | 251 | */ |
252 | 252 | public static function posts_fields_sql_for_orderby(array $orderby_params = []) |
253 | 253 | { |
254 | - $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
254 | + $SQL = ', MIN( '.EEM_Datetime::instance()->table().'.DTT_EVT_start ) as event_start_date '; |
|
255 | 255 | foreach ($orderby_params as $orderby) { |
256 | 256 | switch ($orderby) { |
257 | 257 | case 'ticket_start': |
258 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date'; |
|
258 | + $SQL .= ', '.EEM_Ticket::instance()->table().'.TKT_start_date'; |
|
259 | 259 | break; |
260 | 260 | case 'ticket_end': |
261 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date'; |
|
261 | + $SQL .= ', '.EEM_Ticket::instance()->table().'.TKT_end_date'; |
|
262 | 262 | break; |
263 | 263 | case 'venue_title': |
264 | 264 | $SQL .= ', Venue.post_title AS venue_title'; |
265 | 265 | break; |
266 | 266 | case 'city': |
267 | - $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city'; |
|
267 | + $SQL .= ', '.EEM_Venue::instance()->second_table().'.VNU_city'; |
|
268 | 268 | break; |
269 | 269 | case 'state': |
270 | - $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name'; |
|
270 | + $SQL .= ', '.EEM_State::instance()->table().'.STA_name'; |
|
271 | 271 | break; |
272 | 272 | } |
273 | 273 | } |
@@ -307,12 +307,12 @@ discard block |
||
307 | 307 | */ |
308 | 308 | public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false) |
309 | 309 | { |
310 | - if (! $show_expired) { |
|
311 | - $join = EEM_Event::instance()->table() . '.ID = '; |
|
312 | - $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
310 | + if ( ! $show_expired) { |
|
311 | + $join = EEM_Event::instance()->table().'.ID = '; |
|
312 | + $join .= EEM_Datetime::instance()->table().'.'.EEM_Event::instance()->primary_key_name(); |
|
313 | 313 | // don't add if this is already in the SQL |
314 | 314 | if (strpos($SQL, $join) === false) { |
315 | - $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) '; |
|
315 | + $SQL .= ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.$join.' ) '; |
|
316 | 316 | } |
317 | 317 | } |
318 | 318 | return $SQL; |
@@ -327,7 +327,7 @@ discard block |
||
327 | 327 | */ |
328 | 328 | public static function posts_join_sql_for_terms($SQL = '', $join_terms = '') |
329 | 329 | { |
330 | - if (! empty($join_terms)) { |
|
330 | + if ( ! empty($join_terms)) { |
|
331 | 331 | global $wpdb; |
332 | 332 | $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)"; |
333 | 333 | $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)"; |
@@ -356,13 +356,13 @@ discard block |
||
356 | 356 | case 'ticket_end': |
357 | 357 | $SQL .= EEH_Event_Query::_posts_join_for_datetime( |
358 | 358 | $SQL, |
359 | - EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name() |
|
359 | + EEM_Datetime_Ticket::instance()->table().'.'.EEM_Datetime::instance()->primary_key_name() |
|
360 | 360 | ); |
361 | - $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table(); |
|
361 | + $SQL .= ' LEFT JOIN '.EEM_Ticket::instance()->table(); |
|
362 | 362 | $SQL .= ' ON ('; |
363 | - $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
363 | + $SQL .= EEM_Datetime_Ticket::instance()->table().'.'.EEM_Ticket::instance()->primary_key_name(); |
|
364 | 364 | $SQL .= ' = '; |
365 | - $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
365 | + $SQL .= EEM_Ticket::instance()->table().'.'.EEM_Ticket::instance()->primary_key_name(); |
|
366 | 366 | $SQL .= ' )'; |
367 | 367 | break; |
368 | 368 | case 'venue_title': |
@@ -375,7 +375,7 @@ discard block |
||
375 | 375 | break; |
376 | 376 | case 'start_date': |
377 | 377 | default: |
378 | - $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID'); |
|
378 | + $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table().'.ID'); |
|
379 | 379 | break; |
380 | 380 | } |
381 | 381 | } |
@@ -394,10 +394,10 @@ discard block |
||
394 | 394 | */ |
395 | 395 | protected static function _posts_join_for_datetime($SQL = '', $join = '') |
396 | 396 | { |
397 | - if (! empty($join)) { |
|
398 | - $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
397 | + if ( ! empty($join)) { |
|
398 | + $join .= ' = '.EEM_Datetime::instance()->table().'.'.EEM_Event::instance()->primary_key_name(); |
|
399 | 399 | if (strpos($SQL, $join) === false) { |
400 | - return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )'; |
|
400 | + return ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.$join.' )'; |
|
401 | 401 | } |
402 | 402 | } |
403 | 403 | return ''; |
@@ -417,8 +417,8 @@ discard block |
||
417 | 417 | // Event Venue table name |
418 | 418 | $event_venue_table = EEM_Event_Venue::instance()->table(); |
419 | 419 | // generate conditions for: Event <=> Event Venue JOIN clause |
420 | - $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = '; |
|
421 | - $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name(); |
|
420 | + $event_to_event_venue_join = EEM_Event::instance()->table().'.ID = '; |
|
421 | + $event_to_event_venue_join .= $event_venue_table.'.'.EEM_Event::instance()->primary_key_name(); |
|
422 | 422 | // don't add joins if they have already been added |
423 | 423 | if (strpos($SQL, $event_to_event_venue_join) === false) { |
424 | 424 | // Venue table name |
@@ -506,7 +506,7 @@ discard block |
||
506 | 506 | public static function posts_where_sql_for_show_expired($show_expired = false) |
507 | 507 | { |
508 | 508 | return ! $show_expired |
509 | - ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' ' |
|
509 | + ? ' AND '.EEM_Datetime::instance()->table().'.DTT_EVT_end > \''.current_time('mysql', true).'\' ' |
|
510 | 510 | : ''; |
511 | 511 | } |
512 | 512 | |
@@ -518,7 +518,7 @@ discard block |
||
518 | 518 | public static function posts_where_sql_for_event_category_slug($event_category_slug = null) |
519 | 519 | { |
520 | 520 | global $wpdb; |
521 | - if (! empty($event_category_slug)) { |
|
521 | + if ( ! empty($event_category_slug)) { |
|
522 | 522 | $event_category_slugs_array = array_map('trim', explode(',', $event_category_slug)); |
523 | 523 | $event_category_slugs_prepare = implode(', ', array_fill(0, count($event_category_slugs_array), '%s')); |
524 | 524 | return $wpdb->prepare( |
@@ -541,14 +541,14 @@ discard block |
||
541 | 541 | public static function posts_where_sql_for_event_list_month($month = null) |
542 | 542 | { |
543 | 543 | $SQL = ''; |
544 | - if (! empty($month)) { |
|
544 | + if ( ! empty($month)) { |
|
545 | 545 | $datetime_table = EEM_Datetime::instance()->table(); |
546 | 546 | // event start date is LESS than the end of the month ( so nothing that doesn't start until next month ) |
547 | 547 | $SQL = " AND {$datetime_table}.DTT_EVT_start <= '"; |
548 | - $SQL .= date('Y-m-t 23:59:59', EEH_DTT_Helper::first_of_month_timestamp($month)) . "'"; |
|
548 | + $SQL .= date('Y-m-t 23:59:59', EEH_DTT_Helper::first_of_month_timestamp($month))."'"; |
|
549 | 549 | // event end date is GREATER than the start of the month ( so nothing that ended before this month ) |
550 | 550 | $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '"; |
551 | - $SQL .= date('Y-m-01 0:0:00', EEH_DTT_Helper::first_of_month_timestamp($month)) . "' "; |
|
551 | + $SQL .= date('Y-m-01 0:0:00', EEH_DTT_Helper::first_of_month_timestamp($month))."' "; |
|
552 | 552 | } |
553 | 553 | return $SQL; |
554 | 554 | } |
@@ -609,15 +609,15 @@ discard block |
||
609 | 609 | ? strtoupper($sort) |
610 | 610 | : 'ASC'; |
611 | 611 | // make sure 'orderby' is set in query params |
612 | - if (! isset(self::$_query_params['orderby'])) { |
|
612 | + if ( ! isset(self::$_query_params['orderby'])) { |
|
613 | 613 | self::$_query_params['orderby'] = []; |
614 | 614 | } |
615 | 615 | // loop thru $orderby_params (type cast as array) |
616 | 616 | foreach ($orderby_params as $orderby) { |
617 | 617 | // check if we have already added this param |
618 | - if (isset(self::$_query_params['orderby'][ $orderby ])) { |
|
618 | + if (isset(self::$_query_params['orderby'][$orderby])) { |
|
619 | 619 | // if so then remove from the $orderby_params so that the count() method below is accurate |
620 | - unset($orderby_params[ $orderby ]); |
|
620 | + unset($orderby_params[$orderby]); |
|
621 | 621 | // then bump ahead to the next param |
622 | 622 | continue; |
623 | 623 | } |
@@ -627,39 +627,39 @@ discard block |
||
627 | 627 | switch ($orderby) { |
628 | 628 | case 'id': |
629 | 629 | case 'ID': |
630 | - $SQL .= $glue . $wpdb->posts . '.ID ' . $sort; |
|
630 | + $SQL .= $glue.$wpdb->posts.'.ID '.$sort; |
|
631 | 631 | break; |
632 | 632 | case 'end_date': |
633 | - $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort; |
|
633 | + $SQL .= $glue.EEM_Datetime::instance()->table().'.DTT_EVT_end '.$sort; |
|
634 | 634 | break; |
635 | 635 | case 'event_name': |
636 | - $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort; |
|
636 | + $SQL .= $glue.$wpdb->posts.'.post_title '.$sort; |
|
637 | 637 | break; |
638 | 638 | case 'category_slug': |
639 | - $SQL .= $glue . $wpdb->terms . '.slug ' . $sort; |
|
639 | + $SQL .= $glue.$wpdb->terms.'.slug '.$sort; |
|
640 | 640 | break; |
641 | 641 | case 'ticket_start': |
642 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort; |
|
642 | + $SQL .= $glue.EEM_Ticket::instance()->table().'.TKT_start_date '.$sort; |
|
643 | 643 | break; |
644 | 644 | case 'ticket_end': |
645 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort; |
|
645 | + $SQL .= $glue.EEM_Ticket::instance()->table().'.TKT_end_date '.$sort; |
|
646 | 646 | break; |
647 | 647 | case 'venue_title': |
648 | - $SQL .= $glue . 'venue_title ' . $sort; |
|
648 | + $SQL .= $glue.'venue_title '.$sort; |
|
649 | 649 | break; |
650 | 650 | case 'city': |
651 | - $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort; |
|
651 | + $SQL .= $glue.EEM_Venue::instance()->second_table().'.VNU_city '.$sort; |
|
652 | 652 | break; |
653 | 653 | case 'state': |
654 | - $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort; |
|
654 | + $SQL .= $glue.EEM_State::instance()->table().'.STA_name '.$sort; |
|
655 | 655 | break; |
656 | 656 | case 'start_date': |
657 | 657 | default: |
658 | - $SQL .= $glue . ' event_start_date ' . $sort; |
|
658 | + $SQL .= $glue.' event_start_date '.$sort; |
|
659 | 659 | break; |
660 | 660 | } |
661 | 661 | // add to array of orderby params that have been added |
662 | - self::$_query_params['orderby'][ $orderby ] = true; |
|
662 | + self::$_query_params['orderby'][$orderby] = true; |
|
663 | 663 | $counter++; |
664 | 664 | } |
665 | 665 | return $SQL; |
@@ -17,661 +17,661 @@ |
||
17 | 17 | class EEH_Event_Query |
18 | 18 | { |
19 | 19 | |
20 | - /** |
|
21 | - * Start Date |
|
22 | - * |
|
23 | - * @var $_event_query_month |
|
24 | - */ |
|
25 | - protected static $_event_query_month; |
|
26 | - |
|
27 | - /** |
|
28 | - * Category |
|
29 | - * |
|
30 | - * @var $_event_query_category |
|
31 | - */ |
|
32 | - protected static $_event_query_category; |
|
33 | - |
|
34 | - /** |
|
35 | - * whether to display expired events in the event list |
|
36 | - * |
|
37 | - * @var bool $_show_expired |
|
38 | - */ |
|
39 | - protected static $_event_query_show_expired = false; |
|
40 | - |
|
41 | - /** |
|
42 | - * list of params for controlling how the query results are ordered |
|
43 | - * |
|
44 | - * @var array $_event_query_orderby |
|
45 | - */ |
|
46 | - protected static $_event_query_orderby = []; |
|
47 | - |
|
48 | - /** |
|
49 | - * direction list is sorted |
|
50 | - * |
|
51 | - * @var string $_event_query_sort |
|
52 | - */ |
|
53 | - protected static $_event_query_sort; |
|
54 | - |
|
55 | - /** |
|
56 | - * list of params used to build the query's various clauses |
|
57 | - * |
|
58 | - * @var $_query_params |
|
59 | - */ |
|
60 | - protected static $_query_params = []; |
|
61 | - |
|
62 | - |
|
63 | - /** |
|
64 | - * @return void |
|
65 | - */ |
|
66 | - public static function add_query_filters() |
|
67 | - { |
|
68 | - // add query filters |
|
69 | - add_action('pre_get_posts', ['EEH_Event_Query', 'filter_query_parts'], 10, 1); |
|
70 | - } |
|
71 | - |
|
72 | - |
|
73 | - /** |
|
74 | - * @param WP_Query $WP_Query |
|
75 | - * @return bool |
|
76 | - */ |
|
77 | - public static function apply_query_filters(WP_Query $WP_Query) |
|
78 | - { |
|
79 | - return ( |
|
80 | - isset($WP_Query->query['post_type']) |
|
81 | - && $WP_Query->query['post_type'] === 'espresso_events' |
|
82 | - ) |
|
83 | - || apply_filters('FHEE__EEH_Event_Query__apply_query_filters', false); |
|
84 | - } |
|
85 | - |
|
86 | - |
|
87 | - /** |
|
88 | - * @param WP_Query $WP_Query |
|
89 | - */ |
|
90 | - public static function filter_query_parts(WP_Query $WP_Query) |
|
91 | - { |
|
92 | - // ONLY add our filters if this isn't the main wp_query, |
|
93 | - // because if this is the main wp_query we already have |
|
94 | - // our cpt strategies take care of adding things in. |
|
95 | - if ($WP_Query instanceof WP_Query && ! $WP_Query->is_main_query()) { |
|
96 | - // build event list query |
|
97 | - add_filter('posts_fields', ['EEH_Event_Query', 'posts_fields'], 10, 2); |
|
98 | - add_filter('posts_join', ['EEH_Event_Query', 'posts_join'], 10, 2); |
|
99 | - add_filter('posts_where', ['EEH_Event_Query', 'posts_where'], 10, 2); |
|
100 | - add_filter('posts_orderby', ['EEH_Event_Query', 'posts_orderby'], 10, 2); |
|
101 | - add_filter('posts_clauses_request', ['EEH_Event_Query', 'posts_clauses'], 10, 2); |
|
102 | - } |
|
103 | - } |
|
104 | - |
|
105 | - |
|
106 | - /** |
|
107 | - * @param string $month |
|
108 | - * @param string $category |
|
109 | - * @param bool $show_expired |
|
110 | - * @param string $orderby |
|
111 | - * @param string $sort |
|
112 | - * @throws InvalidArgumentException |
|
113 | - * @throws InvalidDataTypeException |
|
114 | - * @throws InvalidInterfaceException |
|
115 | - */ |
|
116 | - public static function set_query_params( |
|
117 | - $month = '', |
|
118 | - $category = '', |
|
119 | - $show_expired = false, |
|
120 | - $orderby = 'start_date', |
|
121 | - $sort = 'ASC' |
|
122 | - ) { |
|
123 | - self::$_query_params = []; |
|
124 | - EEH_Event_Query::$_event_query_month = EEH_Event_Query::_display_month($month); |
|
125 | - EEH_Event_Query::$_event_query_category = EEH_Event_Query::_event_category_slug($category); |
|
126 | - EEH_Event_Query::$_event_query_show_expired = EEH_Event_Query::_show_expired($show_expired); |
|
127 | - EEH_Event_Query::$_event_query_orderby = EEH_Event_Query::_orderby($orderby); |
|
128 | - EEH_Event_Query::$_event_query_sort = EEH_Event_Query::_sort($sort); |
|
129 | - } |
|
130 | - |
|
131 | - |
|
132 | - /** |
|
133 | - * what month should the event list display events for? |
|
134 | - * |
|
135 | - * @param string $month |
|
136 | - * @return string |
|
137 | - * @throws InvalidArgumentException |
|
138 | - * @throws InvalidDataTypeException |
|
139 | - * @throws InvalidInterfaceException |
|
140 | - */ |
|
141 | - private static function _display_month($month = '') |
|
142 | - { |
|
143 | - return self::getRequest()->getRequestParam('event_query_month', $month); |
|
144 | - } |
|
145 | - |
|
146 | - |
|
147 | - /** |
|
148 | - * @param string $category |
|
149 | - * @return string |
|
150 | - * @throws InvalidArgumentException |
|
151 | - * @throws InvalidDataTypeException |
|
152 | - * @throws InvalidInterfaceException |
|
153 | - */ |
|
154 | - private static function _event_category_slug($category = '') |
|
155 | - { |
|
156 | - return self::getRequest()->getRequestParam('event_query_category', $category); |
|
157 | - } |
|
158 | - |
|
159 | - |
|
160 | - /** |
|
161 | - * @param bool $show_expired |
|
162 | - * @return bool |
|
163 | - * @throws InvalidArgumentException |
|
164 | - * @throws InvalidDataTypeException |
|
165 | - * @throws InvalidInterfaceException |
|
166 | - */ |
|
167 | - private static function _show_expired($show_expired = false) |
|
168 | - { |
|
169 | - // override default expired option if set via filter |
|
170 | - return self::getRequest()->getRequestParam('event_query_show_expired', $show_expired, 'bool'); |
|
171 | - } |
|
172 | - |
|
173 | - |
|
174 | - /** |
|
175 | - * @param string $orderby |
|
176 | - * @return array |
|
177 | - * @throws InvalidArgumentException |
|
178 | - * @throws InvalidDataTypeException |
|
179 | - * @throws InvalidInterfaceException |
|
180 | - */ |
|
181 | - private static function _orderby($orderby = 'start_date') |
|
182 | - { |
|
183 | - $event_query_orderby = self::getRequest()->getRequestParam('event_query_orderby', $orderby); |
|
184 | - $event_query_orderby = is_array($event_query_orderby) |
|
185 | - ? $event_query_orderby |
|
186 | - : explode(',', $event_query_orderby); |
|
187 | - $event_query_orderby = array_map('trim', $event_query_orderby); |
|
188 | - return array_map('sanitize_text_field', $event_query_orderby); |
|
189 | - } |
|
190 | - |
|
191 | - |
|
192 | - /** |
|
193 | - * @param string $sort |
|
194 | - * @return string |
|
195 | - * @throws InvalidArgumentException |
|
196 | - * @throws InvalidDataTypeException |
|
197 | - * @throws InvalidInterfaceException |
|
198 | - */ |
|
199 | - private static function _sort($sort = 'ASC') |
|
200 | - { |
|
201 | - $sort = self::getRequest()->getRequestParam('event_query_sort', $sort); |
|
202 | - return in_array($sort, ['ASC', 'asc', 'DESC', 'desc'], true) |
|
203 | - ? strtoupper($sort) |
|
204 | - : 'ASC'; |
|
205 | - } |
|
206 | - |
|
207 | - |
|
208 | - /** |
|
209 | - * Filters the clauses for the WP_Query object |
|
210 | - * |
|
211 | - * @param array $clauses array of clauses |
|
212 | - * @param WP_Query $wp_query |
|
213 | - * @return array array of clauses |
|
214 | - */ |
|
215 | - public static function posts_clauses($clauses, WP_Query $wp_query) |
|
216 | - { |
|
217 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
218 | - global $wpdb; |
|
219 | - $clauses['groupby'] = $wpdb->posts . '.ID '; |
|
220 | - } |
|
221 | - return $clauses; |
|
222 | - } |
|
223 | - |
|
224 | - |
|
225 | - /** |
|
226 | - * @param string $SQL |
|
227 | - * @param WP_Query $wp_query |
|
228 | - * @return string |
|
229 | - * @throws EE_Error |
|
230 | - * @throws InvalidArgumentException |
|
231 | - * @throws InvalidDataTypeException |
|
232 | - * @throws InvalidInterfaceException |
|
233 | - */ |
|
234 | - public static function posts_fields($SQL, WP_Query $wp_query) |
|
235 | - { |
|
236 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
237 | - // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement |
|
238 | - $SQL .= EEH_Event_Query::posts_fields_sql_for_orderby(EEH_Event_Query::$_event_query_orderby); |
|
239 | - } |
|
240 | - return $SQL; |
|
241 | - } |
|
242 | - |
|
243 | - |
|
244 | - /** |
|
245 | - * @param array $orderby_params |
|
246 | - * @return string |
|
247 | - * @throws EE_Error |
|
248 | - * @throws InvalidArgumentException |
|
249 | - * @throws InvalidDataTypeException |
|
250 | - * @throws InvalidInterfaceException |
|
251 | - */ |
|
252 | - public static function posts_fields_sql_for_orderby(array $orderby_params = []) |
|
253 | - { |
|
254 | - $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
255 | - foreach ($orderby_params as $orderby) { |
|
256 | - switch ($orderby) { |
|
257 | - case 'ticket_start': |
|
258 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date'; |
|
259 | - break; |
|
260 | - case 'ticket_end': |
|
261 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date'; |
|
262 | - break; |
|
263 | - case 'venue_title': |
|
264 | - $SQL .= ', Venue.post_title AS venue_title'; |
|
265 | - break; |
|
266 | - case 'city': |
|
267 | - $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city'; |
|
268 | - break; |
|
269 | - case 'state': |
|
270 | - $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name'; |
|
271 | - break; |
|
272 | - } |
|
273 | - } |
|
274 | - return $SQL; |
|
275 | - } |
|
276 | - |
|
277 | - |
|
278 | - /** |
|
279 | - * @param string $SQL |
|
280 | - * @param WP_Query $wp_query |
|
281 | - * @return string |
|
282 | - * @throws EE_Error |
|
283 | - * @throws InvalidArgumentException |
|
284 | - * @throws InvalidDataTypeException |
|
285 | - * @throws InvalidInterfaceException |
|
286 | - */ |
|
287 | - public static function posts_join($SQL, WP_Query $wp_query) |
|
288 | - { |
|
289 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
290 | - // Category |
|
291 | - $SQL = EEH_Event_Query::posts_join_sql_for_show_expired($SQL, EEH_Event_Query::$_event_query_show_expired); |
|
292 | - $SQL = EEH_Event_Query::posts_join_sql_for_terms($SQL, EEH_Event_Query::$_event_query_category); |
|
293 | - $SQL = EEH_Event_Query::posts_join_for_orderby($SQL, EEH_Event_Query::$_event_query_orderby); |
|
294 | - } |
|
295 | - return $SQL; |
|
296 | - } |
|
297 | - |
|
298 | - |
|
299 | - /** |
|
300 | - * @param string $SQL |
|
301 | - * @param boolean $show_expired if TRUE, then displayed past events |
|
302 | - * @return string |
|
303 | - * @throws EE_Error |
|
304 | - * @throws InvalidArgumentException |
|
305 | - * @throws InvalidDataTypeException |
|
306 | - * @throws InvalidInterfaceException |
|
307 | - */ |
|
308 | - public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false) |
|
309 | - { |
|
310 | - if (! $show_expired) { |
|
311 | - $join = EEM_Event::instance()->table() . '.ID = '; |
|
312 | - $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
313 | - // don't add if this is already in the SQL |
|
314 | - if (strpos($SQL, $join) === false) { |
|
315 | - $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) '; |
|
316 | - } |
|
317 | - } |
|
318 | - return $SQL; |
|
319 | - } |
|
320 | - |
|
321 | - |
|
322 | - /** |
|
323 | - * @param string $SQL |
|
324 | - * @param string $join_terms pass TRUE or term string, doesn't really matter since this value doesn't really get |
|
325 | - * used for anything yet |
|
326 | - * @return string |
|
327 | - */ |
|
328 | - public static function posts_join_sql_for_terms($SQL = '', $join_terms = '') |
|
329 | - { |
|
330 | - if (! empty($join_terms)) { |
|
331 | - global $wpdb; |
|
332 | - $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)"; |
|
333 | - $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)"; |
|
334 | - $SQL .= " LEFT JOIN $wpdb->terms ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id) "; |
|
335 | - } |
|
336 | - return $SQL; |
|
337 | - } |
|
338 | - |
|
339 | - |
|
340 | - /** |
|
341 | - * usage: $SQL .= EEH_Event_Query::posts_join_for_orderby( $orderby_params ); |
|
342 | - * |
|
343 | - * @param string $SQL |
|
344 | - * @param array $orderby_params |
|
345 | - * @return string |
|
346 | - * @throws EE_Error |
|
347 | - * @throws InvalidArgumentException |
|
348 | - * @throws InvalidDataTypeException |
|
349 | - * @throws InvalidInterfaceException |
|
350 | - */ |
|
351 | - public static function posts_join_for_orderby($SQL = '', array $orderby_params = []) |
|
352 | - { |
|
353 | - foreach ($orderby_params as $orderby) { |
|
354 | - switch ($orderby) { |
|
355 | - case 'ticket_start': |
|
356 | - case 'ticket_end': |
|
357 | - $SQL .= EEH_Event_Query::_posts_join_for_datetime( |
|
358 | - $SQL, |
|
359 | - EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name() |
|
360 | - ); |
|
361 | - $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table(); |
|
362 | - $SQL .= ' ON ('; |
|
363 | - $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
364 | - $SQL .= ' = '; |
|
365 | - $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
366 | - $SQL .= ' )'; |
|
367 | - break; |
|
368 | - case 'venue_title': |
|
369 | - case 'city': |
|
370 | - $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
371 | - break; |
|
372 | - case 'state': |
|
373 | - $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
374 | - $SQL .= EEH_Event_Query::_posts_join_for_venue_state($SQL); |
|
375 | - break; |
|
376 | - case 'start_date': |
|
377 | - default: |
|
378 | - $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID'); |
|
379 | - break; |
|
380 | - } |
|
381 | - } |
|
382 | - return $SQL; |
|
383 | - } |
|
384 | - |
|
385 | - |
|
386 | - /** |
|
387 | - * @param string $SQL |
|
388 | - * @param string $join |
|
389 | - * @return string |
|
390 | - * @throws EE_Error |
|
391 | - * @throws InvalidArgumentException |
|
392 | - * @throws InvalidDataTypeException |
|
393 | - * @throws InvalidInterfaceException |
|
394 | - */ |
|
395 | - protected static function _posts_join_for_datetime($SQL = '', $join = '') |
|
396 | - { |
|
397 | - if (! empty($join)) { |
|
398 | - $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
399 | - if (strpos($SQL, $join) === false) { |
|
400 | - return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )'; |
|
401 | - } |
|
402 | - } |
|
403 | - return ''; |
|
404 | - } |
|
405 | - |
|
406 | - |
|
407 | - /** |
|
408 | - * @param string $SQL |
|
409 | - * @return string |
|
410 | - * @throws EE_Error |
|
411 | - * @throws InvalidArgumentException |
|
412 | - * @throws InvalidDataTypeException |
|
413 | - * @throws InvalidInterfaceException |
|
414 | - */ |
|
415 | - protected static function _posts_join_for_event_venue($SQL = '') |
|
416 | - { |
|
417 | - // Event Venue table name |
|
418 | - $event_venue_table = EEM_Event_Venue::instance()->table(); |
|
419 | - // generate conditions for: Event <=> Event Venue JOIN clause |
|
420 | - $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = '; |
|
421 | - $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name(); |
|
422 | - // don't add joins if they have already been added |
|
423 | - if (strpos($SQL, $event_to_event_venue_join) === false) { |
|
424 | - // Venue table name |
|
425 | - $venue_table = EEM_Venue::instance()->table(); |
|
426 | - // Venue table pk |
|
427 | - $venue_table_pk = EEM_Venue::instance()->primary_key_name(); |
|
428 | - // Venue Meta table name |
|
429 | - $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
430 | - // generate JOIN clause for: Event <=> Event Venue |
|
431 | - $venue_SQL = " LEFT JOIN $event_venue_table ON ( $event_to_event_venue_join )"; |
|
432 | - // generate JOIN clause for: Event Venue <=> Venue |
|
433 | - $venue_SQL .= " LEFT JOIN $venue_table as Venue ON ( $event_venue_table.$venue_table_pk = Venue.ID )"; |
|
434 | - // generate JOIN clause for: Venue <=> Venue Meta |
|
435 | - $venue_SQL .= " LEFT JOIN $venue_meta_table ON ( Venue.ID = $venue_meta_table.$venue_table_pk )"; |
|
436 | - unset($event_venue_table, $event_to_event_venue_join, $venue_table, $venue_table_pk, $venue_meta_table); |
|
437 | - return $venue_SQL; |
|
438 | - } |
|
439 | - unset($event_venue_table, $event_to_event_venue_join); |
|
440 | - return ''; |
|
441 | - } |
|
442 | - |
|
443 | - |
|
444 | - /** |
|
445 | - * @param string $SQL |
|
446 | - * @return string |
|
447 | - * @throws EE_Error |
|
448 | - * @throws InvalidArgumentException |
|
449 | - * @throws InvalidDataTypeException |
|
450 | - * @throws InvalidInterfaceException |
|
451 | - */ |
|
452 | - protected static function _posts_join_for_venue_state($SQL = '') |
|
453 | - { |
|
454 | - // Venue Meta table name |
|
455 | - $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
456 | - // State table name |
|
457 | - $state_table = EEM_State::instance()->table(); |
|
458 | - // State table pk |
|
459 | - $state_table_pk = EEM_State::instance()->primary_key_name(); |
|
460 | - // verify vars |
|
461 | - if ($venue_meta_table && $state_table && $state_table_pk) { |
|
462 | - // like: wp_esp_venue_meta.STA_ID = wp_esp_state.STA_ID |
|
463 | - $join = "$venue_meta_table.$state_table_pk = $state_table.$state_table_pk"; |
|
464 | - // don't add join if it has already been added |
|
465 | - if (strpos($SQL, $join) === false) { |
|
466 | - unset($state_table_pk, $venue_meta_table, $venue_table_pk); |
|
467 | - return " LEFT JOIN $state_table ON ( $join )"; |
|
468 | - } |
|
469 | - } |
|
470 | - unset($join, $state_table, $state_table_pk, $venue_meta_table, $venue_table_pk); |
|
471 | - return ''; |
|
472 | - } |
|
473 | - |
|
474 | - |
|
475 | - /** |
|
476 | - * @param string $SQL |
|
477 | - * @param WP_Query $wp_query |
|
478 | - * @return string |
|
479 | - * @throws EE_Error |
|
480 | - * @throws InvalidArgumentException |
|
481 | - * @throws InvalidDataTypeException |
|
482 | - * @throws InvalidInterfaceException |
|
483 | - */ |
|
484 | - public static function posts_where($SQL, WP_Query $wp_query) |
|
485 | - { |
|
486 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
487 | - // Show Expired ? |
|
488 | - $SQL .= EEH_Event_Query::posts_where_sql_for_show_expired(EEH_Event_Query::$_event_query_show_expired); |
|
489 | - // Category |
|
490 | - $SQL .= EEH_Event_Query::posts_where_sql_for_event_category_slug(EEH_Event_Query::$_event_query_category); |
|
491 | - // Start Date |
|
492 | - $SQL .= EEH_Event_Query::posts_where_sql_for_event_list_month(EEH_Event_Query::$_event_query_month); |
|
493 | - } |
|
494 | - return $SQL; |
|
495 | - } |
|
496 | - |
|
497 | - |
|
498 | - /** |
|
499 | - * @param boolean $show_expired if TRUE, then displayed past events |
|
500 | - * @return string |
|
501 | - * @throws EE_Error |
|
502 | - * @throws InvalidArgumentException |
|
503 | - * @throws InvalidDataTypeException |
|
504 | - * @throws InvalidInterfaceException |
|
505 | - */ |
|
506 | - public static function posts_where_sql_for_show_expired($show_expired = false) |
|
507 | - { |
|
508 | - return ! $show_expired |
|
509 | - ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' ' |
|
510 | - : ''; |
|
511 | - } |
|
512 | - |
|
513 | - |
|
514 | - /** |
|
515 | - * @param boolean $event_category_slug |
|
516 | - * @return string |
|
517 | - */ |
|
518 | - public static function posts_where_sql_for_event_category_slug($event_category_slug = null) |
|
519 | - { |
|
520 | - global $wpdb; |
|
521 | - if (! empty($event_category_slug)) { |
|
522 | - $event_category_slugs_array = array_map('trim', explode(',', $event_category_slug)); |
|
523 | - $event_category_slugs_prepare = implode(', ', array_fill(0, count($event_category_slugs_array), '%s')); |
|
524 | - return $wpdb->prepare( |
|
525 | - " AND {$wpdb->terms}.slug IN ({$event_category_slugs_prepare}) ", |
|
526 | - $event_category_slugs_array |
|
527 | - ); |
|
528 | - } |
|
529 | - return ''; |
|
530 | - } |
|
531 | - |
|
532 | - |
|
533 | - /** |
|
534 | - * @param boolean $month |
|
535 | - * @return string |
|
536 | - * @throws EE_Error |
|
537 | - * @throws InvalidArgumentException |
|
538 | - * @throws InvalidDataTypeException |
|
539 | - * @throws InvalidInterfaceException |
|
540 | - */ |
|
541 | - public static function posts_where_sql_for_event_list_month($month = null) |
|
542 | - { |
|
543 | - $SQL = ''; |
|
544 | - if (! empty($month)) { |
|
545 | - $datetime_table = EEM_Datetime::instance()->table(); |
|
546 | - // event start date is LESS than the end of the month ( so nothing that doesn't start until next month ) |
|
547 | - $SQL = " AND {$datetime_table}.DTT_EVT_start <= '"; |
|
548 | - $SQL .= date('Y-m-t 23:59:59', EEH_DTT_Helper::first_of_month_timestamp($month)) . "'"; |
|
549 | - // event end date is GREATER than the start of the month ( so nothing that ended before this month ) |
|
550 | - $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '"; |
|
551 | - $SQL .= date('Y-m-01 0:0:00', EEH_DTT_Helper::first_of_month_timestamp($month)) . "' "; |
|
552 | - } |
|
553 | - return $SQL; |
|
554 | - } |
|
555 | - |
|
556 | - |
|
557 | - /** |
|
558 | - * @param string $SQL |
|
559 | - * @param WP_Query $wp_query |
|
560 | - * @return string |
|
561 | - * @throws EE_Error |
|
562 | - * @throws InvalidArgumentException |
|
563 | - * @throws InvalidDataTypeException |
|
564 | - * @throws InvalidInterfaceException |
|
565 | - */ |
|
566 | - public static function posts_orderby($SQL, WP_Query $wp_query) |
|
567 | - { |
|
568 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
569 | - $SQL = EEH_Event_Query::posts_orderby_sql( |
|
570 | - EEH_Event_Query::$_event_query_orderby, |
|
571 | - EEH_Event_Query::$_event_query_sort |
|
572 | - ); |
|
573 | - } |
|
574 | - return $SQL; |
|
575 | - } |
|
576 | - |
|
577 | - |
|
578 | - /** |
|
579 | - * posts_orderby_sql |
|
580 | - * possible parameters: |
|
581 | - * ID |
|
582 | - * start_date |
|
583 | - * end_date |
|
584 | - * event_name |
|
585 | - * category_slug |
|
586 | - * ticket_start |
|
587 | - * ticket_end |
|
588 | - * venue_title |
|
589 | - * city |
|
590 | - * state |
|
591 | - * **IMPORTANT** |
|
592 | - * make sure to also send the $orderby_params array to the posts_join_for_orderby() method |
|
593 | - * or else some of the table references below will result in MySQL errors |
|
594 | - * |
|
595 | - * @param array $orderby_params |
|
596 | - * @param string $sort |
|
597 | - * @return string |
|
598 | - * @throws EE_Error |
|
599 | - * @throws InvalidArgumentException |
|
600 | - * @throws InvalidDataTypeException |
|
601 | - * @throws InvalidInterfaceException |
|
602 | - */ |
|
603 | - public static function posts_orderby_sql(array $orderby_params = [], $sort = 'ASC') |
|
604 | - { |
|
605 | - global $wpdb; |
|
606 | - $SQL = ''; |
|
607 | - $counter = 0; |
|
608 | - $sort = in_array($sort, ['ASC', 'asc', 'DESC', 'desc'], true) |
|
609 | - ? strtoupper($sort) |
|
610 | - : 'ASC'; |
|
611 | - // make sure 'orderby' is set in query params |
|
612 | - if (! isset(self::$_query_params['orderby'])) { |
|
613 | - self::$_query_params['orderby'] = []; |
|
614 | - } |
|
615 | - // loop thru $orderby_params (type cast as array) |
|
616 | - foreach ($orderby_params as $orderby) { |
|
617 | - // check if we have already added this param |
|
618 | - if (isset(self::$_query_params['orderby'][ $orderby ])) { |
|
619 | - // if so then remove from the $orderby_params so that the count() method below is accurate |
|
620 | - unset($orderby_params[ $orderby ]); |
|
621 | - // then bump ahead to the next param |
|
622 | - continue; |
|
623 | - } |
|
624 | - // this will ad a comma depending on whether this is the first or last param |
|
625 | - $glue = $counter === 0 || $counter === count($orderby_params) ? ' ' : ', '; |
|
626 | - // ok what's we dealing with? |
|
627 | - switch ($orderby) { |
|
628 | - case 'id': |
|
629 | - case 'ID': |
|
630 | - $SQL .= $glue . $wpdb->posts . '.ID ' . $sort; |
|
631 | - break; |
|
632 | - case 'end_date': |
|
633 | - $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort; |
|
634 | - break; |
|
635 | - case 'event_name': |
|
636 | - $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort; |
|
637 | - break; |
|
638 | - case 'category_slug': |
|
639 | - $SQL .= $glue . $wpdb->terms . '.slug ' . $sort; |
|
640 | - break; |
|
641 | - case 'ticket_start': |
|
642 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort; |
|
643 | - break; |
|
644 | - case 'ticket_end': |
|
645 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort; |
|
646 | - break; |
|
647 | - case 'venue_title': |
|
648 | - $SQL .= $glue . 'venue_title ' . $sort; |
|
649 | - break; |
|
650 | - case 'city': |
|
651 | - $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort; |
|
652 | - break; |
|
653 | - case 'state': |
|
654 | - $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort; |
|
655 | - break; |
|
656 | - case 'start_date': |
|
657 | - default: |
|
658 | - $SQL .= $glue . ' event_start_date ' . $sort; |
|
659 | - break; |
|
660 | - } |
|
661 | - // add to array of orderby params that have been added |
|
662 | - self::$_query_params['orderby'][ $orderby ] = true; |
|
663 | - $counter++; |
|
664 | - } |
|
665 | - return $SQL; |
|
666 | - } |
|
667 | - |
|
668 | - |
|
669 | - /** |
|
670 | - * @return RequestInterface |
|
671 | - * @since 4.10.14.p |
|
672 | - */ |
|
673 | - private static function getRequest() |
|
674 | - { |
|
675 | - return LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
676 | - } |
|
20 | + /** |
|
21 | + * Start Date |
|
22 | + * |
|
23 | + * @var $_event_query_month |
|
24 | + */ |
|
25 | + protected static $_event_query_month; |
|
26 | + |
|
27 | + /** |
|
28 | + * Category |
|
29 | + * |
|
30 | + * @var $_event_query_category |
|
31 | + */ |
|
32 | + protected static $_event_query_category; |
|
33 | + |
|
34 | + /** |
|
35 | + * whether to display expired events in the event list |
|
36 | + * |
|
37 | + * @var bool $_show_expired |
|
38 | + */ |
|
39 | + protected static $_event_query_show_expired = false; |
|
40 | + |
|
41 | + /** |
|
42 | + * list of params for controlling how the query results are ordered |
|
43 | + * |
|
44 | + * @var array $_event_query_orderby |
|
45 | + */ |
|
46 | + protected static $_event_query_orderby = []; |
|
47 | + |
|
48 | + /** |
|
49 | + * direction list is sorted |
|
50 | + * |
|
51 | + * @var string $_event_query_sort |
|
52 | + */ |
|
53 | + protected static $_event_query_sort; |
|
54 | + |
|
55 | + /** |
|
56 | + * list of params used to build the query's various clauses |
|
57 | + * |
|
58 | + * @var $_query_params |
|
59 | + */ |
|
60 | + protected static $_query_params = []; |
|
61 | + |
|
62 | + |
|
63 | + /** |
|
64 | + * @return void |
|
65 | + */ |
|
66 | + public static function add_query_filters() |
|
67 | + { |
|
68 | + // add query filters |
|
69 | + add_action('pre_get_posts', ['EEH_Event_Query', 'filter_query_parts'], 10, 1); |
|
70 | + } |
|
71 | + |
|
72 | + |
|
73 | + /** |
|
74 | + * @param WP_Query $WP_Query |
|
75 | + * @return bool |
|
76 | + */ |
|
77 | + public static function apply_query_filters(WP_Query $WP_Query) |
|
78 | + { |
|
79 | + return ( |
|
80 | + isset($WP_Query->query['post_type']) |
|
81 | + && $WP_Query->query['post_type'] === 'espresso_events' |
|
82 | + ) |
|
83 | + || apply_filters('FHEE__EEH_Event_Query__apply_query_filters', false); |
|
84 | + } |
|
85 | + |
|
86 | + |
|
87 | + /** |
|
88 | + * @param WP_Query $WP_Query |
|
89 | + */ |
|
90 | + public static function filter_query_parts(WP_Query $WP_Query) |
|
91 | + { |
|
92 | + // ONLY add our filters if this isn't the main wp_query, |
|
93 | + // because if this is the main wp_query we already have |
|
94 | + // our cpt strategies take care of adding things in. |
|
95 | + if ($WP_Query instanceof WP_Query && ! $WP_Query->is_main_query()) { |
|
96 | + // build event list query |
|
97 | + add_filter('posts_fields', ['EEH_Event_Query', 'posts_fields'], 10, 2); |
|
98 | + add_filter('posts_join', ['EEH_Event_Query', 'posts_join'], 10, 2); |
|
99 | + add_filter('posts_where', ['EEH_Event_Query', 'posts_where'], 10, 2); |
|
100 | + add_filter('posts_orderby', ['EEH_Event_Query', 'posts_orderby'], 10, 2); |
|
101 | + add_filter('posts_clauses_request', ['EEH_Event_Query', 'posts_clauses'], 10, 2); |
|
102 | + } |
|
103 | + } |
|
104 | + |
|
105 | + |
|
106 | + /** |
|
107 | + * @param string $month |
|
108 | + * @param string $category |
|
109 | + * @param bool $show_expired |
|
110 | + * @param string $orderby |
|
111 | + * @param string $sort |
|
112 | + * @throws InvalidArgumentException |
|
113 | + * @throws InvalidDataTypeException |
|
114 | + * @throws InvalidInterfaceException |
|
115 | + */ |
|
116 | + public static function set_query_params( |
|
117 | + $month = '', |
|
118 | + $category = '', |
|
119 | + $show_expired = false, |
|
120 | + $orderby = 'start_date', |
|
121 | + $sort = 'ASC' |
|
122 | + ) { |
|
123 | + self::$_query_params = []; |
|
124 | + EEH_Event_Query::$_event_query_month = EEH_Event_Query::_display_month($month); |
|
125 | + EEH_Event_Query::$_event_query_category = EEH_Event_Query::_event_category_slug($category); |
|
126 | + EEH_Event_Query::$_event_query_show_expired = EEH_Event_Query::_show_expired($show_expired); |
|
127 | + EEH_Event_Query::$_event_query_orderby = EEH_Event_Query::_orderby($orderby); |
|
128 | + EEH_Event_Query::$_event_query_sort = EEH_Event_Query::_sort($sort); |
|
129 | + } |
|
130 | + |
|
131 | + |
|
132 | + /** |
|
133 | + * what month should the event list display events for? |
|
134 | + * |
|
135 | + * @param string $month |
|
136 | + * @return string |
|
137 | + * @throws InvalidArgumentException |
|
138 | + * @throws InvalidDataTypeException |
|
139 | + * @throws InvalidInterfaceException |
|
140 | + */ |
|
141 | + private static function _display_month($month = '') |
|
142 | + { |
|
143 | + return self::getRequest()->getRequestParam('event_query_month', $month); |
|
144 | + } |
|
145 | + |
|
146 | + |
|
147 | + /** |
|
148 | + * @param string $category |
|
149 | + * @return string |
|
150 | + * @throws InvalidArgumentException |
|
151 | + * @throws InvalidDataTypeException |
|
152 | + * @throws InvalidInterfaceException |
|
153 | + */ |
|
154 | + private static function _event_category_slug($category = '') |
|
155 | + { |
|
156 | + return self::getRequest()->getRequestParam('event_query_category', $category); |
|
157 | + } |
|
158 | + |
|
159 | + |
|
160 | + /** |
|
161 | + * @param bool $show_expired |
|
162 | + * @return bool |
|
163 | + * @throws InvalidArgumentException |
|
164 | + * @throws InvalidDataTypeException |
|
165 | + * @throws InvalidInterfaceException |
|
166 | + */ |
|
167 | + private static function _show_expired($show_expired = false) |
|
168 | + { |
|
169 | + // override default expired option if set via filter |
|
170 | + return self::getRequest()->getRequestParam('event_query_show_expired', $show_expired, 'bool'); |
|
171 | + } |
|
172 | + |
|
173 | + |
|
174 | + /** |
|
175 | + * @param string $orderby |
|
176 | + * @return array |
|
177 | + * @throws InvalidArgumentException |
|
178 | + * @throws InvalidDataTypeException |
|
179 | + * @throws InvalidInterfaceException |
|
180 | + */ |
|
181 | + private static function _orderby($orderby = 'start_date') |
|
182 | + { |
|
183 | + $event_query_orderby = self::getRequest()->getRequestParam('event_query_orderby', $orderby); |
|
184 | + $event_query_orderby = is_array($event_query_orderby) |
|
185 | + ? $event_query_orderby |
|
186 | + : explode(',', $event_query_orderby); |
|
187 | + $event_query_orderby = array_map('trim', $event_query_orderby); |
|
188 | + return array_map('sanitize_text_field', $event_query_orderby); |
|
189 | + } |
|
190 | + |
|
191 | + |
|
192 | + /** |
|
193 | + * @param string $sort |
|
194 | + * @return string |
|
195 | + * @throws InvalidArgumentException |
|
196 | + * @throws InvalidDataTypeException |
|
197 | + * @throws InvalidInterfaceException |
|
198 | + */ |
|
199 | + private static function _sort($sort = 'ASC') |
|
200 | + { |
|
201 | + $sort = self::getRequest()->getRequestParam('event_query_sort', $sort); |
|
202 | + return in_array($sort, ['ASC', 'asc', 'DESC', 'desc'], true) |
|
203 | + ? strtoupper($sort) |
|
204 | + : 'ASC'; |
|
205 | + } |
|
206 | + |
|
207 | + |
|
208 | + /** |
|
209 | + * Filters the clauses for the WP_Query object |
|
210 | + * |
|
211 | + * @param array $clauses array of clauses |
|
212 | + * @param WP_Query $wp_query |
|
213 | + * @return array array of clauses |
|
214 | + */ |
|
215 | + public static function posts_clauses($clauses, WP_Query $wp_query) |
|
216 | + { |
|
217 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
218 | + global $wpdb; |
|
219 | + $clauses['groupby'] = $wpdb->posts . '.ID '; |
|
220 | + } |
|
221 | + return $clauses; |
|
222 | + } |
|
223 | + |
|
224 | + |
|
225 | + /** |
|
226 | + * @param string $SQL |
|
227 | + * @param WP_Query $wp_query |
|
228 | + * @return string |
|
229 | + * @throws EE_Error |
|
230 | + * @throws InvalidArgumentException |
|
231 | + * @throws InvalidDataTypeException |
|
232 | + * @throws InvalidInterfaceException |
|
233 | + */ |
|
234 | + public static function posts_fields($SQL, WP_Query $wp_query) |
|
235 | + { |
|
236 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
237 | + // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement |
|
238 | + $SQL .= EEH_Event_Query::posts_fields_sql_for_orderby(EEH_Event_Query::$_event_query_orderby); |
|
239 | + } |
|
240 | + return $SQL; |
|
241 | + } |
|
242 | + |
|
243 | + |
|
244 | + /** |
|
245 | + * @param array $orderby_params |
|
246 | + * @return string |
|
247 | + * @throws EE_Error |
|
248 | + * @throws InvalidArgumentException |
|
249 | + * @throws InvalidDataTypeException |
|
250 | + * @throws InvalidInterfaceException |
|
251 | + */ |
|
252 | + public static function posts_fields_sql_for_orderby(array $orderby_params = []) |
|
253 | + { |
|
254 | + $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
255 | + foreach ($orderby_params as $orderby) { |
|
256 | + switch ($orderby) { |
|
257 | + case 'ticket_start': |
|
258 | + $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date'; |
|
259 | + break; |
|
260 | + case 'ticket_end': |
|
261 | + $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date'; |
|
262 | + break; |
|
263 | + case 'venue_title': |
|
264 | + $SQL .= ', Venue.post_title AS venue_title'; |
|
265 | + break; |
|
266 | + case 'city': |
|
267 | + $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city'; |
|
268 | + break; |
|
269 | + case 'state': |
|
270 | + $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name'; |
|
271 | + break; |
|
272 | + } |
|
273 | + } |
|
274 | + return $SQL; |
|
275 | + } |
|
276 | + |
|
277 | + |
|
278 | + /** |
|
279 | + * @param string $SQL |
|
280 | + * @param WP_Query $wp_query |
|
281 | + * @return string |
|
282 | + * @throws EE_Error |
|
283 | + * @throws InvalidArgumentException |
|
284 | + * @throws InvalidDataTypeException |
|
285 | + * @throws InvalidInterfaceException |
|
286 | + */ |
|
287 | + public static function posts_join($SQL, WP_Query $wp_query) |
|
288 | + { |
|
289 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
290 | + // Category |
|
291 | + $SQL = EEH_Event_Query::posts_join_sql_for_show_expired($SQL, EEH_Event_Query::$_event_query_show_expired); |
|
292 | + $SQL = EEH_Event_Query::posts_join_sql_for_terms($SQL, EEH_Event_Query::$_event_query_category); |
|
293 | + $SQL = EEH_Event_Query::posts_join_for_orderby($SQL, EEH_Event_Query::$_event_query_orderby); |
|
294 | + } |
|
295 | + return $SQL; |
|
296 | + } |
|
297 | + |
|
298 | + |
|
299 | + /** |
|
300 | + * @param string $SQL |
|
301 | + * @param boolean $show_expired if TRUE, then displayed past events |
|
302 | + * @return string |
|
303 | + * @throws EE_Error |
|
304 | + * @throws InvalidArgumentException |
|
305 | + * @throws InvalidDataTypeException |
|
306 | + * @throws InvalidInterfaceException |
|
307 | + */ |
|
308 | + public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false) |
|
309 | + { |
|
310 | + if (! $show_expired) { |
|
311 | + $join = EEM_Event::instance()->table() . '.ID = '; |
|
312 | + $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
313 | + // don't add if this is already in the SQL |
|
314 | + if (strpos($SQL, $join) === false) { |
|
315 | + $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) '; |
|
316 | + } |
|
317 | + } |
|
318 | + return $SQL; |
|
319 | + } |
|
320 | + |
|
321 | + |
|
322 | + /** |
|
323 | + * @param string $SQL |
|
324 | + * @param string $join_terms pass TRUE or term string, doesn't really matter since this value doesn't really get |
|
325 | + * used for anything yet |
|
326 | + * @return string |
|
327 | + */ |
|
328 | + public static function posts_join_sql_for_terms($SQL = '', $join_terms = '') |
|
329 | + { |
|
330 | + if (! empty($join_terms)) { |
|
331 | + global $wpdb; |
|
332 | + $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)"; |
|
333 | + $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)"; |
|
334 | + $SQL .= " LEFT JOIN $wpdb->terms ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id) "; |
|
335 | + } |
|
336 | + return $SQL; |
|
337 | + } |
|
338 | + |
|
339 | + |
|
340 | + /** |
|
341 | + * usage: $SQL .= EEH_Event_Query::posts_join_for_orderby( $orderby_params ); |
|
342 | + * |
|
343 | + * @param string $SQL |
|
344 | + * @param array $orderby_params |
|
345 | + * @return string |
|
346 | + * @throws EE_Error |
|
347 | + * @throws InvalidArgumentException |
|
348 | + * @throws InvalidDataTypeException |
|
349 | + * @throws InvalidInterfaceException |
|
350 | + */ |
|
351 | + public static function posts_join_for_orderby($SQL = '', array $orderby_params = []) |
|
352 | + { |
|
353 | + foreach ($orderby_params as $orderby) { |
|
354 | + switch ($orderby) { |
|
355 | + case 'ticket_start': |
|
356 | + case 'ticket_end': |
|
357 | + $SQL .= EEH_Event_Query::_posts_join_for_datetime( |
|
358 | + $SQL, |
|
359 | + EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name() |
|
360 | + ); |
|
361 | + $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table(); |
|
362 | + $SQL .= ' ON ('; |
|
363 | + $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
364 | + $SQL .= ' = '; |
|
365 | + $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
366 | + $SQL .= ' )'; |
|
367 | + break; |
|
368 | + case 'venue_title': |
|
369 | + case 'city': |
|
370 | + $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
371 | + break; |
|
372 | + case 'state': |
|
373 | + $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
374 | + $SQL .= EEH_Event_Query::_posts_join_for_venue_state($SQL); |
|
375 | + break; |
|
376 | + case 'start_date': |
|
377 | + default: |
|
378 | + $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID'); |
|
379 | + break; |
|
380 | + } |
|
381 | + } |
|
382 | + return $SQL; |
|
383 | + } |
|
384 | + |
|
385 | + |
|
386 | + /** |
|
387 | + * @param string $SQL |
|
388 | + * @param string $join |
|
389 | + * @return string |
|
390 | + * @throws EE_Error |
|
391 | + * @throws InvalidArgumentException |
|
392 | + * @throws InvalidDataTypeException |
|
393 | + * @throws InvalidInterfaceException |
|
394 | + */ |
|
395 | + protected static function _posts_join_for_datetime($SQL = '', $join = '') |
|
396 | + { |
|
397 | + if (! empty($join)) { |
|
398 | + $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
399 | + if (strpos($SQL, $join) === false) { |
|
400 | + return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )'; |
|
401 | + } |
|
402 | + } |
|
403 | + return ''; |
|
404 | + } |
|
405 | + |
|
406 | + |
|
407 | + /** |
|
408 | + * @param string $SQL |
|
409 | + * @return string |
|
410 | + * @throws EE_Error |
|
411 | + * @throws InvalidArgumentException |
|
412 | + * @throws InvalidDataTypeException |
|
413 | + * @throws InvalidInterfaceException |
|
414 | + */ |
|
415 | + protected static function _posts_join_for_event_venue($SQL = '') |
|
416 | + { |
|
417 | + // Event Venue table name |
|
418 | + $event_venue_table = EEM_Event_Venue::instance()->table(); |
|
419 | + // generate conditions for: Event <=> Event Venue JOIN clause |
|
420 | + $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = '; |
|
421 | + $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name(); |
|
422 | + // don't add joins if they have already been added |
|
423 | + if (strpos($SQL, $event_to_event_venue_join) === false) { |
|
424 | + // Venue table name |
|
425 | + $venue_table = EEM_Venue::instance()->table(); |
|
426 | + // Venue table pk |
|
427 | + $venue_table_pk = EEM_Venue::instance()->primary_key_name(); |
|
428 | + // Venue Meta table name |
|
429 | + $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
430 | + // generate JOIN clause for: Event <=> Event Venue |
|
431 | + $venue_SQL = " LEFT JOIN $event_venue_table ON ( $event_to_event_venue_join )"; |
|
432 | + // generate JOIN clause for: Event Venue <=> Venue |
|
433 | + $venue_SQL .= " LEFT JOIN $venue_table as Venue ON ( $event_venue_table.$venue_table_pk = Venue.ID )"; |
|
434 | + // generate JOIN clause for: Venue <=> Venue Meta |
|
435 | + $venue_SQL .= " LEFT JOIN $venue_meta_table ON ( Venue.ID = $venue_meta_table.$venue_table_pk )"; |
|
436 | + unset($event_venue_table, $event_to_event_venue_join, $venue_table, $venue_table_pk, $venue_meta_table); |
|
437 | + return $venue_SQL; |
|
438 | + } |
|
439 | + unset($event_venue_table, $event_to_event_venue_join); |
|
440 | + return ''; |
|
441 | + } |
|
442 | + |
|
443 | + |
|
444 | + /** |
|
445 | + * @param string $SQL |
|
446 | + * @return string |
|
447 | + * @throws EE_Error |
|
448 | + * @throws InvalidArgumentException |
|
449 | + * @throws InvalidDataTypeException |
|
450 | + * @throws InvalidInterfaceException |
|
451 | + */ |
|
452 | + protected static function _posts_join_for_venue_state($SQL = '') |
|
453 | + { |
|
454 | + // Venue Meta table name |
|
455 | + $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
456 | + // State table name |
|
457 | + $state_table = EEM_State::instance()->table(); |
|
458 | + // State table pk |
|
459 | + $state_table_pk = EEM_State::instance()->primary_key_name(); |
|
460 | + // verify vars |
|
461 | + if ($venue_meta_table && $state_table && $state_table_pk) { |
|
462 | + // like: wp_esp_venue_meta.STA_ID = wp_esp_state.STA_ID |
|
463 | + $join = "$venue_meta_table.$state_table_pk = $state_table.$state_table_pk"; |
|
464 | + // don't add join if it has already been added |
|
465 | + if (strpos($SQL, $join) === false) { |
|
466 | + unset($state_table_pk, $venue_meta_table, $venue_table_pk); |
|
467 | + return " LEFT JOIN $state_table ON ( $join )"; |
|
468 | + } |
|
469 | + } |
|
470 | + unset($join, $state_table, $state_table_pk, $venue_meta_table, $venue_table_pk); |
|
471 | + return ''; |
|
472 | + } |
|
473 | + |
|
474 | + |
|
475 | + /** |
|
476 | + * @param string $SQL |
|
477 | + * @param WP_Query $wp_query |
|
478 | + * @return string |
|
479 | + * @throws EE_Error |
|
480 | + * @throws InvalidArgumentException |
|
481 | + * @throws InvalidDataTypeException |
|
482 | + * @throws InvalidInterfaceException |
|
483 | + */ |
|
484 | + public static function posts_where($SQL, WP_Query $wp_query) |
|
485 | + { |
|
486 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
487 | + // Show Expired ? |
|
488 | + $SQL .= EEH_Event_Query::posts_where_sql_for_show_expired(EEH_Event_Query::$_event_query_show_expired); |
|
489 | + // Category |
|
490 | + $SQL .= EEH_Event_Query::posts_where_sql_for_event_category_slug(EEH_Event_Query::$_event_query_category); |
|
491 | + // Start Date |
|
492 | + $SQL .= EEH_Event_Query::posts_where_sql_for_event_list_month(EEH_Event_Query::$_event_query_month); |
|
493 | + } |
|
494 | + return $SQL; |
|
495 | + } |
|
496 | + |
|
497 | + |
|
498 | + /** |
|
499 | + * @param boolean $show_expired if TRUE, then displayed past events |
|
500 | + * @return string |
|
501 | + * @throws EE_Error |
|
502 | + * @throws InvalidArgumentException |
|
503 | + * @throws InvalidDataTypeException |
|
504 | + * @throws InvalidInterfaceException |
|
505 | + */ |
|
506 | + public static function posts_where_sql_for_show_expired($show_expired = false) |
|
507 | + { |
|
508 | + return ! $show_expired |
|
509 | + ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' ' |
|
510 | + : ''; |
|
511 | + } |
|
512 | + |
|
513 | + |
|
514 | + /** |
|
515 | + * @param boolean $event_category_slug |
|
516 | + * @return string |
|
517 | + */ |
|
518 | + public static function posts_where_sql_for_event_category_slug($event_category_slug = null) |
|
519 | + { |
|
520 | + global $wpdb; |
|
521 | + if (! empty($event_category_slug)) { |
|
522 | + $event_category_slugs_array = array_map('trim', explode(',', $event_category_slug)); |
|
523 | + $event_category_slugs_prepare = implode(', ', array_fill(0, count($event_category_slugs_array), '%s')); |
|
524 | + return $wpdb->prepare( |
|
525 | + " AND {$wpdb->terms}.slug IN ({$event_category_slugs_prepare}) ", |
|
526 | + $event_category_slugs_array |
|
527 | + ); |
|
528 | + } |
|
529 | + return ''; |
|
530 | + } |
|
531 | + |
|
532 | + |
|
533 | + /** |
|
534 | + * @param boolean $month |
|
535 | + * @return string |
|
536 | + * @throws EE_Error |
|
537 | + * @throws InvalidArgumentException |
|
538 | + * @throws InvalidDataTypeException |
|
539 | + * @throws InvalidInterfaceException |
|
540 | + */ |
|
541 | + public static function posts_where_sql_for_event_list_month($month = null) |
|
542 | + { |
|
543 | + $SQL = ''; |
|
544 | + if (! empty($month)) { |
|
545 | + $datetime_table = EEM_Datetime::instance()->table(); |
|
546 | + // event start date is LESS than the end of the month ( so nothing that doesn't start until next month ) |
|
547 | + $SQL = " AND {$datetime_table}.DTT_EVT_start <= '"; |
|
548 | + $SQL .= date('Y-m-t 23:59:59', EEH_DTT_Helper::first_of_month_timestamp($month)) . "'"; |
|
549 | + // event end date is GREATER than the start of the month ( so nothing that ended before this month ) |
|
550 | + $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '"; |
|
551 | + $SQL .= date('Y-m-01 0:0:00', EEH_DTT_Helper::first_of_month_timestamp($month)) . "' "; |
|
552 | + } |
|
553 | + return $SQL; |
|
554 | + } |
|
555 | + |
|
556 | + |
|
557 | + /** |
|
558 | + * @param string $SQL |
|
559 | + * @param WP_Query $wp_query |
|
560 | + * @return string |
|
561 | + * @throws EE_Error |
|
562 | + * @throws InvalidArgumentException |
|
563 | + * @throws InvalidDataTypeException |
|
564 | + * @throws InvalidInterfaceException |
|
565 | + */ |
|
566 | + public static function posts_orderby($SQL, WP_Query $wp_query) |
|
567 | + { |
|
568 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
569 | + $SQL = EEH_Event_Query::posts_orderby_sql( |
|
570 | + EEH_Event_Query::$_event_query_orderby, |
|
571 | + EEH_Event_Query::$_event_query_sort |
|
572 | + ); |
|
573 | + } |
|
574 | + return $SQL; |
|
575 | + } |
|
576 | + |
|
577 | + |
|
578 | + /** |
|
579 | + * posts_orderby_sql |
|
580 | + * possible parameters: |
|
581 | + * ID |
|
582 | + * start_date |
|
583 | + * end_date |
|
584 | + * event_name |
|
585 | + * category_slug |
|
586 | + * ticket_start |
|
587 | + * ticket_end |
|
588 | + * venue_title |
|
589 | + * city |
|
590 | + * state |
|
591 | + * **IMPORTANT** |
|
592 | + * make sure to also send the $orderby_params array to the posts_join_for_orderby() method |
|
593 | + * or else some of the table references below will result in MySQL errors |
|
594 | + * |
|
595 | + * @param array $orderby_params |
|
596 | + * @param string $sort |
|
597 | + * @return string |
|
598 | + * @throws EE_Error |
|
599 | + * @throws InvalidArgumentException |
|
600 | + * @throws InvalidDataTypeException |
|
601 | + * @throws InvalidInterfaceException |
|
602 | + */ |
|
603 | + public static function posts_orderby_sql(array $orderby_params = [], $sort = 'ASC') |
|
604 | + { |
|
605 | + global $wpdb; |
|
606 | + $SQL = ''; |
|
607 | + $counter = 0; |
|
608 | + $sort = in_array($sort, ['ASC', 'asc', 'DESC', 'desc'], true) |
|
609 | + ? strtoupper($sort) |
|
610 | + : 'ASC'; |
|
611 | + // make sure 'orderby' is set in query params |
|
612 | + if (! isset(self::$_query_params['orderby'])) { |
|
613 | + self::$_query_params['orderby'] = []; |
|
614 | + } |
|
615 | + // loop thru $orderby_params (type cast as array) |
|
616 | + foreach ($orderby_params as $orderby) { |
|
617 | + // check if we have already added this param |
|
618 | + if (isset(self::$_query_params['orderby'][ $orderby ])) { |
|
619 | + // if so then remove from the $orderby_params so that the count() method below is accurate |
|
620 | + unset($orderby_params[ $orderby ]); |
|
621 | + // then bump ahead to the next param |
|
622 | + continue; |
|
623 | + } |
|
624 | + // this will ad a comma depending on whether this is the first or last param |
|
625 | + $glue = $counter === 0 || $counter === count($orderby_params) ? ' ' : ', '; |
|
626 | + // ok what's we dealing with? |
|
627 | + switch ($orderby) { |
|
628 | + case 'id': |
|
629 | + case 'ID': |
|
630 | + $SQL .= $glue . $wpdb->posts . '.ID ' . $sort; |
|
631 | + break; |
|
632 | + case 'end_date': |
|
633 | + $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort; |
|
634 | + break; |
|
635 | + case 'event_name': |
|
636 | + $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort; |
|
637 | + break; |
|
638 | + case 'category_slug': |
|
639 | + $SQL .= $glue . $wpdb->terms . '.slug ' . $sort; |
|
640 | + break; |
|
641 | + case 'ticket_start': |
|
642 | + $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort; |
|
643 | + break; |
|
644 | + case 'ticket_end': |
|
645 | + $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort; |
|
646 | + break; |
|
647 | + case 'venue_title': |
|
648 | + $SQL .= $glue . 'venue_title ' . $sort; |
|
649 | + break; |
|
650 | + case 'city': |
|
651 | + $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort; |
|
652 | + break; |
|
653 | + case 'state': |
|
654 | + $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort; |
|
655 | + break; |
|
656 | + case 'start_date': |
|
657 | + default: |
|
658 | + $SQL .= $glue . ' event_start_date ' . $sort; |
|
659 | + break; |
|
660 | + } |
|
661 | + // add to array of orderby params that have been added |
|
662 | + self::$_query_params['orderby'][ $orderby ] = true; |
|
663 | + $counter++; |
|
664 | + } |
|
665 | + return $SQL; |
|
666 | + } |
|
667 | + |
|
668 | + |
|
669 | + /** |
|
670 | + * @return RequestInterface |
|
671 | + * @since 4.10.14.p |
|
672 | + */ |
|
673 | + private static function getRequest() |
|
674 | + { |
|
675 | + return LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
676 | + } |
|
677 | 677 | } |
@@ -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; |
@@ -417,9 +417,9 @@ discard block |
||
417 | 417 | // set some defaults |
418 | 418 | foreach ($this->_default_session_vars as $key => $default_var) { |
419 | 419 | if (is_array($default_var)) { |
420 | - $this->_session_data[ $key ] = array(); |
|
420 | + $this->_session_data[$key] = array(); |
|
421 | 421 | } else { |
422 | - $this->_session_data[ $key ] = ''; |
|
422 | + $this->_session_data[$key] = ''; |
|
423 | 423 | } |
424 | 424 | } |
425 | 425 | } |
@@ -555,8 +555,8 @@ discard block |
||
555 | 555 | $this->reset_checkout(); |
556 | 556 | $this->reset_transaction(); |
557 | 557 | } |
558 | - if (! empty($key)) { |
|
559 | - return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null; |
|
558 | + if ( ! empty($key)) { |
|
559 | + return isset($this->_session_data[$key]) ? $this->_session_data[$key] : null; |
|
560 | 560 | } |
561 | 561 | return $this->_session_data; |
562 | 562 | } |
@@ -584,7 +584,7 @@ discard block |
||
584 | 584 | return false; |
585 | 585 | } |
586 | 586 | foreach ($data as $key => $value) { |
587 | - if (isset($this->_default_session_vars[ $key ])) { |
|
587 | + if (isset($this->_default_session_vars[$key])) { |
|
588 | 588 | EE_Error::add_error( |
589 | 589 | sprintf( |
590 | 590 | esc_html__( |
@@ -599,7 +599,7 @@ discard block |
||
599 | 599 | ); |
600 | 600 | return false; |
601 | 601 | } |
602 | - $this->_session_data[ $key ] = $value; |
|
602 | + $this->_session_data[$key] = $value; |
|
603 | 603 | $this->setSaveState(); |
604 | 604 | } |
605 | 605 | return true; |
@@ -630,7 +630,7 @@ discard block |
||
630 | 630 | $this->_user_agent = $this->request->userAgent(); |
631 | 631 | // now let's retrieve what's in the db |
632 | 632 | $session_data = $this->_retrieve_session_data(); |
633 | - if (! empty($session_data)) { |
|
633 | + if ( ! empty($session_data)) { |
|
634 | 634 | // get the current time in UTC |
635 | 635 | $this->_time = $this->_time !== null ? $this->_time : time(); |
636 | 636 | // and reset the session expiration |
@@ -641,7 +641,7 @@ discard block |
||
641 | 641 | // set initial site access time and the session expiration |
642 | 642 | $this->_set_init_access_and_expiration(); |
643 | 643 | // set referer |
644 | - $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = esc_attr( |
|
644 | + $this->_session_data['pages_visited'][$this->_session_data['init_access']] = esc_attr( |
|
645 | 645 | $this->request->getServerParam('HTTP_REFERER') |
646 | 646 | ); |
647 | 647 | // no previous session = go back and create one (on top of the data above) |
@@ -679,7 +679,7 @@ discard block |
||
679 | 679 | */ |
680 | 680 | protected function _retrieve_session_data() |
681 | 681 | { |
682 | - $ssn_key = EE_Session::session_id_prefix . $this->_sid; |
|
682 | + $ssn_key = EE_Session::session_id_prefix.$this->_sid; |
|
683 | 683 | try { |
684 | 684 | // we're using WP's Transient API to store session data using the PHP session ID as the option name |
685 | 685 | $session_data = $this->cache_storage->get($ssn_key, false); |
@@ -688,7 +688,7 @@ discard block |
||
688 | 688 | } |
689 | 689 | if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
690 | 690 | $hash_check = $this->cache_storage->get( |
691 | - EE_Session::hash_check_prefix . $this->_sid, |
|
691 | + EE_Session::hash_check_prefix.$this->_sid, |
|
692 | 692 | false |
693 | 693 | ); |
694 | 694 | if ($hash_check && $hash_check !== md5($session_data)) { |
@@ -698,7 +698,7 @@ discard block |
||
698 | 698 | 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.', |
699 | 699 | 'event_espresso' |
700 | 700 | ), |
701 | - EE_Session::session_id_prefix . $this->_sid |
|
701 | + EE_Session::session_id_prefix.$this->_sid |
|
702 | 702 | ), |
703 | 703 | __FILE__, |
704 | 704 | __FUNCTION__, |
@@ -712,17 +712,17 @@ discard block |
||
712 | 712 | $row = $wpdb->get_row( |
713 | 713 | $wpdb->prepare( |
714 | 714 | "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", |
715 | - '_transient_' . $ssn_key |
|
715 | + '_transient_'.$ssn_key |
|
716 | 716 | ) |
717 | 717 | ); |
718 | 718 | $session_data = is_object($row) ? $row->option_value : null; |
719 | 719 | if ($session_data) { |
720 | 720 | $session_data = preg_replace_callback( |
721 | 721 | '!s:(d+):"(.*?)";!', |
722 | - function ($match) { |
|
722 | + function($match) { |
|
723 | 723 | return $match[1] === strlen($match[2]) |
724 | 724 | ? $match[0] |
725 | - : 's:' . strlen($match[2]) . ':"' . $match[2] . '";'; |
|
725 | + : 's:'.strlen($match[2]).':"'.$match[2].'";'; |
|
726 | 726 | }, |
727 | 727 | $session_data |
728 | 728 | ); |
@@ -733,7 +733,7 @@ discard block |
||
733 | 733 | $session_data = $this->encryption instanceof EE_Encryption |
734 | 734 | ? $this->encryption->base64_string_decode($session_data) |
735 | 735 | : $session_data; |
736 | - if (! is_array($session_data)) { |
|
736 | + if ( ! is_array($session_data)) { |
|
737 | 737 | try { |
738 | 738 | $session_data = maybe_unserialize($session_data); |
739 | 739 | } catch (Exception $e) { |
@@ -747,21 +747,21 @@ discard block |
||
747 | 747 | . '</pre><br>' |
748 | 748 | . $this->find_serialize_error($session_data) |
749 | 749 | : ''; |
750 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
750 | + $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid); |
|
751 | 751 | throw new InvalidSessionDataException($msg, 0, $e); |
752 | 752 | } |
753 | 753 | } |
754 | 754 | // just a check to make sure the session array is indeed an array |
755 | - if (! is_array($session_data)) { |
|
755 | + if ( ! is_array($session_data)) { |
|
756 | 756 | // no?!?! then something is wrong |
757 | 757 | $msg = esc_html__( |
758 | 758 | 'The session data is missing, invalid, or corrupted.', |
759 | 759 | 'event_espresso' |
760 | 760 | ); |
761 | 761 | $msg .= WP_DEBUG |
762 | - ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data) |
|
762 | + ? '<br><pre>'.print_r($session_data, true).'</pre><br>'.$this->find_serialize_error($session_data) |
|
763 | 763 | : ''; |
764 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
764 | + $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid); |
|
765 | 765 | throw new InvalidSessionDataException($msg); |
766 | 766 | } |
767 | 767 | if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) { |
@@ -787,7 +787,7 @@ discard block |
||
787 | 787 | // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length |
788 | 788 | $session_id = $this->request->requestParamIsSet('EESID') |
789 | 789 | ? $this->request->getRequestParam('EESID') |
790 | - : md5(session_id() . get_current_blog_id() . $this->_get_sid_salt()); |
|
790 | + : md5(session_id().get_current_blog_id().$this->_get_sid_salt()); |
|
791 | 791 | return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id); |
792 | 792 | } |
793 | 793 | |
@@ -889,19 +889,19 @@ discard block |
||
889 | 889 | $page_visit = $this->_get_page_visit(); |
890 | 890 | if ($page_visit) { |
891 | 891 | // set pages visited where the first will be the http referrer |
892 | - $this->_session_data['pages_visited'][ $this->_time ] = $page_visit; |
|
892 | + $this->_session_data['pages_visited'][$this->_time] = $page_visit; |
|
893 | 893 | // we'll only save the last 10 page visits. |
894 | 894 | $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10); |
895 | 895 | } |
896 | 896 | break; |
897 | 897 | default: |
898 | 898 | // carry any other data over |
899 | - $session_data[ $key ] = $this->_session_data[ $key ]; |
|
899 | + $session_data[$key] = $this->_session_data[$key]; |
|
900 | 900 | } |
901 | 901 | } |
902 | 902 | $this->_session_data = $session_data; |
903 | 903 | // creating a new session does not require saving to the db just yet |
904 | - if (! $new_session) { |
|
904 | + if ( ! $new_session) { |
|
905 | 905 | // ready? let's save |
906 | 906 | if ($this->_save_session_to_db()) { |
907 | 907 | return true; |
@@ -979,7 +979,7 @@ discard block |
||
979 | 979 | } |
980 | 980 | $transaction = $this->transaction(); |
981 | 981 | if ($transaction instanceof EE_Transaction) { |
982 | - if (! $transaction->ID()) { |
|
982 | + if ( ! $transaction->ID()) { |
|
983 | 983 | $transaction->save(); |
984 | 984 | } |
985 | 985 | $this->_session_data['transaction'] = $transaction->ID(); |
@@ -993,14 +993,14 @@ discard block |
||
993 | 993 | // maybe save hash check |
994 | 994 | if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
995 | 995 | $this->cache_storage->add( |
996 | - EE_Session::hash_check_prefix . $this->_sid, |
|
996 | + EE_Session::hash_check_prefix.$this->_sid, |
|
997 | 997 | md5($session_data), |
998 | 998 | $this->session_lifespan->inSeconds() |
999 | 999 | ); |
1000 | 1000 | } |
1001 | 1001 | // we're using the Transient API for storing session data, |
1002 | 1002 | $saved = $this->cache_storage->add( |
1003 | - EE_Session::session_id_prefix . $this->_sid, |
|
1003 | + EE_Session::session_id_prefix.$this->_sid, |
|
1004 | 1004 | $session_data, |
1005 | 1005 | $this->session_lifespan->inSeconds() |
1006 | 1006 | ); |
@@ -1015,7 +1015,7 @@ discard block |
||
1015 | 1015 | */ |
1016 | 1016 | public function _get_page_visit() |
1017 | 1017 | { |
1018 | - $page_visit = home_url('/') . 'wp-admin/admin-ajax.php'; |
|
1018 | + $page_visit = home_url('/').'wp-admin/admin-ajax.php'; |
|
1019 | 1019 | // check for request url |
1020 | 1020 | if ($this->request->serverParamIsSet('REQUEST_URI')) { |
1021 | 1021 | $page_id = '?'; |
@@ -1027,14 +1027,14 @@ discard block |
||
1027 | 1027 | // check for page_id in SERVER REQUEST |
1028 | 1028 | if ($this->request->requestParamIsSet('page_id')) { |
1029 | 1029 | // rebuild $e_reg without any of the extra parameters |
1030 | - $page_id .= 'page_id=' . $this->request->getRequestParam('page_id', 0, 'int') . '&'; |
|
1030 | + $page_id .= 'page_id='.$this->request->getRequestParam('page_id', 0, 'int').'&'; |
|
1031 | 1031 | } |
1032 | 1032 | // check for $e_reg in SERVER REQUEST |
1033 | 1033 | if ($this->request->requestParamIsSet('ee')) { |
1034 | 1034 | // rebuild $e_reg without any of the extra parameters |
1035 | - $e_reg = 'ee=' . $this->request->getRequestParam('ee'); |
|
1035 | + $e_reg = 'ee='.$this->request->getRequestParam('ee'); |
|
1036 | 1036 | } |
1037 | - $page_visit = esc_url(rtrim($http_host . $request_uri . $page_id . $e_reg, '?')); |
|
1037 | + $page_visit = esc_url(rtrim($http_host.$request_uri.$page_id.$e_reg, '?')); |
|
1038 | 1038 | } |
1039 | 1039 | return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : ''; |
1040 | 1040 | } |
@@ -1071,7 +1071,7 @@ discard block |
||
1071 | 1071 | // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/> |
1072 | 1072 | // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span> <b style="font-size:10px;"> ' . __LINE__ . ' </b> |
1073 | 1073 | // </h3>'; |
1074 | - do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()'); |
|
1074 | + do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : '.$class.'::'.$function.'()'); |
|
1075 | 1075 | $this->reset_cart(); |
1076 | 1076 | $this->reset_checkout(); |
1077 | 1077 | $this->reset_transaction(); |
@@ -1094,7 +1094,7 @@ discard block |
||
1094 | 1094 | public function reset_data($data_to_reset = array(), $show_all_notices = false) |
1095 | 1095 | { |
1096 | 1096 | // if $data_to_reset is not in an array, then put it in one |
1097 | - if (! is_array($data_to_reset)) { |
|
1097 | + if ( ! is_array($data_to_reset)) { |
|
1098 | 1098 | $data_to_reset = array($data_to_reset); |
1099 | 1099 | } |
1100 | 1100 | // nothing ??? go home! |
@@ -1114,11 +1114,11 @@ discard block |
||
1114 | 1114 | // since $data_to_reset is an array, cycle through the values |
1115 | 1115 | foreach ($data_to_reset as $reset) { |
1116 | 1116 | // first check to make sure it is a valid session var |
1117 | - if (isset($this->_session_data[ $reset ])) { |
|
1117 | + if (isset($this->_session_data[$reset])) { |
|
1118 | 1118 | // then check to make sure it is not a default var |
1119 | - if (! array_key_exists($reset, $this->_default_session_vars)) { |
|
1119 | + if ( ! array_key_exists($reset, $this->_default_session_vars)) { |
|
1120 | 1120 | // remove session var |
1121 | - unset($this->_session_data[ $reset ]); |
|
1121 | + unset($this->_session_data[$reset]); |
|
1122 | 1122 | $this->setSaveState(); |
1123 | 1123 | if ($show_all_notices) { |
1124 | 1124 | EE_Error::add_success( |
@@ -1221,7 +1221,7 @@ discard block |
||
1221 | 1221 | // or use that for the new transient cleanup query limit |
1222 | 1222 | add_filter( |
1223 | 1223 | 'FHEE__TransientCacheStorage__clearExpiredTransients__limit', |
1224 | - function () use ($expired_session_transient_delete_query_limit) { |
|
1224 | + function() use ($expired_session_transient_delete_query_limit) { |
|
1225 | 1225 | return $expired_session_transient_delete_query_limit; |
1226 | 1226 | } |
1227 | 1227 | ); |
@@ -1239,7 +1239,7 @@ discard block |
||
1239 | 1239 | $error = '<pre>'; |
1240 | 1240 | $data2 = preg_replace_callback( |
1241 | 1241 | '!s:(\d+):"(.*?)";!', |
1242 | - function ($match) { |
|
1242 | + function($match) { |
|
1243 | 1243 | return ($match[1] === strlen($match[2])) |
1244 | 1244 | ? $match[0] |
1245 | 1245 | : 's:' |
@@ -1251,13 +1251,13 @@ discard block |
||
1251 | 1251 | $data1 |
1252 | 1252 | ); |
1253 | 1253 | $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2); |
1254 | - $error .= $data1 . PHP_EOL; |
|
1255 | - $error .= $data2 . PHP_EOL; |
|
1254 | + $error .= $data1.PHP_EOL; |
|
1255 | + $error .= $data2.PHP_EOL; |
|
1256 | 1256 | for ($i = 0; $i < $max; $i++) { |
1257 | - if (@$data1[ $i ] !== @$data2[ $i ]) { |
|
1258 | - $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL; |
|
1259 | - $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL; |
|
1260 | - $error .= "\t-> Line Number = $i" . PHP_EOL; |
|
1257 | + if (@$data1[$i] !== @$data2[$i]) { |
|
1258 | + $error .= 'Difference '.@$data1[$i].' != '.@$data2[$i].PHP_EOL; |
|
1259 | + $error .= "\t-> ORD number ".ord(@$data1[$i]).' != '.ord(@$data2[$i]).PHP_EOL; |
|
1260 | + $error .= "\t-> Line Number = $i".PHP_EOL; |
|
1261 | 1261 | $start = ($i - 20); |
1262 | 1262 | $start = ($start < 0) ? 0 : $start; |
1263 | 1263 | $length = 40; |
@@ -1272,7 +1272,7 @@ discard block |
||
1272 | 1272 | $error .= "\t-> Section Data1 = "; |
1273 | 1273 | $error .= substr_replace( |
1274 | 1274 | substr($data1, $start, $length), |
1275 | - "<b style=\"color:green\">{$data1[ $i ]}</b>", |
|
1275 | + "<b style=\"color:green\">{$data1[$i]}</b>", |
|
1276 | 1276 | $rpoint, |
1277 | 1277 | $rlength |
1278 | 1278 | ); |
@@ -1280,7 +1280,7 @@ discard block |
||
1280 | 1280 | $error .= "\t-> Section Data2 = "; |
1281 | 1281 | $error .= substr_replace( |
1282 | 1282 | substr($data2, $start, $length), |
1283 | - "<b style=\"color:red\">{$data2[ $i ]}</b>", |
|
1283 | + "<b style=\"color:red\">{$data2[$i]}</b>", |
|
1284 | 1284 | $rpoint, |
1285 | 1285 | $rlength |
1286 | 1286 | ); |
@@ -1311,7 +1311,7 @@ discard block |
||
1311 | 1311 | public function garbageCollection() |
1312 | 1312 | { |
1313 | 1313 | // only perform during regular requests if last garbage collection was over an hour ago |
1314 | - if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1314 | + if ( ! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1315 | 1315 | $this->_last_gc = time(); |
1316 | 1316 | $this->updateSessionSettings(array('last_gc' => $this->_last_gc)); |
1317 | 1317 | /** @type WPDB $wpdb */ |
@@ -1346,7 +1346,7 @@ discard block |
||
1346 | 1346 | // AND option_value < 1508368198 LIMIT 50 |
1347 | 1347 | $expired_sessions = $wpdb->get_col($SQL); |
1348 | 1348 | // valid results? |
1349 | - if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1349 | + if ( ! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1350 | 1350 | $this->cache_storage->deleteMany($expired_sessions, true); |
1351 | 1351 | } |
1352 | 1352 | } |
@@ -24,1310 +24,1310 @@ 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 | - * @return void |
|
414 | - */ |
|
415 | - private function _set_defaults() |
|
416 | - { |
|
417 | - // set some defaults |
|
418 | - foreach ($this->_default_session_vars as $key => $default_var) { |
|
419 | - if (is_array($default_var)) { |
|
420 | - $this->_session_data[ $key ] = array(); |
|
421 | - } else { |
|
422 | - $this->_session_data[ $key ] = ''; |
|
423 | - } |
|
424 | - } |
|
425 | - } |
|
426 | - |
|
427 | - |
|
428 | - /** |
|
429 | - * @retrieve session data |
|
430 | - * @return string |
|
431 | - */ |
|
432 | - public function id() |
|
433 | - { |
|
434 | - return $this->_sid; |
|
435 | - } |
|
436 | - |
|
437 | - |
|
438 | - /** |
|
439 | - * @param \EE_Cart $cart |
|
440 | - * @return bool |
|
441 | - */ |
|
442 | - public function set_cart(EE_Cart $cart) |
|
443 | - { |
|
444 | - $this->_session_data['cart'] = $cart; |
|
445 | - $this->setSaveState(); |
|
446 | - return true; |
|
447 | - } |
|
448 | - |
|
449 | - |
|
450 | - /** |
|
451 | - * reset_cart |
|
452 | - */ |
|
453 | - public function reset_cart() |
|
454 | - { |
|
455 | - do_action('AHEE__EE_Session__reset_cart__before_reset', $this); |
|
456 | - $this->_session_data['cart'] = null; |
|
457 | - $this->setSaveState(); |
|
458 | - } |
|
459 | - |
|
460 | - |
|
461 | - /** |
|
462 | - * @return \EE_Cart |
|
463 | - */ |
|
464 | - public function cart() |
|
465 | - { |
|
466 | - return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart |
|
467 | - ? $this->_session_data['cart'] |
|
468 | - : null; |
|
469 | - } |
|
470 | - |
|
471 | - |
|
472 | - /** |
|
473 | - * @param \EE_Checkout $checkout |
|
474 | - * @return bool |
|
475 | - */ |
|
476 | - public function set_checkout(EE_Checkout $checkout) |
|
477 | - { |
|
478 | - $this->_session_data['checkout'] = $checkout; |
|
479 | - $this->setSaveState(); |
|
480 | - return true; |
|
481 | - } |
|
482 | - |
|
483 | - |
|
484 | - /** |
|
485 | - * reset_checkout |
|
486 | - */ |
|
487 | - public function reset_checkout() |
|
488 | - { |
|
489 | - do_action('AHEE__EE_Session__reset_checkout__before_reset', $this); |
|
490 | - $this->_session_data['checkout'] = null; |
|
491 | - $this->setSaveState(); |
|
492 | - } |
|
493 | - |
|
494 | - |
|
495 | - /** |
|
496 | - * @return \EE_Checkout |
|
497 | - */ |
|
498 | - public function checkout() |
|
499 | - { |
|
500 | - return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout |
|
501 | - ? $this->_session_data['checkout'] |
|
502 | - : null; |
|
503 | - } |
|
504 | - |
|
505 | - |
|
506 | - /** |
|
507 | - * @param \EE_Transaction $transaction |
|
508 | - * @return bool |
|
509 | - * @throws EE_Error |
|
510 | - */ |
|
511 | - public function set_transaction(EE_Transaction $transaction) |
|
512 | - { |
|
513 | - // first remove the session from the transaction before we save the transaction in the session |
|
514 | - $transaction->set_txn_session_data(null); |
|
515 | - $this->_session_data['transaction'] = $transaction; |
|
516 | - $this->setSaveState(); |
|
517 | - return true; |
|
518 | - } |
|
519 | - |
|
520 | - |
|
521 | - /** |
|
522 | - * reset_transaction |
|
523 | - */ |
|
524 | - public function reset_transaction() |
|
525 | - { |
|
526 | - do_action('AHEE__EE_Session__reset_transaction__before_reset', $this); |
|
527 | - $this->_session_data['transaction'] = null; |
|
528 | - $this->setSaveState(); |
|
529 | - } |
|
530 | - |
|
531 | - |
|
532 | - /** |
|
533 | - * @return \EE_Transaction |
|
534 | - */ |
|
535 | - public function transaction() |
|
536 | - { |
|
537 | - return isset($this->_session_data['transaction']) |
|
538 | - && $this->_session_data['transaction'] instanceof EE_Transaction |
|
539 | - ? $this->_session_data['transaction'] |
|
540 | - : null; |
|
541 | - } |
|
542 | - |
|
543 | - |
|
544 | - /** |
|
545 | - * retrieve session data |
|
546 | - * |
|
547 | - * @param null $key |
|
548 | - * @param bool $reset_cache |
|
549 | - * @return array |
|
550 | - */ |
|
551 | - public function get_session_data($key = null, $reset_cache = false) |
|
552 | - { |
|
553 | - if ($reset_cache) { |
|
554 | - $this->reset_cart(); |
|
555 | - $this->reset_checkout(); |
|
556 | - $this->reset_transaction(); |
|
557 | - } |
|
558 | - if (! empty($key)) { |
|
559 | - return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null; |
|
560 | - } |
|
561 | - return $this->_session_data; |
|
562 | - } |
|
563 | - |
|
564 | - |
|
565 | - /** |
|
566 | - * Returns TRUE on success, FALSE on fail |
|
567 | - * |
|
568 | - * @param array $data |
|
569 | - * @return bool |
|
570 | - */ |
|
571 | - public function set_session_data($data) |
|
572 | - { |
|
573 | - // nothing ??? bad data ??? go home! |
|
574 | - if (empty($data) || ! is_array($data)) { |
|
575 | - EE_Error::add_error( |
|
576 | - esc_html__( |
|
577 | - 'No session data or invalid session data was provided.', |
|
578 | - 'event_espresso' |
|
579 | - ), |
|
580 | - __FILE__, |
|
581 | - __FUNCTION__, |
|
582 | - __LINE__ |
|
583 | - ); |
|
584 | - return false; |
|
585 | - } |
|
586 | - foreach ($data as $key => $value) { |
|
587 | - if (isset($this->_default_session_vars[ $key ])) { |
|
588 | - EE_Error::add_error( |
|
589 | - sprintf( |
|
590 | - esc_html__( |
|
591 | - 'Sorry! %s is a default session datum and can not be reset.', |
|
592 | - 'event_espresso' |
|
593 | - ), |
|
594 | - $key |
|
595 | - ), |
|
596 | - __FILE__, |
|
597 | - __FUNCTION__, |
|
598 | - __LINE__ |
|
599 | - ); |
|
600 | - return false; |
|
601 | - } |
|
602 | - $this->_session_data[ $key ] = $value; |
|
603 | - $this->setSaveState(); |
|
604 | - } |
|
605 | - return true; |
|
606 | - } |
|
607 | - |
|
608 | - |
|
609 | - /** |
|
610 | - * @initiate session |
|
611 | - * @return bool TRUE on success, FALSE on fail |
|
612 | - * @throws EE_Error |
|
613 | - * @throws InvalidArgumentException |
|
614 | - * @throws InvalidDataTypeException |
|
615 | - * @throws InvalidInterfaceException |
|
616 | - * @throws InvalidSessionDataException |
|
617 | - * @throws RuntimeException |
|
618 | - * @throws ReflectionException |
|
619 | - */ |
|
620 | - private function _espresso_session() |
|
621 | - { |
|
622 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
623 | - $this->session_start_handler->startSession(); |
|
624 | - $this->status = EE_Session::STATUS_OPEN; |
|
625 | - // get our modified session ID |
|
626 | - $this->_sid = $this->_generate_session_id(); |
|
627 | - // and the visitors IP |
|
628 | - $this->_ip_address = $this->request->ipAddress(); |
|
629 | - // set the "user agent" |
|
630 | - $this->_user_agent = $this->request->userAgent(); |
|
631 | - // now let's retrieve what's in the db |
|
632 | - $session_data = $this->_retrieve_session_data(); |
|
633 | - if (! empty($session_data)) { |
|
634 | - // get the current time in UTC |
|
635 | - $this->_time = $this->_time !== null ? $this->_time : time(); |
|
636 | - // and reset the session expiration |
|
637 | - $this->_expiration = isset($session_data['expiration']) |
|
638 | - ? $session_data['expiration'] |
|
639 | - : $this->_time + $this->session_lifespan->inSeconds(); |
|
640 | - } else { |
|
641 | - // set initial site access time and the session expiration |
|
642 | - $this->_set_init_access_and_expiration(); |
|
643 | - // set referer |
|
644 | - $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = esc_attr( |
|
645 | - $this->request->getServerParam('HTTP_REFERER') |
|
646 | - ); |
|
647 | - // no previous session = go back and create one (on top of the data above) |
|
648 | - return false; |
|
649 | - } |
|
650 | - // now the user agent |
|
651 | - if ($session_data['user_agent'] !== $this->_user_agent) { |
|
652 | - return false; |
|
653 | - } |
|
654 | - // wait a minute... how old are you? |
|
655 | - if ($this->_time > $this->_expiration) { |
|
656 | - // yer too old fer me! |
|
657 | - $this->_expired = true; |
|
658 | - // wipe out everything that isn't a default session datum |
|
659 | - $this->clear_session(__CLASS__, __FUNCTION__); |
|
660 | - } |
|
661 | - // make event espresso session data available to plugin |
|
662 | - $this->_session_data = array_merge($this->_session_data, $session_data); |
|
663 | - return true; |
|
664 | - } |
|
665 | - |
|
666 | - |
|
667 | - /** |
|
668 | - * _get_session_data |
|
669 | - * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup |
|
670 | - * databases |
|
671 | - * |
|
672 | - * @return array |
|
673 | - * @throws EE_Error |
|
674 | - * @throws InvalidArgumentException |
|
675 | - * @throws InvalidSessionDataException |
|
676 | - * @throws InvalidDataTypeException |
|
677 | - * @throws InvalidInterfaceException |
|
678 | - * @throws RuntimeException |
|
679 | - */ |
|
680 | - protected function _retrieve_session_data() |
|
681 | - { |
|
682 | - $ssn_key = EE_Session::session_id_prefix . $this->_sid; |
|
683 | - try { |
|
684 | - // we're using WP's Transient API to store session data using the PHP session ID as the option name |
|
685 | - $session_data = $this->cache_storage->get($ssn_key, false); |
|
686 | - if (empty($session_data)) { |
|
687 | - return array(); |
|
688 | - } |
|
689 | - if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
690 | - $hash_check = $this->cache_storage->get( |
|
691 | - EE_Session::hash_check_prefix . $this->_sid, |
|
692 | - false |
|
693 | - ); |
|
694 | - if ($hash_check && $hash_check !== md5($session_data)) { |
|
695 | - EE_Error::add_error( |
|
696 | - sprintf( |
|
697 | - esc_html__( |
|
698 | - 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.', |
|
699 | - 'event_espresso' |
|
700 | - ), |
|
701 | - EE_Session::session_id_prefix . $this->_sid |
|
702 | - ), |
|
703 | - __FILE__, |
|
704 | - __FUNCTION__, |
|
705 | - __LINE__ |
|
706 | - ); |
|
707 | - } |
|
708 | - } |
|
709 | - } catch (Exception $e) { |
|
710 | - // let's just eat that error for now and attempt to correct any corrupted data |
|
711 | - global $wpdb; |
|
712 | - $row = $wpdb->get_row( |
|
713 | - $wpdb->prepare( |
|
714 | - "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", |
|
715 | - '_transient_' . $ssn_key |
|
716 | - ) |
|
717 | - ); |
|
718 | - $session_data = is_object($row) ? $row->option_value : null; |
|
719 | - if ($session_data) { |
|
720 | - $session_data = preg_replace_callback( |
|
721 | - '!s:(d+):"(.*?)";!', |
|
722 | - function ($match) { |
|
723 | - return $match[1] === strlen($match[2]) |
|
724 | - ? $match[0] |
|
725 | - : 's:' . strlen($match[2]) . ':"' . $match[2] . '";'; |
|
726 | - }, |
|
727 | - $session_data |
|
728 | - ); |
|
729 | - } |
|
730 | - $session_data = maybe_unserialize($session_data); |
|
731 | - } |
|
732 | - // in case the data is encoded... try to decode it |
|
733 | - $session_data = $this->encryption instanceof EE_Encryption |
|
734 | - ? $this->encryption->base64_string_decode($session_data) |
|
735 | - : $session_data; |
|
736 | - if (! is_array($session_data)) { |
|
737 | - try { |
|
738 | - $session_data = maybe_unserialize($session_data); |
|
739 | - } catch (Exception $e) { |
|
740 | - $msg = esc_html__( |
|
741 | - 'An error occurred while attempting to unserialize the session data.', |
|
742 | - 'event_espresso' |
|
743 | - ); |
|
744 | - $msg .= WP_DEBUG |
|
745 | - ? '<br><pre>' |
|
746 | - . print_r($session_data, true) |
|
747 | - . '</pre><br>' |
|
748 | - . $this->find_serialize_error($session_data) |
|
749 | - : ''; |
|
750 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
751 | - throw new InvalidSessionDataException($msg, 0, $e); |
|
752 | - } |
|
753 | - } |
|
754 | - // just a check to make sure the session array is indeed an array |
|
755 | - if (! is_array($session_data)) { |
|
756 | - // no?!?! then something is wrong |
|
757 | - $msg = esc_html__( |
|
758 | - 'The session data is missing, invalid, or corrupted.', |
|
759 | - 'event_espresso' |
|
760 | - ); |
|
761 | - $msg .= WP_DEBUG |
|
762 | - ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data) |
|
763 | - : ''; |
|
764 | - $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
765 | - throw new InvalidSessionDataException($msg); |
|
766 | - } |
|
767 | - if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) { |
|
768 | - $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID( |
|
769 | - $session_data['transaction'] |
|
770 | - ); |
|
771 | - } |
|
772 | - return $session_data; |
|
773 | - } |
|
774 | - |
|
775 | - |
|
776 | - /** |
|
777 | - * _generate_session_id |
|
778 | - * Retrieves the PHP session id either directly from the PHP session, |
|
779 | - * or from the request array if it was passed in from an AJAX request. |
|
780 | - * The session id is then salted and hashed (mmm sounds tasty) |
|
781 | - * so that it can be safely used as a request param |
|
782 | - * |
|
783 | - * @return string |
|
784 | - */ |
|
785 | - protected function _generate_session_id() |
|
786 | - { |
|
787 | - // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length |
|
788 | - $session_id = $this->request->requestParamIsSet('EESID') |
|
789 | - ? $this->request->getRequestParam('EESID') |
|
790 | - : md5(session_id() . get_current_blog_id() . $this->_get_sid_salt()); |
|
791 | - return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id); |
|
792 | - } |
|
793 | - |
|
794 | - |
|
795 | - /** |
|
796 | - * _get_sid_salt |
|
797 | - * |
|
798 | - * @return string |
|
799 | - */ |
|
800 | - protected function _get_sid_salt() |
|
801 | - { |
|
802 | - // was session id salt already saved to db ? |
|
803 | - if (empty($this->_sid_salt)) { |
|
804 | - // no? then maybe use WP defined constant |
|
805 | - if (defined('AUTH_SALT')) { |
|
806 | - $this->_sid_salt = AUTH_SALT; |
|
807 | - } |
|
808 | - // if salt doesn't exist or is too short |
|
809 | - if (strlen($this->_sid_salt) < 32) { |
|
810 | - // create a new one |
|
811 | - $this->_sid_salt = wp_generate_password(64); |
|
812 | - } |
|
813 | - // and save it as a permanent session setting |
|
814 | - $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt)); |
|
815 | - } |
|
816 | - return $this->_sid_salt; |
|
817 | - } |
|
818 | - |
|
819 | - |
|
820 | - /** |
|
821 | - * _set_init_access_and_expiration |
|
822 | - * |
|
823 | - * @return void |
|
824 | - */ |
|
825 | - protected function _set_init_access_and_expiration() |
|
826 | - { |
|
827 | - $this->_time = time(); |
|
828 | - $this->_expiration = $this->_time + $this->session_lifespan->inSeconds(); |
|
829 | - // set initial site access time |
|
830 | - $this->_session_data['init_access'] = $this->_time; |
|
831 | - // and the session expiration |
|
832 | - $this->_session_data['expiration'] = $this->_expiration; |
|
833 | - } |
|
834 | - |
|
835 | - |
|
836 | - /** |
|
837 | - * @update session data prior to saving to the db |
|
838 | - * @param bool $new_session |
|
839 | - * @return bool TRUE on success, FALSE on fail |
|
840 | - * @throws EE_Error |
|
841 | - * @throws InvalidArgumentException |
|
842 | - * @throws InvalidDataTypeException |
|
843 | - * @throws InvalidInterfaceException |
|
844 | - * @throws ReflectionException |
|
845 | - */ |
|
846 | - public function update($new_session = false) |
|
847 | - { |
|
848 | - $this->_session_data = is_array($this->_session_data) && isset($this->_session_data['id']) |
|
849 | - ? $this->_session_data |
|
850 | - : array(); |
|
851 | - if (empty($this->_session_data)) { |
|
852 | - $this->_set_defaults(); |
|
853 | - } |
|
854 | - $session_data = array(); |
|
855 | - foreach ($this->_session_data as $key => $value) { |
|
856 | - switch ($key) { |
|
857 | - case 'id': |
|
858 | - // session ID |
|
859 | - $session_data['id'] = $this->_sid; |
|
860 | - break; |
|
861 | - case 'ip_address': |
|
862 | - // visitor ip address |
|
863 | - $session_data['ip_address'] = $this->request->ipAddress(); |
|
864 | - break; |
|
865 | - case 'user_agent': |
|
866 | - // visitor user_agent |
|
867 | - $session_data['user_agent'] = $this->_user_agent; |
|
868 | - break; |
|
869 | - case 'init_access': |
|
870 | - $session_data['init_access'] = absint($value); |
|
871 | - break; |
|
872 | - case 'last_access': |
|
873 | - // current access time |
|
874 | - $session_data['last_access'] = $this->_time; |
|
875 | - break; |
|
876 | - case 'expiration': |
|
877 | - // when the session expires |
|
878 | - $session_data['expiration'] = ! empty($this->_expiration) |
|
879 | - ? $this->_expiration |
|
880 | - : $session_data['init_access'] + $this->session_lifespan->inSeconds(); |
|
881 | - break; |
|
882 | - case 'user_id': |
|
883 | - // current user if logged in |
|
884 | - $session_data['user_id'] = $this->_wp_user_id(); |
|
885 | - break; |
|
886 | - case 'pages_visited': |
|
887 | - $page_visit = $this->_get_page_visit(); |
|
888 | - if ($page_visit) { |
|
889 | - // set pages visited where the first will be the http referrer |
|
890 | - $this->_session_data['pages_visited'][ $this->_time ] = $page_visit; |
|
891 | - // we'll only save the last 10 page visits. |
|
892 | - $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10); |
|
893 | - } |
|
894 | - break; |
|
895 | - default: |
|
896 | - // carry any other data over |
|
897 | - $session_data[ $key ] = $this->_session_data[ $key ]; |
|
898 | - } |
|
899 | - } |
|
900 | - $this->_session_data = $session_data; |
|
901 | - // creating a new session does not require saving to the db just yet |
|
902 | - if (! $new_session) { |
|
903 | - // ready? let's save |
|
904 | - if ($this->_save_session_to_db()) { |
|
905 | - return true; |
|
906 | - } |
|
907 | - return false; |
|
908 | - } |
|
909 | - // meh, why not? |
|
910 | - return true; |
|
911 | - } |
|
912 | - |
|
913 | - |
|
914 | - /** |
|
915 | - * @create session data array |
|
916 | - * @throws EE_Error |
|
917 | - * @throws InvalidArgumentException |
|
918 | - * @throws InvalidDataTypeException |
|
919 | - * @throws InvalidInterfaceException |
|
920 | - * @throws ReflectionException |
|
921 | - */ |
|
922 | - private function _create_espresso_session() |
|
923 | - { |
|
924 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, ''); |
|
925 | - // use the update function for now with $new_session arg set to TRUE |
|
926 | - $this->update(true); |
|
927 | - } |
|
928 | - |
|
929 | - /** |
|
930 | - * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good |
|
931 | - * too). This is used when determining if we want to save the session or not. |
|
932 | - * @since 4.9.67.p |
|
933 | - * @return bool |
|
934 | - */ |
|
935 | - private function sessionHasStuffWorthSaving() |
|
936 | - { |
|
937 | - return $this->save_state === EE_Session::SAVE_STATE_DIRTY |
|
938 | - // we may want to eventually remove the following |
|
939 | - // on the assumption that the above check is enough |
|
940 | - || $this->cart() instanceof EE_Cart |
|
941 | - || ( |
|
942 | - isset($this->_session_data['ee_notices']) |
|
943 | - && ( |
|
944 | - ! empty($this->_session_data['ee_notices']['attention']) |
|
945 | - || ! empty($this->_session_data['ee_notices']['errors']) |
|
946 | - || ! empty($this->_session_data['ee_notices']['success']) |
|
947 | - ) |
|
948 | - ); |
|
949 | - } |
|
950 | - |
|
951 | - |
|
952 | - /** |
|
953 | - * _save_session_to_db |
|
954 | - * |
|
955 | - * @param bool $clear_session |
|
956 | - * @return bool |
|
957 | - * @throws EE_Error |
|
958 | - * @throws InvalidArgumentException |
|
959 | - * @throws InvalidDataTypeException |
|
960 | - * @throws InvalidInterfaceException |
|
961 | - * @throws ReflectionException |
|
962 | - */ |
|
963 | - private function _save_session_to_db($clear_session = false) |
|
964 | - { |
|
965 | - // don't save sessions for crawlers |
|
966 | - // and unless we're deleting the session data, don't save anything if there isn't a cart |
|
967 | - if ( |
|
968 | - $this->request->isBot() |
|
969 | - || ( |
|
970 | - ! $clear_session |
|
971 | - && ! $this->sessionHasStuffWorthSaving() |
|
972 | - && apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true) |
|
973 | - ) |
|
974 | - ) { |
|
975 | - return false; |
|
976 | - } |
|
977 | - $transaction = $this->transaction(); |
|
978 | - if ($transaction instanceof EE_Transaction) { |
|
979 | - if (! $transaction->ID()) { |
|
980 | - $transaction->save(); |
|
981 | - } |
|
982 | - $this->_session_data['transaction'] = $transaction->ID(); |
|
983 | - } |
|
984 | - // then serialize all of our session data |
|
985 | - $session_data = serialize($this->_session_data); |
|
986 | - // do we need to also encode it to avoid corrupted data when saved to the db? |
|
987 | - $session_data = $this->_use_encryption |
|
988 | - ? $this->encryption->base64_string_encode($session_data) |
|
989 | - : $session_data; |
|
990 | - // maybe save hash check |
|
991 | - if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
992 | - $this->cache_storage->add( |
|
993 | - EE_Session::hash_check_prefix . $this->_sid, |
|
994 | - md5($session_data), |
|
995 | - $this->session_lifespan->inSeconds() |
|
996 | - ); |
|
997 | - } |
|
998 | - // we're using the Transient API for storing session data, |
|
999 | - $saved = $this->cache_storage->add( |
|
1000 | - EE_Session::session_id_prefix . $this->_sid, |
|
1001 | - $session_data, |
|
1002 | - $this->session_lifespan->inSeconds() |
|
1003 | - ); |
|
1004 | - $this->setSaveState(EE_Session::SAVE_STATE_CLEAN); |
|
1005 | - return $saved; |
|
1006 | - } |
|
1007 | - |
|
1008 | - |
|
1009 | - /** |
|
1010 | - * @get the full page request the visitor is accessing |
|
1011 | - * @return string |
|
1012 | - */ |
|
1013 | - public function _get_page_visit() |
|
1014 | - { |
|
1015 | - $page_visit = home_url('/') . 'wp-admin/admin-ajax.php'; |
|
1016 | - // check for request url |
|
1017 | - if ($this->request->serverParamIsSet('REQUEST_URI')) { |
|
1018 | - $page_id = '?'; |
|
1019 | - $e_reg = ''; |
|
1020 | - $request_uri = $this->request->getServerParam('REQUEST_URI'); |
|
1021 | - $ru_bits = explode('?', $request_uri); |
|
1022 | - $request_uri = $ru_bits[0]; |
|
1023 | - $http_host = $this->request->getServerParam('HTTP_HOST'); |
|
1024 | - // check for page_id in SERVER REQUEST |
|
1025 | - if ($this->request->requestParamIsSet('page_id')) { |
|
1026 | - // rebuild $e_reg without any of the extra parameters |
|
1027 | - $page_id .= 'page_id=' . $this->request->getRequestParam('page_id', 0, 'int') . '&'; |
|
1028 | - } |
|
1029 | - // check for $e_reg in SERVER REQUEST |
|
1030 | - if ($this->request->requestParamIsSet('ee')) { |
|
1031 | - // rebuild $e_reg without any of the extra parameters |
|
1032 | - $e_reg = 'ee=' . $this->request->getRequestParam('ee'); |
|
1033 | - } |
|
1034 | - $page_visit = esc_url(rtrim($http_host . $request_uri . $page_id . $e_reg, '?')); |
|
1035 | - } |
|
1036 | - return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : ''; |
|
1037 | - } |
|
1038 | - |
|
1039 | - |
|
1040 | - /** |
|
1041 | - * @the current wp user id |
|
1042 | - * @return int |
|
1043 | - */ |
|
1044 | - public function _wp_user_id() |
|
1045 | - { |
|
1046 | - // if I need to explain the following lines of code, then you shouldn't be looking at this! |
|
1047 | - $this->_wp_user_id = get_current_user_id(); |
|
1048 | - return $this->_wp_user_id; |
|
1049 | - } |
|
1050 | - |
|
1051 | - |
|
1052 | - /** |
|
1053 | - * Clear EE_Session data |
|
1054 | - * |
|
1055 | - * @param string $class |
|
1056 | - * @param string $function |
|
1057 | - * @return void |
|
1058 | - * @throws EE_Error |
|
1059 | - * @throws InvalidArgumentException |
|
1060 | - * @throws InvalidDataTypeException |
|
1061 | - * @throws InvalidInterfaceException |
|
1062 | - * @throws ReflectionException |
|
1063 | - */ |
|
1064 | - public function clear_session($class = '', $function = '') |
|
1065 | - { |
|
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 | + * @return void |
|
414 | + */ |
|
415 | + private function _set_defaults() |
|
416 | + { |
|
417 | + // set some defaults |
|
418 | + foreach ($this->_default_session_vars as $key => $default_var) { |
|
419 | + if (is_array($default_var)) { |
|
420 | + $this->_session_data[ $key ] = array(); |
|
421 | + } else { |
|
422 | + $this->_session_data[ $key ] = ''; |
|
423 | + } |
|
424 | + } |
|
425 | + } |
|
426 | + |
|
427 | + |
|
428 | + /** |
|
429 | + * @retrieve session data |
|
430 | + * @return string |
|
431 | + */ |
|
432 | + public function id() |
|
433 | + { |
|
434 | + return $this->_sid; |
|
435 | + } |
|
436 | + |
|
437 | + |
|
438 | + /** |
|
439 | + * @param \EE_Cart $cart |
|
440 | + * @return bool |
|
441 | + */ |
|
442 | + public function set_cart(EE_Cart $cart) |
|
443 | + { |
|
444 | + $this->_session_data['cart'] = $cart; |
|
445 | + $this->setSaveState(); |
|
446 | + return true; |
|
447 | + } |
|
448 | + |
|
449 | + |
|
450 | + /** |
|
451 | + * reset_cart |
|
452 | + */ |
|
453 | + public function reset_cart() |
|
454 | + { |
|
455 | + do_action('AHEE__EE_Session__reset_cart__before_reset', $this); |
|
456 | + $this->_session_data['cart'] = null; |
|
457 | + $this->setSaveState(); |
|
458 | + } |
|
459 | + |
|
460 | + |
|
461 | + /** |
|
462 | + * @return \EE_Cart |
|
463 | + */ |
|
464 | + public function cart() |
|
465 | + { |
|
466 | + return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart |
|
467 | + ? $this->_session_data['cart'] |
|
468 | + : null; |
|
469 | + } |
|
470 | + |
|
471 | + |
|
472 | + /** |
|
473 | + * @param \EE_Checkout $checkout |
|
474 | + * @return bool |
|
475 | + */ |
|
476 | + public function set_checkout(EE_Checkout $checkout) |
|
477 | + { |
|
478 | + $this->_session_data['checkout'] = $checkout; |
|
479 | + $this->setSaveState(); |
|
480 | + return true; |
|
481 | + } |
|
482 | + |
|
483 | + |
|
484 | + /** |
|
485 | + * reset_checkout |
|
486 | + */ |
|
487 | + public function reset_checkout() |
|
488 | + { |
|
489 | + do_action('AHEE__EE_Session__reset_checkout__before_reset', $this); |
|
490 | + $this->_session_data['checkout'] = null; |
|
491 | + $this->setSaveState(); |
|
492 | + } |
|
493 | + |
|
494 | + |
|
495 | + /** |
|
496 | + * @return \EE_Checkout |
|
497 | + */ |
|
498 | + public function checkout() |
|
499 | + { |
|
500 | + return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout |
|
501 | + ? $this->_session_data['checkout'] |
|
502 | + : null; |
|
503 | + } |
|
504 | + |
|
505 | + |
|
506 | + /** |
|
507 | + * @param \EE_Transaction $transaction |
|
508 | + * @return bool |
|
509 | + * @throws EE_Error |
|
510 | + */ |
|
511 | + public function set_transaction(EE_Transaction $transaction) |
|
512 | + { |
|
513 | + // first remove the session from the transaction before we save the transaction in the session |
|
514 | + $transaction->set_txn_session_data(null); |
|
515 | + $this->_session_data['transaction'] = $transaction; |
|
516 | + $this->setSaveState(); |
|
517 | + return true; |
|
518 | + } |
|
519 | + |
|
520 | + |
|
521 | + /** |
|
522 | + * reset_transaction |
|
523 | + */ |
|
524 | + public function reset_transaction() |
|
525 | + { |
|
526 | + do_action('AHEE__EE_Session__reset_transaction__before_reset', $this); |
|
527 | + $this->_session_data['transaction'] = null; |
|
528 | + $this->setSaveState(); |
|
529 | + } |
|
530 | + |
|
531 | + |
|
532 | + /** |
|
533 | + * @return \EE_Transaction |
|
534 | + */ |
|
535 | + public function transaction() |
|
536 | + { |
|
537 | + return isset($this->_session_data['transaction']) |
|
538 | + && $this->_session_data['transaction'] instanceof EE_Transaction |
|
539 | + ? $this->_session_data['transaction'] |
|
540 | + : null; |
|
541 | + } |
|
542 | + |
|
543 | + |
|
544 | + /** |
|
545 | + * retrieve session data |
|
546 | + * |
|
547 | + * @param null $key |
|
548 | + * @param bool $reset_cache |
|
549 | + * @return array |
|
550 | + */ |
|
551 | + public function get_session_data($key = null, $reset_cache = false) |
|
552 | + { |
|
553 | + if ($reset_cache) { |
|
554 | + $this->reset_cart(); |
|
555 | + $this->reset_checkout(); |
|
556 | + $this->reset_transaction(); |
|
557 | + } |
|
558 | + if (! empty($key)) { |
|
559 | + return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null; |
|
560 | + } |
|
561 | + return $this->_session_data; |
|
562 | + } |
|
563 | + |
|
564 | + |
|
565 | + /** |
|
566 | + * Returns TRUE on success, FALSE on fail |
|
567 | + * |
|
568 | + * @param array $data |
|
569 | + * @return bool |
|
570 | + */ |
|
571 | + public function set_session_data($data) |
|
572 | + { |
|
573 | + // nothing ??? bad data ??? go home! |
|
574 | + if (empty($data) || ! is_array($data)) { |
|
575 | + EE_Error::add_error( |
|
576 | + esc_html__( |
|
577 | + 'No session data or invalid session data was provided.', |
|
578 | + 'event_espresso' |
|
579 | + ), |
|
580 | + __FILE__, |
|
581 | + __FUNCTION__, |
|
582 | + __LINE__ |
|
583 | + ); |
|
584 | + return false; |
|
585 | + } |
|
586 | + foreach ($data as $key => $value) { |
|
587 | + if (isset($this->_default_session_vars[ $key ])) { |
|
588 | + EE_Error::add_error( |
|
589 | + sprintf( |
|
590 | + esc_html__( |
|
591 | + 'Sorry! %s is a default session datum and can not be reset.', |
|
592 | + 'event_espresso' |
|
593 | + ), |
|
594 | + $key |
|
595 | + ), |
|
596 | + __FILE__, |
|
597 | + __FUNCTION__, |
|
598 | + __LINE__ |
|
599 | + ); |
|
600 | + return false; |
|
601 | + } |
|
602 | + $this->_session_data[ $key ] = $value; |
|
603 | + $this->setSaveState(); |
|
604 | + } |
|
605 | + return true; |
|
606 | + } |
|
607 | + |
|
608 | + |
|
609 | + /** |
|
610 | + * @initiate session |
|
611 | + * @return bool TRUE on success, FALSE on fail |
|
612 | + * @throws EE_Error |
|
613 | + * @throws InvalidArgumentException |
|
614 | + * @throws InvalidDataTypeException |
|
615 | + * @throws InvalidInterfaceException |
|
616 | + * @throws InvalidSessionDataException |
|
617 | + * @throws RuntimeException |
|
618 | + * @throws ReflectionException |
|
619 | + */ |
|
620 | + private function _espresso_session() |
|
621 | + { |
|
622 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
623 | + $this->session_start_handler->startSession(); |
|
624 | + $this->status = EE_Session::STATUS_OPEN; |
|
625 | + // get our modified session ID |
|
626 | + $this->_sid = $this->_generate_session_id(); |
|
627 | + // and the visitors IP |
|
628 | + $this->_ip_address = $this->request->ipAddress(); |
|
629 | + // set the "user agent" |
|
630 | + $this->_user_agent = $this->request->userAgent(); |
|
631 | + // now let's retrieve what's in the db |
|
632 | + $session_data = $this->_retrieve_session_data(); |
|
633 | + if (! empty($session_data)) { |
|
634 | + // get the current time in UTC |
|
635 | + $this->_time = $this->_time !== null ? $this->_time : time(); |
|
636 | + // and reset the session expiration |
|
637 | + $this->_expiration = isset($session_data['expiration']) |
|
638 | + ? $session_data['expiration'] |
|
639 | + : $this->_time + $this->session_lifespan->inSeconds(); |
|
640 | + } else { |
|
641 | + // set initial site access time and the session expiration |
|
642 | + $this->_set_init_access_and_expiration(); |
|
643 | + // set referer |
|
644 | + $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = esc_attr( |
|
645 | + $this->request->getServerParam('HTTP_REFERER') |
|
646 | + ); |
|
647 | + // no previous session = go back and create one (on top of the data above) |
|
648 | + return false; |
|
649 | + } |
|
650 | + // now the user agent |
|
651 | + if ($session_data['user_agent'] !== $this->_user_agent) { |
|
652 | + return false; |
|
653 | + } |
|
654 | + // wait a minute... how old are you? |
|
655 | + if ($this->_time > $this->_expiration) { |
|
656 | + // yer too old fer me! |
|
657 | + $this->_expired = true; |
|
658 | + // wipe out everything that isn't a default session datum |
|
659 | + $this->clear_session(__CLASS__, __FUNCTION__); |
|
660 | + } |
|
661 | + // make event espresso session data available to plugin |
|
662 | + $this->_session_data = array_merge($this->_session_data, $session_data); |
|
663 | + return true; |
|
664 | + } |
|
665 | + |
|
666 | + |
|
667 | + /** |
|
668 | + * _get_session_data |
|
669 | + * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup |
|
670 | + * databases |
|
671 | + * |
|
672 | + * @return array |
|
673 | + * @throws EE_Error |
|
674 | + * @throws InvalidArgumentException |
|
675 | + * @throws InvalidSessionDataException |
|
676 | + * @throws InvalidDataTypeException |
|
677 | + * @throws InvalidInterfaceException |
|
678 | + * @throws RuntimeException |
|
679 | + */ |
|
680 | + protected function _retrieve_session_data() |
|
681 | + { |
|
682 | + $ssn_key = EE_Session::session_id_prefix . $this->_sid; |
|
683 | + try { |
|
684 | + // we're using WP's Transient API to store session data using the PHP session ID as the option name |
|
685 | + $session_data = $this->cache_storage->get($ssn_key, false); |
|
686 | + if (empty($session_data)) { |
|
687 | + return array(); |
|
688 | + } |
|
689 | + if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
690 | + $hash_check = $this->cache_storage->get( |
|
691 | + EE_Session::hash_check_prefix . $this->_sid, |
|
692 | + false |
|
693 | + ); |
|
694 | + if ($hash_check && $hash_check !== md5($session_data)) { |
|
695 | + EE_Error::add_error( |
|
696 | + sprintf( |
|
697 | + esc_html__( |
|
698 | + 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.', |
|
699 | + 'event_espresso' |
|
700 | + ), |
|
701 | + EE_Session::session_id_prefix . $this->_sid |
|
702 | + ), |
|
703 | + __FILE__, |
|
704 | + __FUNCTION__, |
|
705 | + __LINE__ |
|
706 | + ); |
|
707 | + } |
|
708 | + } |
|
709 | + } catch (Exception $e) { |
|
710 | + // let's just eat that error for now and attempt to correct any corrupted data |
|
711 | + global $wpdb; |
|
712 | + $row = $wpdb->get_row( |
|
713 | + $wpdb->prepare( |
|
714 | + "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", |
|
715 | + '_transient_' . $ssn_key |
|
716 | + ) |
|
717 | + ); |
|
718 | + $session_data = is_object($row) ? $row->option_value : null; |
|
719 | + if ($session_data) { |
|
720 | + $session_data = preg_replace_callback( |
|
721 | + '!s:(d+):"(.*?)";!', |
|
722 | + function ($match) { |
|
723 | + return $match[1] === strlen($match[2]) |
|
724 | + ? $match[0] |
|
725 | + : 's:' . strlen($match[2]) . ':"' . $match[2] . '";'; |
|
726 | + }, |
|
727 | + $session_data |
|
728 | + ); |
|
729 | + } |
|
730 | + $session_data = maybe_unserialize($session_data); |
|
731 | + } |
|
732 | + // in case the data is encoded... try to decode it |
|
733 | + $session_data = $this->encryption instanceof EE_Encryption |
|
734 | + ? $this->encryption->base64_string_decode($session_data) |
|
735 | + : $session_data; |
|
736 | + if (! is_array($session_data)) { |
|
737 | + try { |
|
738 | + $session_data = maybe_unserialize($session_data); |
|
739 | + } catch (Exception $e) { |
|
740 | + $msg = esc_html__( |
|
741 | + 'An error occurred while attempting to unserialize the session data.', |
|
742 | + 'event_espresso' |
|
743 | + ); |
|
744 | + $msg .= WP_DEBUG |
|
745 | + ? '<br><pre>' |
|
746 | + . print_r($session_data, true) |
|
747 | + . '</pre><br>' |
|
748 | + . $this->find_serialize_error($session_data) |
|
749 | + : ''; |
|
750 | + $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
751 | + throw new InvalidSessionDataException($msg, 0, $e); |
|
752 | + } |
|
753 | + } |
|
754 | + // just a check to make sure the session array is indeed an array |
|
755 | + if (! is_array($session_data)) { |
|
756 | + // no?!?! then something is wrong |
|
757 | + $msg = esc_html__( |
|
758 | + 'The session data is missing, invalid, or corrupted.', |
|
759 | + 'event_espresso' |
|
760 | + ); |
|
761 | + $msg .= WP_DEBUG |
|
762 | + ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data) |
|
763 | + : ''; |
|
764 | + $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid); |
|
765 | + throw new InvalidSessionDataException($msg); |
|
766 | + } |
|
767 | + if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) { |
|
768 | + $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID( |
|
769 | + $session_data['transaction'] |
|
770 | + ); |
|
771 | + } |
|
772 | + return $session_data; |
|
773 | + } |
|
774 | + |
|
775 | + |
|
776 | + /** |
|
777 | + * _generate_session_id |
|
778 | + * Retrieves the PHP session id either directly from the PHP session, |
|
779 | + * or from the request array if it was passed in from an AJAX request. |
|
780 | + * The session id is then salted and hashed (mmm sounds tasty) |
|
781 | + * so that it can be safely used as a request param |
|
782 | + * |
|
783 | + * @return string |
|
784 | + */ |
|
785 | + protected function _generate_session_id() |
|
786 | + { |
|
787 | + // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length |
|
788 | + $session_id = $this->request->requestParamIsSet('EESID') |
|
789 | + ? $this->request->getRequestParam('EESID') |
|
790 | + : md5(session_id() . get_current_blog_id() . $this->_get_sid_salt()); |
|
791 | + return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id); |
|
792 | + } |
|
793 | + |
|
794 | + |
|
795 | + /** |
|
796 | + * _get_sid_salt |
|
797 | + * |
|
798 | + * @return string |
|
799 | + */ |
|
800 | + protected function _get_sid_salt() |
|
801 | + { |
|
802 | + // was session id salt already saved to db ? |
|
803 | + if (empty($this->_sid_salt)) { |
|
804 | + // no? then maybe use WP defined constant |
|
805 | + if (defined('AUTH_SALT')) { |
|
806 | + $this->_sid_salt = AUTH_SALT; |
|
807 | + } |
|
808 | + // if salt doesn't exist or is too short |
|
809 | + if (strlen($this->_sid_salt) < 32) { |
|
810 | + // create a new one |
|
811 | + $this->_sid_salt = wp_generate_password(64); |
|
812 | + } |
|
813 | + // and save it as a permanent session setting |
|
814 | + $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt)); |
|
815 | + } |
|
816 | + return $this->_sid_salt; |
|
817 | + } |
|
818 | + |
|
819 | + |
|
820 | + /** |
|
821 | + * _set_init_access_and_expiration |
|
822 | + * |
|
823 | + * @return void |
|
824 | + */ |
|
825 | + protected function _set_init_access_and_expiration() |
|
826 | + { |
|
827 | + $this->_time = time(); |
|
828 | + $this->_expiration = $this->_time + $this->session_lifespan->inSeconds(); |
|
829 | + // set initial site access time |
|
830 | + $this->_session_data['init_access'] = $this->_time; |
|
831 | + // and the session expiration |
|
832 | + $this->_session_data['expiration'] = $this->_expiration; |
|
833 | + } |
|
834 | + |
|
835 | + |
|
836 | + /** |
|
837 | + * @update session data prior to saving to the db |
|
838 | + * @param bool $new_session |
|
839 | + * @return bool TRUE on success, FALSE on fail |
|
840 | + * @throws EE_Error |
|
841 | + * @throws InvalidArgumentException |
|
842 | + * @throws InvalidDataTypeException |
|
843 | + * @throws InvalidInterfaceException |
|
844 | + * @throws ReflectionException |
|
845 | + */ |
|
846 | + public function update($new_session = false) |
|
847 | + { |
|
848 | + $this->_session_data = is_array($this->_session_data) && isset($this->_session_data['id']) |
|
849 | + ? $this->_session_data |
|
850 | + : array(); |
|
851 | + if (empty($this->_session_data)) { |
|
852 | + $this->_set_defaults(); |
|
853 | + } |
|
854 | + $session_data = array(); |
|
855 | + foreach ($this->_session_data as $key => $value) { |
|
856 | + switch ($key) { |
|
857 | + case 'id': |
|
858 | + // session ID |
|
859 | + $session_data['id'] = $this->_sid; |
|
860 | + break; |
|
861 | + case 'ip_address': |
|
862 | + // visitor ip address |
|
863 | + $session_data['ip_address'] = $this->request->ipAddress(); |
|
864 | + break; |
|
865 | + case 'user_agent': |
|
866 | + // visitor user_agent |
|
867 | + $session_data['user_agent'] = $this->_user_agent; |
|
868 | + break; |
|
869 | + case 'init_access': |
|
870 | + $session_data['init_access'] = absint($value); |
|
871 | + break; |
|
872 | + case 'last_access': |
|
873 | + // current access time |
|
874 | + $session_data['last_access'] = $this->_time; |
|
875 | + break; |
|
876 | + case 'expiration': |
|
877 | + // when the session expires |
|
878 | + $session_data['expiration'] = ! empty($this->_expiration) |
|
879 | + ? $this->_expiration |
|
880 | + : $session_data['init_access'] + $this->session_lifespan->inSeconds(); |
|
881 | + break; |
|
882 | + case 'user_id': |
|
883 | + // current user if logged in |
|
884 | + $session_data['user_id'] = $this->_wp_user_id(); |
|
885 | + break; |
|
886 | + case 'pages_visited': |
|
887 | + $page_visit = $this->_get_page_visit(); |
|
888 | + if ($page_visit) { |
|
889 | + // set pages visited where the first will be the http referrer |
|
890 | + $this->_session_data['pages_visited'][ $this->_time ] = $page_visit; |
|
891 | + // we'll only save the last 10 page visits. |
|
892 | + $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10); |
|
893 | + } |
|
894 | + break; |
|
895 | + default: |
|
896 | + // carry any other data over |
|
897 | + $session_data[ $key ] = $this->_session_data[ $key ]; |
|
898 | + } |
|
899 | + } |
|
900 | + $this->_session_data = $session_data; |
|
901 | + // creating a new session does not require saving to the db just yet |
|
902 | + if (! $new_session) { |
|
903 | + // ready? let's save |
|
904 | + if ($this->_save_session_to_db()) { |
|
905 | + return true; |
|
906 | + } |
|
907 | + return false; |
|
908 | + } |
|
909 | + // meh, why not? |
|
910 | + return true; |
|
911 | + } |
|
912 | + |
|
913 | + |
|
914 | + /** |
|
915 | + * @create session data array |
|
916 | + * @throws EE_Error |
|
917 | + * @throws InvalidArgumentException |
|
918 | + * @throws InvalidDataTypeException |
|
919 | + * @throws InvalidInterfaceException |
|
920 | + * @throws ReflectionException |
|
921 | + */ |
|
922 | + private function _create_espresso_session() |
|
923 | + { |
|
924 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, ''); |
|
925 | + // use the update function for now with $new_session arg set to TRUE |
|
926 | + $this->update(true); |
|
927 | + } |
|
928 | + |
|
929 | + /** |
|
930 | + * Detects if there is anything worth saving in the session (eg the cart is a good one, notices are pretty good |
|
931 | + * too). This is used when determining if we want to save the session or not. |
|
932 | + * @since 4.9.67.p |
|
933 | + * @return bool |
|
934 | + */ |
|
935 | + private function sessionHasStuffWorthSaving() |
|
936 | + { |
|
937 | + return $this->save_state === EE_Session::SAVE_STATE_DIRTY |
|
938 | + // we may want to eventually remove the following |
|
939 | + // on the assumption that the above check is enough |
|
940 | + || $this->cart() instanceof EE_Cart |
|
941 | + || ( |
|
942 | + isset($this->_session_data['ee_notices']) |
|
943 | + && ( |
|
944 | + ! empty($this->_session_data['ee_notices']['attention']) |
|
945 | + || ! empty($this->_session_data['ee_notices']['errors']) |
|
946 | + || ! empty($this->_session_data['ee_notices']['success']) |
|
947 | + ) |
|
948 | + ); |
|
949 | + } |
|
950 | + |
|
951 | + |
|
952 | + /** |
|
953 | + * _save_session_to_db |
|
954 | + * |
|
955 | + * @param bool $clear_session |
|
956 | + * @return bool |
|
957 | + * @throws EE_Error |
|
958 | + * @throws InvalidArgumentException |
|
959 | + * @throws InvalidDataTypeException |
|
960 | + * @throws InvalidInterfaceException |
|
961 | + * @throws ReflectionException |
|
962 | + */ |
|
963 | + private function _save_session_to_db($clear_session = false) |
|
964 | + { |
|
965 | + // don't save sessions for crawlers |
|
966 | + // and unless we're deleting the session data, don't save anything if there isn't a cart |
|
967 | + if ( |
|
968 | + $this->request->isBot() |
|
969 | + || ( |
|
970 | + ! $clear_session |
|
971 | + && ! $this->sessionHasStuffWorthSaving() |
|
972 | + && apply_filters('FHEE__EE_Session___save_session_to_db__abort_session_save', true) |
|
973 | + ) |
|
974 | + ) { |
|
975 | + return false; |
|
976 | + } |
|
977 | + $transaction = $this->transaction(); |
|
978 | + if ($transaction instanceof EE_Transaction) { |
|
979 | + if (! $transaction->ID()) { |
|
980 | + $transaction->save(); |
|
981 | + } |
|
982 | + $this->_session_data['transaction'] = $transaction->ID(); |
|
983 | + } |
|
984 | + // then serialize all of our session data |
|
985 | + $session_data = serialize($this->_session_data); |
|
986 | + // do we need to also encode it to avoid corrupted data when saved to the db? |
|
987 | + $session_data = $this->_use_encryption |
|
988 | + ? $this->encryption->base64_string_encode($session_data) |
|
989 | + : $session_data; |
|
990 | + // maybe save hash check |
|
991 | + if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) { |
|
992 | + $this->cache_storage->add( |
|
993 | + EE_Session::hash_check_prefix . $this->_sid, |
|
994 | + md5($session_data), |
|
995 | + $this->session_lifespan->inSeconds() |
|
996 | + ); |
|
997 | + } |
|
998 | + // we're using the Transient API for storing session data, |
|
999 | + $saved = $this->cache_storage->add( |
|
1000 | + EE_Session::session_id_prefix . $this->_sid, |
|
1001 | + $session_data, |
|
1002 | + $this->session_lifespan->inSeconds() |
|
1003 | + ); |
|
1004 | + $this->setSaveState(EE_Session::SAVE_STATE_CLEAN); |
|
1005 | + return $saved; |
|
1006 | + } |
|
1007 | + |
|
1008 | + |
|
1009 | + /** |
|
1010 | + * @get the full page request the visitor is accessing |
|
1011 | + * @return string |
|
1012 | + */ |
|
1013 | + public function _get_page_visit() |
|
1014 | + { |
|
1015 | + $page_visit = home_url('/') . 'wp-admin/admin-ajax.php'; |
|
1016 | + // check for request url |
|
1017 | + if ($this->request->serverParamIsSet('REQUEST_URI')) { |
|
1018 | + $page_id = '?'; |
|
1019 | + $e_reg = ''; |
|
1020 | + $request_uri = $this->request->getServerParam('REQUEST_URI'); |
|
1021 | + $ru_bits = explode('?', $request_uri); |
|
1022 | + $request_uri = $ru_bits[0]; |
|
1023 | + $http_host = $this->request->getServerParam('HTTP_HOST'); |
|
1024 | + // check for page_id in SERVER REQUEST |
|
1025 | + if ($this->request->requestParamIsSet('page_id')) { |
|
1026 | + // rebuild $e_reg without any of the extra parameters |
|
1027 | + $page_id .= 'page_id=' . $this->request->getRequestParam('page_id', 0, 'int') . '&'; |
|
1028 | + } |
|
1029 | + // check for $e_reg in SERVER REQUEST |
|
1030 | + if ($this->request->requestParamIsSet('ee')) { |
|
1031 | + // rebuild $e_reg without any of the extra parameters |
|
1032 | + $e_reg = 'ee=' . $this->request->getRequestParam('ee'); |
|
1033 | + } |
|
1034 | + $page_visit = esc_url(rtrim($http_host . $request_uri . $page_id . $e_reg, '?')); |
|
1035 | + } |
|
1036 | + return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : ''; |
|
1037 | + } |
|
1038 | + |
|
1039 | + |
|
1040 | + /** |
|
1041 | + * @the current wp user id |
|
1042 | + * @return int |
|
1043 | + */ |
|
1044 | + public function _wp_user_id() |
|
1045 | + { |
|
1046 | + // if I need to explain the following lines of code, then you shouldn't be looking at this! |
|
1047 | + $this->_wp_user_id = get_current_user_id(); |
|
1048 | + return $this->_wp_user_id; |
|
1049 | + } |
|
1050 | + |
|
1051 | + |
|
1052 | + /** |
|
1053 | + * Clear EE_Session data |
|
1054 | + * |
|
1055 | + * @param string $class |
|
1056 | + * @param string $function |
|
1057 | + * @return void |
|
1058 | + * @throws EE_Error |
|
1059 | + * @throws InvalidArgumentException |
|
1060 | + * @throws InvalidDataTypeException |
|
1061 | + * @throws InvalidInterfaceException |
|
1062 | + * @throws ReflectionException |
|
1063 | + */ |
|
1064 | + public function clear_session($class = '', $function = '') |
|
1065 | + { |
|
1066 | 1066 | // echo ' |
1067 | 1067 | // <h3 style="color:#999;line-height:.9em;"> |
1068 | 1068 | // <span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/> |
1069 | 1069 | // <span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span> <b style="font-size:10px;"> ' . __LINE__ . ' </b> |
1070 | 1070 | // </h3>'; |
1071 | - do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()'); |
|
1072 | - $this->reset_cart(); |
|
1073 | - $this->reset_checkout(); |
|
1074 | - $this->reset_transaction(); |
|
1075 | - // wipe out everything that isn't a default session datum |
|
1076 | - $this->reset_data(array_keys($this->_session_data)); |
|
1077 | - // reset initial site access time and the session expiration |
|
1078 | - $this->_set_init_access_and_expiration(); |
|
1079 | - $this->setSaveState(); |
|
1080 | - $this->_save_session_to_db(true); |
|
1081 | - } |
|
1082 | - |
|
1083 | - |
|
1084 | - /** |
|
1085 | - * resets all non-default session vars. Returns TRUE on success, FALSE on fail |
|
1086 | - * |
|
1087 | - * @param array|mixed $data_to_reset |
|
1088 | - * @param bool $show_all_notices |
|
1089 | - * @return bool |
|
1090 | - */ |
|
1091 | - public function reset_data($data_to_reset = array(), $show_all_notices = false) |
|
1092 | - { |
|
1093 | - // if $data_to_reset is not in an array, then put it in one |
|
1094 | - if (! is_array($data_to_reset)) { |
|
1095 | - $data_to_reset = array($data_to_reset); |
|
1096 | - } |
|
1097 | - // nothing ??? go home! |
|
1098 | - if (empty($data_to_reset)) { |
|
1099 | - EE_Error::add_error( |
|
1100 | - esc_html__( |
|
1101 | - 'No session data could be reset, because no session var name was provided.', |
|
1102 | - 'event_espresso' |
|
1103 | - ), |
|
1104 | - __FILE__, |
|
1105 | - __FUNCTION__, |
|
1106 | - __LINE__ |
|
1107 | - ); |
|
1108 | - return false; |
|
1109 | - } |
|
1110 | - $return_value = true; |
|
1111 | - // since $data_to_reset is an array, cycle through the values |
|
1112 | - foreach ($data_to_reset as $reset) { |
|
1113 | - // first check to make sure it is a valid session var |
|
1114 | - if (isset($this->_session_data[ $reset ])) { |
|
1115 | - // then check to make sure it is not a default var |
|
1116 | - if (! array_key_exists($reset, $this->_default_session_vars)) { |
|
1117 | - // remove session var |
|
1118 | - unset($this->_session_data[ $reset ]); |
|
1119 | - $this->setSaveState(); |
|
1120 | - if ($show_all_notices) { |
|
1121 | - EE_Error::add_success( |
|
1122 | - sprintf( |
|
1123 | - esc_html__('The session variable %s was removed.', 'event_espresso'), |
|
1124 | - $reset |
|
1125 | - ), |
|
1126 | - __FILE__, |
|
1127 | - __FUNCTION__, |
|
1128 | - __LINE__ |
|
1129 | - ); |
|
1130 | - } |
|
1131 | - } else { |
|
1132 | - // yeeeeeeeeerrrrrrrrrrr OUT !!!! |
|
1133 | - if ($show_all_notices) { |
|
1134 | - EE_Error::add_error( |
|
1135 | - sprintf( |
|
1136 | - esc_html__( |
|
1137 | - 'Sorry! %s is a default session datum and can not be reset.', |
|
1138 | - 'event_espresso' |
|
1139 | - ), |
|
1140 | - $reset |
|
1141 | - ), |
|
1142 | - __FILE__, |
|
1143 | - __FUNCTION__, |
|
1144 | - __LINE__ |
|
1145 | - ); |
|
1146 | - } |
|
1147 | - $return_value = false; |
|
1148 | - } |
|
1149 | - } elseif ($show_all_notices) { |
|
1150 | - // oops! that session var does not exist! |
|
1151 | - EE_Error::add_error( |
|
1152 | - sprintf( |
|
1153 | - esc_html__( |
|
1154 | - 'The session item provided, %s, is invalid or does not exist.', |
|
1155 | - 'event_espresso' |
|
1156 | - ), |
|
1157 | - $reset |
|
1158 | - ), |
|
1159 | - __FILE__, |
|
1160 | - __FUNCTION__, |
|
1161 | - __LINE__ |
|
1162 | - ); |
|
1163 | - $return_value = false; |
|
1164 | - } |
|
1165 | - } // end of foreach |
|
1166 | - return $return_value; |
|
1167 | - } |
|
1168 | - |
|
1169 | - |
|
1170 | - /** |
|
1171 | - * wp_loaded |
|
1172 | - * |
|
1173 | - * @throws EE_Error |
|
1174 | - * @throws InvalidDataTypeException |
|
1175 | - * @throws InvalidInterfaceException |
|
1176 | - * @throws InvalidArgumentException |
|
1177 | - * @throws ReflectionException |
|
1178 | - */ |
|
1179 | - public function wp_loaded() |
|
1180 | - { |
|
1181 | - if ($this->request->requestParamIsSet('clear_session')) { |
|
1182 | - $this->clear_session(__CLASS__, __FUNCTION__); |
|
1183 | - } |
|
1184 | - } |
|
1185 | - |
|
1186 | - |
|
1187 | - /** |
|
1188 | - * Used to reset the entire object (for tests). |
|
1189 | - * |
|
1190 | - * @since 4.3.0 |
|
1191 | - * @throws EE_Error |
|
1192 | - * @throws InvalidDataTypeException |
|
1193 | - * @throws InvalidInterfaceException |
|
1194 | - * @throws InvalidArgumentException |
|
1195 | - * @throws ReflectionException |
|
1196 | - */ |
|
1197 | - public function reset_instance() |
|
1198 | - { |
|
1199 | - $this->clear_session(); |
|
1200 | - self::$_instance = null; |
|
1201 | - } |
|
1202 | - |
|
1203 | - |
|
1204 | - public function configure_garbage_collection_filters() |
|
1205 | - { |
|
1206 | - // run old filter we had for controlling session cleanup |
|
1207 | - $expired_session_transient_delete_query_limit = absint( |
|
1208 | - apply_filters( |
|
1209 | - 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1210 | - 50 |
|
1211 | - ) |
|
1212 | - ); |
|
1213 | - // is there a value? or one that is different than the default 50 records? |
|
1214 | - if ($expired_session_transient_delete_query_limit === 0) { |
|
1215 | - // hook into TransientCacheStorage in case Session cleanup was turned off |
|
1216 | - add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero'); |
|
1217 | - } elseif ($expired_session_transient_delete_query_limit !== 50) { |
|
1218 | - // or use that for the new transient cleanup query limit |
|
1219 | - add_filter( |
|
1220 | - 'FHEE__TransientCacheStorage__clearExpiredTransients__limit', |
|
1221 | - function () use ($expired_session_transient_delete_query_limit) { |
|
1222 | - return $expired_session_transient_delete_query_limit; |
|
1223 | - } |
|
1224 | - ); |
|
1225 | - } |
|
1226 | - } |
|
1227 | - |
|
1228 | - |
|
1229 | - /** |
|
1230 | - * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996 |
|
1231 | - * @param $data1 |
|
1232 | - * @return string |
|
1233 | - */ |
|
1234 | - private function find_serialize_error($data1) |
|
1235 | - { |
|
1236 | - $error = '<pre>'; |
|
1237 | - $data2 = preg_replace_callback( |
|
1238 | - '!s:(\d+):"(.*?)";!', |
|
1239 | - function ($match) { |
|
1240 | - return ($match[1] === strlen($match[2])) |
|
1241 | - ? $match[0] |
|
1242 | - : 's:' |
|
1243 | - . strlen($match[2]) |
|
1244 | - . ':"' |
|
1245 | - . $match[2] |
|
1246 | - . '";'; |
|
1247 | - }, |
|
1248 | - $data1 |
|
1249 | - ); |
|
1250 | - $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2); |
|
1251 | - $error .= $data1 . PHP_EOL; |
|
1252 | - $error .= $data2 . PHP_EOL; |
|
1253 | - for ($i = 0; $i < $max; $i++) { |
|
1254 | - if (@$data1[ $i ] !== @$data2[ $i ]) { |
|
1255 | - $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL; |
|
1256 | - $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL; |
|
1257 | - $error .= "\t-> Line Number = $i" . PHP_EOL; |
|
1258 | - $start = ($i - 20); |
|
1259 | - $start = ($start < 0) ? 0 : $start; |
|
1260 | - $length = 40; |
|
1261 | - $point = $max - $i; |
|
1262 | - if ($point < 20) { |
|
1263 | - $rlength = 1; |
|
1264 | - $rpoint = -$point; |
|
1265 | - } else { |
|
1266 | - $rpoint = $length - 20; |
|
1267 | - $rlength = 1; |
|
1268 | - } |
|
1269 | - $error .= "\t-> Section Data1 = "; |
|
1270 | - $error .= substr_replace( |
|
1271 | - substr($data1, $start, $length), |
|
1272 | - "<b style=\"color:green\">{$data1[ $i ]}</b>", |
|
1273 | - $rpoint, |
|
1274 | - $rlength |
|
1275 | - ); |
|
1276 | - $error .= PHP_EOL; |
|
1277 | - $error .= "\t-> Section Data2 = "; |
|
1278 | - $error .= substr_replace( |
|
1279 | - substr($data2, $start, $length), |
|
1280 | - "<b style=\"color:red\">{$data2[ $i ]}</b>", |
|
1281 | - $rpoint, |
|
1282 | - $rlength |
|
1283 | - ); |
|
1284 | - $error .= PHP_EOL; |
|
1285 | - } |
|
1286 | - } |
|
1287 | - $error .= '</pre>'; |
|
1288 | - return $error; |
|
1289 | - } |
|
1290 | - |
|
1291 | - |
|
1292 | - /** |
|
1293 | - * Saves an array of settings used for configuring aspects of session behaviour |
|
1294 | - * |
|
1295 | - * @param array $updated_settings |
|
1296 | - */ |
|
1297 | - private function updateSessionSettings(array $updated_settings = array()) |
|
1298 | - { |
|
1299 | - // add existing settings, but only if not included in incoming $updated_settings array |
|
1300 | - $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array()); |
|
1301 | - update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings); |
|
1302 | - } |
|
1303 | - |
|
1304 | - |
|
1305 | - /** |
|
1306 | - * garbage_collection |
|
1307 | - */ |
|
1308 | - public function garbageCollection() |
|
1309 | - { |
|
1310 | - // only perform during regular requests if last garbage collection was over an hour ago |
|
1311 | - if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1312 | - $this->_last_gc = time(); |
|
1313 | - $this->updateSessionSettings(array('last_gc' => $this->_last_gc)); |
|
1314 | - /** @type WPDB $wpdb */ |
|
1315 | - global $wpdb; |
|
1316 | - // filter the query limit. Set to 0 to turn off garbage collection |
|
1317 | - $expired_session_transient_delete_query_limit = absint( |
|
1318 | - apply_filters( |
|
1319 | - 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1320 | - 50 |
|
1321 | - ) |
|
1322 | - ); |
|
1323 | - // non-zero LIMIT means take out the trash |
|
1324 | - if ($expired_session_transient_delete_query_limit) { |
|
1325 | - $session_key = str_replace('_', '\_', EE_Session::session_id_prefix); |
|
1326 | - $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix); |
|
1327 | - // since transient expiration timestamps are set in the future, we can compare against NOW |
|
1328 | - // but we only want to pick up any trash that's been around for more than a day |
|
1329 | - $expiration = time() - DAY_IN_SECONDS; |
|
1330 | - $SQL = " |
|
1071 | + do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()'); |
|
1072 | + $this->reset_cart(); |
|
1073 | + $this->reset_checkout(); |
|
1074 | + $this->reset_transaction(); |
|
1075 | + // wipe out everything that isn't a default session datum |
|
1076 | + $this->reset_data(array_keys($this->_session_data)); |
|
1077 | + // reset initial site access time and the session expiration |
|
1078 | + $this->_set_init_access_and_expiration(); |
|
1079 | + $this->setSaveState(); |
|
1080 | + $this->_save_session_to_db(true); |
|
1081 | + } |
|
1082 | + |
|
1083 | + |
|
1084 | + /** |
|
1085 | + * resets all non-default session vars. Returns TRUE on success, FALSE on fail |
|
1086 | + * |
|
1087 | + * @param array|mixed $data_to_reset |
|
1088 | + * @param bool $show_all_notices |
|
1089 | + * @return bool |
|
1090 | + */ |
|
1091 | + public function reset_data($data_to_reset = array(), $show_all_notices = false) |
|
1092 | + { |
|
1093 | + // if $data_to_reset is not in an array, then put it in one |
|
1094 | + if (! is_array($data_to_reset)) { |
|
1095 | + $data_to_reset = array($data_to_reset); |
|
1096 | + } |
|
1097 | + // nothing ??? go home! |
|
1098 | + if (empty($data_to_reset)) { |
|
1099 | + EE_Error::add_error( |
|
1100 | + esc_html__( |
|
1101 | + 'No session data could be reset, because no session var name was provided.', |
|
1102 | + 'event_espresso' |
|
1103 | + ), |
|
1104 | + __FILE__, |
|
1105 | + __FUNCTION__, |
|
1106 | + __LINE__ |
|
1107 | + ); |
|
1108 | + return false; |
|
1109 | + } |
|
1110 | + $return_value = true; |
|
1111 | + // since $data_to_reset is an array, cycle through the values |
|
1112 | + foreach ($data_to_reset as $reset) { |
|
1113 | + // first check to make sure it is a valid session var |
|
1114 | + if (isset($this->_session_data[ $reset ])) { |
|
1115 | + // then check to make sure it is not a default var |
|
1116 | + if (! array_key_exists($reset, $this->_default_session_vars)) { |
|
1117 | + // remove session var |
|
1118 | + unset($this->_session_data[ $reset ]); |
|
1119 | + $this->setSaveState(); |
|
1120 | + if ($show_all_notices) { |
|
1121 | + EE_Error::add_success( |
|
1122 | + sprintf( |
|
1123 | + esc_html__('The session variable %s was removed.', 'event_espresso'), |
|
1124 | + $reset |
|
1125 | + ), |
|
1126 | + __FILE__, |
|
1127 | + __FUNCTION__, |
|
1128 | + __LINE__ |
|
1129 | + ); |
|
1130 | + } |
|
1131 | + } else { |
|
1132 | + // yeeeeeeeeerrrrrrrrrrr OUT !!!! |
|
1133 | + if ($show_all_notices) { |
|
1134 | + EE_Error::add_error( |
|
1135 | + sprintf( |
|
1136 | + esc_html__( |
|
1137 | + 'Sorry! %s is a default session datum and can not be reset.', |
|
1138 | + 'event_espresso' |
|
1139 | + ), |
|
1140 | + $reset |
|
1141 | + ), |
|
1142 | + __FILE__, |
|
1143 | + __FUNCTION__, |
|
1144 | + __LINE__ |
|
1145 | + ); |
|
1146 | + } |
|
1147 | + $return_value = false; |
|
1148 | + } |
|
1149 | + } elseif ($show_all_notices) { |
|
1150 | + // oops! that session var does not exist! |
|
1151 | + EE_Error::add_error( |
|
1152 | + sprintf( |
|
1153 | + esc_html__( |
|
1154 | + 'The session item provided, %s, is invalid or does not exist.', |
|
1155 | + 'event_espresso' |
|
1156 | + ), |
|
1157 | + $reset |
|
1158 | + ), |
|
1159 | + __FILE__, |
|
1160 | + __FUNCTION__, |
|
1161 | + __LINE__ |
|
1162 | + ); |
|
1163 | + $return_value = false; |
|
1164 | + } |
|
1165 | + } // end of foreach |
|
1166 | + return $return_value; |
|
1167 | + } |
|
1168 | + |
|
1169 | + |
|
1170 | + /** |
|
1171 | + * wp_loaded |
|
1172 | + * |
|
1173 | + * @throws EE_Error |
|
1174 | + * @throws InvalidDataTypeException |
|
1175 | + * @throws InvalidInterfaceException |
|
1176 | + * @throws InvalidArgumentException |
|
1177 | + * @throws ReflectionException |
|
1178 | + */ |
|
1179 | + public function wp_loaded() |
|
1180 | + { |
|
1181 | + if ($this->request->requestParamIsSet('clear_session')) { |
|
1182 | + $this->clear_session(__CLASS__, __FUNCTION__); |
|
1183 | + } |
|
1184 | + } |
|
1185 | + |
|
1186 | + |
|
1187 | + /** |
|
1188 | + * Used to reset the entire object (for tests). |
|
1189 | + * |
|
1190 | + * @since 4.3.0 |
|
1191 | + * @throws EE_Error |
|
1192 | + * @throws InvalidDataTypeException |
|
1193 | + * @throws InvalidInterfaceException |
|
1194 | + * @throws InvalidArgumentException |
|
1195 | + * @throws ReflectionException |
|
1196 | + */ |
|
1197 | + public function reset_instance() |
|
1198 | + { |
|
1199 | + $this->clear_session(); |
|
1200 | + self::$_instance = null; |
|
1201 | + } |
|
1202 | + |
|
1203 | + |
|
1204 | + public function configure_garbage_collection_filters() |
|
1205 | + { |
|
1206 | + // run old filter we had for controlling session cleanup |
|
1207 | + $expired_session_transient_delete_query_limit = absint( |
|
1208 | + apply_filters( |
|
1209 | + 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1210 | + 50 |
|
1211 | + ) |
|
1212 | + ); |
|
1213 | + // is there a value? or one that is different than the default 50 records? |
|
1214 | + if ($expired_session_transient_delete_query_limit === 0) { |
|
1215 | + // hook into TransientCacheStorage in case Session cleanup was turned off |
|
1216 | + add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero'); |
|
1217 | + } elseif ($expired_session_transient_delete_query_limit !== 50) { |
|
1218 | + // or use that for the new transient cleanup query limit |
|
1219 | + add_filter( |
|
1220 | + 'FHEE__TransientCacheStorage__clearExpiredTransients__limit', |
|
1221 | + function () use ($expired_session_transient_delete_query_limit) { |
|
1222 | + return $expired_session_transient_delete_query_limit; |
|
1223 | + } |
|
1224 | + ); |
|
1225 | + } |
|
1226 | + } |
|
1227 | + |
|
1228 | + |
|
1229 | + /** |
|
1230 | + * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996 |
|
1231 | + * @param $data1 |
|
1232 | + * @return string |
|
1233 | + */ |
|
1234 | + private function find_serialize_error($data1) |
|
1235 | + { |
|
1236 | + $error = '<pre>'; |
|
1237 | + $data2 = preg_replace_callback( |
|
1238 | + '!s:(\d+):"(.*?)";!', |
|
1239 | + function ($match) { |
|
1240 | + return ($match[1] === strlen($match[2])) |
|
1241 | + ? $match[0] |
|
1242 | + : 's:' |
|
1243 | + . strlen($match[2]) |
|
1244 | + . ':"' |
|
1245 | + . $match[2] |
|
1246 | + . '";'; |
|
1247 | + }, |
|
1248 | + $data1 |
|
1249 | + ); |
|
1250 | + $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2); |
|
1251 | + $error .= $data1 . PHP_EOL; |
|
1252 | + $error .= $data2 . PHP_EOL; |
|
1253 | + for ($i = 0; $i < $max; $i++) { |
|
1254 | + if (@$data1[ $i ] !== @$data2[ $i ]) { |
|
1255 | + $error .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL; |
|
1256 | + $error .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL; |
|
1257 | + $error .= "\t-> Line Number = $i" . PHP_EOL; |
|
1258 | + $start = ($i - 20); |
|
1259 | + $start = ($start < 0) ? 0 : $start; |
|
1260 | + $length = 40; |
|
1261 | + $point = $max - $i; |
|
1262 | + if ($point < 20) { |
|
1263 | + $rlength = 1; |
|
1264 | + $rpoint = -$point; |
|
1265 | + } else { |
|
1266 | + $rpoint = $length - 20; |
|
1267 | + $rlength = 1; |
|
1268 | + } |
|
1269 | + $error .= "\t-> Section Data1 = "; |
|
1270 | + $error .= substr_replace( |
|
1271 | + substr($data1, $start, $length), |
|
1272 | + "<b style=\"color:green\">{$data1[ $i ]}</b>", |
|
1273 | + $rpoint, |
|
1274 | + $rlength |
|
1275 | + ); |
|
1276 | + $error .= PHP_EOL; |
|
1277 | + $error .= "\t-> Section Data2 = "; |
|
1278 | + $error .= substr_replace( |
|
1279 | + substr($data2, $start, $length), |
|
1280 | + "<b style=\"color:red\">{$data2[ $i ]}</b>", |
|
1281 | + $rpoint, |
|
1282 | + $rlength |
|
1283 | + ); |
|
1284 | + $error .= PHP_EOL; |
|
1285 | + } |
|
1286 | + } |
|
1287 | + $error .= '</pre>'; |
|
1288 | + return $error; |
|
1289 | + } |
|
1290 | + |
|
1291 | + |
|
1292 | + /** |
|
1293 | + * Saves an array of settings used for configuring aspects of session behaviour |
|
1294 | + * |
|
1295 | + * @param array $updated_settings |
|
1296 | + */ |
|
1297 | + private function updateSessionSettings(array $updated_settings = array()) |
|
1298 | + { |
|
1299 | + // add existing settings, but only if not included in incoming $updated_settings array |
|
1300 | + $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array()); |
|
1301 | + update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings); |
|
1302 | + } |
|
1303 | + |
|
1304 | + |
|
1305 | + /** |
|
1306 | + * garbage_collection |
|
1307 | + */ |
|
1308 | + public function garbageCollection() |
|
1309 | + { |
|
1310 | + // only perform during regular requests if last garbage collection was over an hour ago |
|
1311 | + if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) { |
|
1312 | + $this->_last_gc = time(); |
|
1313 | + $this->updateSessionSettings(array('last_gc' => $this->_last_gc)); |
|
1314 | + /** @type WPDB $wpdb */ |
|
1315 | + global $wpdb; |
|
1316 | + // filter the query limit. Set to 0 to turn off garbage collection |
|
1317 | + $expired_session_transient_delete_query_limit = absint( |
|
1318 | + apply_filters( |
|
1319 | + 'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit', |
|
1320 | + 50 |
|
1321 | + ) |
|
1322 | + ); |
|
1323 | + // non-zero LIMIT means take out the trash |
|
1324 | + if ($expired_session_transient_delete_query_limit) { |
|
1325 | + $session_key = str_replace('_', '\_', EE_Session::session_id_prefix); |
|
1326 | + $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix); |
|
1327 | + // since transient expiration timestamps are set in the future, we can compare against NOW |
|
1328 | + // but we only want to pick up any trash that's been around for more than a day |
|
1329 | + $expiration = time() - DAY_IN_SECONDS; |
|
1330 | + $SQL = " |
|
1331 | 1331 | SELECT option_name |
1332 | 1332 | FROM {$wpdb->options} |
1333 | 1333 | WHERE |
@@ -1336,17 +1336,17 @@ discard block |
||
1336 | 1336 | AND option_value < {$expiration} |
1337 | 1337 | LIMIT {$expired_session_transient_delete_query_limit} |
1338 | 1338 | "; |
1339 | - // produces something like: |
|
1340 | - // SELECT option_name FROM wp_options |
|
1341 | - // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%' |
|
1342 | - // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' ) |
|
1343 | - // AND option_value < 1508368198 LIMIT 50 |
|
1344 | - $expired_sessions = $wpdb->get_col($SQL); |
|
1345 | - // valid results? |
|
1346 | - if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1347 | - $this->cache_storage->deleteMany($expired_sessions, true); |
|
1348 | - } |
|
1349 | - } |
|
1350 | - } |
|
1351 | - } |
|
1339 | + // produces something like: |
|
1340 | + // SELECT option_name FROM wp_options |
|
1341 | + // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%' |
|
1342 | + // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' ) |
|
1343 | + // AND option_value < 1508368198 LIMIT 50 |
|
1344 | + $expired_sessions = $wpdb->get_col($SQL); |
|
1345 | + // valid results? |
|
1346 | + if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) { |
|
1347 | + $this->cache_storage->deleteMany($expired_sessions, true); |
|
1348 | + } |
|
1349 | + } |
|
1350 | + } |
|
1351 | + } |
|
1352 | 1352 | } |
@@ -19,798 +19,798 @@ discard block |
||
19 | 19 | { |
20 | 20 | |
21 | 21 | |
22 | - /** |
|
23 | - * prefix to be added onto an addon's plugin slug to make a wp option name |
|
24 | - * which will be used to store the plugin's activation history |
|
25 | - */ |
|
26 | - const ee_addon_version_history_option_prefix = 'ee_version_history_'; |
|
27 | - |
|
28 | - /** |
|
29 | - * @var $_version |
|
30 | - * @type string |
|
31 | - */ |
|
32 | - protected $_version = ''; |
|
33 | - |
|
34 | - /** |
|
35 | - * @var $_min_core_version |
|
36 | - * @type string |
|
37 | - */ |
|
38 | - protected $_min_core_version = ''; |
|
39 | - |
|
40 | - /** |
|
41 | - * derived from plugin 'main_file_path using plugin_basename() |
|
42 | - * |
|
43 | - * @type string $_plugin_basename |
|
44 | - */ |
|
45 | - protected $_plugin_basename = ''; |
|
46 | - |
|
47 | - /** |
|
48 | - * A non-internationalized name to identify this addon for use in URLs, etc |
|
49 | - * |
|
50 | - * @type string $_plugin_slug |
|
51 | - */ |
|
52 | - protected $_plugin_slug = ''; |
|
53 | - |
|
54 | - /** |
|
55 | - * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/ |
|
56 | - * |
|
57 | - * @type string _addon_name |
|
58 | - */ |
|
59 | - protected $_addon_name = ''; |
|
60 | - |
|
61 | - /** |
|
62 | - * one of the EE_System::req_type_* constants |
|
63 | - * |
|
64 | - * @type int $_req_type |
|
65 | - */ |
|
66 | - protected $_req_type; |
|
67 | - |
|
68 | - /** |
|
69 | - * page slug to be used when generating the "Settings" link on the WP plugin page |
|
70 | - * |
|
71 | - * @type string $_plugin_action_slug |
|
72 | - */ |
|
73 | - protected $_plugin_action_slug = ''; |
|
74 | - |
|
75 | - /** |
|
76 | - * if not empty, inserts a new table row after this plugin's row on the WP Plugins page |
|
77 | - * that can be used for adding upgrading/marketing info |
|
78 | - * |
|
79 | - * @type array $_plugins_page_row |
|
80 | - */ |
|
81 | - protected $_plugins_page_row = array(); |
|
82 | - |
|
83 | - |
|
84 | - /** |
|
85 | - * filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc. |
|
86 | - * |
|
87 | - * @type string |
|
88 | - */ |
|
89 | - protected $_main_plugin_file; |
|
90 | - |
|
91 | - /** |
|
92 | - * This is the slug used to identify this add-on within the plugin update engine. |
|
93 | - * |
|
94 | - * @type string |
|
95 | - */ |
|
96 | - protected $pue_slug; |
|
97 | - |
|
98 | - |
|
99 | - /** |
|
100 | - * @var EE_Dependency_Map $dependency_map |
|
101 | - */ |
|
102 | - private $dependency_map; |
|
103 | - |
|
104 | - |
|
105 | - /** |
|
106 | - * @var DomainInterface $domain |
|
107 | - */ |
|
108 | - private $domain; |
|
109 | - |
|
110 | - |
|
111 | - /** |
|
112 | - * @param EE_Dependency_Map $dependency_map [optional] |
|
113 | - * @param DomainInterface $domain [optional] |
|
114 | - */ |
|
115 | - public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null) |
|
116 | - { |
|
117 | - if ($dependency_map instanceof EE_Dependency_Map) { |
|
118 | - $this->setDependencyMap($dependency_map); |
|
119 | - } |
|
120 | - if ($domain instanceof DomainInterface) { |
|
121 | - $this->setDomain($domain); |
|
122 | - } |
|
123 | - add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init')); |
|
124 | - } |
|
125 | - |
|
126 | - |
|
127 | - /** |
|
128 | - * @param EE_Dependency_Map $dependency_map |
|
129 | - */ |
|
130 | - public function setDependencyMap($dependency_map) |
|
131 | - { |
|
132 | - $this->dependency_map = $dependency_map; |
|
133 | - } |
|
134 | - |
|
135 | - |
|
136 | - /** |
|
137 | - * @return EE_Dependency_Map |
|
138 | - */ |
|
139 | - public function dependencyMap() |
|
140 | - { |
|
141 | - return $this->dependency_map; |
|
142 | - } |
|
143 | - |
|
144 | - |
|
145 | - /** |
|
146 | - * @param DomainInterface $domain |
|
147 | - */ |
|
148 | - public function setDomain(DomainInterface $domain) |
|
149 | - { |
|
150 | - $this->domain = $domain; |
|
151 | - } |
|
152 | - |
|
153 | - /** |
|
154 | - * @return DomainInterface |
|
155 | - */ |
|
156 | - public function domain() |
|
157 | - { |
|
158 | - return $this->domain; |
|
159 | - } |
|
160 | - |
|
161 | - |
|
162 | - /** |
|
163 | - * @param mixed $version |
|
164 | - */ |
|
165 | - public function set_version($version = null) |
|
166 | - { |
|
167 | - $this->_version = $version; |
|
168 | - } |
|
169 | - |
|
170 | - |
|
171 | - /** |
|
172 | - * get__version |
|
173 | - * |
|
174 | - * @return string |
|
175 | - */ |
|
176 | - public function version() |
|
177 | - { |
|
178 | - return $this->_version; |
|
179 | - } |
|
180 | - |
|
181 | - |
|
182 | - /** |
|
183 | - * @param mixed $min_core_version |
|
184 | - */ |
|
185 | - public function set_min_core_version($min_core_version = null) |
|
186 | - { |
|
187 | - $this->_min_core_version = $min_core_version; |
|
188 | - } |
|
189 | - |
|
190 | - |
|
191 | - /** |
|
192 | - * get__min_core_version |
|
193 | - * |
|
194 | - * @return string |
|
195 | - */ |
|
196 | - public function min_core_version() |
|
197 | - { |
|
198 | - return $this->_min_core_version; |
|
199 | - } |
|
200 | - |
|
201 | - |
|
202 | - /** |
|
203 | - * Sets addon_name |
|
204 | - * |
|
205 | - * @param string $addon_name |
|
206 | - * @return boolean |
|
207 | - */ |
|
208 | - public function set_name($addon_name) |
|
209 | - { |
|
210 | - return $this->_addon_name = $addon_name; |
|
211 | - } |
|
212 | - |
|
213 | - |
|
214 | - /** |
|
215 | - * Gets addon_name |
|
216 | - * |
|
217 | - * @return string |
|
218 | - */ |
|
219 | - public function name() |
|
220 | - { |
|
221 | - return $this->_addon_name; |
|
222 | - } |
|
223 | - |
|
224 | - |
|
225 | - /** |
|
226 | - * @return string |
|
227 | - */ |
|
228 | - public function plugin_basename() |
|
229 | - { |
|
230 | - |
|
231 | - return $this->_plugin_basename; |
|
232 | - } |
|
233 | - |
|
234 | - |
|
235 | - /** |
|
236 | - * @param string $plugin_basename |
|
237 | - */ |
|
238 | - public function set_plugin_basename($plugin_basename) |
|
239 | - { |
|
240 | - |
|
241 | - $this->_plugin_basename = $plugin_basename; |
|
242 | - } |
|
243 | - |
|
244 | - |
|
245 | - /** |
|
246 | - * @return string |
|
247 | - */ |
|
248 | - public function plugin_slug() |
|
249 | - { |
|
250 | - |
|
251 | - return $this->_plugin_slug; |
|
252 | - } |
|
253 | - |
|
254 | - |
|
255 | - /** |
|
256 | - * @param string $plugin_slug |
|
257 | - */ |
|
258 | - public function set_plugin_slug($plugin_slug) |
|
259 | - { |
|
260 | - |
|
261 | - $this->_plugin_slug = $plugin_slug; |
|
262 | - } |
|
263 | - |
|
264 | - |
|
265 | - /** |
|
266 | - * @return string |
|
267 | - */ |
|
268 | - public function plugin_action_slug() |
|
269 | - { |
|
270 | - |
|
271 | - return $this->_plugin_action_slug; |
|
272 | - } |
|
273 | - |
|
274 | - |
|
275 | - /** |
|
276 | - * @param string $plugin_action_slug |
|
277 | - */ |
|
278 | - public function set_plugin_action_slug($plugin_action_slug) |
|
279 | - { |
|
280 | - |
|
281 | - $this->_plugin_action_slug = $plugin_action_slug; |
|
282 | - } |
|
283 | - |
|
284 | - |
|
285 | - /** |
|
286 | - * @return array |
|
287 | - */ |
|
288 | - public function get_plugins_page_row() |
|
289 | - { |
|
290 | - |
|
291 | - return $this->_plugins_page_row; |
|
292 | - } |
|
293 | - |
|
294 | - |
|
295 | - /** |
|
296 | - * @param array $plugins_page_row |
|
297 | - */ |
|
298 | - public function set_plugins_page_row($plugins_page_row = array()) |
|
299 | - { |
|
300 | - // sigh.... check for example content that I stupidly merged to master and remove it if found |
|
301 | - if ( |
|
302 | - ! is_array($plugins_page_row) |
|
303 | - && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false |
|
304 | - ) { |
|
305 | - $plugins_page_row = array(); |
|
306 | - } |
|
307 | - $this->_plugins_page_row = (array) $plugins_page_row; |
|
308 | - } |
|
309 | - |
|
310 | - |
|
311 | - /** |
|
312 | - * Called when EE core detects this addon has been activated for the first time. |
|
313 | - * If the site isn't in maintenance mode, should setup the addon's database |
|
314 | - * |
|
315 | - * @return void |
|
316 | - */ |
|
317 | - public function new_install() |
|
318 | - { |
|
319 | - $classname = get_class($this); |
|
320 | - do_action("AHEE__{$classname}__new_install"); |
|
321 | - do_action('AHEE__EE_Addon__new_install', $this); |
|
322 | - EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
323 | - add_action( |
|
324 | - 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
325 | - array($this, 'initialize_db_if_no_migrations_required') |
|
326 | - ); |
|
327 | - } |
|
328 | - |
|
329 | - |
|
330 | - /** |
|
331 | - * Called when EE core detects this addon has been reactivated. When this happens, |
|
332 | - * it's good to just check that your data is still intact |
|
333 | - * |
|
334 | - * @return void |
|
335 | - */ |
|
336 | - public function reactivation() |
|
337 | - { |
|
338 | - $classname = get_class($this); |
|
339 | - do_action("AHEE__{$classname}__reactivation"); |
|
340 | - do_action('AHEE__EE_Addon__reactivation', $this); |
|
341 | - EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
342 | - add_action( |
|
343 | - 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
344 | - array($this, 'initialize_db_if_no_migrations_required') |
|
345 | - ); |
|
346 | - } |
|
347 | - |
|
348 | - |
|
349 | - /** |
|
350 | - * Called when the registered deactivation hook for this addon fires. |
|
351 | - * |
|
352 | - * @throws EE_Error |
|
353 | - */ |
|
354 | - public function deactivation() |
|
355 | - { |
|
356 | - $classname = get_class($this); |
|
357 | - do_action("AHEE__{$classname}__deactivation"); |
|
358 | - do_action('AHEE__EE_Addon__deactivation', $this); |
|
359 | - // check if the site no longer needs to be in maintenance mode |
|
360 | - EE_Register_Addon::deregister($this->name()); |
|
361 | - EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
362 | - } |
|
363 | - |
|
364 | - |
|
365 | - /** |
|
366 | - * Takes care of double-checking that we're not in maintenance mode, and then |
|
367 | - * initializing this addon's necessary initial data. This is called by default on new activations |
|
368 | - * and reactivations. |
|
369 | - * |
|
370 | - * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data. |
|
371 | - * This is a resource-intensive job so we prefer to only do it when necessary |
|
372 | - * @return void |
|
373 | - * @throws \EE_Error |
|
374 | - * @throws InvalidInterfaceException |
|
375 | - * @throws InvalidDataTypeException |
|
376 | - * @throws InvalidArgumentException |
|
377 | - */ |
|
378 | - public function initialize_db_if_no_migrations_required($verify_schema = true) |
|
379 | - { |
|
380 | - if ($verify_schema === '') { |
|
381 | - // wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name |
|
382 | - // (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it |
|
383 | - // calls them with an argument of an empty string (ie ""), which evaluates to false |
|
384 | - // so we need to treat the empty string as if nothing had been passed, and should instead use the default |
|
385 | - $verify_schema = true; |
|
386 | - } |
|
387 | - if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
388 | - if ($verify_schema) { |
|
389 | - $this->initialize_db(); |
|
390 | - } |
|
391 | - $this->initialize_default_data(); |
|
392 | - // @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe |
|
393 | - EE_Data_Migration_Manager::instance()->update_current_database_state_to( |
|
394 | - array( |
|
395 | - 'slug' => $this->name(), |
|
396 | - 'version' => $this->version(), |
|
397 | - ) |
|
398 | - ); |
|
399 | - /* make sure core's data is a-ok |
|
22 | + /** |
|
23 | + * prefix to be added onto an addon's plugin slug to make a wp option name |
|
24 | + * which will be used to store the plugin's activation history |
|
25 | + */ |
|
26 | + const ee_addon_version_history_option_prefix = 'ee_version_history_'; |
|
27 | + |
|
28 | + /** |
|
29 | + * @var $_version |
|
30 | + * @type string |
|
31 | + */ |
|
32 | + protected $_version = ''; |
|
33 | + |
|
34 | + /** |
|
35 | + * @var $_min_core_version |
|
36 | + * @type string |
|
37 | + */ |
|
38 | + protected $_min_core_version = ''; |
|
39 | + |
|
40 | + /** |
|
41 | + * derived from plugin 'main_file_path using plugin_basename() |
|
42 | + * |
|
43 | + * @type string $_plugin_basename |
|
44 | + */ |
|
45 | + protected $_plugin_basename = ''; |
|
46 | + |
|
47 | + /** |
|
48 | + * A non-internationalized name to identify this addon for use in URLs, etc |
|
49 | + * |
|
50 | + * @type string $_plugin_slug |
|
51 | + */ |
|
52 | + protected $_plugin_slug = ''; |
|
53 | + |
|
54 | + /** |
|
55 | + * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/ |
|
56 | + * |
|
57 | + * @type string _addon_name |
|
58 | + */ |
|
59 | + protected $_addon_name = ''; |
|
60 | + |
|
61 | + /** |
|
62 | + * one of the EE_System::req_type_* constants |
|
63 | + * |
|
64 | + * @type int $_req_type |
|
65 | + */ |
|
66 | + protected $_req_type; |
|
67 | + |
|
68 | + /** |
|
69 | + * page slug to be used when generating the "Settings" link on the WP plugin page |
|
70 | + * |
|
71 | + * @type string $_plugin_action_slug |
|
72 | + */ |
|
73 | + protected $_plugin_action_slug = ''; |
|
74 | + |
|
75 | + /** |
|
76 | + * if not empty, inserts a new table row after this plugin's row on the WP Plugins page |
|
77 | + * that can be used for adding upgrading/marketing info |
|
78 | + * |
|
79 | + * @type array $_plugins_page_row |
|
80 | + */ |
|
81 | + protected $_plugins_page_row = array(); |
|
82 | + |
|
83 | + |
|
84 | + /** |
|
85 | + * filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc. |
|
86 | + * |
|
87 | + * @type string |
|
88 | + */ |
|
89 | + protected $_main_plugin_file; |
|
90 | + |
|
91 | + /** |
|
92 | + * This is the slug used to identify this add-on within the plugin update engine. |
|
93 | + * |
|
94 | + * @type string |
|
95 | + */ |
|
96 | + protected $pue_slug; |
|
97 | + |
|
98 | + |
|
99 | + /** |
|
100 | + * @var EE_Dependency_Map $dependency_map |
|
101 | + */ |
|
102 | + private $dependency_map; |
|
103 | + |
|
104 | + |
|
105 | + /** |
|
106 | + * @var DomainInterface $domain |
|
107 | + */ |
|
108 | + private $domain; |
|
109 | + |
|
110 | + |
|
111 | + /** |
|
112 | + * @param EE_Dependency_Map $dependency_map [optional] |
|
113 | + * @param DomainInterface $domain [optional] |
|
114 | + */ |
|
115 | + public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null) |
|
116 | + { |
|
117 | + if ($dependency_map instanceof EE_Dependency_Map) { |
|
118 | + $this->setDependencyMap($dependency_map); |
|
119 | + } |
|
120 | + if ($domain instanceof DomainInterface) { |
|
121 | + $this->setDomain($domain); |
|
122 | + } |
|
123 | + add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init')); |
|
124 | + } |
|
125 | + |
|
126 | + |
|
127 | + /** |
|
128 | + * @param EE_Dependency_Map $dependency_map |
|
129 | + */ |
|
130 | + public function setDependencyMap($dependency_map) |
|
131 | + { |
|
132 | + $this->dependency_map = $dependency_map; |
|
133 | + } |
|
134 | + |
|
135 | + |
|
136 | + /** |
|
137 | + * @return EE_Dependency_Map |
|
138 | + */ |
|
139 | + public function dependencyMap() |
|
140 | + { |
|
141 | + return $this->dependency_map; |
|
142 | + } |
|
143 | + |
|
144 | + |
|
145 | + /** |
|
146 | + * @param DomainInterface $domain |
|
147 | + */ |
|
148 | + public function setDomain(DomainInterface $domain) |
|
149 | + { |
|
150 | + $this->domain = $domain; |
|
151 | + } |
|
152 | + |
|
153 | + /** |
|
154 | + * @return DomainInterface |
|
155 | + */ |
|
156 | + public function domain() |
|
157 | + { |
|
158 | + return $this->domain; |
|
159 | + } |
|
160 | + |
|
161 | + |
|
162 | + /** |
|
163 | + * @param mixed $version |
|
164 | + */ |
|
165 | + public function set_version($version = null) |
|
166 | + { |
|
167 | + $this->_version = $version; |
|
168 | + } |
|
169 | + |
|
170 | + |
|
171 | + /** |
|
172 | + * get__version |
|
173 | + * |
|
174 | + * @return string |
|
175 | + */ |
|
176 | + public function version() |
|
177 | + { |
|
178 | + return $this->_version; |
|
179 | + } |
|
180 | + |
|
181 | + |
|
182 | + /** |
|
183 | + * @param mixed $min_core_version |
|
184 | + */ |
|
185 | + public function set_min_core_version($min_core_version = null) |
|
186 | + { |
|
187 | + $this->_min_core_version = $min_core_version; |
|
188 | + } |
|
189 | + |
|
190 | + |
|
191 | + /** |
|
192 | + * get__min_core_version |
|
193 | + * |
|
194 | + * @return string |
|
195 | + */ |
|
196 | + public function min_core_version() |
|
197 | + { |
|
198 | + return $this->_min_core_version; |
|
199 | + } |
|
200 | + |
|
201 | + |
|
202 | + /** |
|
203 | + * Sets addon_name |
|
204 | + * |
|
205 | + * @param string $addon_name |
|
206 | + * @return boolean |
|
207 | + */ |
|
208 | + public function set_name($addon_name) |
|
209 | + { |
|
210 | + return $this->_addon_name = $addon_name; |
|
211 | + } |
|
212 | + |
|
213 | + |
|
214 | + /** |
|
215 | + * Gets addon_name |
|
216 | + * |
|
217 | + * @return string |
|
218 | + */ |
|
219 | + public function name() |
|
220 | + { |
|
221 | + return $this->_addon_name; |
|
222 | + } |
|
223 | + |
|
224 | + |
|
225 | + /** |
|
226 | + * @return string |
|
227 | + */ |
|
228 | + public function plugin_basename() |
|
229 | + { |
|
230 | + |
|
231 | + return $this->_plugin_basename; |
|
232 | + } |
|
233 | + |
|
234 | + |
|
235 | + /** |
|
236 | + * @param string $plugin_basename |
|
237 | + */ |
|
238 | + public function set_plugin_basename($plugin_basename) |
|
239 | + { |
|
240 | + |
|
241 | + $this->_plugin_basename = $plugin_basename; |
|
242 | + } |
|
243 | + |
|
244 | + |
|
245 | + /** |
|
246 | + * @return string |
|
247 | + */ |
|
248 | + public function plugin_slug() |
|
249 | + { |
|
250 | + |
|
251 | + return $this->_plugin_slug; |
|
252 | + } |
|
253 | + |
|
254 | + |
|
255 | + /** |
|
256 | + * @param string $plugin_slug |
|
257 | + */ |
|
258 | + public function set_plugin_slug($plugin_slug) |
|
259 | + { |
|
260 | + |
|
261 | + $this->_plugin_slug = $plugin_slug; |
|
262 | + } |
|
263 | + |
|
264 | + |
|
265 | + /** |
|
266 | + * @return string |
|
267 | + */ |
|
268 | + public function plugin_action_slug() |
|
269 | + { |
|
270 | + |
|
271 | + return $this->_plugin_action_slug; |
|
272 | + } |
|
273 | + |
|
274 | + |
|
275 | + /** |
|
276 | + * @param string $plugin_action_slug |
|
277 | + */ |
|
278 | + public function set_plugin_action_slug($plugin_action_slug) |
|
279 | + { |
|
280 | + |
|
281 | + $this->_plugin_action_slug = $plugin_action_slug; |
|
282 | + } |
|
283 | + |
|
284 | + |
|
285 | + /** |
|
286 | + * @return array |
|
287 | + */ |
|
288 | + public function get_plugins_page_row() |
|
289 | + { |
|
290 | + |
|
291 | + return $this->_plugins_page_row; |
|
292 | + } |
|
293 | + |
|
294 | + |
|
295 | + /** |
|
296 | + * @param array $plugins_page_row |
|
297 | + */ |
|
298 | + public function set_plugins_page_row($plugins_page_row = array()) |
|
299 | + { |
|
300 | + // sigh.... check for example content that I stupidly merged to master and remove it if found |
|
301 | + if ( |
|
302 | + ! is_array($plugins_page_row) |
|
303 | + && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false |
|
304 | + ) { |
|
305 | + $plugins_page_row = array(); |
|
306 | + } |
|
307 | + $this->_plugins_page_row = (array) $plugins_page_row; |
|
308 | + } |
|
309 | + |
|
310 | + |
|
311 | + /** |
|
312 | + * Called when EE core detects this addon has been activated for the first time. |
|
313 | + * If the site isn't in maintenance mode, should setup the addon's database |
|
314 | + * |
|
315 | + * @return void |
|
316 | + */ |
|
317 | + public function new_install() |
|
318 | + { |
|
319 | + $classname = get_class($this); |
|
320 | + do_action("AHEE__{$classname}__new_install"); |
|
321 | + do_action('AHEE__EE_Addon__new_install', $this); |
|
322 | + EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
323 | + add_action( |
|
324 | + 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
325 | + array($this, 'initialize_db_if_no_migrations_required') |
|
326 | + ); |
|
327 | + } |
|
328 | + |
|
329 | + |
|
330 | + /** |
|
331 | + * Called when EE core detects this addon has been reactivated. When this happens, |
|
332 | + * it's good to just check that your data is still intact |
|
333 | + * |
|
334 | + * @return void |
|
335 | + */ |
|
336 | + public function reactivation() |
|
337 | + { |
|
338 | + $classname = get_class($this); |
|
339 | + do_action("AHEE__{$classname}__reactivation"); |
|
340 | + do_action('AHEE__EE_Addon__reactivation', $this); |
|
341 | + EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
342 | + add_action( |
|
343 | + 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
344 | + array($this, 'initialize_db_if_no_migrations_required') |
|
345 | + ); |
|
346 | + } |
|
347 | + |
|
348 | + |
|
349 | + /** |
|
350 | + * Called when the registered deactivation hook for this addon fires. |
|
351 | + * |
|
352 | + * @throws EE_Error |
|
353 | + */ |
|
354 | + public function deactivation() |
|
355 | + { |
|
356 | + $classname = get_class($this); |
|
357 | + do_action("AHEE__{$classname}__deactivation"); |
|
358 | + do_action('AHEE__EE_Addon__deactivation', $this); |
|
359 | + // check if the site no longer needs to be in maintenance mode |
|
360 | + EE_Register_Addon::deregister($this->name()); |
|
361 | + EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
362 | + } |
|
363 | + |
|
364 | + |
|
365 | + /** |
|
366 | + * Takes care of double-checking that we're not in maintenance mode, and then |
|
367 | + * initializing this addon's necessary initial data. This is called by default on new activations |
|
368 | + * and reactivations. |
|
369 | + * |
|
370 | + * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data. |
|
371 | + * This is a resource-intensive job so we prefer to only do it when necessary |
|
372 | + * @return void |
|
373 | + * @throws \EE_Error |
|
374 | + * @throws InvalidInterfaceException |
|
375 | + * @throws InvalidDataTypeException |
|
376 | + * @throws InvalidArgumentException |
|
377 | + */ |
|
378 | + public function initialize_db_if_no_migrations_required($verify_schema = true) |
|
379 | + { |
|
380 | + if ($verify_schema === '') { |
|
381 | + // wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name |
|
382 | + // (ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it |
|
383 | + // calls them with an argument of an empty string (ie ""), which evaluates to false |
|
384 | + // so we need to treat the empty string as if nothing had been passed, and should instead use the default |
|
385 | + $verify_schema = true; |
|
386 | + } |
|
387 | + if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) { |
|
388 | + if ($verify_schema) { |
|
389 | + $this->initialize_db(); |
|
390 | + } |
|
391 | + $this->initialize_default_data(); |
|
392 | + // @todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe |
|
393 | + EE_Data_Migration_Manager::instance()->update_current_database_state_to( |
|
394 | + array( |
|
395 | + 'slug' => $this->name(), |
|
396 | + 'version' => $this->version(), |
|
397 | + ) |
|
398 | + ); |
|
399 | + /* make sure core's data is a-ok |
|
400 | 400 | * (at the time of writing, we especially want to verify all the caps are present |
401 | 401 | * because payment method type capabilities are added dynamically, and it's |
402 | 402 | * possible this addon added a payment method. But it's also possible |
403 | 403 | * other data needs to be verified) |
404 | 404 | */ |
405 | - EEH_Activation::initialize_db_content(); |
|
406 | - /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */ |
|
407 | - $rewrite_rules = LoaderFactory::getLoader()->getShared( |
|
408 | - 'EventEspresso\core\domain\services\custom_post_types\RewriteRules' |
|
409 | - ); |
|
410 | - $rewrite_rules->flushRewriteRules(); |
|
411 | - // in case there are lots of addons being activated at once, let's force garbage collection |
|
412 | - // to help avoid memory limit errors |
|
413 | - // EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true ); |
|
414 | - gc_collect_cycles(); |
|
415 | - } else { |
|
416 | - // ask the data migration manager to init this addon's data |
|
417 | - // when migrations are finished because we can't do it now |
|
418 | - EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name()); |
|
419 | - } |
|
420 | - } |
|
421 | - |
|
422 | - |
|
423 | - /** |
|
424 | - * Used to setup this addon's database tables, but not necessarily any default |
|
425 | - * data in them. The default is to actually use the most up-to-date data migration script |
|
426 | - * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration() |
|
427 | - * methods to setup the db. |
|
428 | - */ |
|
429 | - public function initialize_db() |
|
430 | - { |
|
431 | - // find the migration script that sets the database to be compatible with the code |
|
432 | - $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name()); |
|
433 | - if ($current_dms_name) { |
|
434 | - $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name); |
|
435 | - $current_data_migration_script->set_migrating(false); |
|
436 | - $current_data_migration_script->schema_changes_before_migration(); |
|
437 | - $current_data_migration_script->schema_changes_after_migration(); |
|
438 | - if ($current_data_migration_script->get_errors()) { |
|
439 | - foreach ($current_data_migration_script->get_errors() as $error) { |
|
440 | - EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
441 | - } |
|
442 | - } |
|
443 | - } |
|
444 | - // if not DMS was found that should be ok. This addon just doesn't require any database changes |
|
445 | - EE_Data_Migration_Manager::instance()->update_current_database_state_to( |
|
446 | - array( |
|
447 | - 'slug' => $this->name(), |
|
448 | - 'version' => $this->version(), |
|
449 | - ) |
|
450 | - ); |
|
451 | - } |
|
452 | - |
|
453 | - |
|
454 | - /** |
|
455 | - * If you want to setup default data for the addon, override this method, and call |
|
456 | - * parent::initialize_default_data() from within it. This is normally called |
|
457 | - * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db() |
|
458 | - * and should verify default data is present (but this is also called |
|
459 | - * on reactivations and just after migrations, so please verify you actually want |
|
460 | - * to ADD default data, because it may already be present). |
|
461 | - * However, please call this parent (currently it just fires a hook which other |
|
462 | - * addons may be depending on) |
|
463 | - */ |
|
464 | - public function initialize_default_data() |
|
465 | - { |
|
466 | - /** |
|
467 | - * Called when an addon is ensuring its default data is set (possibly called |
|
468 | - * on a reactivation, so first check for the absence of other data before setting |
|
469 | - * default data) |
|
470 | - * |
|
471 | - * @param EE_Addon $addon the addon that called this |
|
472 | - */ |
|
473 | - do_action('AHEE__EE_Addon__initialize_default_data__begin', $this); |
|
474 | - // override to insert default data. It is safe to use the models here |
|
475 | - // because the site should not be in maintenance mode |
|
476 | - } |
|
477 | - |
|
478 | - |
|
479 | - /** |
|
480 | - * EE Core detected that this addon has been upgraded. We should check if there |
|
481 | - * are any new migration scripts, and if so put the site into maintenance mode until |
|
482 | - * they're ran |
|
483 | - * |
|
484 | - * @return void |
|
485 | - */ |
|
486 | - public function upgrade() |
|
487 | - { |
|
488 | - $classname = get_class($this); |
|
489 | - do_action("AHEE__{$classname}__upgrade"); |
|
490 | - do_action('AHEE__EE_Addon__upgrade', $this); |
|
491 | - EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
492 | - // also it's possible there is new default data that needs to be added |
|
493 | - add_action( |
|
494 | - 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
495 | - array($this, 'initialize_db_if_no_migrations_required') |
|
496 | - ); |
|
497 | - } |
|
498 | - |
|
499 | - |
|
500 | - /** |
|
501 | - * If Core detects this addon has been downgraded, you may want to invoke some special logic here. |
|
502 | - */ |
|
503 | - public function downgrade() |
|
504 | - { |
|
505 | - $classname = get_class($this); |
|
506 | - do_action("AHEE__{$classname}__downgrade"); |
|
507 | - do_action('AHEE__EE_Addon__downgrade', $this); |
|
508 | - // it's possible there's old default data that needs to be double-checked |
|
509 | - add_action( |
|
510 | - 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
511 | - array($this, 'initialize_db_if_no_migrations_required') |
|
512 | - ); |
|
513 | - } |
|
514 | - |
|
515 | - |
|
516 | - /** |
|
517 | - * set_db_update_option_name |
|
518 | - * Until we do something better, we'll just check for migration scripts upon |
|
519 | - * plugin activation only. In the future, we'll want to do it on plugin updates too |
|
520 | - * |
|
521 | - * @return bool |
|
522 | - */ |
|
523 | - public function set_db_update_option_name() |
|
524 | - { |
|
525 | - EE_Error::doing_it_wrong( |
|
526 | - __FUNCTION__, |
|
527 | - esc_html__( |
|
528 | - 'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option', |
|
529 | - 'event_espresso' |
|
530 | - ), |
|
531 | - '4.3.0.alpha.016' |
|
532 | - ); |
|
533 | - // let's just handle this on the next request, ok? right now we're just not really ready |
|
534 | - return $this->set_activation_indicator_option(); |
|
535 | - } |
|
536 | - |
|
537 | - |
|
538 | - /** |
|
539 | - * Returns the name of the activation indicator option |
|
540 | - * (an option which is set temporarily to indicate that this addon was just activated) |
|
541 | - * |
|
542 | - * @deprecated since version 4.3.0.alpha.016 |
|
543 | - * @return string |
|
544 | - */ |
|
545 | - public function get_db_update_option_name() |
|
546 | - { |
|
547 | - EE_Error::doing_it_wrong( |
|
548 | - __FUNCTION__, |
|
549 | - esc_html__( |
|
550 | - 'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name', |
|
551 | - 'event_espresso' |
|
552 | - ), |
|
553 | - '4.3.0.alpha.016' |
|
554 | - ); |
|
555 | - return $this->get_activation_indicator_option_name(); |
|
556 | - } |
|
557 | - |
|
558 | - |
|
559 | - /** |
|
560 | - * When the addon is activated, this should be called to set a wordpress option that |
|
561 | - * indicates it was activated. This is especially useful for detecting reactivations. |
|
562 | - * |
|
563 | - * @return bool |
|
564 | - */ |
|
565 | - public function set_activation_indicator_option() |
|
566 | - { |
|
567 | - // let's just handle this on the next request, ok? right now we're just not really ready |
|
568 | - return update_option($this->get_activation_indicator_option_name(), true); |
|
569 | - } |
|
570 | - |
|
571 | - |
|
572 | - /** |
|
573 | - * Gets the name of the wp option which is used to temporarily indicate that this addon was activated |
|
574 | - * |
|
575 | - * @return string |
|
576 | - */ |
|
577 | - public function get_activation_indicator_option_name() |
|
578 | - { |
|
579 | - return 'ee_activation_' . $this->name(); |
|
580 | - } |
|
581 | - |
|
582 | - |
|
583 | - /** |
|
584 | - * Used by EE_System to set the request type of this addon. Should not be used by addon developers |
|
585 | - * |
|
586 | - * @param int $req_type |
|
587 | - */ |
|
588 | - public function set_req_type($req_type) |
|
589 | - { |
|
590 | - $this->_req_type = $req_type; |
|
591 | - } |
|
592 | - |
|
593 | - |
|
594 | - /** |
|
595 | - * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation, |
|
596 | - * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by |
|
597 | - * EE_System when it is checking for new install or upgrades of addons |
|
598 | - */ |
|
599 | - public function detect_req_type($redetect = false) |
|
600 | - { |
|
601 | - if ($this->_req_type === null || $redetect) { |
|
602 | - $this->detect_activation_or_upgrade(); |
|
603 | - } |
|
604 | - return $this->_req_type; |
|
605 | - } |
|
606 | - |
|
607 | - |
|
608 | - /** |
|
609 | - * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.) |
|
610 | - * Should only be called once per request |
|
611 | - * |
|
612 | - * @return void |
|
613 | - */ |
|
614 | - public function detect_activation_or_upgrade() |
|
615 | - { |
|
616 | - $activation_history_for_addon = $this->get_activation_history(); |
|
617 | - $request_type = EE_System::detect_req_type_given_activation_history( |
|
618 | - $activation_history_for_addon, |
|
619 | - $this->get_activation_indicator_option_name(), |
|
620 | - $this->version() |
|
621 | - ); |
|
622 | - $this->set_req_type($request_type); |
|
623 | - $classname = get_class($this); |
|
624 | - switch ($request_type) { |
|
625 | - case EE_System::req_type_new_activation: |
|
626 | - do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation"); |
|
627 | - do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this); |
|
628 | - $this->new_install(); |
|
629 | - $this->update_list_of_installed_versions($activation_history_for_addon); |
|
630 | - break; |
|
631 | - case EE_System::req_type_reactivation: |
|
632 | - do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation"); |
|
633 | - do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this); |
|
634 | - $this->reactivation(); |
|
635 | - $this->update_list_of_installed_versions($activation_history_for_addon); |
|
636 | - break; |
|
637 | - case EE_System::req_type_upgrade: |
|
638 | - do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade"); |
|
639 | - do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this); |
|
640 | - $this->upgrade(); |
|
641 | - $this->update_list_of_installed_versions($activation_history_for_addon); |
|
642 | - break; |
|
643 | - case EE_System::req_type_downgrade: |
|
644 | - do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade"); |
|
645 | - do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this); |
|
646 | - $this->downgrade(); |
|
647 | - $this->update_list_of_installed_versions($activation_history_for_addon); |
|
648 | - break; |
|
649 | - case EE_System::req_type_normal: |
|
650 | - default: |
|
651 | - break; |
|
652 | - } |
|
653 | - |
|
654 | - do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete"); |
|
655 | - } |
|
656 | - |
|
657 | - /** |
|
658 | - * Updates the version history for this addon |
|
659 | - * |
|
660 | - * @param array $version_history |
|
661 | - * @param string $current_version_to_add |
|
662 | - * @return boolean success |
|
663 | - */ |
|
664 | - public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null) |
|
665 | - { |
|
666 | - if (! $version_history) { |
|
667 | - $version_history = $this->get_activation_history(); |
|
668 | - } |
|
669 | - if ($current_version_to_add === null) { |
|
670 | - $current_version_to_add = $this->version(); |
|
671 | - } |
|
672 | - $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time()); |
|
673 | - // resave |
|
674 | - return update_option($this->get_activation_history_option_name(), $version_history); |
|
675 | - } |
|
676 | - |
|
677 | - /** |
|
678 | - * Gets the name of the wp option that stores the activation history |
|
679 | - * of this addon |
|
680 | - * |
|
681 | - * @return string |
|
682 | - */ |
|
683 | - public function get_activation_history_option_name() |
|
684 | - { |
|
685 | - return self::ee_addon_version_history_option_prefix . $this->name(); |
|
686 | - } |
|
687 | - |
|
688 | - |
|
689 | - /** |
|
690 | - * Gets the wp option which stores the activation history for this addon |
|
691 | - * |
|
692 | - * @return array |
|
693 | - */ |
|
694 | - public function get_activation_history() |
|
695 | - { |
|
696 | - return get_option($this->get_activation_history_option_name(), null); |
|
697 | - } |
|
698 | - |
|
699 | - |
|
700 | - /** |
|
701 | - * @param string $config_section |
|
702 | - */ |
|
703 | - public function set_config_section($config_section = '') |
|
704 | - { |
|
705 | - $this->_config_section = ! empty($config_section) ? $config_section : 'addons'; |
|
706 | - } |
|
707 | - |
|
708 | - /** |
|
709 | - * Sets the filepath to the main plugin file |
|
710 | - * |
|
711 | - * @param string $filepath |
|
712 | - */ |
|
713 | - public function set_main_plugin_file($filepath) |
|
714 | - { |
|
715 | - $this->_main_plugin_file = $filepath; |
|
716 | - } |
|
717 | - |
|
718 | - /** |
|
719 | - * gets the filepath to teh main file |
|
720 | - * |
|
721 | - * @return string |
|
722 | - */ |
|
723 | - public function get_main_plugin_file() |
|
724 | - { |
|
725 | - return $this->_main_plugin_file; |
|
726 | - } |
|
727 | - |
|
728 | - /** |
|
729 | - * Gets the filename (no path) of the main file (the main file loaded |
|
730 | - * by WP) |
|
731 | - * |
|
732 | - * @return string |
|
733 | - */ |
|
734 | - public function get_main_plugin_file_basename() |
|
735 | - { |
|
736 | - return plugin_basename($this->get_main_plugin_file()); |
|
737 | - } |
|
738 | - |
|
739 | - /** |
|
740 | - * Gets the folder name which contains the main plugin file |
|
741 | - * |
|
742 | - * @return string |
|
743 | - */ |
|
744 | - public function get_main_plugin_file_dirname() |
|
745 | - { |
|
746 | - return dirname($this->get_main_plugin_file()); |
|
747 | - } |
|
748 | - |
|
749 | - |
|
750 | - /** |
|
751 | - * sets hooks used in the admin |
|
752 | - * |
|
753 | - * @return void |
|
754 | - */ |
|
755 | - public function admin_init() |
|
756 | - { |
|
757 | - // is admin and not in M-Mode ? |
|
758 | - if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) { |
|
759 | - add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2); |
|
760 | - add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3); |
|
761 | - } |
|
762 | - } |
|
763 | - |
|
764 | - |
|
765 | - /** |
|
766 | - * plugin_actions |
|
767 | - * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page. |
|
768 | - * |
|
769 | - * @param $links |
|
770 | - * @param $file |
|
771 | - * @return array |
|
772 | - */ |
|
773 | - public function plugin_action_links($links, $file) |
|
774 | - { |
|
775 | - if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') { |
|
776 | - // before other links |
|
777 | - array_unshift( |
|
778 | - $links, |
|
779 | - '<a href="admin.php?page=' . $this->plugin_action_slug() . '">' |
|
780 | - . esc_html__('Settings', 'event_espresso') |
|
781 | - . '</a>' |
|
782 | - ); |
|
783 | - } |
|
784 | - return $links; |
|
785 | - } |
|
786 | - |
|
787 | - |
|
788 | - /** |
|
789 | - * after_plugin_row |
|
790 | - * Add additional content to the plugins page plugin row |
|
791 | - * Inserts another row |
|
792 | - * |
|
793 | - * @param $plugin_file |
|
794 | - * @param $plugin_data |
|
795 | - * @param $status |
|
796 | - * @return void |
|
797 | - */ |
|
798 | - public function after_plugin_row($plugin_file, $plugin_data, $status) |
|
799 | - { |
|
800 | - $after_plugin_row = ''; |
|
801 | - $plugins_page_row = $this->get_plugins_page_row(); |
|
802 | - if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) { |
|
803 | - $class = $status ? 'active' : 'inactive'; |
|
804 | - $link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : ''; |
|
805 | - $link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : ''; |
|
806 | - $description = isset($plugins_page_row['description']) |
|
807 | - ? $plugins_page_row['description'] |
|
808 | - : ''; |
|
809 | - if (! empty($link_text) && ! empty($link_url) && ! empty($description)) { |
|
810 | - $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">'; |
|
811 | - $after_plugin_row .= '<th class="check-column" scope="row"></th>'; |
|
812 | - $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">'; |
|
813 | - $after_plugin_row .= '<style> |
|
405 | + EEH_Activation::initialize_db_content(); |
|
406 | + /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */ |
|
407 | + $rewrite_rules = LoaderFactory::getLoader()->getShared( |
|
408 | + 'EventEspresso\core\domain\services\custom_post_types\RewriteRules' |
|
409 | + ); |
|
410 | + $rewrite_rules->flushRewriteRules(); |
|
411 | + // in case there are lots of addons being activated at once, let's force garbage collection |
|
412 | + // to help avoid memory limit errors |
|
413 | + // EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true ); |
|
414 | + gc_collect_cycles(); |
|
415 | + } else { |
|
416 | + // ask the data migration manager to init this addon's data |
|
417 | + // when migrations are finished because we can't do it now |
|
418 | + EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name()); |
|
419 | + } |
|
420 | + } |
|
421 | + |
|
422 | + |
|
423 | + /** |
|
424 | + * Used to setup this addon's database tables, but not necessarily any default |
|
425 | + * data in them. The default is to actually use the most up-to-date data migration script |
|
426 | + * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration() |
|
427 | + * methods to setup the db. |
|
428 | + */ |
|
429 | + public function initialize_db() |
|
430 | + { |
|
431 | + // find the migration script that sets the database to be compatible with the code |
|
432 | + $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name()); |
|
433 | + if ($current_dms_name) { |
|
434 | + $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name); |
|
435 | + $current_data_migration_script->set_migrating(false); |
|
436 | + $current_data_migration_script->schema_changes_before_migration(); |
|
437 | + $current_data_migration_script->schema_changes_after_migration(); |
|
438 | + if ($current_data_migration_script->get_errors()) { |
|
439 | + foreach ($current_data_migration_script->get_errors() as $error) { |
|
440 | + EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
441 | + } |
|
442 | + } |
|
443 | + } |
|
444 | + // if not DMS was found that should be ok. This addon just doesn't require any database changes |
|
445 | + EE_Data_Migration_Manager::instance()->update_current_database_state_to( |
|
446 | + array( |
|
447 | + 'slug' => $this->name(), |
|
448 | + 'version' => $this->version(), |
|
449 | + ) |
|
450 | + ); |
|
451 | + } |
|
452 | + |
|
453 | + |
|
454 | + /** |
|
455 | + * If you want to setup default data for the addon, override this method, and call |
|
456 | + * parent::initialize_default_data() from within it. This is normally called |
|
457 | + * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db() |
|
458 | + * and should verify default data is present (but this is also called |
|
459 | + * on reactivations and just after migrations, so please verify you actually want |
|
460 | + * to ADD default data, because it may already be present). |
|
461 | + * However, please call this parent (currently it just fires a hook which other |
|
462 | + * addons may be depending on) |
|
463 | + */ |
|
464 | + public function initialize_default_data() |
|
465 | + { |
|
466 | + /** |
|
467 | + * Called when an addon is ensuring its default data is set (possibly called |
|
468 | + * on a reactivation, so first check for the absence of other data before setting |
|
469 | + * default data) |
|
470 | + * |
|
471 | + * @param EE_Addon $addon the addon that called this |
|
472 | + */ |
|
473 | + do_action('AHEE__EE_Addon__initialize_default_data__begin', $this); |
|
474 | + // override to insert default data. It is safe to use the models here |
|
475 | + // because the site should not be in maintenance mode |
|
476 | + } |
|
477 | + |
|
478 | + |
|
479 | + /** |
|
480 | + * EE Core detected that this addon has been upgraded. We should check if there |
|
481 | + * are any new migration scripts, and if so put the site into maintenance mode until |
|
482 | + * they're ran |
|
483 | + * |
|
484 | + * @return void |
|
485 | + */ |
|
486 | + public function upgrade() |
|
487 | + { |
|
488 | + $classname = get_class($this); |
|
489 | + do_action("AHEE__{$classname}__upgrade"); |
|
490 | + do_action('AHEE__EE_Addon__upgrade', $this); |
|
491 | + EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old(); |
|
492 | + // also it's possible there is new default data that needs to be added |
|
493 | + add_action( |
|
494 | + 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
495 | + array($this, 'initialize_db_if_no_migrations_required') |
|
496 | + ); |
|
497 | + } |
|
498 | + |
|
499 | + |
|
500 | + /** |
|
501 | + * If Core detects this addon has been downgraded, you may want to invoke some special logic here. |
|
502 | + */ |
|
503 | + public function downgrade() |
|
504 | + { |
|
505 | + $classname = get_class($this); |
|
506 | + do_action("AHEE__{$classname}__downgrade"); |
|
507 | + do_action('AHEE__EE_Addon__downgrade', $this); |
|
508 | + // it's possible there's old default data that needs to be double-checked |
|
509 | + add_action( |
|
510 | + 'AHEE__EE_System__perform_activations_upgrades_and_migrations', |
|
511 | + array($this, 'initialize_db_if_no_migrations_required') |
|
512 | + ); |
|
513 | + } |
|
514 | + |
|
515 | + |
|
516 | + /** |
|
517 | + * set_db_update_option_name |
|
518 | + * Until we do something better, we'll just check for migration scripts upon |
|
519 | + * plugin activation only. In the future, we'll want to do it on plugin updates too |
|
520 | + * |
|
521 | + * @return bool |
|
522 | + */ |
|
523 | + public function set_db_update_option_name() |
|
524 | + { |
|
525 | + EE_Error::doing_it_wrong( |
|
526 | + __FUNCTION__, |
|
527 | + esc_html__( |
|
528 | + 'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option', |
|
529 | + 'event_espresso' |
|
530 | + ), |
|
531 | + '4.3.0.alpha.016' |
|
532 | + ); |
|
533 | + // let's just handle this on the next request, ok? right now we're just not really ready |
|
534 | + return $this->set_activation_indicator_option(); |
|
535 | + } |
|
536 | + |
|
537 | + |
|
538 | + /** |
|
539 | + * Returns the name of the activation indicator option |
|
540 | + * (an option which is set temporarily to indicate that this addon was just activated) |
|
541 | + * |
|
542 | + * @deprecated since version 4.3.0.alpha.016 |
|
543 | + * @return string |
|
544 | + */ |
|
545 | + public function get_db_update_option_name() |
|
546 | + { |
|
547 | + EE_Error::doing_it_wrong( |
|
548 | + __FUNCTION__, |
|
549 | + esc_html__( |
|
550 | + 'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name', |
|
551 | + 'event_espresso' |
|
552 | + ), |
|
553 | + '4.3.0.alpha.016' |
|
554 | + ); |
|
555 | + return $this->get_activation_indicator_option_name(); |
|
556 | + } |
|
557 | + |
|
558 | + |
|
559 | + /** |
|
560 | + * When the addon is activated, this should be called to set a wordpress option that |
|
561 | + * indicates it was activated. This is especially useful for detecting reactivations. |
|
562 | + * |
|
563 | + * @return bool |
|
564 | + */ |
|
565 | + public function set_activation_indicator_option() |
|
566 | + { |
|
567 | + // let's just handle this on the next request, ok? right now we're just not really ready |
|
568 | + return update_option($this->get_activation_indicator_option_name(), true); |
|
569 | + } |
|
570 | + |
|
571 | + |
|
572 | + /** |
|
573 | + * Gets the name of the wp option which is used to temporarily indicate that this addon was activated |
|
574 | + * |
|
575 | + * @return string |
|
576 | + */ |
|
577 | + public function get_activation_indicator_option_name() |
|
578 | + { |
|
579 | + return 'ee_activation_' . $this->name(); |
|
580 | + } |
|
581 | + |
|
582 | + |
|
583 | + /** |
|
584 | + * Used by EE_System to set the request type of this addon. Should not be used by addon developers |
|
585 | + * |
|
586 | + * @param int $req_type |
|
587 | + */ |
|
588 | + public function set_req_type($req_type) |
|
589 | + { |
|
590 | + $this->_req_type = $req_type; |
|
591 | + } |
|
592 | + |
|
593 | + |
|
594 | + /** |
|
595 | + * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation, |
|
596 | + * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by |
|
597 | + * EE_System when it is checking for new install or upgrades of addons |
|
598 | + */ |
|
599 | + public function detect_req_type($redetect = false) |
|
600 | + { |
|
601 | + if ($this->_req_type === null || $redetect) { |
|
602 | + $this->detect_activation_or_upgrade(); |
|
603 | + } |
|
604 | + return $this->_req_type; |
|
605 | + } |
|
606 | + |
|
607 | + |
|
608 | + /** |
|
609 | + * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.) |
|
610 | + * Should only be called once per request |
|
611 | + * |
|
612 | + * @return void |
|
613 | + */ |
|
614 | + public function detect_activation_or_upgrade() |
|
615 | + { |
|
616 | + $activation_history_for_addon = $this->get_activation_history(); |
|
617 | + $request_type = EE_System::detect_req_type_given_activation_history( |
|
618 | + $activation_history_for_addon, |
|
619 | + $this->get_activation_indicator_option_name(), |
|
620 | + $this->version() |
|
621 | + ); |
|
622 | + $this->set_req_type($request_type); |
|
623 | + $classname = get_class($this); |
|
624 | + switch ($request_type) { |
|
625 | + case EE_System::req_type_new_activation: |
|
626 | + do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation"); |
|
627 | + do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this); |
|
628 | + $this->new_install(); |
|
629 | + $this->update_list_of_installed_versions($activation_history_for_addon); |
|
630 | + break; |
|
631 | + case EE_System::req_type_reactivation: |
|
632 | + do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation"); |
|
633 | + do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this); |
|
634 | + $this->reactivation(); |
|
635 | + $this->update_list_of_installed_versions($activation_history_for_addon); |
|
636 | + break; |
|
637 | + case EE_System::req_type_upgrade: |
|
638 | + do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade"); |
|
639 | + do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this); |
|
640 | + $this->upgrade(); |
|
641 | + $this->update_list_of_installed_versions($activation_history_for_addon); |
|
642 | + break; |
|
643 | + case EE_System::req_type_downgrade: |
|
644 | + do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade"); |
|
645 | + do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this); |
|
646 | + $this->downgrade(); |
|
647 | + $this->update_list_of_installed_versions($activation_history_for_addon); |
|
648 | + break; |
|
649 | + case EE_System::req_type_normal: |
|
650 | + default: |
|
651 | + break; |
|
652 | + } |
|
653 | + |
|
654 | + do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete"); |
|
655 | + } |
|
656 | + |
|
657 | + /** |
|
658 | + * Updates the version history for this addon |
|
659 | + * |
|
660 | + * @param array $version_history |
|
661 | + * @param string $current_version_to_add |
|
662 | + * @return boolean success |
|
663 | + */ |
|
664 | + public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null) |
|
665 | + { |
|
666 | + if (! $version_history) { |
|
667 | + $version_history = $this->get_activation_history(); |
|
668 | + } |
|
669 | + if ($current_version_to_add === null) { |
|
670 | + $current_version_to_add = $this->version(); |
|
671 | + } |
|
672 | + $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time()); |
|
673 | + // resave |
|
674 | + return update_option($this->get_activation_history_option_name(), $version_history); |
|
675 | + } |
|
676 | + |
|
677 | + /** |
|
678 | + * Gets the name of the wp option that stores the activation history |
|
679 | + * of this addon |
|
680 | + * |
|
681 | + * @return string |
|
682 | + */ |
|
683 | + public function get_activation_history_option_name() |
|
684 | + { |
|
685 | + return self::ee_addon_version_history_option_prefix . $this->name(); |
|
686 | + } |
|
687 | + |
|
688 | + |
|
689 | + /** |
|
690 | + * Gets the wp option which stores the activation history for this addon |
|
691 | + * |
|
692 | + * @return array |
|
693 | + */ |
|
694 | + public function get_activation_history() |
|
695 | + { |
|
696 | + return get_option($this->get_activation_history_option_name(), null); |
|
697 | + } |
|
698 | + |
|
699 | + |
|
700 | + /** |
|
701 | + * @param string $config_section |
|
702 | + */ |
|
703 | + public function set_config_section($config_section = '') |
|
704 | + { |
|
705 | + $this->_config_section = ! empty($config_section) ? $config_section : 'addons'; |
|
706 | + } |
|
707 | + |
|
708 | + /** |
|
709 | + * Sets the filepath to the main plugin file |
|
710 | + * |
|
711 | + * @param string $filepath |
|
712 | + */ |
|
713 | + public function set_main_plugin_file($filepath) |
|
714 | + { |
|
715 | + $this->_main_plugin_file = $filepath; |
|
716 | + } |
|
717 | + |
|
718 | + /** |
|
719 | + * gets the filepath to teh main file |
|
720 | + * |
|
721 | + * @return string |
|
722 | + */ |
|
723 | + public function get_main_plugin_file() |
|
724 | + { |
|
725 | + return $this->_main_plugin_file; |
|
726 | + } |
|
727 | + |
|
728 | + /** |
|
729 | + * Gets the filename (no path) of the main file (the main file loaded |
|
730 | + * by WP) |
|
731 | + * |
|
732 | + * @return string |
|
733 | + */ |
|
734 | + public function get_main_plugin_file_basename() |
|
735 | + { |
|
736 | + return plugin_basename($this->get_main_plugin_file()); |
|
737 | + } |
|
738 | + |
|
739 | + /** |
|
740 | + * Gets the folder name which contains the main plugin file |
|
741 | + * |
|
742 | + * @return string |
|
743 | + */ |
|
744 | + public function get_main_plugin_file_dirname() |
|
745 | + { |
|
746 | + return dirname($this->get_main_plugin_file()); |
|
747 | + } |
|
748 | + |
|
749 | + |
|
750 | + /** |
|
751 | + * sets hooks used in the admin |
|
752 | + * |
|
753 | + * @return void |
|
754 | + */ |
|
755 | + public function admin_init() |
|
756 | + { |
|
757 | + // is admin and not in M-Mode ? |
|
758 | + if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) { |
|
759 | + add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2); |
|
760 | + add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3); |
|
761 | + } |
|
762 | + } |
|
763 | + |
|
764 | + |
|
765 | + /** |
|
766 | + * plugin_actions |
|
767 | + * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page. |
|
768 | + * |
|
769 | + * @param $links |
|
770 | + * @param $file |
|
771 | + * @return array |
|
772 | + */ |
|
773 | + public function plugin_action_links($links, $file) |
|
774 | + { |
|
775 | + if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') { |
|
776 | + // before other links |
|
777 | + array_unshift( |
|
778 | + $links, |
|
779 | + '<a href="admin.php?page=' . $this->plugin_action_slug() . '">' |
|
780 | + . esc_html__('Settings', 'event_espresso') |
|
781 | + . '</a>' |
|
782 | + ); |
|
783 | + } |
|
784 | + return $links; |
|
785 | + } |
|
786 | + |
|
787 | + |
|
788 | + /** |
|
789 | + * after_plugin_row |
|
790 | + * Add additional content to the plugins page plugin row |
|
791 | + * Inserts another row |
|
792 | + * |
|
793 | + * @param $plugin_file |
|
794 | + * @param $plugin_data |
|
795 | + * @param $status |
|
796 | + * @return void |
|
797 | + */ |
|
798 | + public function after_plugin_row($plugin_file, $plugin_data, $status) |
|
799 | + { |
|
800 | + $after_plugin_row = ''; |
|
801 | + $plugins_page_row = $this->get_plugins_page_row(); |
|
802 | + if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) { |
|
803 | + $class = $status ? 'active' : 'inactive'; |
|
804 | + $link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : ''; |
|
805 | + $link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : ''; |
|
806 | + $description = isset($plugins_page_row['description']) |
|
807 | + ? $plugins_page_row['description'] |
|
808 | + : ''; |
|
809 | + if (! empty($link_text) && ! empty($link_url) && ! empty($description)) { |
|
810 | + $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">'; |
|
811 | + $after_plugin_row .= '<th class="check-column" scope="row"></th>'; |
|
812 | + $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">'; |
|
813 | + $after_plugin_row .= '<style> |
|
814 | 814 | .ee-button, |
815 | 815 | .ee-button:active, |
816 | 816 | .ee-button:visited { |
@@ -847,64 +847,64 @@ discard block |
||
847 | 847 | } |
848 | 848 | .ee-button:active { top:0; } |
849 | 849 | </style>'; |
850 | - $after_plugin_row .= ' |
|
850 | + $after_plugin_row .= ' |
|
851 | 851 | <p class="ee-addon-upsell-info-dv"> |
852 | 852 | <a class="ee-button" href="' . $link_url . '">' |
853 | - . $link_text |
|
854 | - . ' <span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>' |
|
855 | - . '</a> |
|
853 | + . $link_text |
|
854 | + . ' <span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>' |
|
855 | + . '</a> |
|
856 | 856 | </p>'; |
857 | - $after_plugin_row .= '</td>'; |
|
858 | - $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">'; |
|
859 | - $after_plugin_row .= $description; |
|
860 | - $after_plugin_row .= '</td>'; |
|
861 | - $after_plugin_row .= '</tr>'; |
|
862 | - } else { |
|
863 | - $after_plugin_row .= $description; |
|
864 | - } |
|
865 | - } |
|
866 | - |
|
867 | - echo $after_plugin_row; |
|
868 | - } |
|
869 | - |
|
870 | - |
|
871 | - /** |
|
872 | - * A safe space for addons to add additional logic like setting hooks that need to be set early in the request. |
|
873 | - * Child classes that have logic like that to run can override this method declaration. This was not made abstract |
|
874 | - * for back compat reasons. |
|
875 | - * |
|
876 | - * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999. |
|
877 | - * |
|
878 | - * It is recommended, if client code is `de-registering` an add-on, then do it on the |
|
879 | - * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this |
|
880 | - * callback does not get run/set in that request. |
|
881 | - * |
|
882 | - * Also, keep in mind that if a registered add-on happens to be deactivated via |
|
883 | - * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method |
|
884 | - * (including setting hooks etc) will have executed before the plugin was deactivated. If you use |
|
885 | - * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's |
|
886 | - * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there. Just remember |
|
887 | - * to call `parent::deactivation`. |
|
888 | - * |
|
889 | - * @since 4.9.26 |
|
890 | - */ |
|
891 | - public function after_registration() |
|
892 | - { |
|
893 | - // cricket chirp... cricket chirp... |
|
894 | - } |
|
895 | - |
|
896 | - /** |
|
897 | - * @return string |
|
898 | - */ |
|
899 | - public function getPueSlug() |
|
900 | - { |
|
901 | - return $this->pue_slug; |
|
902 | - } |
|
903 | - /** |
|
904 | - * @param string $pue_slug |
|
905 | - */ |
|
906 | - public function setPueSlug($pue_slug) |
|
907 | - { |
|
908 | - $this->pue_slug = $pue_slug; |
|
909 | - } |
|
857 | + $after_plugin_row .= '</td>'; |
|
858 | + $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">'; |
|
859 | + $after_plugin_row .= $description; |
|
860 | + $after_plugin_row .= '</td>'; |
|
861 | + $after_plugin_row .= '</tr>'; |
|
862 | + } else { |
|
863 | + $after_plugin_row .= $description; |
|
864 | + } |
|
865 | + } |
|
866 | + |
|
867 | + echo $after_plugin_row; |
|
868 | + } |
|
869 | + |
|
870 | + |
|
871 | + /** |
|
872 | + * A safe space for addons to add additional logic like setting hooks that need to be set early in the request. |
|
873 | + * Child classes that have logic like that to run can override this method declaration. This was not made abstract |
|
874 | + * for back compat reasons. |
|
875 | + * |
|
876 | + * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999. |
|
877 | + * |
|
878 | + * It is recommended, if client code is `de-registering` an add-on, then do it on the |
|
879 | + * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this |
|
880 | + * callback does not get run/set in that request. |
|
881 | + * |
|
882 | + * Also, keep in mind that if a registered add-on happens to be deactivated via |
|
883 | + * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method |
|
884 | + * (including setting hooks etc) will have executed before the plugin was deactivated. If you use |
|
885 | + * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's |
|
886 | + * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there. Just remember |
|
887 | + * to call `parent::deactivation`. |
|
888 | + * |
|
889 | + * @since 4.9.26 |
|
890 | + */ |
|
891 | + public function after_registration() |
|
892 | + { |
|
893 | + // cricket chirp... cricket chirp... |
|
894 | + } |
|
895 | + |
|
896 | + /** |
|
897 | + * @return string |
|
898 | + */ |
|
899 | + public function getPueSlug() |
|
900 | + { |
|
901 | + return $this->pue_slug; |
|
902 | + } |
|
903 | + /** |
|
904 | + * @param string $pue_slug |
|
905 | + */ |
|
906 | + public function setPueSlug($pue_slug) |
|
907 | + { |
|
908 | + $this->pue_slug = $pue_slug; |
|
909 | + } |
|
910 | 910 | } |
@@ -576,7 +576,7 @@ discard block |
||
576 | 576 | */ |
577 | 577 | public function get_activation_indicator_option_name() |
578 | 578 | { |
579 | - return 'ee_activation_' . $this->name(); |
|
579 | + return 'ee_activation_'.$this->name(); |
|
580 | 580 | } |
581 | 581 | |
582 | 582 | |
@@ -663,13 +663,13 @@ discard block |
||
663 | 663 | */ |
664 | 664 | public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null) |
665 | 665 | { |
666 | - if (! $version_history) { |
|
666 | + if ( ! $version_history) { |
|
667 | 667 | $version_history = $this->get_activation_history(); |
668 | 668 | } |
669 | 669 | if ($current_version_to_add === null) { |
670 | 670 | $current_version_to_add = $this->version(); |
671 | 671 | } |
672 | - $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time()); |
|
672 | + $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time()); |
|
673 | 673 | // resave |
674 | 674 | return update_option($this->get_activation_history_option_name(), $version_history); |
675 | 675 | } |
@@ -682,7 +682,7 @@ discard block |
||
682 | 682 | */ |
683 | 683 | public function get_activation_history_option_name() |
684 | 684 | { |
685 | - return self::ee_addon_version_history_option_prefix . $this->name(); |
|
685 | + return self::ee_addon_version_history_option_prefix.$this->name(); |
|
686 | 686 | } |
687 | 687 | |
688 | 688 | |
@@ -757,7 +757,7 @@ discard block |
||
757 | 757 | // is admin and not in M-Mode ? |
758 | 758 | if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) { |
759 | 759 | add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2); |
760 | - add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3); |
|
760 | + add_filter('after_plugin_row_'.$this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3); |
|
761 | 761 | } |
762 | 762 | } |
763 | 763 | |
@@ -776,7 +776,7 @@ discard block |
||
776 | 776 | // before other links |
777 | 777 | array_unshift( |
778 | 778 | $links, |
779 | - '<a href="admin.php?page=' . $this->plugin_action_slug() . '">' |
|
779 | + '<a href="admin.php?page='.$this->plugin_action_slug().'">' |
|
780 | 780 | . esc_html__('Settings', 'event_espresso') |
781 | 781 | . '</a>' |
782 | 782 | ); |
@@ -799,15 +799,15 @@ discard block |
||
799 | 799 | { |
800 | 800 | $after_plugin_row = ''; |
801 | 801 | $plugins_page_row = $this->get_plugins_page_row(); |
802 | - if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) { |
|
802 | + if ( ! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) { |
|
803 | 803 | $class = $status ? 'active' : 'inactive'; |
804 | 804 | $link_text = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : ''; |
805 | 805 | $link_url = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : ''; |
806 | 806 | $description = isset($plugins_page_row['description']) |
807 | 807 | ? $plugins_page_row['description'] |
808 | 808 | : ''; |
809 | - if (! empty($link_text) && ! empty($link_url) && ! empty($description)) { |
|
810 | - $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">'; |
|
809 | + if ( ! empty($link_text) && ! empty($link_url) && ! empty($description)) { |
|
810 | + $after_plugin_row .= '<tr id="'.sanitize_title($plugin_file).'-ee-addon" class="'.$class.'">'; |
|
811 | 811 | $after_plugin_row .= '<th class="check-column" scope="row"></th>'; |
812 | 812 | $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">'; |
813 | 813 | $after_plugin_row .= '<style> |
@@ -849,7 +849,7 @@ discard block |
||
849 | 849 | </style>'; |
850 | 850 | $after_plugin_row .= ' |
851 | 851 | <p class="ee-addon-upsell-info-dv"> |
852 | - <a class="ee-button" href="' . $link_url . '">' |
|
852 | + <a class="ee-button" href="' . $link_url.'">' |
|
853 | 853 | . $link_text |
854 | 854 | . ' <span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>' |
855 | 855 | . '</a> |
@@ -22,206 +22,206 @@ |
||
22 | 22 | */ |
23 | 23 | class ModelObjNode extends BaseNode |
24 | 24 | { |
25 | - /** |
|
26 | - * @var int|string |
|
27 | - */ |
|
28 | - protected $id; |
|
25 | + /** |
|
26 | + * @var int|string |
|
27 | + */ |
|
28 | + protected $id; |
|
29 | 29 | |
30 | - /** |
|
31 | - * @var EEM_Base |
|
32 | - */ |
|
33 | - protected $model; |
|
30 | + /** |
|
31 | + * @var EEM_Base |
|
32 | + */ |
|
33 | + protected $model; |
|
34 | 34 | |
35 | - /** |
|
36 | - * @var RelationNode[] |
|
37 | - */ |
|
38 | - protected $nodes; |
|
35 | + /** |
|
36 | + * @var RelationNode[] |
|
37 | + */ |
|
38 | + protected $nodes; |
|
39 | 39 | |
40 | - /** |
|
41 | - * We don't pass the model objects because this needs to serialize to something tiny for effiency. |
|
42 | - * @param $model_obj_id |
|
43 | - * @param EEM_Base $model |
|
44 | - * @param array $dont_traverse_models array of model names we DON'T want to traverse. |
|
45 | - */ |
|
46 | - public function __construct($model_obj_id, EEM_Base $model, array $dont_traverse_models = []) |
|
47 | - { |
|
48 | - $this->id = $model_obj_id; |
|
49 | - $this->model = $model; |
|
50 | - $this->dont_traverse_models = $dont_traverse_models; |
|
51 | - } |
|
40 | + /** |
|
41 | + * We don't pass the model objects because this needs to serialize to something tiny for effiency. |
|
42 | + * @param $model_obj_id |
|
43 | + * @param EEM_Base $model |
|
44 | + * @param array $dont_traverse_models array of model names we DON'T want to traverse. |
|
45 | + */ |
|
46 | + public function __construct($model_obj_id, EEM_Base $model, array $dont_traverse_models = []) |
|
47 | + { |
|
48 | + $this->id = $model_obj_id; |
|
49 | + $this->model = $model; |
|
50 | + $this->dont_traverse_models = $dont_traverse_models; |
|
51 | + } |
|
52 | 52 | |
53 | - /** |
|
54 | - * Creates a relation node for each relation of this model's relations. |
|
55 | - * Does NOT call `discover` on them yet though. |
|
56 | - * @since 4.10.12.p |
|
57 | - * @throws \EE_Error |
|
58 | - * @throws InvalidDataTypeException |
|
59 | - * @throws InvalidInterfaceException |
|
60 | - * @throws InvalidArgumentException |
|
61 | - * @throws ReflectionException |
|
62 | - */ |
|
63 | - protected function discover() |
|
64 | - { |
|
65 | - $this->nodes = []; |
|
66 | - foreach ($this->model->relation_settings() as $relationName => $relation) { |
|
67 | - // Make sure this isn't one of the models we were told to not traverse into. |
|
68 | - if (in_array($relationName, $this->dont_traverse_models)) { |
|
69 | - continue; |
|
70 | - } |
|
71 | - if ($relation instanceof EE_Has_Many_Relation) { |
|
72 | - $this->nodes[ $relationName ] = new RelationNode( |
|
73 | - $this->id, |
|
74 | - $this->model, |
|
75 | - $relation->get_other_model(), |
|
76 | - $this->dont_traverse_models |
|
77 | - ); |
|
78 | - } elseif ( |
|
79 | - $relation instanceof EE_HABTM_Relation && |
|
80 | - ! in_array( |
|
81 | - $relation->get_join_model()->get_this_model_name(), |
|
82 | - $this->dont_traverse_models |
|
83 | - ) |
|
84 | - ) { |
|
85 | - $this->nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode( |
|
86 | - $this->id, |
|
87 | - $this->model, |
|
88 | - $relation->get_join_model(), |
|
89 | - $this->dont_traverse_models |
|
90 | - ); |
|
91 | - } |
|
92 | - } |
|
93 | - ksort($this->nodes); |
|
94 | - } |
|
53 | + /** |
|
54 | + * Creates a relation node for each relation of this model's relations. |
|
55 | + * Does NOT call `discover` on them yet though. |
|
56 | + * @since 4.10.12.p |
|
57 | + * @throws \EE_Error |
|
58 | + * @throws InvalidDataTypeException |
|
59 | + * @throws InvalidInterfaceException |
|
60 | + * @throws InvalidArgumentException |
|
61 | + * @throws ReflectionException |
|
62 | + */ |
|
63 | + protected function discover() |
|
64 | + { |
|
65 | + $this->nodes = []; |
|
66 | + foreach ($this->model->relation_settings() as $relationName => $relation) { |
|
67 | + // Make sure this isn't one of the models we were told to not traverse into. |
|
68 | + if (in_array($relationName, $this->dont_traverse_models)) { |
|
69 | + continue; |
|
70 | + } |
|
71 | + if ($relation instanceof EE_Has_Many_Relation) { |
|
72 | + $this->nodes[ $relationName ] = new RelationNode( |
|
73 | + $this->id, |
|
74 | + $this->model, |
|
75 | + $relation->get_other_model(), |
|
76 | + $this->dont_traverse_models |
|
77 | + ); |
|
78 | + } elseif ( |
|
79 | + $relation instanceof EE_HABTM_Relation && |
|
80 | + ! in_array( |
|
81 | + $relation->get_join_model()->get_this_model_name(), |
|
82 | + $this->dont_traverse_models |
|
83 | + ) |
|
84 | + ) { |
|
85 | + $this->nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode( |
|
86 | + $this->id, |
|
87 | + $this->model, |
|
88 | + $relation->get_join_model(), |
|
89 | + $this->dont_traverse_models |
|
90 | + ); |
|
91 | + } |
|
92 | + } |
|
93 | + ksort($this->nodes); |
|
94 | + } |
|
95 | 95 | |
96 | 96 | |
97 | - /** |
|
98 | - * Whether this item has already been initialized |
|
99 | - */ |
|
100 | - protected function isDiscovered() |
|
101 | - { |
|
102 | - return $this->nodes !== null && is_array($this->nodes); |
|
103 | - } |
|
97 | + /** |
|
98 | + * Whether this item has already been initialized |
|
99 | + */ |
|
100 | + protected function isDiscovered() |
|
101 | + { |
|
102 | + return $this->nodes !== null && is_array($this->nodes); |
|
103 | + } |
|
104 | 104 | |
105 | - /** |
|
106 | - * @since 4.10.12.p |
|
107 | - * @return boolean |
|
108 | - */ |
|
109 | - public function isComplete() |
|
110 | - { |
|
111 | - if ($this->complete === null) { |
|
112 | - $this->complete = false; |
|
113 | - } |
|
114 | - return $this->complete; |
|
115 | - } |
|
105 | + /** |
|
106 | + * @since 4.10.12.p |
|
107 | + * @return boolean |
|
108 | + */ |
|
109 | + public function isComplete() |
|
110 | + { |
|
111 | + if ($this->complete === null) { |
|
112 | + $this->complete = false; |
|
113 | + } |
|
114 | + return $this->complete; |
|
115 | + } |
|
116 | 116 | |
117 | - /** |
|
118 | - * Triggers working on each child relation node that has work to do. |
|
119 | - * @since 4.10.12.p |
|
120 | - * @param $model_objects_to_identify |
|
121 | - * @return int units of work done |
|
122 | - */ |
|
123 | - protected function work($model_objects_to_identify) |
|
124 | - { |
|
125 | - $num_identified = 0; |
|
126 | - // Begin assuming we'll finish all the work on this node and its children... |
|
127 | - $this->complete = true; |
|
128 | - foreach ($this->nodes as $model_name => $relation_node) { |
|
129 | - $num_identified += $relation_node->visit($model_objects_to_identify - $num_identified); |
|
130 | - // To save on space when serializing, only bother keeping a record of relation nodes that actually found |
|
131 | - // related model objects. |
|
132 | - if ($relation_node->isComplete() && $relation_node->countSubNodes() === 0) { |
|
133 | - unset($this->nodes[ $model_name ]); |
|
134 | - } |
|
135 | - if ($num_identified >= $model_objects_to_identify) { |
|
136 | - // ...but admit we're wrong if the work exceeded the budget. |
|
137 | - $this->complete = false; |
|
138 | - break; |
|
139 | - } |
|
140 | - } |
|
141 | - return $num_identified; |
|
142 | - } |
|
117 | + /** |
|
118 | + * Triggers working on each child relation node that has work to do. |
|
119 | + * @since 4.10.12.p |
|
120 | + * @param $model_objects_to_identify |
|
121 | + * @return int units of work done |
|
122 | + */ |
|
123 | + protected function work($model_objects_to_identify) |
|
124 | + { |
|
125 | + $num_identified = 0; |
|
126 | + // Begin assuming we'll finish all the work on this node and its children... |
|
127 | + $this->complete = true; |
|
128 | + foreach ($this->nodes as $model_name => $relation_node) { |
|
129 | + $num_identified += $relation_node->visit($model_objects_to_identify - $num_identified); |
|
130 | + // To save on space when serializing, only bother keeping a record of relation nodes that actually found |
|
131 | + // related model objects. |
|
132 | + if ($relation_node->isComplete() && $relation_node->countSubNodes() === 0) { |
|
133 | + unset($this->nodes[ $model_name ]); |
|
134 | + } |
|
135 | + if ($num_identified >= $model_objects_to_identify) { |
|
136 | + // ...but admit we're wrong if the work exceeded the budget. |
|
137 | + $this->complete = false; |
|
138 | + break; |
|
139 | + } |
|
140 | + } |
|
141 | + return $num_identified; |
|
142 | + } |
|
143 | 143 | |
144 | - /** |
|
145 | - * @since 4.10.12.p |
|
146 | - * @return array |
|
147 | - * @throws \EE_Error |
|
148 | - * @throws InvalidDataTypeException |
|
149 | - * @throws InvalidInterfaceException |
|
150 | - * @throws InvalidArgumentException |
|
151 | - * @throws ReflectionException |
|
152 | - */ |
|
153 | - public function toArray() |
|
154 | - { |
|
155 | - $tree = [ |
|
156 | - 'id' => $this->id, |
|
157 | - 'complete' => $this->isComplete(), |
|
158 | - 'rels' => [] |
|
159 | - ]; |
|
160 | - if ($this->nodes === null) { |
|
161 | - $tree['rels'] = null; |
|
162 | - } else { |
|
163 | - foreach ($this->nodes as $relation_name => $relation_node) { |
|
164 | - $tree['rels'][ $relation_name ] = $relation_node->toArray(); |
|
165 | - } |
|
166 | - } |
|
167 | - return $tree; |
|
168 | - } |
|
144 | + /** |
|
145 | + * @since 4.10.12.p |
|
146 | + * @return array |
|
147 | + * @throws \EE_Error |
|
148 | + * @throws InvalidDataTypeException |
|
149 | + * @throws InvalidInterfaceException |
|
150 | + * @throws InvalidArgumentException |
|
151 | + * @throws ReflectionException |
|
152 | + */ |
|
153 | + public function toArray() |
|
154 | + { |
|
155 | + $tree = [ |
|
156 | + 'id' => $this->id, |
|
157 | + 'complete' => $this->isComplete(), |
|
158 | + 'rels' => [] |
|
159 | + ]; |
|
160 | + if ($this->nodes === null) { |
|
161 | + $tree['rels'] = null; |
|
162 | + } else { |
|
163 | + foreach ($this->nodes as $relation_name => $relation_node) { |
|
164 | + $tree['rels'][ $relation_name ] = $relation_node->toArray(); |
|
165 | + } |
|
166 | + } |
|
167 | + return $tree; |
|
168 | + } |
|
169 | 169 | |
170 | - /** |
|
171 | - * @since 4.10.12.p |
|
172 | - * @return array|mixed |
|
173 | - * @throws InvalidArgumentException |
|
174 | - * @throws InvalidDataTypeException |
|
175 | - * @throws InvalidInterfaceException |
|
176 | - * @throws ReflectionException |
|
177 | - * @throws \EE_Error |
|
178 | - */ |
|
179 | - public function getIds() |
|
180 | - { |
|
181 | - $ids = [ |
|
182 | - $this->model->get_this_model_name() => [ |
|
183 | - $this->id => $this->id |
|
184 | - ] |
|
185 | - ]; |
|
186 | - if ($this->nodes && is_array($this->nodes)) { |
|
187 | - foreach ($this->nodes as $relation_node) { |
|
188 | - $ids = array_replace_recursive($ids, $relation_node->getIds()); |
|
189 | - } |
|
190 | - } |
|
191 | - return $ids; |
|
192 | - } |
|
170 | + /** |
|
171 | + * @since 4.10.12.p |
|
172 | + * @return array|mixed |
|
173 | + * @throws InvalidArgumentException |
|
174 | + * @throws InvalidDataTypeException |
|
175 | + * @throws InvalidInterfaceException |
|
176 | + * @throws ReflectionException |
|
177 | + * @throws \EE_Error |
|
178 | + */ |
|
179 | + public function getIds() |
|
180 | + { |
|
181 | + $ids = [ |
|
182 | + $this->model->get_this_model_name() => [ |
|
183 | + $this->id => $this->id |
|
184 | + ] |
|
185 | + ]; |
|
186 | + if ($this->nodes && is_array($this->nodes)) { |
|
187 | + foreach ($this->nodes as $relation_node) { |
|
188 | + $ids = array_replace_recursive($ids, $relation_node->getIds()); |
|
189 | + } |
|
190 | + } |
|
191 | + return $ids; |
|
192 | + } |
|
193 | 193 | |
194 | - /** |
|
195 | - * Don't serialize the models. Just record their names on some dynamic properties. |
|
196 | - * @since 4.10.12.p |
|
197 | - */ |
|
198 | - public function __sleep() |
|
199 | - { |
|
200 | - $this->m = $this->model->get_this_model_name(); |
|
201 | - return array_merge( |
|
202 | - [ |
|
203 | - 'm', |
|
204 | - 'id', |
|
205 | - 'nodes', |
|
206 | - ], |
|
207 | - parent::__sleep() |
|
208 | - ); |
|
209 | - } |
|
194 | + /** |
|
195 | + * Don't serialize the models. Just record their names on some dynamic properties. |
|
196 | + * @since 4.10.12.p |
|
197 | + */ |
|
198 | + public function __sleep() |
|
199 | + { |
|
200 | + $this->m = $this->model->get_this_model_name(); |
|
201 | + return array_merge( |
|
202 | + [ |
|
203 | + 'm', |
|
204 | + 'id', |
|
205 | + 'nodes', |
|
206 | + ], |
|
207 | + parent::__sleep() |
|
208 | + ); |
|
209 | + } |
|
210 | 210 | |
211 | - /** |
|
212 | - * Use the dynamic properties to instantiate the models we use. |
|
213 | - * @since 4.10.12.p |
|
214 | - * @throws EE_Error |
|
215 | - * @throws InvalidArgumentException |
|
216 | - * @throws InvalidDataTypeException |
|
217 | - * @throws InvalidInterfaceException |
|
218 | - * @throws ReflectionException |
|
219 | - */ |
|
220 | - public function __wakeup() |
|
221 | - { |
|
222 | - $this->model = EE_Registry::instance()->load_model($this->m); |
|
223 | - parent::__wakeup(); |
|
224 | - } |
|
211 | + /** |
|
212 | + * Use the dynamic properties to instantiate the models we use. |
|
213 | + * @since 4.10.12.p |
|
214 | + * @throws EE_Error |
|
215 | + * @throws InvalidArgumentException |
|
216 | + * @throws InvalidDataTypeException |
|
217 | + * @throws InvalidInterfaceException |
|
218 | + * @throws ReflectionException |
|
219 | + */ |
|
220 | + public function __wakeup() |
|
221 | + { |
|
222 | + $this->model = EE_Registry::instance()->load_model($this->m); |
|
223 | + parent::__wakeup(); |
|
224 | + } |
|
225 | 225 | } |
226 | 226 | // End of file Visitor.php |
227 | 227 | // Location: EventEspresso\core\services\orm\tree_traversal/Visitor.php |
@@ -69,7 +69,7 @@ discard block |
||
69 | 69 | continue; |
70 | 70 | } |
71 | 71 | if ($relation instanceof EE_Has_Many_Relation) { |
72 | - $this->nodes[ $relationName ] = new RelationNode( |
|
72 | + $this->nodes[$relationName] = new RelationNode( |
|
73 | 73 | $this->id, |
74 | 74 | $this->model, |
75 | 75 | $relation->get_other_model(), |
@@ -82,7 +82,7 @@ discard block |
||
82 | 82 | $this->dont_traverse_models |
83 | 83 | ) |
84 | 84 | ) { |
85 | - $this->nodes[ $relation->get_join_model()->get_this_model_name() ] = new RelationNode( |
|
85 | + $this->nodes[$relation->get_join_model()->get_this_model_name()] = new RelationNode( |
|
86 | 86 | $this->id, |
87 | 87 | $this->model, |
88 | 88 | $relation->get_join_model(), |
@@ -130,7 +130,7 @@ discard block |
||
130 | 130 | // To save on space when serializing, only bother keeping a record of relation nodes that actually found |
131 | 131 | // related model objects. |
132 | 132 | if ($relation_node->isComplete() && $relation_node->countSubNodes() === 0) { |
133 | - unset($this->nodes[ $model_name ]); |
|
133 | + unset($this->nodes[$model_name]); |
|
134 | 134 | } |
135 | 135 | if ($num_identified >= $model_objects_to_identify) { |
136 | 136 | // ...but admit we're wrong if the work exceeded the budget. |
@@ -161,7 +161,7 @@ discard block |
||
161 | 161 | $tree['rels'] = null; |
162 | 162 | } else { |
163 | 163 | foreach ($this->nodes as $relation_name => $relation_node) { |
164 | - $tree['rels'][ $relation_name ] = $relation_node->toArray(); |
|
164 | + $tree['rels'][$relation_name] = $relation_node->toArray(); |
|
165 | 165 | } |
166 | 166 | } |
167 | 167 | return $tree; |
@@ -26,775 +26,775 @@ |
||
26 | 26 | class EE_Registration_Processor extends EE_Processor_Base |
27 | 27 | { |
28 | 28 | |
29 | - /** |
|
30 | - * @var EE_Registration_Processor $_instance |
|
31 | - * @access private |
|
32 | - */ |
|
33 | - private static $_instance; |
|
34 | - |
|
35 | - /** |
|
36 | - * initial reg status at the beginning of this request. |
|
37 | - * indexed by registration ID |
|
38 | - * |
|
39 | - * @var array |
|
40 | - */ |
|
41 | - protected $_old_reg_status = []; |
|
42 | - |
|
43 | - /** |
|
44 | - * reg status at the end of the request after all processing. |
|
45 | - * indexed by registration ID |
|
46 | - * |
|
47 | - * @var array |
|
48 | - */ |
|
49 | - protected $_new_reg_status = []; |
|
50 | - |
|
51 | - /** |
|
52 | - * amounts paid at the end of the request after all processing. |
|
53 | - * indexed by registration ID |
|
54 | - * |
|
55 | - * @var array |
|
56 | - */ |
|
57 | - protected static $_amount_paid = []; |
|
58 | - |
|
59 | - /** |
|
60 | - * Cache of the reg final price for registrations corresponding to a ticket line item |
|
61 | - * |
|
62 | - * @deprecated |
|
63 | - * @var array @see EEH_Line_Item::calculate_reg_final_prices_per_line_item()'s return value |
|
64 | - */ |
|
65 | - protected $_reg_final_price_per_tkt_line_item; |
|
66 | - |
|
67 | - /** |
|
68 | - * @var RequestInterface $request |
|
69 | - */ |
|
70 | - protected $request; |
|
71 | - |
|
72 | - |
|
73 | - /** |
|
74 | - * @singleton method used to instantiate class object |
|
75 | - * @param RequestInterface|null $request |
|
76 | - * @return EE_Registration_Processor instance |
|
77 | - * @throws InvalidArgumentException |
|
78 | - * @throws InvalidInterfaceException |
|
79 | - * @throws InvalidDataTypeException |
|
80 | - */ |
|
81 | - public static function instance(RequestInterface $request = null) |
|
82 | - { |
|
83 | - // check if class object is instantiated |
|
84 | - if (! self::$_instance instanceof EE_Registration_Processor) { |
|
85 | - if (! $request instanceof RequestInterface) { |
|
86 | - $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request'); |
|
87 | - } |
|
88 | - self::$_instance = new self($request); |
|
89 | - } |
|
90 | - return self::$_instance; |
|
91 | - } |
|
92 | - |
|
93 | - |
|
94 | - /** |
|
95 | - * EE_Registration_Processor constructor. |
|
96 | - * |
|
97 | - * @param RequestInterface $request |
|
98 | - */ |
|
99 | - public function __construct(RequestInterface $request) |
|
100 | - { |
|
101 | - $this->request = $request; |
|
102 | - } |
|
103 | - |
|
104 | - |
|
105 | - /** |
|
106 | - * @param int $REG_ID |
|
107 | - * @return string |
|
108 | - */ |
|
109 | - public function old_reg_status($REG_ID) |
|
110 | - { |
|
111 | - return isset($this->_old_reg_status[ $REG_ID ]) ? $this->_old_reg_status[ $REG_ID ] : null; |
|
112 | - } |
|
113 | - |
|
114 | - |
|
115 | - /** |
|
116 | - * @param int $REG_ID |
|
117 | - * @param string $old_reg_status |
|
118 | - */ |
|
119 | - public function set_old_reg_status($REG_ID, $old_reg_status) |
|
120 | - { |
|
121 | - // only set the first time |
|
122 | - if (! isset($this->_old_reg_status[ $REG_ID ])) { |
|
123 | - $this->_old_reg_status[ $REG_ID ] = $old_reg_status; |
|
124 | - } |
|
125 | - } |
|
126 | - |
|
127 | - |
|
128 | - /** |
|
129 | - * @param int $REG_ID |
|
130 | - * @return string |
|
131 | - */ |
|
132 | - public function new_reg_status($REG_ID) |
|
133 | - { |
|
134 | - return isset($this->_new_reg_status[ $REG_ID ]) ? $this->_new_reg_status[ $REG_ID ] : null; |
|
135 | - } |
|
136 | - |
|
137 | - |
|
138 | - /** |
|
139 | - * @param int $REG_ID |
|
140 | - * @param string $new_reg_status |
|
141 | - */ |
|
142 | - public function set_new_reg_status($REG_ID, $new_reg_status) |
|
143 | - { |
|
144 | - $this->_new_reg_status[ $REG_ID ] = $new_reg_status; |
|
145 | - } |
|
146 | - |
|
147 | - |
|
148 | - /** |
|
149 | - * reg_status_updated |
|
150 | - * |
|
151 | - * @param int $REG_ID |
|
152 | - * @return bool |
|
153 | - */ |
|
154 | - public function reg_status_updated($REG_ID) |
|
155 | - { |
|
156 | - return $this->new_reg_status($REG_ID) !== $this->old_reg_status($REG_ID); |
|
157 | - } |
|
158 | - |
|
159 | - |
|
160 | - /** |
|
161 | - * @param EE_Registration $registration |
|
162 | - * @throws EE_Error |
|
163 | - * @throws EntityNotFoundException |
|
164 | - * @throws InvalidArgumentException |
|
165 | - * @throws InvalidDataTypeException |
|
166 | - * @throws InvalidInterfaceException |
|
167 | - * @throws ReflectionException |
|
168 | - * @throws RuntimeException |
|
169 | - */ |
|
170 | - public function update_registration_status_and_trigger_notifications(EE_Registration $registration) |
|
171 | - { |
|
172 | - $this->toggle_incomplete_registration_status_to_default($registration, false); |
|
173 | - $this->toggle_registration_status_for_default_approved_events($registration, false); |
|
174 | - $this->toggle_registration_status_if_no_monies_owing($registration, false); |
|
175 | - $registration->save(); |
|
176 | - // trigger notifications |
|
177 | - $this->trigger_registration_update_notifications($registration); |
|
178 | - } |
|
179 | - |
|
180 | - |
|
181 | - /** |
|
182 | - * manually_update_registration_status |
|
183 | - * |
|
184 | - * @access public |
|
185 | - * @param EE_Registration $registration |
|
186 | - * @param string $new_reg_status |
|
187 | - * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave that up |
|
188 | - * to client code |
|
189 | - * @return bool |
|
190 | - * @throws EE_Error |
|
191 | - * @throws EntityNotFoundException |
|
192 | - * @throws InvalidArgumentException |
|
193 | - * @throws InvalidDataTypeException |
|
194 | - * @throws InvalidInterfaceException |
|
195 | - * @throws ReflectionException |
|
196 | - * @throws RuntimeException |
|
197 | - */ |
|
198 | - public function manually_update_registration_status( |
|
199 | - EE_Registration $registration, |
|
200 | - $new_reg_status = '', |
|
201 | - $save = true |
|
202 | - ) { |
|
203 | - // set initial REG_Status |
|
204 | - $this->set_old_reg_status($registration->ID(), $registration->status_ID()); |
|
205 | - // set incoming REG_Status |
|
206 | - $this->set_new_reg_status($registration->ID(), $new_reg_status); |
|
207 | - // toggle reg status but only if it has changed and the user can do so |
|
208 | - if ( |
|
209 | - $this->reg_status_updated($registration->ID()) |
|
210 | - && ( |
|
211 | - (! $this->request->isAdmin() || $this->request->isFrontAjax()) |
|
212 | - || EE_Registry::instance()->CAP->current_user_can( |
|
213 | - 'ee_edit_registration', |
|
214 | - 'toggle_registration_status', |
|
215 | - $registration->ID() |
|
216 | - ) |
|
217 | - ) |
|
218 | - ) { |
|
219 | - // change status to new value |
|
220 | - $updated = $registration->set_status($this->new_reg_status($registration->ID())); |
|
221 | - if ($updated && $save) { |
|
222 | - $registration->save(); |
|
223 | - } |
|
224 | - return true; |
|
225 | - } |
|
226 | - return false; |
|
227 | - } |
|
228 | - |
|
229 | - |
|
230 | - /** |
|
231 | - * toggle_incomplete_registration_status_to_default |
|
232 | - * changes any incomplete registrations to either the event or global default registration status |
|
233 | - * |
|
234 | - * @access public |
|
235 | - * @param EE_Registration $registration |
|
236 | - * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave |
|
237 | - * that up to client code |
|
238 | - * @param ContextInterface|null $context |
|
239 | - * @return void |
|
240 | - * @throws EE_Error |
|
241 | - * @throws InvalidArgumentException |
|
242 | - * @throws ReflectionException |
|
243 | - * @throws RuntimeException |
|
244 | - * @throws EntityNotFoundException |
|
245 | - * @throws InvalidDataTypeException |
|
246 | - * @throws InvalidInterfaceException |
|
247 | - */ |
|
248 | - public function toggle_incomplete_registration_status_to_default( |
|
249 | - EE_Registration $registration, |
|
250 | - $save = true, |
|
251 | - ContextInterface $context = null |
|
252 | - ) { |
|
253 | - $existing_reg_status = $registration->status_ID(); |
|
254 | - // set initial REG_Status |
|
255 | - $this->set_old_reg_status($registration->ID(), $existing_reg_status); |
|
256 | - // is the registration currently incomplete ? |
|
257 | - if ($registration->status_ID() === EEM_Registration::status_id_incomplete) { |
|
258 | - // grab default reg status for the event, if set |
|
259 | - $event_default_registration_status = $registration->event()->default_registration_status(); |
|
260 | - // if no default reg status is set for the event, then use the global value |
|
261 | - $STS_ID = ! empty($event_default_registration_status) |
|
262 | - ? $event_default_registration_status |
|
263 | - : EE_Registry::instance()->CFG->registration->default_STS_ID; |
|
264 | - // if the event default reg status is approved, then downgrade temporarily to payment pending to ensure that payments are triggered |
|
265 | - $STS_ID = $STS_ID === EEM_Registration::status_id_approved ? EEM_Registration::status_id_pending_payment |
|
266 | - : $STS_ID; |
|
267 | - // set incoming REG_Status |
|
268 | - $this->set_new_reg_status($registration->ID(), $STS_ID); |
|
269 | - $registration->set_status($STS_ID, false, $context); |
|
270 | - if ($save) { |
|
271 | - $registration->save(); |
|
272 | - } |
|
273 | - // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
|
274 | - if (! EE_Processor_Base::$IPN) { |
|
275 | - // otherwise, send out notifications |
|
276 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
|
277 | - } |
|
278 | - // DEBUG LOG |
|
279 | - // $this->log( |
|
280 | - // __CLASS__, |
|
281 | - // __FUNCTION__, |
|
282 | - // __LINE__, |
|
283 | - // $registration->transaction(), |
|
284 | - // array( |
|
285 | - // 'IPN' => EE_Processor_Base::$IPN, |
|
286 | - // 'deliver_notifications' => has_filter( |
|
287 | - // 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
288 | - // ), |
|
289 | - // ) |
|
290 | - // ); |
|
291 | - } |
|
292 | - } |
|
293 | - |
|
294 | - |
|
295 | - /** |
|
296 | - * toggle_registration_status_for_default_approved_events |
|
297 | - * |
|
298 | - * @access public |
|
299 | - * @param EE_Registration $registration |
|
300 | - * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave that up |
|
301 | - * to client code |
|
302 | - * @return bool |
|
303 | - * @throws EE_Error |
|
304 | - * @throws EntityNotFoundException |
|
305 | - * @throws InvalidArgumentException |
|
306 | - * @throws InvalidDataTypeException |
|
307 | - * @throws InvalidInterfaceException |
|
308 | - * @throws ReflectionException |
|
309 | - * @throws RuntimeException |
|
310 | - */ |
|
311 | - public function toggle_registration_status_for_default_approved_events(EE_Registration $registration, $save = true) |
|
312 | - { |
|
313 | - $reg_status = $registration->status_ID(); |
|
314 | - // set initial REG_Status |
|
315 | - $this->set_old_reg_status($registration->ID(), $reg_status); |
|
316 | - // if not already, toggle reg status to approved IF the event default reg status is approved |
|
317 | - // ( as long as the registration wasn't cancelled or declined at some point ) |
|
318 | - if ( |
|
319 | - $reg_status !== EEM_Registration::status_id_cancelled |
|
320 | - && $reg_status |
|
321 | - !== EEM_Registration::status_id_declined |
|
322 | - && $reg_status !== EEM_Registration::status_id_approved |
|
323 | - && $registration->event()->default_registration_status() === EEM_Registration::status_id_approved |
|
324 | - ) { |
|
325 | - // set incoming REG_Status |
|
326 | - $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved); |
|
327 | - // toggle status to approved |
|
328 | - $registration->set_status(EEM_Registration::status_id_approved); |
|
329 | - if ($save) { |
|
330 | - $registration->save(); |
|
331 | - } |
|
332 | - // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
|
333 | - if (! EE_Processor_Base::$IPN) { |
|
334 | - // otherwise, send out notifications |
|
335 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
|
336 | - } |
|
337 | - // DEBUG LOG |
|
338 | - // $this->log( |
|
339 | - // __CLASS__, |
|
340 | - // __FUNCTION__, |
|
341 | - // __LINE__, |
|
342 | - // $registration->transaction(), |
|
343 | - // array( |
|
344 | - // 'IPN' => EE_Processor_Base::$IPN, |
|
345 | - // 'deliver_notifications' => has_filter( |
|
346 | - // 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
347 | - // ), |
|
348 | - // ) |
|
349 | - // ); |
|
350 | - return true; |
|
351 | - } |
|
352 | - return false; |
|
353 | - } |
|
354 | - |
|
355 | - |
|
356 | - /** |
|
357 | - * toggle_registration_statuses_if_no_monies_owing |
|
358 | - * |
|
359 | - * @access public |
|
360 | - * @param EE_Registration $registration |
|
361 | - * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave that up |
|
362 | - * to client code |
|
363 | - * @param array $additional_details |
|
364 | - * @return bool |
|
365 | - * @throws EE_Error |
|
366 | - * @throws EntityNotFoundException |
|
367 | - * @throws InvalidArgumentException |
|
368 | - * @throws InvalidDataTypeException |
|
369 | - * @throws InvalidInterfaceException |
|
370 | - * @throws ReflectionException |
|
371 | - * @throws RuntimeException |
|
372 | - */ |
|
373 | - public function toggle_registration_status_if_no_monies_owing( |
|
374 | - EE_Registration $registration, |
|
375 | - $save = true, |
|
376 | - array $additional_details = [] |
|
377 | - ) { |
|
378 | - // set initial REG_Status |
|
379 | - $this->set_old_reg_status($registration->ID(), $registration->status_ID()); |
|
380 | - // was a payment just made ? |
|
381 | - $payment = isset($additional_details['payment_updates'], $additional_details['last_payment']) |
|
382 | - && $additional_details['payment_updates'] |
|
383 | - && $additional_details['last_payment'] instanceof EE_Payment |
|
384 | - ? $additional_details['last_payment'] |
|
385 | - : null; |
|
386 | - $total_paid = array_sum(self::$_amount_paid); |
|
387 | - // toggle reg status to approved IF |
|
388 | - if ( |
|
29 | + /** |
|
30 | + * @var EE_Registration_Processor $_instance |
|
31 | + * @access private |
|
32 | + */ |
|
33 | + private static $_instance; |
|
34 | + |
|
35 | + /** |
|
36 | + * initial reg status at the beginning of this request. |
|
37 | + * indexed by registration ID |
|
38 | + * |
|
39 | + * @var array |
|
40 | + */ |
|
41 | + protected $_old_reg_status = []; |
|
42 | + |
|
43 | + /** |
|
44 | + * reg status at the end of the request after all processing. |
|
45 | + * indexed by registration ID |
|
46 | + * |
|
47 | + * @var array |
|
48 | + */ |
|
49 | + protected $_new_reg_status = []; |
|
50 | + |
|
51 | + /** |
|
52 | + * amounts paid at the end of the request after all processing. |
|
53 | + * indexed by registration ID |
|
54 | + * |
|
55 | + * @var array |
|
56 | + */ |
|
57 | + protected static $_amount_paid = []; |
|
58 | + |
|
59 | + /** |
|
60 | + * Cache of the reg final price for registrations corresponding to a ticket line item |
|
61 | + * |
|
62 | + * @deprecated |
|
63 | + * @var array @see EEH_Line_Item::calculate_reg_final_prices_per_line_item()'s return value |
|
64 | + */ |
|
65 | + protected $_reg_final_price_per_tkt_line_item; |
|
66 | + |
|
67 | + /** |
|
68 | + * @var RequestInterface $request |
|
69 | + */ |
|
70 | + protected $request; |
|
71 | + |
|
72 | + |
|
73 | + /** |
|
74 | + * @singleton method used to instantiate class object |
|
75 | + * @param RequestInterface|null $request |
|
76 | + * @return EE_Registration_Processor instance |
|
77 | + * @throws InvalidArgumentException |
|
78 | + * @throws InvalidInterfaceException |
|
79 | + * @throws InvalidDataTypeException |
|
80 | + */ |
|
81 | + public static function instance(RequestInterface $request = null) |
|
82 | + { |
|
83 | + // check if class object is instantiated |
|
84 | + if (! self::$_instance instanceof EE_Registration_Processor) { |
|
85 | + if (! $request instanceof RequestInterface) { |
|
86 | + $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request'); |
|
87 | + } |
|
88 | + self::$_instance = new self($request); |
|
89 | + } |
|
90 | + return self::$_instance; |
|
91 | + } |
|
92 | + |
|
93 | + |
|
94 | + /** |
|
95 | + * EE_Registration_Processor constructor. |
|
96 | + * |
|
97 | + * @param RequestInterface $request |
|
98 | + */ |
|
99 | + public function __construct(RequestInterface $request) |
|
100 | + { |
|
101 | + $this->request = $request; |
|
102 | + } |
|
103 | + |
|
104 | + |
|
105 | + /** |
|
106 | + * @param int $REG_ID |
|
107 | + * @return string |
|
108 | + */ |
|
109 | + public function old_reg_status($REG_ID) |
|
110 | + { |
|
111 | + return isset($this->_old_reg_status[ $REG_ID ]) ? $this->_old_reg_status[ $REG_ID ] : null; |
|
112 | + } |
|
113 | + |
|
114 | + |
|
115 | + /** |
|
116 | + * @param int $REG_ID |
|
117 | + * @param string $old_reg_status |
|
118 | + */ |
|
119 | + public function set_old_reg_status($REG_ID, $old_reg_status) |
|
120 | + { |
|
121 | + // only set the first time |
|
122 | + if (! isset($this->_old_reg_status[ $REG_ID ])) { |
|
123 | + $this->_old_reg_status[ $REG_ID ] = $old_reg_status; |
|
124 | + } |
|
125 | + } |
|
126 | + |
|
127 | + |
|
128 | + /** |
|
129 | + * @param int $REG_ID |
|
130 | + * @return string |
|
131 | + */ |
|
132 | + public function new_reg_status($REG_ID) |
|
133 | + { |
|
134 | + return isset($this->_new_reg_status[ $REG_ID ]) ? $this->_new_reg_status[ $REG_ID ] : null; |
|
135 | + } |
|
136 | + |
|
137 | + |
|
138 | + /** |
|
139 | + * @param int $REG_ID |
|
140 | + * @param string $new_reg_status |
|
141 | + */ |
|
142 | + public function set_new_reg_status($REG_ID, $new_reg_status) |
|
143 | + { |
|
144 | + $this->_new_reg_status[ $REG_ID ] = $new_reg_status; |
|
145 | + } |
|
146 | + |
|
147 | + |
|
148 | + /** |
|
149 | + * reg_status_updated |
|
150 | + * |
|
151 | + * @param int $REG_ID |
|
152 | + * @return bool |
|
153 | + */ |
|
154 | + public function reg_status_updated($REG_ID) |
|
155 | + { |
|
156 | + return $this->new_reg_status($REG_ID) !== $this->old_reg_status($REG_ID); |
|
157 | + } |
|
158 | + |
|
159 | + |
|
160 | + /** |
|
161 | + * @param EE_Registration $registration |
|
162 | + * @throws EE_Error |
|
163 | + * @throws EntityNotFoundException |
|
164 | + * @throws InvalidArgumentException |
|
165 | + * @throws InvalidDataTypeException |
|
166 | + * @throws InvalidInterfaceException |
|
167 | + * @throws ReflectionException |
|
168 | + * @throws RuntimeException |
|
169 | + */ |
|
170 | + public function update_registration_status_and_trigger_notifications(EE_Registration $registration) |
|
171 | + { |
|
172 | + $this->toggle_incomplete_registration_status_to_default($registration, false); |
|
173 | + $this->toggle_registration_status_for_default_approved_events($registration, false); |
|
174 | + $this->toggle_registration_status_if_no_monies_owing($registration, false); |
|
175 | + $registration->save(); |
|
176 | + // trigger notifications |
|
177 | + $this->trigger_registration_update_notifications($registration); |
|
178 | + } |
|
179 | + |
|
180 | + |
|
181 | + /** |
|
182 | + * manually_update_registration_status |
|
183 | + * |
|
184 | + * @access public |
|
185 | + * @param EE_Registration $registration |
|
186 | + * @param string $new_reg_status |
|
187 | + * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave that up |
|
188 | + * to client code |
|
189 | + * @return bool |
|
190 | + * @throws EE_Error |
|
191 | + * @throws EntityNotFoundException |
|
192 | + * @throws InvalidArgumentException |
|
193 | + * @throws InvalidDataTypeException |
|
194 | + * @throws InvalidInterfaceException |
|
195 | + * @throws ReflectionException |
|
196 | + * @throws RuntimeException |
|
197 | + */ |
|
198 | + public function manually_update_registration_status( |
|
199 | + EE_Registration $registration, |
|
200 | + $new_reg_status = '', |
|
201 | + $save = true |
|
202 | + ) { |
|
203 | + // set initial REG_Status |
|
204 | + $this->set_old_reg_status($registration->ID(), $registration->status_ID()); |
|
205 | + // set incoming REG_Status |
|
206 | + $this->set_new_reg_status($registration->ID(), $new_reg_status); |
|
207 | + // toggle reg status but only if it has changed and the user can do so |
|
208 | + if ( |
|
209 | + $this->reg_status_updated($registration->ID()) |
|
210 | + && ( |
|
211 | + (! $this->request->isAdmin() || $this->request->isFrontAjax()) |
|
212 | + || EE_Registry::instance()->CAP->current_user_can( |
|
213 | + 'ee_edit_registration', |
|
214 | + 'toggle_registration_status', |
|
215 | + $registration->ID() |
|
216 | + ) |
|
217 | + ) |
|
218 | + ) { |
|
219 | + // change status to new value |
|
220 | + $updated = $registration->set_status($this->new_reg_status($registration->ID())); |
|
221 | + if ($updated && $save) { |
|
222 | + $registration->save(); |
|
223 | + } |
|
224 | + return true; |
|
225 | + } |
|
226 | + return false; |
|
227 | + } |
|
228 | + |
|
229 | + |
|
230 | + /** |
|
231 | + * toggle_incomplete_registration_status_to_default |
|
232 | + * changes any incomplete registrations to either the event or global default registration status |
|
233 | + * |
|
234 | + * @access public |
|
235 | + * @param EE_Registration $registration |
|
236 | + * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave |
|
237 | + * that up to client code |
|
238 | + * @param ContextInterface|null $context |
|
239 | + * @return void |
|
240 | + * @throws EE_Error |
|
241 | + * @throws InvalidArgumentException |
|
242 | + * @throws ReflectionException |
|
243 | + * @throws RuntimeException |
|
244 | + * @throws EntityNotFoundException |
|
245 | + * @throws InvalidDataTypeException |
|
246 | + * @throws InvalidInterfaceException |
|
247 | + */ |
|
248 | + public function toggle_incomplete_registration_status_to_default( |
|
249 | + EE_Registration $registration, |
|
250 | + $save = true, |
|
251 | + ContextInterface $context = null |
|
252 | + ) { |
|
253 | + $existing_reg_status = $registration->status_ID(); |
|
254 | + // set initial REG_Status |
|
255 | + $this->set_old_reg_status($registration->ID(), $existing_reg_status); |
|
256 | + // is the registration currently incomplete ? |
|
257 | + if ($registration->status_ID() === EEM_Registration::status_id_incomplete) { |
|
258 | + // grab default reg status for the event, if set |
|
259 | + $event_default_registration_status = $registration->event()->default_registration_status(); |
|
260 | + // if no default reg status is set for the event, then use the global value |
|
261 | + $STS_ID = ! empty($event_default_registration_status) |
|
262 | + ? $event_default_registration_status |
|
263 | + : EE_Registry::instance()->CFG->registration->default_STS_ID; |
|
264 | + // if the event default reg status is approved, then downgrade temporarily to payment pending to ensure that payments are triggered |
|
265 | + $STS_ID = $STS_ID === EEM_Registration::status_id_approved ? EEM_Registration::status_id_pending_payment |
|
266 | + : $STS_ID; |
|
267 | + // set incoming REG_Status |
|
268 | + $this->set_new_reg_status($registration->ID(), $STS_ID); |
|
269 | + $registration->set_status($STS_ID, false, $context); |
|
270 | + if ($save) { |
|
271 | + $registration->save(); |
|
272 | + } |
|
273 | + // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
|
274 | + if (! EE_Processor_Base::$IPN) { |
|
275 | + // otherwise, send out notifications |
|
276 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
|
277 | + } |
|
278 | + // DEBUG LOG |
|
279 | + // $this->log( |
|
280 | + // __CLASS__, |
|
281 | + // __FUNCTION__, |
|
282 | + // __LINE__, |
|
283 | + // $registration->transaction(), |
|
284 | + // array( |
|
285 | + // 'IPN' => EE_Processor_Base::$IPN, |
|
286 | + // 'deliver_notifications' => has_filter( |
|
287 | + // 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
288 | + // ), |
|
289 | + // ) |
|
290 | + // ); |
|
291 | + } |
|
292 | + } |
|
293 | + |
|
294 | + |
|
295 | + /** |
|
296 | + * toggle_registration_status_for_default_approved_events |
|
297 | + * |
|
298 | + * @access public |
|
299 | + * @param EE_Registration $registration |
|
300 | + * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave that up |
|
301 | + * to client code |
|
302 | + * @return bool |
|
303 | + * @throws EE_Error |
|
304 | + * @throws EntityNotFoundException |
|
305 | + * @throws InvalidArgumentException |
|
306 | + * @throws InvalidDataTypeException |
|
307 | + * @throws InvalidInterfaceException |
|
308 | + * @throws ReflectionException |
|
309 | + * @throws RuntimeException |
|
310 | + */ |
|
311 | + public function toggle_registration_status_for_default_approved_events(EE_Registration $registration, $save = true) |
|
312 | + { |
|
313 | + $reg_status = $registration->status_ID(); |
|
314 | + // set initial REG_Status |
|
315 | + $this->set_old_reg_status($registration->ID(), $reg_status); |
|
316 | + // if not already, toggle reg status to approved IF the event default reg status is approved |
|
317 | + // ( as long as the registration wasn't cancelled or declined at some point ) |
|
318 | + if ( |
|
319 | + $reg_status !== EEM_Registration::status_id_cancelled |
|
320 | + && $reg_status |
|
321 | + !== EEM_Registration::status_id_declined |
|
322 | + && $reg_status !== EEM_Registration::status_id_approved |
|
323 | + && $registration->event()->default_registration_status() === EEM_Registration::status_id_approved |
|
324 | + ) { |
|
325 | + // set incoming REG_Status |
|
326 | + $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved); |
|
327 | + // toggle status to approved |
|
328 | + $registration->set_status(EEM_Registration::status_id_approved); |
|
329 | + if ($save) { |
|
330 | + $registration->save(); |
|
331 | + } |
|
332 | + // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
|
333 | + if (! EE_Processor_Base::$IPN) { |
|
334 | + // otherwise, send out notifications |
|
335 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
|
336 | + } |
|
337 | + // DEBUG LOG |
|
338 | + // $this->log( |
|
339 | + // __CLASS__, |
|
340 | + // __FUNCTION__, |
|
341 | + // __LINE__, |
|
342 | + // $registration->transaction(), |
|
343 | + // array( |
|
344 | + // 'IPN' => EE_Processor_Base::$IPN, |
|
345 | + // 'deliver_notifications' => has_filter( |
|
346 | + // 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
347 | + // ), |
|
348 | + // ) |
|
349 | + // ); |
|
350 | + return true; |
|
351 | + } |
|
352 | + return false; |
|
353 | + } |
|
354 | + |
|
355 | + |
|
356 | + /** |
|
357 | + * toggle_registration_statuses_if_no_monies_owing |
|
358 | + * |
|
359 | + * @access public |
|
360 | + * @param EE_Registration $registration |
|
361 | + * @param bool $save TRUE will save the registration if the status is updated, FALSE will leave that up |
|
362 | + * to client code |
|
363 | + * @param array $additional_details |
|
364 | + * @return bool |
|
365 | + * @throws EE_Error |
|
366 | + * @throws EntityNotFoundException |
|
367 | + * @throws InvalidArgumentException |
|
368 | + * @throws InvalidDataTypeException |
|
369 | + * @throws InvalidInterfaceException |
|
370 | + * @throws ReflectionException |
|
371 | + * @throws RuntimeException |
|
372 | + */ |
|
373 | + public function toggle_registration_status_if_no_monies_owing( |
|
374 | + EE_Registration $registration, |
|
375 | + $save = true, |
|
376 | + array $additional_details = [] |
|
377 | + ) { |
|
378 | + // set initial REG_Status |
|
379 | + $this->set_old_reg_status($registration->ID(), $registration->status_ID()); |
|
380 | + // was a payment just made ? |
|
381 | + $payment = isset($additional_details['payment_updates'], $additional_details['last_payment']) |
|
382 | + && $additional_details['payment_updates'] |
|
383 | + && $additional_details['last_payment'] instanceof EE_Payment |
|
384 | + ? $additional_details['last_payment'] |
|
385 | + : null; |
|
386 | + $total_paid = array_sum(self::$_amount_paid); |
|
387 | + // toggle reg status to approved IF |
|
388 | + if ( |
|
389 | 389 | // REG status is pending payment |
390 | - $registration->status_ID() === EEM_Registration::status_id_pending_payment |
|
391 | - // AND no monies are owing |
|
392 | - && ( |
|
393 | - ( |
|
394 | - $registration->transaction()->is_completed() |
|
395 | - || $registration->transaction()->is_overpaid() |
|
396 | - || $registration->transaction()->is_free() |
|
397 | - || apply_filters( |
|
398 | - 'FHEE__EE_Registration_Processor__toggle_registration_status_if_no_monies_owing', |
|
399 | - false, |
|
400 | - $registration |
|
401 | - ) |
|
402 | - ) |
|
403 | - || ( |
|
404 | - $payment instanceof EE_Payment && $payment->is_approved() |
|
405 | - && // this specific registration has not yet been paid for |
|
406 | - ! isset(self::$_amount_paid[ $registration->ID() ]) |
|
407 | - && // payment amount, less what we have already attributed to other registrations, is greater than this reg's final price |
|
408 | - $payment->amount() - $total_paid >= $registration->final_price() |
|
409 | - ) |
|
410 | - ) |
|
411 | - ) { |
|
412 | - // mark as paid |
|
413 | - self::$_amount_paid[ $registration->ID() ] = $registration->final_price(); |
|
414 | - // track new REG_Status |
|
415 | - $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved); |
|
416 | - // toggle status to approved |
|
417 | - $registration->set_status(EEM_Registration::status_id_approved); |
|
418 | - if ($save) { |
|
419 | - $registration->save(); |
|
420 | - } |
|
421 | - // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
|
422 | - if (! EE_Processor_Base::$IPN) { |
|
423 | - // otherwise, send out notifications |
|
424 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
|
425 | - } |
|
426 | - // DEBUG LOG |
|
427 | - // $this->log( |
|
428 | - // __CLASS__, |
|
429 | - // __FUNCTION__, |
|
430 | - // __LINE__, |
|
431 | - // $registration->transaction(), |
|
432 | - // array( |
|
433 | - // 'IPN' => EE_Processor_Base::$IPN, |
|
434 | - // 'deliver_notifications' => has_filter( |
|
435 | - // 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
436 | - // ), |
|
437 | - // ) |
|
438 | - // ); |
|
439 | - return true; |
|
440 | - } |
|
441 | - return false; |
|
442 | - } |
|
443 | - |
|
444 | - |
|
445 | - /** |
|
446 | - * registration_status_changed |
|
447 | - * |
|
448 | - * @access public |
|
449 | - * @param EE_Registration $registration |
|
450 | - * @param array $additional_details |
|
451 | - * @return void |
|
452 | - */ |
|
453 | - public function trigger_registration_update_notifications($registration, array $additional_details = []) |
|
454 | - { |
|
455 | - try { |
|
456 | - if (! $registration instanceof EE_Registration) { |
|
457 | - throw new EE_Error( |
|
458 | - esc_html__('An invalid registration was received.', 'event_espresso') |
|
459 | - ); |
|
460 | - } |
|
461 | - // EE_Registry::instance()->load_helper('Debug_Tools'); |
|
462 | - // EEH_Debug_Tools::log( |
|
463 | - // __CLASS__, |
|
464 | - // __FUNCTION__, |
|
465 | - // __LINE__, |
|
466 | - // array($registration->transaction(), $additional_details), |
|
467 | - // false, |
|
468 | - // 'EE_Transaction: ' . $registration->transaction()->ID() |
|
469 | - // ); |
|
470 | - if (! $registration->is_primary_registrant()) { |
|
471 | - return; |
|
472 | - } |
|
473 | - do_action( |
|
474 | - 'AHEE__EE_Registration_Processor__trigger_registration_update_notifications', |
|
475 | - $registration, |
|
476 | - $additional_details |
|
477 | - ); |
|
478 | - } catch (Exception $e) { |
|
479 | - EE_Error::add_error($e->getMessage(), $e->getFile(), 'unknown_function_from_exception', $e->getLine()); |
|
480 | - } |
|
481 | - } |
|
482 | - |
|
483 | - |
|
484 | - /** |
|
485 | - * sets reg status based either on passed param or on transaction status and event pre-approval setting |
|
486 | - * |
|
487 | - * @param EE_Registration $registration |
|
488 | - * @param array $additional_details |
|
489 | - * @return bool |
|
490 | - * @throws EE_Error |
|
491 | - * @throws EntityNotFoundException |
|
492 | - * @throws InvalidArgumentException |
|
493 | - * @throws InvalidDataTypeException |
|
494 | - * @throws InvalidInterfaceException |
|
495 | - * @throws ReflectionException |
|
496 | - * @throws RuntimeException |
|
497 | - */ |
|
498 | - public function update_registration_after_checkout_or_payment( |
|
499 | - EE_Registration $registration, |
|
500 | - array $additional_details = [] |
|
501 | - ) { |
|
502 | - // set initial REG_Status |
|
503 | - $this->set_old_reg_status($registration->ID(), $registration->status_ID()); |
|
504 | - // if the registration status gets updated, then save the registration |
|
505 | - if ( |
|
506 | - $this->toggle_registration_status_for_default_approved_events($registration, false) |
|
507 | - || $this->toggle_registration_status_if_no_monies_owing( |
|
508 | - $registration, |
|
509 | - false, |
|
510 | - $additional_details |
|
511 | - ) |
|
512 | - ) { |
|
513 | - $registration->save(); |
|
514 | - } |
|
515 | - // set new REG_Status |
|
516 | - $this->set_new_reg_status($registration->ID(), $registration->status_ID()); |
|
517 | - return $this->reg_status_updated($registration->ID()) |
|
518 | - && $this->new_reg_status($registration->ID()) === EEM_Registration::status_id_approved; |
|
519 | - } |
|
520 | - |
|
521 | - |
|
522 | - /** |
|
523 | - * Updates the registration' final prices based on the current line item tree (taking into account |
|
524 | - * discounts, taxes, and other line items unrelated to tickets.) |
|
525 | - * |
|
526 | - * @param EE_Transaction $transaction |
|
527 | - * @param boolean $save_regs whether to immediately save registrations in this function or not |
|
528 | - * @return void |
|
529 | - * @throws EE_Error |
|
530 | - * @throws InvalidArgumentException |
|
531 | - * @throws InvalidDataTypeException |
|
532 | - * @throws InvalidInterfaceException |
|
533 | - * @throws RuntimeException |
|
534 | - * @throws ReflectionException |
|
535 | - */ |
|
536 | - public function update_registration_final_prices($transaction, $save_regs = true) |
|
537 | - { |
|
538 | - $reg_final_price_per_ticket_line_item = EEH_Line_Item::calculate_reg_final_prices_per_line_item( |
|
539 | - $transaction->total_line_item() |
|
540 | - ); |
|
541 | - foreach ($transaction->registrations() as $registration) { |
|
542 | - /** @var EE_Line_Item $line_item */ |
|
543 | - $line_item = EEM_Line_Item::instance()->get_line_item_for_registration($registration); |
|
544 | - if (isset($reg_final_price_per_ticket_line_item[ $line_item->ID() ])) { |
|
545 | - $registration->set_final_price($reg_final_price_per_ticket_line_item[ $line_item->ID() ]); |
|
546 | - if ($save_regs) { |
|
547 | - $registration->save(); |
|
548 | - } |
|
549 | - } |
|
550 | - } |
|
551 | - // and make sure there's no rounding problem |
|
552 | - $this->fix_reg_final_price_rounding_issue($transaction); |
|
553 | - } |
|
554 | - |
|
555 | - |
|
556 | - /** |
|
557 | - * Makes sure there is no rounding errors for the REG_final_prices. |
|
558 | - * Eg, if we have 3 registrations for $1, and there is a $0.01 discount between the three of them, |
|
559 | - * they will each be for $0.99333333, which gets rounded to $1 again. |
|
560 | - * So the transaction total will be $2.99, but each registration will be for $1, |
|
561 | - * so if each registrant paid individually they will have overpaid by $0.01. |
|
562 | - * So in order to overcome this, we check for any difference, and if there is a difference |
|
563 | - * we just grab one registrant at random and make them responsible for it. |
|
564 | - * This should be used after setting REG_final_prices (it's done automatically as part of |
|
565 | - * EE_Registration_Processor::update_registration_final_prices()) |
|
566 | - * |
|
567 | - * @param EE_Transaction $transaction |
|
568 | - * @return bool success verifying that there is NO difference after this method is done |
|
569 | - * @throws EE_Error |
|
570 | - * @throws InvalidArgumentException |
|
571 | - * @throws InvalidDataTypeException |
|
572 | - * @throws InvalidInterfaceException |
|
573 | - * @throws ReflectionException |
|
574 | - */ |
|
575 | - public function fix_reg_final_price_rounding_issue($transaction) |
|
576 | - { |
|
577 | - $reg_final_price_sum = EEM_Registration::instance()->sum( |
|
578 | - [ |
|
579 | - [ |
|
580 | - 'TXN_ID' => $transaction->ID(), |
|
581 | - ], |
|
582 | - ], |
|
583 | - 'REG_final_price' |
|
584 | - ); |
|
585 | - $diff = $transaction->total() - $reg_final_price_sum; |
|
586 | - // ok then, just grab one of the registrations |
|
587 | - if ($diff !== (float) 0) { |
|
588 | - $a_reg = EEM_Registration::instance()->get_one( |
|
589 | - [ |
|
590 | - [ |
|
591 | - 'TXN_ID' => $transaction->ID(), |
|
592 | - ], |
|
593 | - ] |
|
594 | - ); |
|
595 | - return $a_reg instanceof EE_Registration |
|
596 | - && $a_reg->save(['REG_final_price' => $a_reg->final_price() + $diff]); |
|
597 | - } |
|
598 | - return true; |
|
599 | - } |
|
600 | - |
|
601 | - |
|
602 | - /** |
|
603 | - * update_registration_after_being_canceled_or_declined |
|
604 | - * |
|
605 | - * @param EE_Registration $registration |
|
606 | - * @param array $closed_reg_statuses |
|
607 | - * @param bool $update_reg |
|
608 | - * @return bool |
|
609 | - * @throws EE_Error |
|
610 | - * @throws RuntimeException |
|
611 | - * @throws ReflectionException |
|
612 | - */ |
|
613 | - public function update_registration_after_being_canceled_or_declined( |
|
614 | - EE_Registration $registration, |
|
615 | - array $closed_reg_statuses = [], |
|
616 | - $update_reg = true |
|
617 | - ) { |
|
618 | - // these reg statuses should not be considered in any calculations involving monies owing |
|
619 | - $closed_reg_statuses = ! empty($closed_reg_statuses) |
|
620 | - ? $closed_reg_statuses |
|
621 | - : EEM_Registration::closed_reg_statuses(); |
|
622 | - if (! in_array($registration->status_ID(), $closed_reg_statuses, true)) { |
|
623 | - return false; |
|
624 | - } |
|
625 | - // release a reserved ticket by decrementing ticket and datetime reserved values |
|
626 | - $registration->release_reserved_ticket(true, 'RegProcessor:' . __LINE__); |
|
627 | - $registration->set_final_price(0); |
|
628 | - if ($update_reg) { |
|
629 | - $registration->save(); |
|
630 | - } |
|
631 | - return true; |
|
632 | - } |
|
633 | - |
|
634 | - |
|
635 | - /** |
|
636 | - * update_canceled_or_declined_registration_after_being_reinstated |
|
637 | - * |
|
638 | - * @param EE_Registration $registration |
|
639 | - * @param array $closed_reg_statuses |
|
640 | - * @param bool $update_reg |
|
641 | - * @return bool |
|
642 | - * @throws EE_Error |
|
643 | - * @throws RuntimeException |
|
644 | - * @throws ReflectionException |
|
645 | - */ |
|
646 | - public function update_canceled_or_declined_registration_after_being_reinstated( |
|
647 | - EE_Registration $registration, |
|
648 | - array $closed_reg_statuses = [], |
|
649 | - $update_reg = true |
|
650 | - ) { |
|
651 | - // these reg statuses should not be considered in any calculations involving monies owing |
|
652 | - $closed_reg_statuses = ! empty($closed_reg_statuses) ? $closed_reg_statuses |
|
653 | - : EEM_Registration::closed_reg_statuses(); |
|
654 | - if (in_array($registration->status_ID(), $closed_reg_statuses, true)) { |
|
655 | - return false; |
|
656 | - } |
|
657 | - $ticket = $registration->ticket(); |
|
658 | - if (! $ticket instanceof EE_Ticket) { |
|
659 | - throw new EE_Error( |
|
660 | - sprintf( |
|
661 | - esc_html__( |
|
662 | - 'The Ticket for Registration %1$d was not found or is invalid.', |
|
663 | - 'event_espresso' |
|
664 | - ), |
|
665 | - $registration->ticket_ID() |
|
666 | - ) |
|
667 | - ); |
|
668 | - } |
|
669 | - $registration->set_final_price($ticket->price()); |
|
670 | - if ($update_reg) { |
|
671 | - $registration->save(); |
|
672 | - } |
|
673 | - return true; |
|
674 | - } |
|
675 | - |
|
676 | - |
|
677 | - /** |
|
678 | - * generate_ONE_registration_from_line_item |
|
679 | - * Although a ticket line item may have a quantity greater than 1, |
|
680 | - * this method will ONLY CREATE ONE REGISTRATION !!! |
|
681 | - * Regardless of the ticket line item quantity. |
|
682 | - * This means that any code calling this method is responsible for ensuring |
|
683 | - * that the final registration count matches the ticket line item quantity. |
|
684 | - * This was done to make it easier to match the number of registrations |
|
685 | - * to the number of tickets in the cart, when the cart has been edited |
|
686 | - * after SPCO has already been initialized. So if an additional ticket was added to the cart, you can simply pass |
|
687 | - * the line item to this method to add a second ticket, and in this case, you would not want to add 2 tickets. |
|
688 | - * |
|
689 | - * @param EE_Line_Item $line_item |
|
690 | - * @param EE_Transaction $transaction |
|
691 | - * @param int $att_nmbr |
|
692 | - * @param int $total_ticket_count |
|
693 | - * @return EE_Registration | null |
|
694 | - * @throws OutOfRangeException |
|
695 | - * @throws UnexpectedEntityException |
|
696 | - * @throws EE_Error |
|
697 | - * @throws ReflectionException |
|
698 | - * @deprecated |
|
699 | - * @since 4.9.1 |
|
700 | - */ |
|
701 | - public function generate_ONE_registration_from_line_item( |
|
702 | - EE_Line_Item $line_item, |
|
703 | - EE_Transaction $transaction, |
|
704 | - $att_nmbr = 1, |
|
705 | - $total_ticket_count = 1 |
|
706 | - ) { |
|
707 | - EE_Error::doing_it_wrong( |
|
708 | - __CLASS__ . '::' . __FUNCTION__, |
|
709 | - sprintf( |
|
710 | - esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
711 | - '\EventEspresso\core\domain\services\registration\CreateRegistrationService::create()' |
|
712 | - ), |
|
713 | - '4.9.1', |
|
714 | - '5.0.0' |
|
715 | - ); |
|
716 | - // grab the related ticket object for this line_item |
|
717 | - $ticket = $line_item->ticket(); |
|
718 | - if (! $ticket instanceof EE_Ticket) { |
|
719 | - EE_Error::add_error( |
|
720 | - sprintf( |
|
721 | - esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'), |
|
722 | - $line_item->ID() |
|
723 | - ), |
|
724 | - __FILE__, |
|
725 | - __FUNCTION__, |
|
726 | - __LINE__ |
|
727 | - ); |
|
728 | - return null; |
|
729 | - } |
|
730 | - $registration_service = new CreateRegistrationService(); |
|
731 | - // then generate a new registration from that |
|
732 | - return $registration_service->create( |
|
733 | - $ticket->get_related_event(), |
|
734 | - $transaction, |
|
735 | - $ticket, |
|
736 | - $line_item, |
|
737 | - $att_nmbr, |
|
738 | - $total_ticket_count |
|
739 | - ); |
|
740 | - } |
|
741 | - |
|
742 | - |
|
743 | - /** |
|
744 | - * generates reg_url_link |
|
745 | - * |
|
746 | - * @param int $att_nmbr |
|
747 | - * @param EE_Line_Item | string $item |
|
748 | - * @return RegUrlLink |
|
749 | - * @throws InvalidArgumentException |
|
750 | - * @deprecated |
|
751 | - * @since 4.9.1 |
|
752 | - */ |
|
753 | - public function generate_reg_url_link($att_nmbr, $item) |
|
754 | - { |
|
755 | - EE_Error::doing_it_wrong( |
|
756 | - __CLASS__ . '::' . __FUNCTION__, |
|
757 | - sprintf( |
|
758 | - esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
759 | - 'EventEspresso\core\domain\entities\RegUrlLink' |
|
760 | - ), |
|
761 | - '4.9.1', |
|
762 | - '5.0.0' |
|
763 | - ); |
|
764 | - return new RegUrlLink($att_nmbr, $item); |
|
765 | - } |
|
766 | - |
|
767 | - |
|
768 | - /** |
|
769 | - * generates reg code |
|
770 | - * |
|
771 | - * @param EE_Registration $registration |
|
772 | - * @return RegCode |
|
773 | - * @throws EE_Error |
|
774 | - * @throws EntityNotFoundException |
|
775 | - * @throws InvalidArgumentException |
|
776 | - * @since 4.9.1 |
|
777 | - * @deprecated |
|
778 | - */ |
|
779 | - public function generate_reg_code(EE_Registration $registration) |
|
780 | - { |
|
781 | - EE_Error::doing_it_wrong( |
|
782 | - __CLASS__ . '::' . __FUNCTION__, |
|
783 | - sprintf( |
|
784 | - esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
785 | - 'EventEspresso\core\domain\entities\RegCode' |
|
786 | - ), |
|
787 | - '4.9.1', |
|
788 | - '5.0.0' |
|
789 | - ); |
|
790 | - return apply_filters( |
|
791 | - 'FHEE__EE_Registration_Processor___generate_reg_code__new_reg_code', |
|
792 | - new RegCode( |
|
793 | - RegUrlLink::fromRegistration($registration), |
|
794 | - $registration->transaction(), |
|
795 | - $registration->ticket() |
|
796 | - ), |
|
797 | - $registration |
|
798 | - ); |
|
799 | - } |
|
390 | + $registration->status_ID() === EEM_Registration::status_id_pending_payment |
|
391 | + // AND no monies are owing |
|
392 | + && ( |
|
393 | + ( |
|
394 | + $registration->transaction()->is_completed() |
|
395 | + || $registration->transaction()->is_overpaid() |
|
396 | + || $registration->transaction()->is_free() |
|
397 | + || apply_filters( |
|
398 | + 'FHEE__EE_Registration_Processor__toggle_registration_status_if_no_monies_owing', |
|
399 | + false, |
|
400 | + $registration |
|
401 | + ) |
|
402 | + ) |
|
403 | + || ( |
|
404 | + $payment instanceof EE_Payment && $payment->is_approved() |
|
405 | + && // this specific registration has not yet been paid for |
|
406 | + ! isset(self::$_amount_paid[ $registration->ID() ]) |
|
407 | + && // payment amount, less what we have already attributed to other registrations, is greater than this reg's final price |
|
408 | + $payment->amount() - $total_paid >= $registration->final_price() |
|
409 | + ) |
|
410 | + ) |
|
411 | + ) { |
|
412 | + // mark as paid |
|
413 | + self::$_amount_paid[ $registration->ID() ] = $registration->final_price(); |
|
414 | + // track new REG_Status |
|
415 | + $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved); |
|
416 | + // toggle status to approved |
|
417 | + $registration->set_status(EEM_Registration::status_id_approved); |
|
418 | + if ($save) { |
|
419 | + $registration->save(); |
|
420 | + } |
|
421 | + // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
|
422 | + if (! EE_Processor_Base::$IPN) { |
|
423 | + // otherwise, send out notifications |
|
424 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
|
425 | + } |
|
426 | + // DEBUG LOG |
|
427 | + // $this->log( |
|
428 | + // __CLASS__, |
|
429 | + // __FUNCTION__, |
|
430 | + // __LINE__, |
|
431 | + // $registration->transaction(), |
|
432 | + // array( |
|
433 | + // 'IPN' => EE_Processor_Base::$IPN, |
|
434 | + // 'deliver_notifications' => has_filter( |
|
435 | + // 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
436 | + // ), |
|
437 | + // ) |
|
438 | + // ); |
|
439 | + return true; |
|
440 | + } |
|
441 | + return false; |
|
442 | + } |
|
443 | + |
|
444 | + |
|
445 | + /** |
|
446 | + * registration_status_changed |
|
447 | + * |
|
448 | + * @access public |
|
449 | + * @param EE_Registration $registration |
|
450 | + * @param array $additional_details |
|
451 | + * @return void |
|
452 | + */ |
|
453 | + public function trigger_registration_update_notifications($registration, array $additional_details = []) |
|
454 | + { |
|
455 | + try { |
|
456 | + if (! $registration instanceof EE_Registration) { |
|
457 | + throw new EE_Error( |
|
458 | + esc_html__('An invalid registration was received.', 'event_espresso') |
|
459 | + ); |
|
460 | + } |
|
461 | + // EE_Registry::instance()->load_helper('Debug_Tools'); |
|
462 | + // EEH_Debug_Tools::log( |
|
463 | + // __CLASS__, |
|
464 | + // __FUNCTION__, |
|
465 | + // __LINE__, |
|
466 | + // array($registration->transaction(), $additional_details), |
|
467 | + // false, |
|
468 | + // 'EE_Transaction: ' . $registration->transaction()->ID() |
|
469 | + // ); |
|
470 | + if (! $registration->is_primary_registrant()) { |
|
471 | + return; |
|
472 | + } |
|
473 | + do_action( |
|
474 | + 'AHEE__EE_Registration_Processor__trigger_registration_update_notifications', |
|
475 | + $registration, |
|
476 | + $additional_details |
|
477 | + ); |
|
478 | + } catch (Exception $e) { |
|
479 | + EE_Error::add_error($e->getMessage(), $e->getFile(), 'unknown_function_from_exception', $e->getLine()); |
|
480 | + } |
|
481 | + } |
|
482 | + |
|
483 | + |
|
484 | + /** |
|
485 | + * sets reg status based either on passed param or on transaction status and event pre-approval setting |
|
486 | + * |
|
487 | + * @param EE_Registration $registration |
|
488 | + * @param array $additional_details |
|
489 | + * @return bool |
|
490 | + * @throws EE_Error |
|
491 | + * @throws EntityNotFoundException |
|
492 | + * @throws InvalidArgumentException |
|
493 | + * @throws InvalidDataTypeException |
|
494 | + * @throws InvalidInterfaceException |
|
495 | + * @throws ReflectionException |
|
496 | + * @throws RuntimeException |
|
497 | + */ |
|
498 | + public function update_registration_after_checkout_or_payment( |
|
499 | + EE_Registration $registration, |
|
500 | + array $additional_details = [] |
|
501 | + ) { |
|
502 | + // set initial REG_Status |
|
503 | + $this->set_old_reg_status($registration->ID(), $registration->status_ID()); |
|
504 | + // if the registration status gets updated, then save the registration |
|
505 | + if ( |
|
506 | + $this->toggle_registration_status_for_default_approved_events($registration, false) |
|
507 | + || $this->toggle_registration_status_if_no_monies_owing( |
|
508 | + $registration, |
|
509 | + false, |
|
510 | + $additional_details |
|
511 | + ) |
|
512 | + ) { |
|
513 | + $registration->save(); |
|
514 | + } |
|
515 | + // set new REG_Status |
|
516 | + $this->set_new_reg_status($registration->ID(), $registration->status_ID()); |
|
517 | + return $this->reg_status_updated($registration->ID()) |
|
518 | + && $this->new_reg_status($registration->ID()) === EEM_Registration::status_id_approved; |
|
519 | + } |
|
520 | + |
|
521 | + |
|
522 | + /** |
|
523 | + * Updates the registration' final prices based on the current line item tree (taking into account |
|
524 | + * discounts, taxes, and other line items unrelated to tickets.) |
|
525 | + * |
|
526 | + * @param EE_Transaction $transaction |
|
527 | + * @param boolean $save_regs whether to immediately save registrations in this function or not |
|
528 | + * @return void |
|
529 | + * @throws EE_Error |
|
530 | + * @throws InvalidArgumentException |
|
531 | + * @throws InvalidDataTypeException |
|
532 | + * @throws InvalidInterfaceException |
|
533 | + * @throws RuntimeException |
|
534 | + * @throws ReflectionException |
|
535 | + */ |
|
536 | + public function update_registration_final_prices($transaction, $save_regs = true) |
|
537 | + { |
|
538 | + $reg_final_price_per_ticket_line_item = EEH_Line_Item::calculate_reg_final_prices_per_line_item( |
|
539 | + $transaction->total_line_item() |
|
540 | + ); |
|
541 | + foreach ($transaction->registrations() as $registration) { |
|
542 | + /** @var EE_Line_Item $line_item */ |
|
543 | + $line_item = EEM_Line_Item::instance()->get_line_item_for_registration($registration); |
|
544 | + if (isset($reg_final_price_per_ticket_line_item[ $line_item->ID() ])) { |
|
545 | + $registration->set_final_price($reg_final_price_per_ticket_line_item[ $line_item->ID() ]); |
|
546 | + if ($save_regs) { |
|
547 | + $registration->save(); |
|
548 | + } |
|
549 | + } |
|
550 | + } |
|
551 | + // and make sure there's no rounding problem |
|
552 | + $this->fix_reg_final_price_rounding_issue($transaction); |
|
553 | + } |
|
554 | + |
|
555 | + |
|
556 | + /** |
|
557 | + * Makes sure there is no rounding errors for the REG_final_prices. |
|
558 | + * Eg, if we have 3 registrations for $1, and there is a $0.01 discount between the three of them, |
|
559 | + * they will each be for $0.99333333, which gets rounded to $1 again. |
|
560 | + * So the transaction total will be $2.99, but each registration will be for $1, |
|
561 | + * so if each registrant paid individually they will have overpaid by $0.01. |
|
562 | + * So in order to overcome this, we check for any difference, and if there is a difference |
|
563 | + * we just grab one registrant at random and make them responsible for it. |
|
564 | + * This should be used after setting REG_final_prices (it's done automatically as part of |
|
565 | + * EE_Registration_Processor::update_registration_final_prices()) |
|
566 | + * |
|
567 | + * @param EE_Transaction $transaction |
|
568 | + * @return bool success verifying that there is NO difference after this method is done |
|
569 | + * @throws EE_Error |
|
570 | + * @throws InvalidArgumentException |
|
571 | + * @throws InvalidDataTypeException |
|
572 | + * @throws InvalidInterfaceException |
|
573 | + * @throws ReflectionException |
|
574 | + */ |
|
575 | + public function fix_reg_final_price_rounding_issue($transaction) |
|
576 | + { |
|
577 | + $reg_final_price_sum = EEM_Registration::instance()->sum( |
|
578 | + [ |
|
579 | + [ |
|
580 | + 'TXN_ID' => $transaction->ID(), |
|
581 | + ], |
|
582 | + ], |
|
583 | + 'REG_final_price' |
|
584 | + ); |
|
585 | + $diff = $transaction->total() - $reg_final_price_sum; |
|
586 | + // ok then, just grab one of the registrations |
|
587 | + if ($diff !== (float) 0) { |
|
588 | + $a_reg = EEM_Registration::instance()->get_one( |
|
589 | + [ |
|
590 | + [ |
|
591 | + 'TXN_ID' => $transaction->ID(), |
|
592 | + ], |
|
593 | + ] |
|
594 | + ); |
|
595 | + return $a_reg instanceof EE_Registration |
|
596 | + && $a_reg->save(['REG_final_price' => $a_reg->final_price() + $diff]); |
|
597 | + } |
|
598 | + return true; |
|
599 | + } |
|
600 | + |
|
601 | + |
|
602 | + /** |
|
603 | + * update_registration_after_being_canceled_or_declined |
|
604 | + * |
|
605 | + * @param EE_Registration $registration |
|
606 | + * @param array $closed_reg_statuses |
|
607 | + * @param bool $update_reg |
|
608 | + * @return bool |
|
609 | + * @throws EE_Error |
|
610 | + * @throws RuntimeException |
|
611 | + * @throws ReflectionException |
|
612 | + */ |
|
613 | + public function update_registration_after_being_canceled_or_declined( |
|
614 | + EE_Registration $registration, |
|
615 | + array $closed_reg_statuses = [], |
|
616 | + $update_reg = true |
|
617 | + ) { |
|
618 | + // these reg statuses should not be considered in any calculations involving monies owing |
|
619 | + $closed_reg_statuses = ! empty($closed_reg_statuses) |
|
620 | + ? $closed_reg_statuses |
|
621 | + : EEM_Registration::closed_reg_statuses(); |
|
622 | + if (! in_array($registration->status_ID(), $closed_reg_statuses, true)) { |
|
623 | + return false; |
|
624 | + } |
|
625 | + // release a reserved ticket by decrementing ticket and datetime reserved values |
|
626 | + $registration->release_reserved_ticket(true, 'RegProcessor:' . __LINE__); |
|
627 | + $registration->set_final_price(0); |
|
628 | + if ($update_reg) { |
|
629 | + $registration->save(); |
|
630 | + } |
|
631 | + return true; |
|
632 | + } |
|
633 | + |
|
634 | + |
|
635 | + /** |
|
636 | + * update_canceled_or_declined_registration_after_being_reinstated |
|
637 | + * |
|
638 | + * @param EE_Registration $registration |
|
639 | + * @param array $closed_reg_statuses |
|
640 | + * @param bool $update_reg |
|
641 | + * @return bool |
|
642 | + * @throws EE_Error |
|
643 | + * @throws RuntimeException |
|
644 | + * @throws ReflectionException |
|
645 | + */ |
|
646 | + public function update_canceled_or_declined_registration_after_being_reinstated( |
|
647 | + EE_Registration $registration, |
|
648 | + array $closed_reg_statuses = [], |
|
649 | + $update_reg = true |
|
650 | + ) { |
|
651 | + // these reg statuses should not be considered in any calculations involving monies owing |
|
652 | + $closed_reg_statuses = ! empty($closed_reg_statuses) ? $closed_reg_statuses |
|
653 | + : EEM_Registration::closed_reg_statuses(); |
|
654 | + if (in_array($registration->status_ID(), $closed_reg_statuses, true)) { |
|
655 | + return false; |
|
656 | + } |
|
657 | + $ticket = $registration->ticket(); |
|
658 | + if (! $ticket instanceof EE_Ticket) { |
|
659 | + throw new EE_Error( |
|
660 | + sprintf( |
|
661 | + esc_html__( |
|
662 | + 'The Ticket for Registration %1$d was not found or is invalid.', |
|
663 | + 'event_espresso' |
|
664 | + ), |
|
665 | + $registration->ticket_ID() |
|
666 | + ) |
|
667 | + ); |
|
668 | + } |
|
669 | + $registration->set_final_price($ticket->price()); |
|
670 | + if ($update_reg) { |
|
671 | + $registration->save(); |
|
672 | + } |
|
673 | + return true; |
|
674 | + } |
|
675 | + |
|
676 | + |
|
677 | + /** |
|
678 | + * generate_ONE_registration_from_line_item |
|
679 | + * Although a ticket line item may have a quantity greater than 1, |
|
680 | + * this method will ONLY CREATE ONE REGISTRATION !!! |
|
681 | + * Regardless of the ticket line item quantity. |
|
682 | + * This means that any code calling this method is responsible for ensuring |
|
683 | + * that the final registration count matches the ticket line item quantity. |
|
684 | + * This was done to make it easier to match the number of registrations |
|
685 | + * to the number of tickets in the cart, when the cart has been edited |
|
686 | + * after SPCO has already been initialized. So if an additional ticket was added to the cart, you can simply pass |
|
687 | + * the line item to this method to add a second ticket, and in this case, you would not want to add 2 tickets. |
|
688 | + * |
|
689 | + * @param EE_Line_Item $line_item |
|
690 | + * @param EE_Transaction $transaction |
|
691 | + * @param int $att_nmbr |
|
692 | + * @param int $total_ticket_count |
|
693 | + * @return EE_Registration | null |
|
694 | + * @throws OutOfRangeException |
|
695 | + * @throws UnexpectedEntityException |
|
696 | + * @throws EE_Error |
|
697 | + * @throws ReflectionException |
|
698 | + * @deprecated |
|
699 | + * @since 4.9.1 |
|
700 | + */ |
|
701 | + public function generate_ONE_registration_from_line_item( |
|
702 | + EE_Line_Item $line_item, |
|
703 | + EE_Transaction $transaction, |
|
704 | + $att_nmbr = 1, |
|
705 | + $total_ticket_count = 1 |
|
706 | + ) { |
|
707 | + EE_Error::doing_it_wrong( |
|
708 | + __CLASS__ . '::' . __FUNCTION__, |
|
709 | + sprintf( |
|
710 | + esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
711 | + '\EventEspresso\core\domain\services\registration\CreateRegistrationService::create()' |
|
712 | + ), |
|
713 | + '4.9.1', |
|
714 | + '5.0.0' |
|
715 | + ); |
|
716 | + // grab the related ticket object for this line_item |
|
717 | + $ticket = $line_item->ticket(); |
|
718 | + if (! $ticket instanceof EE_Ticket) { |
|
719 | + EE_Error::add_error( |
|
720 | + sprintf( |
|
721 | + esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'), |
|
722 | + $line_item->ID() |
|
723 | + ), |
|
724 | + __FILE__, |
|
725 | + __FUNCTION__, |
|
726 | + __LINE__ |
|
727 | + ); |
|
728 | + return null; |
|
729 | + } |
|
730 | + $registration_service = new CreateRegistrationService(); |
|
731 | + // then generate a new registration from that |
|
732 | + return $registration_service->create( |
|
733 | + $ticket->get_related_event(), |
|
734 | + $transaction, |
|
735 | + $ticket, |
|
736 | + $line_item, |
|
737 | + $att_nmbr, |
|
738 | + $total_ticket_count |
|
739 | + ); |
|
740 | + } |
|
741 | + |
|
742 | + |
|
743 | + /** |
|
744 | + * generates reg_url_link |
|
745 | + * |
|
746 | + * @param int $att_nmbr |
|
747 | + * @param EE_Line_Item | string $item |
|
748 | + * @return RegUrlLink |
|
749 | + * @throws InvalidArgumentException |
|
750 | + * @deprecated |
|
751 | + * @since 4.9.1 |
|
752 | + */ |
|
753 | + public function generate_reg_url_link($att_nmbr, $item) |
|
754 | + { |
|
755 | + EE_Error::doing_it_wrong( |
|
756 | + __CLASS__ . '::' . __FUNCTION__, |
|
757 | + sprintf( |
|
758 | + esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
759 | + 'EventEspresso\core\domain\entities\RegUrlLink' |
|
760 | + ), |
|
761 | + '4.9.1', |
|
762 | + '5.0.0' |
|
763 | + ); |
|
764 | + return new RegUrlLink($att_nmbr, $item); |
|
765 | + } |
|
766 | + |
|
767 | + |
|
768 | + /** |
|
769 | + * generates reg code |
|
770 | + * |
|
771 | + * @param EE_Registration $registration |
|
772 | + * @return RegCode |
|
773 | + * @throws EE_Error |
|
774 | + * @throws EntityNotFoundException |
|
775 | + * @throws InvalidArgumentException |
|
776 | + * @since 4.9.1 |
|
777 | + * @deprecated |
|
778 | + */ |
|
779 | + public function generate_reg_code(EE_Registration $registration) |
|
780 | + { |
|
781 | + EE_Error::doing_it_wrong( |
|
782 | + __CLASS__ . '::' . __FUNCTION__, |
|
783 | + sprintf( |
|
784 | + esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
|
785 | + 'EventEspresso\core\domain\entities\RegCode' |
|
786 | + ), |
|
787 | + '4.9.1', |
|
788 | + '5.0.0' |
|
789 | + ); |
|
790 | + return apply_filters( |
|
791 | + 'FHEE__EE_Registration_Processor___generate_reg_code__new_reg_code', |
|
792 | + new RegCode( |
|
793 | + RegUrlLink::fromRegistration($registration), |
|
794 | + $registration->transaction(), |
|
795 | + $registration->ticket() |
|
796 | + ), |
|
797 | + $registration |
|
798 | + ); |
|
799 | + } |
|
800 | 800 | } |
@@ -81,8 +81,8 @@ discard block |
||
81 | 81 | public static function instance(RequestInterface $request = null) |
82 | 82 | { |
83 | 83 | // check if class object is instantiated |
84 | - if (! self::$_instance instanceof EE_Registration_Processor) { |
|
85 | - if (! $request instanceof RequestInterface) { |
|
84 | + if ( ! self::$_instance instanceof EE_Registration_Processor) { |
|
85 | + if ( ! $request instanceof RequestInterface) { |
|
86 | 86 | $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\Request'); |
87 | 87 | } |
88 | 88 | self::$_instance = new self($request); |
@@ -108,7 +108,7 @@ discard block |
||
108 | 108 | */ |
109 | 109 | public function old_reg_status($REG_ID) |
110 | 110 | { |
111 | - return isset($this->_old_reg_status[ $REG_ID ]) ? $this->_old_reg_status[ $REG_ID ] : null; |
|
111 | + return isset($this->_old_reg_status[$REG_ID]) ? $this->_old_reg_status[$REG_ID] : null; |
|
112 | 112 | } |
113 | 113 | |
114 | 114 | |
@@ -119,8 +119,8 @@ discard block |
||
119 | 119 | public function set_old_reg_status($REG_ID, $old_reg_status) |
120 | 120 | { |
121 | 121 | // only set the first time |
122 | - if (! isset($this->_old_reg_status[ $REG_ID ])) { |
|
123 | - $this->_old_reg_status[ $REG_ID ] = $old_reg_status; |
|
122 | + if ( ! isset($this->_old_reg_status[$REG_ID])) { |
|
123 | + $this->_old_reg_status[$REG_ID] = $old_reg_status; |
|
124 | 124 | } |
125 | 125 | } |
126 | 126 | |
@@ -131,7 +131,7 @@ discard block |
||
131 | 131 | */ |
132 | 132 | public function new_reg_status($REG_ID) |
133 | 133 | { |
134 | - return isset($this->_new_reg_status[ $REG_ID ]) ? $this->_new_reg_status[ $REG_ID ] : null; |
|
134 | + return isset($this->_new_reg_status[$REG_ID]) ? $this->_new_reg_status[$REG_ID] : null; |
|
135 | 135 | } |
136 | 136 | |
137 | 137 | |
@@ -141,7 +141,7 @@ discard block |
||
141 | 141 | */ |
142 | 142 | public function set_new_reg_status($REG_ID, $new_reg_status) |
143 | 143 | { |
144 | - $this->_new_reg_status[ $REG_ID ] = $new_reg_status; |
|
144 | + $this->_new_reg_status[$REG_ID] = $new_reg_status; |
|
145 | 145 | } |
146 | 146 | |
147 | 147 | |
@@ -208,7 +208,7 @@ discard block |
||
208 | 208 | if ( |
209 | 209 | $this->reg_status_updated($registration->ID()) |
210 | 210 | && ( |
211 | - (! $this->request->isAdmin() || $this->request->isFrontAjax()) |
|
211 | + ( ! $this->request->isAdmin() || $this->request->isFrontAjax()) |
|
212 | 212 | || EE_Registry::instance()->CAP->current_user_can( |
213 | 213 | 'ee_edit_registration', |
214 | 214 | 'toggle_registration_status', |
@@ -271,7 +271,7 @@ discard block |
||
271 | 271 | $registration->save(); |
272 | 272 | } |
273 | 273 | // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
274 | - if (! EE_Processor_Base::$IPN) { |
|
274 | + if ( ! EE_Processor_Base::$IPN) { |
|
275 | 275 | // otherwise, send out notifications |
276 | 276 | add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
277 | 277 | } |
@@ -330,7 +330,7 @@ discard block |
||
330 | 330 | $registration->save(); |
331 | 331 | } |
332 | 332 | // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
333 | - if (! EE_Processor_Base::$IPN) { |
|
333 | + if ( ! EE_Processor_Base::$IPN) { |
|
334 | 334 | // otherwise, send out notifications |
335 | 335 | add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
336 | 336 | } |
@@ -378,7 +378,7 @@ discard block |
||
378 | 378 | // set initial REG_Status |
379 | 379 | $this->set_old_reg_status($registration->ID(), $registration->status_ID()); |
380 | 380 | // was a payment just made ? |
381 | - $payment = isset($additional_details['payment_updates'], $additional_details['last_payment']) |
|
381 | + $payment = isset($additional_details['payment_updates'], $additional_details['last_payment']) |
|
382 | 382 | && $additional_details['payment_updates'] |
383 | 383 | && $additional_details['last_payment'] instanceof EE_Payment |
384 | 384 | ? $additional_details['last_payment'] |
@@ -403,14 +403,14 @@ discard block |
||
403 | 403 | || ( |
404 | 404 | $payment instanceof EE_Payment && $payment->is_approved() |
405 | 405 | && // this specific registration has not yet been paid for |
406 | - ! isset(self::$_amount_paid[ $registration->ID() ]) |
|
406 | + ! isset(self::$_amount_paid[$registration->ID()]) |
|
407 | 407 | && // payment amount, less what we have already attributed to other registrations, is greater than this reg's final price |
408 | 408 | $payment->amount() - $total_paid >= $registration->final_price() |
409 | 409 | ) |
410 | 410 | ) |
411 | 411 | ) { |
412 | 412 | // mark as paid |
413 | - self::$_amount_paid[ $registration->ID() ] = $registration->final_price(); |
|
413 | + self::$_amount_paid[$registration->ID()] = $registration->final_price(); |
|
414 | 414 | // track new REG_Status |
415 | 415 | $this->set_new_reg_status($registration->ID(), EEM_Registration::status_id_approved); |
416 | 416 | // toggle status to approved |
@@ -419,7 +419,7 @@ discard block |
||
419 | 419 | $registration->save(); |
420 | 420 | } |
421 | 421 | // don't trigger notifications during IPNs because they will get triggered by EE_Payment_Processor |
422 | - if (! EE_Processor_Base::$IPN) { |
|
422 | + if ( ! EE_Processor_Base::$IPN) { |
|
423 | 423 | // otherwise, send out notifications |
424 | 424 | add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true', 10); |
425 | 425 | } |
@@ -453,7 +453,7 @@ discard block |
||
453 | 453 | public function trigger_registration_update_notifications($registration, array $additional_details = []) |
454 | 454 | { |
455 | 455 | try { |
456 | - if (! $registration instanceof EE_Registration) { |
|
456 | + if ( ! $registration instanceof EE_Registration) { |
|
457 | 457 | throw new EE_Error( |
458 | 458 | esc_html__('An invalid registration was received.', 'event_espresso') |
459 | 459 | ); |
@@ -467,7 +467,7 @@ discard block |
||
467 | 467 | // false, |
468 | 468 | // 'EE_Transaction: ' . $registration->transaction()->ID() |
469 | 469 | // ); |
470 | - if (! $registration->is_primary_registrant()) { |
|
470 | + if ( ! $registration->is_primary_registrant()) { |
|
471 | 471 | return; |
472 | 472 | } |
473 | 473 | do_action( |
@@ -541,8 +541,8 @@ discard block |
||
541 | 541 | foreach ($transaction->registrations() as $registration) { |
542 | 542 | /** @var EE_Line_Item $line_item */ |
543 | 543 | $line_item = EEM_Line_Item::instance()->get_line_item_for_registration($registration); |
544 | - if (isset($reg_final_price_per_ticket_line_item[ $line_item->ID() ])) { |
|
545 | - $registration->set_final_price($reg_final_price_per_ticket_line_item[ $line_item->ID() ]); |
|
544 | + if (isset($reg_final_price_per_ticket_line_item[$line_item->ID()])) { |
|
545 | + $registration->set_final_price($reg_final_price_per_ticket_line_item[$line_item->ID()]); |
|
546 | 546 | if ($save_regs) { |
547 | 547 | $registration->save(); |
548 | 548 | } |
@@ -582,7 +582,7 @@ discard block |
||
582 | 582 | ], |
583 | 583 | 'REG_final_price' |
584 | 584 | ); |
585 | - $diff = $transaction->total() - $reg_final_price_sum; |
|
585 | + $diff = $transaction->total() - $reg_final_price_sum; |
|
586 | 586 | // ok then, just grab one of the registrations |
587 | 587 | if ($diff !== (float) 0) { |
588 | 588 | $a_reg = EEM_Registration::instance()->get_one( |
@@ -619,11 +619,11 @@ discard block |
||
619 | 619 | $closed_reg_statuses = ! empty($closed_reg_statuses) |
620 | 620 | ? $closed_reg_statuses |
621 | 621 | : EEM_Registration::closed_reg_statuses(); |
622 | - if (! in_array($registration->status_ID(), $closed_reg_statuses, true)) { |
|
622 | + if ( ! in_array($registration->status_ID(), $closed_reg_statuses, true)) { |
|
623 | 623 | return false; |
624 | 624 | } |
625 | 625 | // release a reserved ticket by decrementing ticket and datetime reserved values |
626 | - $registration->release_reserved_ticket(true, 'RegProcessor:' . __LINE__); |
|
626 | + $registration->release_reserved_ticket(true, 'RegProcessor:'.__LINE__); |
|
627 | 627 | $registration->set_final_price(0); |
628 | 628 | if ($update_reg) { |
629 | 629 | $registration->save(); |
@@ -655,7 +655,7 @@ discard block |
||
655 | 655 | return false; |
656 | 656 | } |
657 | 657 | $ticket = $registration->ticket(); |
658 | - if (! $ticket instanceof EE_Ticket) { |
|
658 | + if ( ! $ticket instanceof EE_Ticket) { |
|
659 | 659 | throw new EE_Error( |
660 | 660 | sprintf( |
661 | 661 | esc_html__( |
@@ -705,7 +705,7 @@ discard block |
||
705 | 705 | $total_ticket_count = 1 |
706 | 706 | ) { |
707 | 707 | EE_Error::doing_it_wrong( |
708 | - __CLASS__ . '::' . __FUNCTION__, |
|
708 | + __CLASS__.'::'.__FUNCTION__, |
|
709 | 709 | sprintf( |
710 | 710 | esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
711 | 711 | '\EventEspresso\core\domain\services\registration\CreateRegistrationService::create()' |
@@ -715,7 +715,7 @@ discard block |
||
715 | 715 | ); |
716 | 716 | // grab the related ticket object for this line_item |
717 | 717 | $ticket = $line_item->ticket(); |
718 | - if (! $ticket instanceof EE_Ticket) { |
|
718 | + if ( ! $ticket instanceof EE_Ticket) { |
|
719 | 719 | EE_Error::add_error( |
720 | 720 | sprintf( |
721 | 721 | esc_html__('Line item %s did not contain a valid ticket', 'event_espresso'), |
@@ -753,7 +753,7 @@ discard block |
||
753 | 753 | public function generate_reg_url_link($att_nmbr, $item) |
754 | 754 | { |
755 | 755 | EE_Error::doing_it_wrong( |
756 | - __CLASS__ . '::' . __FUNCTION__, |
|
756 | + __CLASS__.'::'.__FUNCTION__, |
|
757 | 757 | sprintf( |
758 | 758 | esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
759 | 759 | 'EventEspresso\core\domain\entities\RegUrlLink' |
@@ -779,7 +779,7 @@ discard block |
||
779 | 779 | public function generate_reg_code(EE_Registration $registration) |
780 | 780 | { |
781 | 781 | EE_Error::doing_it_wrong( |
782 | - __CLASS__ . '::' . __FUNCTION__, |
|
782 | + __CLASS__.'::'.__FUNCTION__, |
|
783 | 783 | sprintf( |
784 | 784 | esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'), |
785 | 785 | 'EventEspresso\core\domain\entities\RegCode' |