@@ -15,87 +15,87 @@ |
||
15 | 15 | */ |
16 | 16 | class Domain extends DomainBase implements CaffeinatedInterface |
17 | 17 | { |
18 | - /** |
|
19 | - * URL path component used to denote an API request |
|
20 | - */ |
|
21 | - const API_NAMESPACE = 'ee/v'; |
|
22 | - |
|
23 | - const ASSET_NAMESPACE = 'eventespresso'; |
|
24 | - |
|
25 | - const TEXT_DOMAIN = 'event_espresso'; |
|
26 | - |
|
27 | - /** |
|
28 | - * Slug used for the context where a registration status is changed from a manual trigger in the Registration Admin |
|
29 | - * Page ui. |
|
30 | - */ |
|
31 | - const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN |
|
32 | - = 'manual_registration_status_change_from_registration_admin'; |
|
33 | - |
|
34 | - const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY |
|
35 | - = 'manual_registration_status_change_from_registration_admin_and_notify'; |
|
36 | - |
|
37 | - |
|
38 | - /** |
|
39 | - * Whether or not EE core is the full premium version. |
|
40 | - * @since 4.9.59.p |
|
41 | - * @var bool |
|
42 | - */ |
|
43 | - private $caffeinated; |
|
44 | - |
|
45 | - /** |
|
46 | - * @since $VID:$ |
|
47 | - * @var bool |
|
48 | - */ |
|
49 | - private $multisite; |
|
50 | - |
|
51 | - |
|
52 | - public function __construct(FilePath $plugin_file, Version $version) |
|
53 | - { |
|
54 | - parent::__construct($plugin_file, $version); |
|
55 | - $this->setCaffeinated(); |
|
56 | - $this->multisite = is_multisite(); |
|
57 | - } |
|
58 | - |
|
59 | - /** |
|
60 | - * Whether or not EE core is the full premium version. |
|
61 | - * @since 4.9.59.p |
|
62 | - * @return bool |
|
63 | - */ |
|
64 | - public function isCaffeinated() |
|
65 | - { |
|
66 | - return $this->caffeinated; |
|
67 | - } |
|
68 | - |
|
69 | - |
|
70 | - /** |
|
71 | - * Setter for $is_caffeinated property. |
|
72 | - * @since 4.9.59.p |
|
73 | - */ |
|
74 | - private function setCaffeinated() |
|
75 | - { |
|
76 | - $this->caffeinated = (! defined('EE_DECAF') || EE_DECAF !== true) |
|
77 | - && is_readable($this->pluginPath() . 'caffeinated/brewing_regular.php'); |
|
78 | - } |
|
79 | - |
|
80 | - |
|
81 | - /** |
|
82 | - * This should be used everywhere the Event Espresso brand name is referenced in public facing interfaces |
|
83 | - * to allow for filtering the brand. |
|
84 | - * |
|
85 | - * @return string |
|
86 | - */ |
|
87 | - public static function brandName() |
|
88 | - { |
|
89 | - return (string) apply_filters('FHEE__EventEspresso_core_domain_Domain__brandName', 'Event Espresso'); |
|
90 | - } |
|
91 | - |
|
92 | - |
|
93 | - /** |
|
94 | - * @return bool |
|
95 | - * @since $VID:$ |
|
96 | - */ |
|
97 | - public function isMultiSite(): bool |
|
98 | - { |
|
99 | - return $this->multisite; |
|
100 | - } |
|
18 | + /** |
|
19 | + * URL path component used to denote an API request |
|
20 | + */ |
|
21 | + const API_NAMESPACE = 'ee/v'; |
|
22 | + |
|
23 | + const ASSET_NAMESPACE = 'eventespresso'; |
|
24 | + |
|
25 | + const TEXT_DOMAIN = 'event_espresso'; |
|
26 | + |
|
27 | + /** |
|
28 | + * Slug used for the context where a registration status is changed from a manual trigger in the Registration Admin |
|
29 | + * Page ui. |
|
30 | + */ |
|
31 | + const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN |
|
32 | + = 'manual_registration_status_change_from_registration_admin'; |
|
33 | + |
|
34 | + const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY |
|
35 | + = 'manual_registration_status_change_from_registration_admin_and_notify'; |
|
36 | + |
|
37 | + |
|
38 | + /** |
|
39 | + * Whether or not EE core is the full premium version. |
|
40 | + * @since 4.9.59.p |
|
41 | + * @var bool |
|
42 | + */ |
|
43 | + private $caffeinated; |
|
44 | + |
|
45 | + /** |
|
46 | + * @since $VID:$ |
|
47 | + * @var bool |
|
48 | + */ |
|
49 | + private $multisite; |
|
50 | + |
|
51 | + |
|
52 | + public function __construct(FilePath $plugin_file, Version $version) |
|
53 | + { |
|
54 | + parent::__construct($plugin_file, $version); |
|
55 | + $this->setCaffeinated(); |
|
56 | + $this->multisite = is_multisite(); |
|
57 | + } |
|
58 | + |
|
59 | + /** |
|
60 | + * Whether or not EE core is the full premium version. |
|
61 | + * @since 4.9.59.p |
|
62 | + * @return bool |
|
63 | + */ |
|
64 | + public function isCaffeinated() |
|
65 | + { |
|
66 | + return $this->caffeinated; |
|
67 | + } |
|
68 | + |
|
69 | + |
|
70 | + /** |
|
71 | + * Setter for $is_caffeinated property. |
|
72 | + * @since 4.9.59.p |
|
73 | + */ |
|
74 | + private function setCaffeinated() |
|
75 | + { |
|
76 | + $this->caffeinated = (! defined('EE_DECAF') || EE_DECAF !== true) |
|
77 | + && is_readable($this->pluginPath() . 'caffeinated/brewing_regular.php'); |
|
78 | + } |
|
79 | + |
|
80 | + |
|
81 | + /** |
|
82 | + * This should be used everywhere the Event Espresso brand name is referenced in public facing interfaces |
|
83 | + * to allow for filtering the brand. |
|
84 | + * |
|
85 | + * @return string |
|
86 | + */ |
|
87 | + public static function brandName() |
|
88 | + { |
|
89 | + return (string) apply_filters('FHEE__EventEspresso_core_domain_Domain__brandName', 'Event Espresso'); |
|
90 | + } |
|
91 | + |
|
92 | + |
|
93 | + /** |
|
94 | + * @return bool |
|
95 | + * @since $VID:$ |
|
96 | + */ |
|
97 | + public function isMultiSite(): bool |
|
98 | + { |
|
99 | + return $this->multisite; |
|
100 | + } |
|
101 | 101 | } |
@@ -22,862 +22,862 @@ |
||
22 | 22 | */ |
23 | 23 | class EE_SPCO_Reg_Step_Attendee_Information extends EE_SPCO_Reg_Step |
24 | 24 | { |
25 | - /** |
|
26 | - * @var RegForm |
|
27 | - */ |
|
28 | - public $reg_form; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var int |
|
32 | - */ |
|
33 | - protected $reg_form_count = 0; |
|
34 | - |
|
35 | - |
|
36 | - /** |
|
37 | - * class constructor |
|
38 | - * |
|
39 | - * @access public |
|
40 | - * @param EE_Checkout $checkout |
|
41 | - */ |
|
42 | - public function __construct(EE_Checkout $checkout) |
|
43 | - { |
|
44 | - $this->_slug = 'attendee_information'; |
|
45 | - $this->_name = esc_html__('Attendee Information', 'event_espresso'); |
|
46 | - $this->checkout = $checkout; |
|
47 | - $this->_reset_success_message(); |
|
48 | - $this->set_instructions( |
|
49 | - esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso') |
|
50 | - ); |
|
51 | - } |
|
52 | - |
|
53 | - |
|
54 | - public function translate_js_strings() |
|
55 | - { |
|
56 | - EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
57 | - ' is a required question.', |
|
58 | - 'event_espresso' |
|
59 | - ); |
|
60 | - EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
61 | - ' is a required question. Please enter a value for at least one of the options.', |
|
62 | - 'event_espresso' |
|
63 | - ); |
|
64 | - EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__( |
|
65 | - 'Please answer all required questions correctly before proceeding.', |
|
66 | - 'event_espresso' |
|
67 | - ); |
|
68 | - EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
69 | - esc_html_x( |
|
70 | - 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.', |
|
71 | - 'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.', |
|
72 | - 'event_espresso' |
|
73 | - ), |
|
74 | - '<br/>' |
|
75 | - ); |
|
76 | - EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
77 | - 'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.', |
|
78 | - 'event_espresso' |
|
79 | - ); |
|
80 | - EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
81 | - 'You must enter a valid email address.', |
|
82 | - 'event_espresso' |
|
83 | - ); |
|
84 | - EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__( |
|
85 | - 'You must enter a valid email address and answer all other required questions before you can proceed.', |
|
86 | - 'event_espresso' |
|
87 | - ); |
|
88 | - } |
|
89 | - |
|
90 | - |
|
91 | - public function enqueue_styles_and_scripts() |
|
92 | - { |
|
93 | - } |
|
94 | - |
|
95 | - |
|
96 | - /** |
|
97 | - * @return boolean |
|
98 | - */ |
|
99 | - public function initialize_reg_step(): bool |
|
100 | - { |
|
101 | - return true; |
|
102 | - } |
|
103 | - |
|
104 | - |
|
105 | - /** |
|
106 | - * @return RegForm |
|
107 | - * @throws DomainException |
|
108 | - * @throws InvalidArgumentException |
|
109 | - * @throws EntityNotFoundException |
|
110 | - * @throws InvalidDataTypeException |
|
111 | - * @throws InvalidInterfaceException |
|
112 | - */ |
|
113 | - public function generate_reg_form(): RegForm |
|
114 | - { |
|
115 | - $this->setLegacyFiltersForRegFormGeneration(); |
|
116 | - /** @var RegFormDependencyHandler $dependency_handler */ |
|
117 | - $dependency_handler = LoaderFactory::getShared(RegFormDependencyHandler::class); |
|
118 | - $dependency_handler->registerDependencies(); |
|
119 | - // TODO detect if event has a reg form UUID and swap this out for form generated by new reg form builder |
|
120 | - return LoaderFactory::getShared(RegForm::class, [$this]); |
|
121 | - } |
|
122 | - |
|
123 | - |
|
124 | - /** |
|
125 | - * @since $VID:$ |
|
126 | - */ |
|
127 | - private function setLegacyFiltersForRegFormGeneration() |
|
128 | - { |
|
129 | - add_filter( |
|
130 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_groups_query_parameters', |
|
131 | - [$this, 'registrationQuestionGroupsQueryParameters'], |
|
132 | - 1, |
|
133 | - 2 |
|
134 | - ); |
|
135 | - add_filter( |
|
136 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_group_reg_form', |
|
137 | - [$this, 'registrationQuestionGroupsRegForm'], |
|
138 | - 1, |
|
139 | - 3 |
|
140 | - ); |
|
141 | - add_filter( |
|
142 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__printCopyInfo', |
|
143 | - [$this, 'registrationRegFormPrintCopyInfo'], |
|
144 | - 1, |
|
145 | - 2 |
|
146 | - ); |
|
147 | - add_filter( |
|
148 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__related_questions_query_params', |
|
149 | - [$this, 'registrationRegFormRelatedQuestionsQueryParams'], |
|
150 | - 1, |
|
151 | - 3 |
|
152 | - ); |
|
153 | - add_filter( |
|
154 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__before_question_group_questions', |
|
155 | - [$this, 'registrationRegFormBeforeQuestionGroupQuestions'], |
|
156 | - 1, |
|
157 | - 3 |
|
158 | - ); |
|
159 | - add_filter( |
|
160 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__subsections_array', |
|
161 | - [$this, 'registrationRegFormSubsections'], |
|
162 | - 1, |
|
163 | - 3 |
|
164 | - ); |
|
165 | - add_filter( |
|
166 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__after_question_group_questions', |
|
167 | - [$this, 'registrationRegFormAfterQuestionGroupQuestions'], |
|
168 | - 1, |
|
169 | - 3 |
|
170 | - ); |
|
171 | - add_filter( |
|
172 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_AutoCopyAttendeeInfoForm__construct__template_args', |
|
173 | - [$this, 'autoCopyAttendeeInfoTemplateArgs'], |
|
174 | - 1 |
|
175 | - ); |
|
176 | - add_filter( |
|
177 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_CountryOptions__generateLegacyCountryOptions__country_options', |
|
178 | - [$this, 'generateQuestionInputCountryOptions'], |
|
179 | - 1, |
|
180 | - 4 |
|
181 | - ); |
|
182 | - add_filter( |
|
183 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_StateOptions__generateLegacyStateOptions__state_options', |
|
184 | - [$this, 'generateQuestionInputStateOptions'], |
|
185 | - 1, |
|
186 | - 4 |
|
187 | - ); |
|
188 | - } |
|
189 | - |
|
190 | - |
|
191 | - /** |
|
192 | - * @param array $query_params |
|
193 | - * @param EE_Registration $registration |
|
194 | - * @return mixed|void |
|
195 | - * @since $VID:$ |
|
196 | - */ |
|
197 | - public function registrationQuestionGroupsQueryParameters( |
|
198 | - array $query_params, |
|
199 | - EE_Registration $registration |
|
200 | - ) { |
|
201 | - return apply_filters( |
|
202 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters', |
|
203 | - $query_params, |
|
204 | - $registration, |
|
205 | - $this |
|
206 | - ); |
|
207 | - } |
|
208 | - |
|
209 | - |
|
210 | - /** |
|
211 | - * @param RegFormQuestionGroup $question_group_reg_form |
|
212 | - * @param EE_Registration $registration |
|
213 | - * @param EE_Question_Group $question_group |
|
214 | - * @return mixed|void |
|
215 | - * @since $VID:$ |
|
216 | - */ |
|
217 | - public function registrationQuestionGroupsRegForm( |
|
218 | - RegFormQuestionGroup $question_group_reg_form, |
|
219 | - EE_Registration $registration, |
|
220 | - EE_Question_Group $question_group |
|
221 | - ) { |
|
222 | - return apply_filters( |
|
223 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form', |
|
224 | - $question_group_reg_form, |
|
225 | - $registration, |
|
226 | - $question_group, |
|
227 | - $this |
|
228 | - ); |
|
229 | - } |
|
230 | - |
|
231 | - |
|
232 | - /** |
|
233 | - * @param int $print_copy_info |
|
234 | - * @param int $attendee_nmbr |
|
235 | - * @return mixed|void |
|
236 | - * @since $VID:$ |
|
237 | - */ |
|
238 | - public function registrationRegFormPrintCopyInfo( |
|
239 | - int $print_copy_info, |
|
240 | - int $attendee_nmbr |
|
241 | - ) { |
|
242 | - return apply_filters( |
|
243 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form___printCopyInfo', |
|
244 | - $print_copy_info, |
|
245 | - $attendee_nmbr |
|
246 | - ); |
|
247 | - } |
|
248 | - |
|
249 | - |
|
250 | - /** |
|
251 | - * @param array $query_params |
|
252 | - * @param EE_Question_Group $question_group |
|
253 | - * @param EE_Registration $registration |
|
254 | - * @return mixed|void |
|
255 | - * @since $VID:$ |
|
256 | - */ |
|
257 | - public function registrationRegFormRelatedQuestionsQueryParams( |
|
258 | - array $query_params, |
|
259 | - EE_Question_Group $question_group, |
|
260 | - EE_Registration $registration |
|
261 | - ) { |
|
262 | - return apply_filters( |
|
263 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params', |
|
264 | - $query_params, |
|
265 | - $question_group, |
|
266 | - $registration, |
|
267 | - $this |
|
268 | - ); |
|
269 | - } |
|
270 | - |
|
271 | - |
|
272 | - /** |
|
273 | - * @param $html |
|
274 | - * @param EE_Registration $registration |
|
275 | - * @param EE_Question_Group $question_group |
|
276 | - * @return mixed|void |
|
277 | - * @since $VID:$ |
|
278 | - */ |
|
279 | - public function registrationRegFormBeforeQuestionGroupQuestions( |
|
280 | - $html, |
|
281 | - EE_Registration $registration, |
|
282 | - EE_Question_Group $question_group |
|
283 | - ) { |
|
284 | - return apply_filters( |
|
285 | - 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', |
|
286 | - $html, |
|
287 | - $registration, |
|
288 | - $question_group, |
|
289 | - $this |
|
290 | - ); |
|
291 | - } |
|
292 | - |
|
293 | - |
|
294 | - /** |
|
295 | - * @param array $form_subsections |
|
296 | - * @param EE_Registration $registration |
|
297 | - * @param EE_Question_Group $question_group |
|
298 | - * @return mixed|void |
|
299 | - * @since $VID:$ |
|
300 | - */ |
|
301 | - public function registrationRegFormSubsections( |
|
302 | - array $form_subsections, |
|
303 | - EE_Registration $registration, |
|
304 | - EE_Question_Group $question_group |
|
305 | - ) { |
|
306 | - return apply_filters( |
|
307 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array', |
|
308 | - $form_subsections, |
|
309 | - $registration, |
|
310 | - $question_group, |
|
311 | - $this |
|
312 | - ); |
|
313 | - } |
|
314 | - |
|
315 | - |
|
316 | - /** |
|
317 | - * @param $html |
|
318 | - * @param EE_Registration $registration |
|
319 | - * @param EE_Question_Group $question_group |
|
320 | - * @return mixed|void |
|
321 | - * @since $VID:$ |
|
322 | - */ |
|
323 | - public function registrationRegFormAfterQuestionGroupQuestions( |
|
324 | - $html, |
|
325 | - EE_Registration $registration, |
|
326 | - EE_Question_Group $question_group |
|
327 | - ) { |
|
328 | - return apply_filters( |
|
329 | - 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', |
|
330 | - $html, |
|
331 | - $registration, |
|
332 | - $question_group, |
|
333 | - $this |
|
334 | - ); |
|
335 | - } |
|
336 | - |
|
337 | - |
|
338 | - /** |
|
339 | - * @param array $template_args |
|
340 | - * @return mixed|void |
|
341 | - * @since $VID:$ |
|
342 | - */ |
|
343 | - public function autoCopyAttendeeInfoTemplateArgs(array $template_args = []) |
|
344 | - { |
|
345 | - return apply_filters( |
|
346 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
|
347 | - $template_args |
|
348 | - ); |
|
349 | - } |
|
350 | - |
|
351 | - |
|
352 | - /** |
|
353 | - * @param array $country_options |
|
354 | - * @param EE_Registration $registration |
|
355 | - * @param EE_Question $question |
|
356 | - * @param EE_Answer|null $answer |
|
357 | - * @return mixed|void |
|
358 | - * @since $VID:$ |
|
359 | - */ |
|
360 | - public function generateQuestionInputCountryOptions( |
|
361 | - array $country_options, |
|
362 | - EE_Registration $registration, |
|
363 | - EE_Question $question, |
|
364 | - ?EE_Answer $answer |
|
365 | - ) { |
|
366 | - return apply_filters( |
|
367 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options', |
|
368 | - $country_options, |
|
369 | - $this, |
|
370 | - $registration, |
|
371 | - $question, |
|
372 | - $answer |
|
373 | - ); |
|
374 | - } |
|
375 | - |
|
376 | - |
|
377 | - /** |
|
378 | - * @param array $state_options |
|
379 | - * @param EE_Registration $registration |
|
380 | - * @param EE_Question $question |
|
381 | - * @param EE_Answer|null $answer |
|
382 | - * @return mixed|void |
|
383 | - * @since $VID:$ |
|
384 | - */ |
|
385 | - public function generateQuestionInputStateOptions( |
|
386 | - array $state_options, |
|
387 | - EE_Registration $registration, |
|
388 | - EE_Question $question, |
|
389 | - ?EE_Answer $answer |
|
390 | - ) { |
|
391 | - return apply_filters( |
|
392 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options', |
|
393 | - $state_options, |
|
394 | - $this, |
|
395 | - $registration, |
|
396 | - $question, |
|
397 | - $answer |
|
398 | - ); |
|
399 | - } |
|
400 | - |
|
401 | - |
|
402 | - /** |
|
403 | - * looking for hooks? |
|
404 | - * this method has been replaced by: |
|
405 | - * EventEspresso\core\domain\services\registration\form\v1\RegForm::getRegForm() |
|
406 | - * |
|
407 | - * @deprecated $VID:$ |
|
408 | - */ |
|
409 | - private function _registrations_reg_form() |
|
410 | - { |
|
411 | - } |
|
412 | - |
|
413 | - |
|
414 | - /** |
|
415 | - * looking for hooks? |
|
416 | - * this method has been replaced by: |
|
417 | - * EventEspresso\core\domain\services\registration\form\v1\RegForm::additionalAttendeeRegInfoInput() |
|
418 | - * |
|
419 | - * @deprecated $VID:$ |
|
420 | - */ |
|
421 | - private function _additional_attendee_reg_info_input() |
|
422 | - { |
|
423 | - } |
|
424 | - |
|
425 | - |
|
426 | - /** |
|
427 | - * looking for hooks? |
|
428 | - * this method has been replaced by: |
|
429 | - * EventEspresso\core\domain\services\registration\form\v1\RegForm::questionGroupRegForm() |
|
430 | - * |
|
431 | - * @deprecated $VID:$ |
|
432 | - */ |
|
433 | - private function _question_group_reg_form() |
|
434 | - { |
|
435 | - } |
|
436 | - |
|
437 | - |
|
438 | - /** |
|
439 | - * looking for hooks? |
|
440 | - * this method has been replaced by: |
|
441 | - * EventEspresso\core\domain\services\registration\form\v1\RegForm::questionGroupHeader() |
|
442 | - * |
|
443 | - * @deprecated $VID:$ |
|
444 | - */ |
|
445 | - private function _question_group_header() |
|
446 | - { |
|
447 | - } |
|
448 | - |
|
449 | - |
|
450 | - /** |
|
451 | - * looking for hooks? |
|
452 | - * this method has been replaced by: |
|
453 | - * EventEspresso\core\domain\services\registration\form\v1\CopyAttendeeInfoForm |
|
454 | - * |
|
455 | - * @deprecated $VID:$ |
|
456 | - */ |
|
457 | - private function _copy_attendee_info_form() |
|
458 | - { |
|
459 | - } |
|
460 | - |
|
461 | - |
|
462 | - /** |
|
463 | - * looking for hooks? |
|
464 | - * this method has been replaced by: |
|
465 | - * EventEspresso\core\domain\services\registration\form\v1\AutoCopyAttendeeInfoForm |
|
466 | - * |
|
467 | - * @deprecated $VID:$ |
|
468 | - */ |
|
469 | - private function _auto_copy_attendee_info() |
|
470 | - { |
|
471 | - } |
|
472 | - |
|
473 | - |
|
474 | - /** |
|
475 | - * looking for hooks? |
|
476 | - * this method has been replaced by: |
|
477 | - * EventEspresso\core\domain\services\registration\form\v1\CopyAttendeeInfoForm |
|
478 | - * |
|
479 | - * @deprecated $VID:$ |
|
480 | - */ |
|
481 | - private function _copy_attendee_info_inputs() |
|
482 | - { |
|
483 | - } |
|
484 | - |
|
485 | - |
|
486 | - /** |
|
487 | - * looking for hooks? |
|
488 | - * this method has been replaced by: |
|
489 | - * EventEspresso\core\domain\services\registration\form\v1\RegForm::additionalPrimaryRegistrantInputs() |
|
490 | - * |
|
491 | - * @deprecated $VID:$ |
|
492 | - */ |
|
493 | - private function _additional_primary_registrant_inputs() |
|
494 | - { |
|
495 | - } |
|
496 | - |
|
497 | - |
|
498 | - /** |
|
499 | - * looking for hooks? |
|
500 | - * this method has been replaced by: |
|
501 | - * EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory::create() |
|
502 | - * |
|
503 | - * @param EE_Registration $registration |
|
504 | - * @param EE_Question $question |
|
505 | - * @return EE_Form_Input_Base |
|
506 | - * @throws EE_Error |
|
507 | - * @throws ReflectionException |
|
508 | - * @deprecated $VID:$ |
|
509 | - */ |
|
510 | - public function reg_form_question(EE_Registration $registration, EE_Question $question): EE_Form_Input_Base |
|
511 | - { |
|
512 | - /** @var RegFormQuestionFactory $reg_form_question_factory */ |
|
513 | - $reg_form_question_factory = LoaderFactory::getShared(RegFormQuestionFactory::class); |
|
514 | - return $reg_form_question_factory->create($registration, $question); |
|
515 | - } |
|
516 | - |
|
517 | - |
|
518 | - /** |
|
519 | - * looking for hooks? |
|
520 | - * this method has been replaced by: |
|
521 | - * EventEspresso\core\domain\services\registration\form\v1\RegForm::generateQuestionInput() |
|
522 | - * |
|
523 | - * @deprecated $VID:$ |
|
524 | - */ |
|
525 | - private function _generate_question_input() |
|
526 | - { |
|
527 | - } |
|
528 | - |
|
529 | - |
|
530 | - /** |
|
531 | - * looking for hooks? |
|
532 | - * this method has been replaced by: |
|
533 | - * EventEspresso\core\domain\services\registration\form\v1\CountryOptions::forLegacyFormInput() |
|
534 | - * |
|
535 | - * @param array|null $countries_list |
|
536 | - * @param EE_Question|null $question |
|
537 | - * @param EE_Registration|null $registration |
|
538 | - * @param EE_Answer|null $answer |
|
539 | - * @return array 2d keys are country IDs, values are their names |
|
540 | - * @throws EE_Error |
|
541 | - * @throws ReflectionException |
|
542 | - * @deprecated $VID:$ |
|
543 | - */ |
|
544 | - public function use_cached_countries_for_form_input( |
|
545 | - array $countries_list = null, |
|
546 | - EE_Question $question = null, |
|
547 | - EE_Registration $registration = null, |
|
548 | - EE_Answer $answer = null |
|
549 | - ): array { |
|
550 | - /** @var CountryOptions $country_options */ |
|
551 | - $country_options = LoaderFactory::getShared(CountryOptions::class, [$this->checkout->action]); |
|
552 | - return $country_options->forLegacyFormInput($countries_list, $question, $registration, $answer); |
|
553 | - } |
|
554 | - |
|
555 | - |
|
556 | - /** |
|
557 | - * looking for hooks? |
|
558 | - * this method has been replaced by: |
|
559 | - * EventEspresso\core\domain\services\registration\form\v1\StateOptions::forLegacyFormInput() |
|
560 | - * |
|
561 | - * @param array|null $states_list |
|
562 | - * @param EE_Question|null $question |
|
563 | - * @param EE_Registration|null $registration |
|
564 | - * @param EE_Answer|null $answer |
|
565 | - * @return array 2d keys are state IDs, values are their names |
|
566 | - * @throws EE_Error |
|
567 | - * @throws ReflectionException |
|
568 | - * @deprecated $VID:$ |
|
569 | - */ |
|
570 | - public function use_cached_states_for_form_input( |
|
571 | - array $states_list = null, |
|
572 | - EE_Question $question = null, |
|
573 | - EE_Registration $registration = null, |
|
574 | - EE_Answer $answer = null |
|
575 | - ): array { |
|
576 | - /** @var StateOptions $state_options */ |
|
577 | - $state_options = LoaderFactory::getShared(StateOptions::class, [$this->checkout->action]); |
|
578 | - return $state_options->forLegacyFormInput($states_list, $question, $registration, $answer); |
|
579 | - } |
|
580 | - |
|
581 | - |
|
582 | - /********************************************************************************************************/ |
|
583 | - /**************************************** PROCESS REG STEP ****************************************/ |
|
584 | - /********************************************************************************************************/ |
|
585 | - |
|
586 | - |
|
587 | - /** |
|
588 | - * @return bool |
|
589 | - * @throws EE_Error |
|
590 | - * @throws InvalidArgumentException |
|
591 | - * @throws ReflectionException |
|
592 | - * @throws RuntimeException |
|
593 | - * @throws InvalidDataTypeException |
|
594 | - * @throws InvalidInterfaceException |
|
595 | - */ |
|
596 | - public function process_reg_step(): bool |
|
597 | - { |
|
598 | - $this->setLegacyFiltersForRegFormProcessing(); |
|
599 | - // grab validated data from form |
|
600 | - $valid_data = $this->checkout->current_step->valid_data(); |
|
601 | - // if we don't have any $valid_data then something went TERRIBLY WRONG !!! |
|
602 | - if (empty($valid_data)) { |
|
603 | - return $this->inValidDataError(); |
|
604 | - } |
|
605 | - if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
606 | - return $this->inValidTransactionError(); |
|
607 | - } |
|
608 | - // get cached registrations |
|
609 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
610 | - // verify we got the goods |
|
611 | - if (empty($registrations)) { |
|
612 | - return $this->noRegistrationsError(); |
|
613 | - } |
|
614 | - /** @var RegFormHandler $reg_form_handler */ |
|
615 | - $reg_form_handler = LoaderFactory::getNew(RegFormHandler::class, [$this->checkout]); |
|
616 | - // extract attendee info from form data and save to model objects |
|
617 | - if (! $reg_form_handler->processRegistrations($registrations, $valid_data)) { |
|
618 | - // return immediately if the previous step exited early due to errors |
|
619 | - return false; |
|
620 | - } |
|
621 | - // if first pass thru SPCO, |
|
622 | - // then let's check processed registrations against the total number of tickets in the cart |
|
623 | - $registrations_processed = $reg_form_handler->attendeeCount(); |
|
624 | - if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
625 | - return $this->registrationProcessingError($registrations_processed); |
|
626 | - } |
|
627 | - // mark this reg step as completed |
|
628 | - $this->set_completed(); |
|
629 | - $this->_set_success_message( |
|
630 | - esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso') |
|
631 | - ); |
|
632 | - // do action in case a plugin wants to do something with the data submitted in step 1. |
|
633 | - // passes EE_Single_Page_Checkout, and it's posted data |
|
634 | - do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data); |
|
635 | - return true; |
|
636 | - } |
|
637 | - |
|
638 | - |
|
639 | - /** |
|
640 | - * @since $VID:$ |
|
641 | - */ |
|
642 | - private function setLegacyFiltersForRegFormProcessing() |
|
643 | - { |
|
644 | - add_filter( |
|
645 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegistrations__bypass', |
|
646 | - [$this, 'preRegistrationProcess'], |
|
647 | - 1, |
|
648 | - 5 |
|
649 | - ); |
|
650 | - add_filter( |
|
651 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegFormData__registrant_form_data', |
|
652 | - [$this, 'validDataLineItem'], |
|
653 | - 1, |
|
654 | - 2 |
|
655 | - ); |
|
656 | - add_filter( |
|
657 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormInputHandler__saveRegistrationFormInput', |
|
658 | - [$this, 'saveRegistrationFormInput'], |
|
659 | - 1, |
|
660 | - 4 |
|
661 | - ); |
|
662 | - add_filter( |
|
663 | - 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantData__ensureCriticalRegistrantDataIsSet', |
|
664 | - [$this, 'mergeAddressDetailsWithCriticalAttendeeDetails'], |
|
665 | - 1 |
|
666 | - ); |
|
667 | - } |
|
668 | - |
|
669 | - |
|
670 | - /** |
|
671 | - * @param bool $bypass |
|
672 | - * @param int $attendee_count |
|
673 | - * @param EE_Registration $registration |
|
674 | - * @param array $registrations |
|
675 | - * @param array $reg_form_data |
|
676 | - * @return mixed|void |
|
677 | - * @since $VID:$ |
|
678 | - */ |
|
679 | - public function preRegistrationProcess( |
|
680 | - bool $bypass, |
|
681 | - int $attendee_count, |
|
682 | - EE_Registration $registration, |
|
683 | - array $registrations, |
|
684 | - array $reg_form_data |
|
685 | - ) { |
|
686 | - return apply_filters( |
|
687 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process', |
|
688 | - $bypass, |
|
689 | - $attendee_count, |
|
690 | - $registration, |
|
691 | - $registrations, |
|
692 | - $reg_form_data, |
|
693 | - $this |
|
694 | - ); |
|
695 | - } |
|
696 | - |
|
697 | - |
|
698 | - /** |
|
699 | - * @param array $reg_form_data |
|
700 | - * @param EE_Registration $registration |
|
701 | - * @return mixed|void |
|
702 | - * @since $VID:$ |
|
703 | - */ |
|
704 | - public function validDataLineItem(array $reg_form_data, EE_Registration $registration) |
|
705 | - { |
|
706 | - return apply_filters( |
|
707 | - 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
|
708 | - $reg_form_data, |
|
709 | - $registration |
|
710 | - ); |
|
711 | - } |
|
712 | - |
|
713 | - |
|
714 | - /** |
|
715 | - * @param bool $save |
|
716 | - * @param EE_Registration $registration |
|
717 | - * @param $form_input |
|
718 | - * @param $input_value |
|
719 | - * @return mixed|void |
|
720 | - * @since $VID:$ |
|
721 | - */ |
|
722 | - public function saveRegistrationFormInput(bool $save, EE_Registration $registration, $form_input, $input_value) |
|
723 | - { |
|
724 | - return apply_filters( |
|
725 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input', |
|
726 | - $save, |
|
727 | - $registration, |
|
728 | - $form_input, |
|
729 | - $input_value, |
|
730 | - $this |
|
731 | - ); |
|
732 | - } |
|
733 | - |
|
734 | - |
|
735 | - /** |
|
736 | - * @param bool $merge_data |
|
737 | - * @return mixed|void |
|
738 | - * @since $VID:$ |
|
739 | - */ |
|
740 | - public function mergeAddressDetailsWithCriticalAttendeeDetails(bool $merge_data) |
|
741 | - { |
|
742 | - return apply_filters( |
|
743 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
|
744 | - $merge_data |
|
745 | - ); |
|
746 | - } |
|
747 | - |
|
748 | - |
|
749 | - /** |
|
750 | - * @return bool |
|
751 | - * @since $VID:$ |
|
752 | - */ |
|
753 | - private function inValidDataError(): bool |
|
754 | - { |
|
755 | - EE_Error::add_error( |
|
756 | - esc_html__('No valid question responses were received.', 'event_espresso'), |
|
757 | - __FILE__, |
|
758 | - __FUNCTION__, |
|
759 | - __LINE__ |
|
760 | - ); |
|
761 | - return false; |
|
762 | - } |
|
763 | - |
|
764 | - |
|
765 | - /** |
|
766 | - * @return bool |
|
767 | - * @since $VID:$ |
|
768 | - */ |
|
769 | - private function inValidTransactionError(): bool |
|
770 | - { |
|
771 | - EE_Error::add_error( |
|
772 | - esc_html__( |
|
773 | - 'A valid transaction could not be initiated for processing your registrations.', |
|
774 | - 'event_espresso' |
|
775 | - ), |
|
776 | - __FILE__, |
|
777 | - __FUNCTION__, |
|
778 | - __LINE__ |
|
779 | - ); |
|
780 | - return false; |
|
781 | - } |
|
782 | - |
|
783 | - |
|
784 | - /** |
|
785 | - * @return bool |
|
786 | - * @since $VID:$ |
|
787 | - */ |
|
788 | - private function noRegistrationsError(): bool |
|
789 | - { |
|
790 | - // combine the old translated string with a new one, in order to not break translations |
|
791 | - $error_message = esc_html__( |
|
792 | - 'Your form data could not be applied to any valid registrations.', |
|
793 | - 'event_espresso' |
|
794 | - ); |
|
795 | - $error_message .= sprintf( |
|
796 | - esc_html_x( |
|
797 | - '%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
798 | - '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
799 | - 'event_espresso' |
|
800 | - ), |
|
801 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" >', |
|
802 | - '</a>', |
|
803 | - '<br />' |
|
804 | - ); |
|
805 | - EE_Error::add_error($error_message, __FILE__, __FUNCTION__, __LINE__); |
|
806 | - return false; |
|
807 | - } |
|
808 | - |
|
809 | - |
|
810 | - /** |
|
811 | - * @param int $registrations_processed |
|
812 | - * @return bool |
|
813 | - * @since $VID:$ |
|
814 | - */ |
|
815 | - private function registrationProcessingError(int $registrations_processed): bool |
|
816 | - { |
|
817 | - // generate a correctly translated string for all possible singular/plural combinations |
|
818 | - if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
|
819 | - $error_msg = sprintf( |
|
820 | - esc_html_x( |
|
821 | - 'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed', |
|
822 | - 'There was 1 ticket in the Event Queue, but 2 registrations were processed', |
|
823 | - 'event_espresso' |
|
824 | - ), |
|
825 | - $this->checkout->total_ticket_count, |
|
826 | - $registrations_processed |
|
827 | - ); |
|
828 | - } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) { |
|
829 | - $error_msg = sprintf( |
|
830 | - esc_html_x( |
|
831 | - 'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed', |
|
832 | - 'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed', |
|
833 | - 'event_espresso' |
|
834 | - ), |
|
835 | - $this->checkout->total_ticket_count, |
|
836 | - $registrations_processed |
|
837 | - ); |
|
838 | - } else { |
|
839 | - $error_msg = sprintf( |
|
840 | - esc_html__( |
|
841 | - 'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed', |
|
842 | - 'event_espresso' |
|
843 | - ), |
|
844 | - $this->checkout->total_ticket_count, |
|
845 | - $registrations_processed |
|
846 | - ); |
|
847 | - } |
|
848 | - EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
849 | - return false; |
|
850 | - } |
|
851 | - |
|
852 | - |
|
853 | - /** |
|
854 | - * update_reg_step |
|
855 | - * this is the final step after a user revisits the site to edit their attendee information |
|
856 | - * this gets called AFTER the process_reg_step() method above |
|
857 | - * |
|
858 | - * @return bool |
|
859 | - * @throws EE_Error |
|
860 | - * @throws InvalidArgumentException |
|
861 | - * @throws ReflectionException |
|
862 | - * @throws RuntimeException |
|
863 | - * @throws InvalidDataTypeException |
|
864 | - * @throws InvalidInterfaceException |
|
865 | - */ |
|
866 | - public function update_reg_step(): bool |
|
867 | - { |
|
868 | - // save everything |
|
869 | - if ($this->process_reg_step()) { |
|
870 | - $this->checkout->redirect = true; |
|
871 | - $this->checkout->redirect_url = add_query_arg( |
|
872 | - [ |
|
873 | - 'e_reg_url_link' => $this->checkout->reg_url_link, |
|
874 | - 'revisit' => true, |
|
875 | - ], |
|
876 | - $this->checkout->thank_you_page_url |
|
877 | - ); |
|
878 | - $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
879 | - return true; |
|
880 | - } |
|
881 | - return false; |
|
882 | - } |
|
25 | + /** |
|
26 | + * @var RegForm |
|
27 | + */ |
|
28 | + public $reg_form; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var int |
|
32 | + */ |
|
33 | + protected $reg_form_count = 0; |
|
34 | + |
|
35 | + |
|
36 | + /** |
|
37 | + * class constructor |
|
38 | + * |
|
39 | + * @access public |
|
40 | + * @param EE_Checkout $checkout |
|
41 | + */ |
|
42 | + public function __construct(EE_Checkout $checkout) |
|
43 | + { |
|
44 | + $this->_slug = 'attendee_information'; |
|
45 | + $this->_name = esc_html__('Attendee Information', 'event_espresso'); |
|
46 | + $this->checkout = $checkout; |
|
47 | + $this->_reset_success_message(); |
|
48 | + $this->set_instructions( |
|
49 | + esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso') |
|
50 | + ); |
|
51 | + } |
|
52 | + |
|
53 | + |
|
54 | + public function translate_js_strings() |
|
55 | + { |
|
56 | + EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
57 | + ' is a required question.', |
|
58 | + 'event_espresso' |
|
59 | + ); |
|
60 | + EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
61 | + ' is a required question. Please enter a value for at least one of the options.', |
|
62 | + 'event_espresso' |
|
63 | + ); |
|
64 | + EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__( |
|
65 | + 'Please answer all required questions correctly before proceeding.', |
|
66 | + 'event_espresso' |
|
67 | + ); |
|
68 | + EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
69 | + esc_html_x( |
|
70 | + 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.', |
|
71 | + 'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.', |
|
72 | + 'event_espresso' |
|
73 | + ), |
|
74 | + '<br/>' |
|
75 | + ); |
|
76 | + EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
77 | + 'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.', |
|
78 | + 'event_espresso' |
|
79 | + ); |
|
80 | + EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
81 | + 'You must enter a valid email address.', |
|
82 | + 'event_espresso' |
|
83 | + ); |
|
84 | + EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__( |
|
85 | + 'You must enter a valid email address and answer all other required questions before you can proceed.', |
|
86 | + 'event_espresso' |
|
87 | + ); |
|
88 | + } |
|
89 | + |
|
90 | + |
|
91 | + public function enqueue_styles_and_scripts() |
|
92 | + { |
|
93 | + } |
|
94 | + |
|
95 | + |
|
96 | + /** |
|
97 | + * @return boolean |
|
98 | + */ |
|
99 | + public function initialize_reg_step(): bool |
|
100 | + { |
|
101 | + return true; |
|
102 | + } |
|
103 | + |
|
104 | + |
|
105 | + /** |
|
106 | + * @return RegForm |
|
107 | + * @throws DomainException |
|
108 | + * @throws InvalidArgumentException |
|
109 | + * @throws EntityNotFoundException |
|
110 | + * @throws InvalidDataTypeException |
|
111 | + * @throws InvalidInterfaceException |
|
112 | + */ |
|
113 | + public function generate_reg_form(): RegForm |
|
114 | + { |
|
115 | + $this->setLegacyFiltersForRegFormGeneration(); |
|
116 | + /** @var RegFormDependencyHandler $dependency_handler */ |
|
117 | + $dependency_handler = LoaderFactory::getShared(RegFormDependencyHandler::class); |
|
118 | + $dependency_handler->registerDependencies(); |
|
119 | + // TODO detect if event has a reg form UUID and swap this out for form generated by new reg form builder |
|
120 | + return LoaderFactory::getShared(RegForm::class, [$this]); |
|
121 | + } |
|
122 | + |
|
123 | + |
|
124 | + /** |
|
125 | + * @since $VID:$ |
|
126 | + */ |
|
127 | + private function setLegacyFiltersForRegFormGeneration() |
|
128 | + { |
|
129 | + add_filter( |
|
130 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_groups_query_parameters', |
|
131 | + [$this, 'registrationQuestionGroupsQueryParameters'], |
|
132 | + 1, |
|
133 | + 2 |
|
134 | + ); |
|
135 | + add_filter( |
|
136 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__question_group_reg_form', |
|
137 | + [$this, 'registrationQuestionGroupsRegForm'], |
|
138 | + 1, |
|
139 | + 3 |
|
140 | + ); |
|
141 | + add_filter( |
|
142 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantForm__generateFormArgs__printCopyInfo', |
|
143 | + [$this, 'registrationRegFormPrintCopyInfo'], |
|
144 | + 1, |
|
145 | + 2 |
|
146 | + ); |
|
147 | + add_filter( |
|
148 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__related_questions_query_params', |
|
149 | + [$this, 'registrationRegFormRelatedQuestionsQueryParams'], |
|
150 | + 1, |
|
151 | + 3 |
|
152 | + ); |
|
153 | + add_filter( |
|
154 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__before_question_group_questions', |
|
155 | + [$this, 'registrationRegFormBeforeQuestionGroupQuestions'], |
|
156 | + 1, |
|
157 | + 3 |
|
158 | + ); |
|
159 | + add_filter( |
|
160 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__subsections_array', |
|
161 | + [$this, 'registrationRegFormSubsections'], |
|
162 | + 1, |
|
163 | + 3 |
|
164 | + ); |
|
165 | + add_filter( |
|
166 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormQuestionGroup__generateFormArgs__after_question_group_questions', |
|
167 | + [$this, 'registrationRegFormAfterQuestionGroupQuestions'], |
|
168 | + 1, |
|
169 | + 3 |
|
170 | + ); |
|
171 | + add_filter( |
|
172 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_AutoCopyAttendeeInfoForm__construct__template_args', |
|
173 | + [$this, 'autoCopyAttendeeInfoTemplateArgs'], |
|
174 | + 1 |
|
175 | + ); |
|
176 | + add_filter( |
|
177 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_CountryOptions__generateLegacyCountryOptions__country_options', |
|
178 | + [$this, 'generateQuestionInputCountryOptions'], |
|
179 | + 1, |
|
180 | + 4 |
|
181 | + ); |
|
182 | + add_filter( |
|
183 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_StateOptions__generateLegacyStateOptions__state_options', |
|
184 | + [$this, 'generateQuestionInputStateOptions'], |
|
185 | + 1, |
|
186 | + 4 |
|
187 | + ); |
|
188 | + } |
|
189 | + |
|
190 | + |
|
191 | + /** |
|
192 | + * @param array $query_params |
|
193 | + * @param EE_Registration $registration |
|
194 | + * @return mixed|void |
|
195 | + * @since $VID:$ |
|
196 | + */ |
|
197 | + public function registrationQuestionGroupsQueryParameters( |
|
198 | + array $query_params, |
|
199 | + EE_Registration $registration |
|
200 | + ) { |
|
201 | + return apply_filters( |
|
202 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters', |
|
203 | + $query_params, |
|
204 | + $registration, |
|
205 | + $this |
|
206 | + ); |
|
207 | + } |
|
208 | + |
|
209 | + |
|
210 | + /** |
|
211 | + * @param RegFormQuestionGroup $question_group_reg_form |
|
212 | + * @param EE_Registration $registration |
|
213 | + * @param EE_Question_Group $question_group |
|
214 | + * @return mixed|void |
|
215 | + * @since $VID:$ |
|
216 | + */ |
|
217 | + public function registrationQuestionGroupsRegForm( |
|
218 | + RegFormQuestionGroup $question_group_reg_form, |
|
219 | + EE_Registration $registration, |
|
220 | + EE_Question_Group $question_group |
|
221 | + ) { |
|
222 | + return apply_filters( |
|
223 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form', |
|
224 | + $question_group_reg_form, |
|
225 | + $registration, |
|
226 | + $question_group, |
|
227 | + $this |
|
228 | + ); |
|
229 | + } |
|
230 | + |
|
231 | + |
|
232 | + /** |
|
233 | + * @param int $print_copy_info |
|
234 | + * @param int $attendee_nmbr |
|
235 | + * @return mixed|void |
|
236 | + * @since $VID:$ |
|
237 | + */ |
|
238 | + public function registrationRegFormPrintCopyInfo( |
|
239 | + int $print_copy_info, |
|
240 | + int $attendee_nmbr |
|
241 | + ) { |
|
242 | + return apply_filters( |
|
243 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form___printCopyInfo', |
|
244 | + $print_copy_info, |
|
245 | + $attendee_nmbr |
|
246 | + ); |
|
247 | + } |
|
248 | + |
|
249 | + |
|
250 | + /** |
|
251 | + * @param array $query_params |
|
252 | + * @param EE_Question_Group $question_group |
|
253 | + * @param EE_Registration $registration |
|
254 | + * @return mixed|void |
|
255 | + * @since $VID:$ |
|
256 | + */ |
|
257 | + public function registrationRegFormRelatedQuestionsQueryParams( |
|
258 | + array $query_params, |
|
259 | + EE_Question_Group $question_group, |
|
260 | + EE_Registration $registration |
|
261 | + ) { |
|
262 | + return apply_filters( |
|
263 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params', |
|
264 | + $query_params, |
|
265 | + $question_group, |
|
266 | + $registration, |
|
267 | + $this |
|
268 | + ); |
|
269 | + } |
|
270 | + |
|
271 | + |
|
272 | + /** |
|
273 | + * @param $html |
|
274 | + * @param EE_Registration $registration |
|
275 | + * @param EE_Question_Group $question_group |
|
276 | + * @return mixed|void |
|
277 | + * @since $VID:$ |
|
278 | + */ |
|
279 | + public function registrationRegFormBeforeQuestionGroupQuestions( |
|
280 | + $html, |
|
281 | + EE_Registration $registration, |
|
282 | + EE_Question_Group $question_group |
|
283 | + ) { |
|
284 | + return apply_filters( |
|
285 | + 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', |
|
286 | + $html, |
|
287 | + $registration, |
|
288 | + $question_group, |
|
289 | + $this |
|
290 | + ); |
|
291 | + } |
|
292 | + |
|
293 | + |
|
294 | + /** |
|
295 | + * @param array $form_subsections |
|
296 | + * @param EE_Registration $registration |
|
297 | + * @param EE_Question_Group $question_group |
|
298 | + * @return mixed|void |
|
299 | + * @since $VID:$ |
|
300 | + */ |
|
301 | + public function registrationRegFormSubsections( |
|
302 | + array $form_subsections, |
|
303 | + EE_Registration $registration, |
|
304 | + EE_Question_Group $question_group |
|
305 | + ) { |
|
306 | + return apply_filters( |
|
307 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array', |
|
308 | + $form_subsections, |
|
309 | + $registration, |
|
310 | + $question_group, |
|
311 | + $this |
|
312 | + ); |
|
313 | + } |
|
314 | + |
|
315 | + |
|
316 | + /** |
|
317 | + * @param $html |
|
318 | + * @param EE_Registration $registration |
|
319 | + * @param EE_Question_Group $question_group |
|
320 | + * @return mixed|void |
|
321 | + * @since $VID:$ |
|
322 | + */ |
|
323 | + public function registrationRegFormAfterQuestionGroupQuestions( |
|
324 | + $html, |
|
325 | + EE_Registration $registration, |
|
326 | + EE_Question_Group $question_group |
|
327 | + ) { |
|
328 | + return apply_filters( |
|
329 | + 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', |
|
330 | + $html, |
|
331 | + $registration, |
|
332 | + $question_group, |
|
333 | + $this |
|
334 | + ); |
|
335 | + } |
|
336 | + |
|
337 | + |
|
338 | + /** |
|
339 | + * @param array $template_args |
|
340 | + * @return mixed|void |
|
341 | + * @since $VID:$ |
|
342 | + */ |
|
343 | + public function autoCopyAttendeeInfoTemplateArgs(array $template_args = []) |
|
344 | + { |
|
345 | + return apply_filters( |
|
346 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
|
347 | + $template_args |
|
348 | + ); |
|
349 | + } |
|
350 | + |
|
351 | + |
|
352 | + /** |
|
353 | + * @param array $country_options |
|
354 | + * @param EE_Registration $registration |
|
355 | + * @param EE_Question $question |
|
356 | + * @param EE_Answer|null $answer |
|
357 | + * @return mixed|void |
|
358 | + * @since $VID:$ |
|
359 | + */ |
|
360 | + public function generateQuestionInputCountryOptions( |
|
361 | + array $country_options, |
|
362 | + EE_Registration $registration, |
|
363 | + EE_Question $question, |
|
364 | + ?EE_Answer $answer |
|
365 | + ) { |
|
366 | + return apply_filters( |
|
367 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options', |
|
368 | + $country_options, |
|
369 | + $this, |
|
370 | + $registration, |
|
371 | + $question, |
|
372 | + $answer |
|
373 | + ); |
|
374 | + } |
|
375 | + |
|
376 | + |
|
377 | + /** |
|
378 | + * @param array $state_options |
|
379 | + * @param EE_Registration $registration |
|
380 | + * @param EE_Question $question |
|
381 | + * @param EE_Answer|null $answer |
|
382 | + * @return mixed|void |
|
383 | + * @since $VID:$ |
|
384 | + */ |
|
385 | + public function generateQuestionInputStateOptions( |
|
386 | + array $state_options, |
|
387 | + EE_Registration $registration, |
|
388 | + EE_Question $question, |
|
389 | + ?EE_Answer $answer |
|
390 | + ) { |
|
391 | + return apply_filters( |
|
392 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options', |
|
393 | + $state_options, |
|
394 | + $this, |
|
395 | + $registration, |
|
396 | + $question, |
|
397 | + $answer |
|
398 | + ); |
|
399 | + } |
|
400 | + |
|
401 | + |
|
402 | + /** |
|
403 | + * looking for hooks? |
|
404 | + * this method has been replaced by: |
|
405 | + * EventEspresso\core\domain\services\registration\form\v1\RegForm::getRegForm() |
|
406 | + * |
|
407 | + * @deprecated $VID:$ |
|
408 | + */ |
|
409 | + private function _registrations_reg_form() |
|
410 | + { |
|
411 | + } |
|
412 | + |
|
413 | + |
|
414 | + /** |
|
415 | + * looking for hooks? |
|
416 | + * this method has been replaced by: |
|
417 | + * EventEspresso\core\domain\services\registration\form\v1\RegForm::additionalAttendeeRegInfoInput() |
|
418 | + * |
|
419 | + * @deprecated $VID:$ |
|
420 | + */ |
|
421 | + private function _additional_attendee_reg_info_input() |
|
422 | + { |
|
423 | + } |
|
424 | + |
|
425 | + |
|
426 | + /** |
|
427 | + * looking for hooks? |
|
428 | + * this method has been replaced by: |
|
429 | + * EventEspresso\core\domain\services\registration\form\v1\RegForm::questionGroupRegForm() |
|
430 | + * |
|
431 | + * @deprecated $VID:$ |
|
432 | + */ |
|
433 | + private function _question_group_reg_form() |
|
434 | + { |
|
435 | + } |
|
436 | + |
|
437 | + |
|
438 | + /** |
|
439 | + * looking for hooks? |
|
440 | + * this method has been replaced by: |
|
441 | + * EventEspresso\core\domain\services\registration\form\v1\RegForm::questionGroupHeader() |
|
442 | + * |
|
443 | + * @deprecated $VID:$ |
|
444 | + */ |
|
445 | + private function _question_group_header() |
|
446 | + { |
|
447 | + } |
|
448 | + |
|
449 | + |
|
450 | + /** |
|
451 | + * looking for hooks? |
|
452 | + * this method has been replaced by: |
|
453 | + * EventEspresso\core\domain\services\registration\form\v1\CopyAttendeeInfoForm |
|
454 | + * |
|
455 | + * @deprecated $VID:$ |
|
456 | + */ |
|
457 | + private function _copy_attendee_info_form() |
|
458 | + { |
|
459 | + } |
|
460 | + |
|
461 | + |
|
462 | + /** |
|
463 | + * looking for hooks? |
|
464 | + * this method has been replaced by: |
|
465 | + * EventEspresso\core\domain\services\registration\form\v1\AutoCopyAttendeeInfoForm |
|
466 | + * |
|
467 | + * @deprecated $VID:$ |
|
468 | + */ |
|
469 | + private function _auto_copy_attendee_info() |
|
470 | + { |
|
471 | + } |
|
472 | + |
|
473 | + |
|
474 | + /** |
|
475 | + * looking for hooks? |
|
476 | + * this method has been replaced by: |
|
477 | + * EventEspresso\core\domain\services\registration\form\v1\CopyAttendeeInfoForm |
|
478 | + * |
|
479 | + * @deprecated $VID:$ |
|
480 | + */ |
|
481 | + private function _copy_attendee_info_inputs() |
|
482 | + { |
|
483 | + } |
|
484 | + |
|
485 | + |
|
486 | + /** |
|
487 | + * looking for hooks? |
|
488 | + * this method has been replaced by: |
|
489 | + * EventEspresso\core\domain\services\registration\form\v1\RegForm::additionalPrimaryRegistrantInputs() |
|
490 | + * |
|
491 | + * @deprecated $VID:$ |
|
492 | + */ |
|
493 | + private function _additional_primary_registrant_inputs() |
|
494 | + { |
|
495 | + } |
|
496 | + |
|
497 | + |
|
498 | + /** |
|
499 | + * looking for hooks? |
|
500 | + * this method has been replaced by: |
|
501 | + * EventEspresso\core\domain\services\registration\form\v1\RegFormQuestionFactory::create() |
|
502 | + * |
|
503 | + * @param EE_Registration $registration |
|
504 | + * @param EE_Question $question |
|
505 | + * @return EE_Form_Input_Base |
|
506 | + * @throws EE_Error |
|
507 | + * @throws ReflectionException |
|
508 | + * @deprecated $VID:$ |
|
509 | + */ |
|
510 | + public function reg_form_question(EE_Registration $registration, EE_Question $question): EE_Form_Input_Base |
|
511 | + { |
|
512 | + /** @var RegFormQuestionFactory $reg_form_question_factory */ |
|
513 | + $reg_form_question_factory = LoaderFactory::getShared(RegFormQuestionFactory::class); |
|
514 | + return $reg_form_question_factory->create($registration, $question); |
|
515 | + } |
|
516 | + |
|
517 | + |
|
518 | + /** |
|
519 | + * looking for hooks? |
|
520 | + * this method has been replaced by: |
|
521 | + * EventEspresso\core\domain\services\registration\form\v1\RegForm::generateQuestionInput() |
|
522 | + * |
|
523 | + * @deprecated $VID:$ |
|
524 | + */ |
|
525 | + private function _generate_question_input() |
|
526 | + { |
|
527 | + } |
|
528 | + |
|
529 | + |
|
530 | + /** |
|
531 | + * looking for hooks? |
|
532 | + * this method has been replaced by: |
|
533 | + * EventEspresso\core\domain\services\registration\form\v1\CountryOptions::forLegacyFormInput() |
|
534 | + * |
|
535 | + * @param array|null $countries_list |
|
536 | + * @param EE_Question|null $question |
|
537 | + * @param EE_Registration|null $registration |
|
538 | + * @param EE_Answer|null $answer |
|
539 | + * @return array 2d keys are country IDs, values are their names |
|
540 | + * @throws EE_Error |
|
541 | + * @throws ReflectionException |
|
542 | + * @deprecated $VID:$ |
|
543 | + */ |
|
544 | + public function use_cached_countries_for_form_input( |
|
545 | + array $countries_list = null, |
|
546 | + EE_Question $question = null, |
|
547 | + EE_Registration $registration = null, |
|
548 | + EE_Answer $answer = null |
|
549 | + ): array { |
|
550 | + /** @var CountryOptions $country_options */ |
|
551 | + $country_options = LoaderFactory::getShared(CountryOptions::class, [$this->checkout->action]); |
|
552 | + return $country_options->forLegacyFormInput($countries_list, $question, $registration, $answer); |
|
553 | + } |
|
554 | + |
|
555 | + |
|
556 | + /** |
|
557 | + * looking for hooks? |
|
558 | + * this method has been replaced by: |
|
559 | + * EventEspresso\core\domain\services\registration\form\v1\StateOptions::forLegacyFormInput() |
|
560 | + * |
|
561 | + * @param array|null $states_list |
|
562 | + * @param EE_Question|null $question |
|
563 | + * @param EE_Registration|null $registration |
|
564 | + * @param EE_Answer|null $answer |
|
565 | + * @return array 2d keys are state IDs, values are their names |
|
566 | + * @throws EE_Error |
|
567 | + * @throws ReflectionException |
|
568 | + * @deprecated $VID:$ |
|
569 | + */ |
|
570 | + public function use_cached_states_for_form_input( |
|
571 | + array $states_list = null, |
|
572 | + EE_Question $question = null, |
|
573 | + EE_Registration $registration = null, |
|
574 | + EE_Answer $answer = null |
|
575 | + ): array { |
|
576 | + /** @var StateOptions $state_options */ |
|
577 | + $state_options = LoaderFactory::getShared(StateOptions::class, [$this->checkout->action]); |
|
578 | + return $state_options->forLegacyFormInput($states_list, $question, $registration, $answer); |
|
579 | + } |
|
580 | + |
|
581 | + |
|
582 | + /********************************************************************************************************/ |
|
583 | + /**************************************** PROCESS REG STEP ****************************************/ |
|
584 | + /********************************************************************************************************/ |
|
585 | + |
|
586 | + |
|
587 | + /** |
|
588 | + * @return bool |
|
589 | + * @throws EE_Error |
|
590 | + * @throws InvalidArgumentException |
|
591 | + * @throws ReflectionException |
|
592 | + * @throws RuntimeException |
|
593 | + * @throws InvalidDataTypeException |
|
594 | + * @throws InvalidInterfaceException |
|
595 | + */ |
|
596 | + public function process_reg_step(): bool |
|
597 | + { |
|
598 | + $this->setLegacyFiltersForRegFormProcessing(); |
|
599 | + // grab validated data from form |
|
600 | + $valid_data = $this->checkout->current_step->valid_data(); |
|
601 | + // if we don't have any $valid_data then something went TERRIBLY WRONG !!! |
|
602 | + if (empty($valid_data)) { |
|
603 | + return $this->inValidDataError(); |
|
604 | + } |
|
605 | + if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
606 | + return $this->inValidTransactionError(); |
|
607 | + } |
|
608 | + // get cached registrations |
|
609 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
610 | + // verify we got the goods |
|
611 | + if (empty($registrations)) { |
|
612 | + return $this->noRegistrationsError(); |
|
613 | + } |
|
614 | + /** @var RegFormHandler $reg_form_handler */ |
|
615 | + $reg_form_handler = LoaderFactory::getNew(RegFormHandler::class, [$this->checkout]); |
|
616 | + // extract attendee info from form data and save to model objects |
|
617 | + if (! $reg_form_handler->processRegistrations($registrations, $valid_data)) { |
|
618 | + // return immediately if the previous step exited early due to errors |
|
619 | + return false; |
|
620 | + } |
|
621 | + // if first pass thru SPCO, |
|
622 | + // then let's check processed registrations against the total number of tickets in the cart |
|
623 | + $registrations_processed = $reg_form_handler->attendeeCount(); |
|
624 | + if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
625 | + return $this->registrationProcessingError($registrations_processed); |
|
626 | + } |
|
627 | + // mark this reg step as completed |
|
628 | + $this->set_completed(); |
|
629 | + $this->_set_success_message( |
|
630 | + esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso') |
|
631 | + ); |
|
632 | + // do action in case a plugin wants to do something with the data submitted in step 1. |
|
633 | + // passes EE_Single_Page_Checkout, and it's posted data |
|
634 | + do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data); |
|
635 | + return true; |
|
636 | + } |
|
637 | + |
|
638 | + |
|
639 | + /** |
|
640 | + * @since $VID:$ |
|
641 | + */ |
|
642 | + private function setLegacyFiltersForRegFormProcessing() |
|
643 | + { |
|
644 | + add_filter( |
|
645 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegistrations__bypass', |
|
646 | + [$this, 'preRegistrationProcess'], |
|
647 | + 1, |
|
648 | + 5 |
|
649 | + ); |
|
650 | + add_filter( |
|
651 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormHandler__processRegFormData__registrant_form_data', |
|
652 | + [$this, 'validDataLineItem'], |
|
653 | + 1, |
|
654 | + 2 |
|
655 | + ); |
|
656 | + add_filter( |
|
657 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegFormInputHandler__saveRegistrationFormInput', |
|
658 | + [$this, 'saveRegistrationFormInput'], |
|
659 | + 1, |
|
660 | + 4 |
|
661 | + ); |
|
662 | + add_filter( |
|
663 | + 'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegistrantData__ensureCriticalRegistrantDataIsSet', |
|
664 | + [$this, 'mergeAddressDetailsWithCriticalAttendeeDetails'], |
|
665 | + 1 |
|
666 | + ); |
|
667 | + } |
|
668 | + |
|
669 | + |
|
670 | + /** |
|
671 | + * @param bool $bypass |
|
672 | + * @param int $attendee_count |
|
673 | + * @param EE_Registration $registration |
|
674 | + * @param array $registrations |
|
675 | + * @param array $reg_form_data |
|
676 | + * @return mixed|void |
|
677 | + * @since $VID:$ |
|
678 | + */ |
|
679 | + public function preRegistrationProcess( |
|
680 | + bool $bypass, |
|
681 | + int $attendee_count, |
|
682 | + EE_Registration $registration, |
|
683 | + array $registrations, |
|
684 | + array $reg_form_data |
|
685 | + ) { |
|
686 | + return apply_filters( |
|
687 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process', |
|
688 | + $bypass, |
|
689 | + $attendee_count, |
|
690 | + $registration, |
|
691 | + $registrations, |
|
692 | + $reg_form_data, |
|
693 | + $this |
|
694 | + ); |
|
695 | + } |
|
696 | + |
|
697 | + |
|
698 | + /** |
|
699 | + * @param array $reg_form_data |
|
700 | + * @param EE_Registration $registration |
|
701 | + * @return mixed|void |
|
702 | + * @since $VID:$ |
|
703 | + */ |
|
704 | + public function validDataLineItem(array $reg_form_data, EE_Registration $registration) |
|
705 | + { |
|
706 | + return apply_filters( |
|
707 | + 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
|
708 | + $reg_form_data, |
|
709 | + $registration |
|
710 | + ); |
|
711 | + } |
|
712 | + |
|
713 | + |
|
714 | + /** |
|
715 | + * @param bool $save |
|
716 | + * @param EE_Registration $registration |
|
717 | + * @param $form_input |
|
718 | + * @param $input_value |
|
719 | + * @return mixed|void |
|
720 | + * @since $VID:$ |
|
721 | + */ |
|
722 | + public function saveRegistrationFormInput(bool $save, EE_Registration $registration, $form_input, $input_value) |
|
723 | + { |
|
724 | + return apply_filters( |
|
725 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input', |
|
726 | + $save, |
|
727 | + $registration, |
|
728 | + $form_input, |
|
729 | + $input_value, |
|
730 | + $this |
|
731 | + ); |
|
732 | + } |
|
733 | + |
|
734 | + |
|
735 | + /** |
|
736 | + * @param bool $merge_data |
|
737 | + * @return mixed|void |
|
738 | + * @since $VID:$ |
|
739 | + */ |
|
740 | + public function mergeAddressDetailsWithCriticalAttendeeDetails(bool $merge_data) |
|
741 | + { |
|
742 | + return apply_filters( |
|
743 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
|
744 | + $merge_data |
|
745 | + ); |
|
746 | + } |
|
747 | + |
|
748 | + |
|
749 | + /** |
|
750 | + * @return bool |
|
751 | + * @since $VID:$ |
|
752 | + */ |
|
753 | + private function inValidDataError(): bool |
|
754 | + { |
|
755 | + EE_Error::add_error( |
|
756 | + esc_html__('No valid question responses were received.', 'event_espresso'), |
|
757 | + __FILE__, |
|
758 | + __FUNCTION__, |
|
759 | + __LINE__ |
|
760 | + ); |
|
761 | + return false; |
|
762 | + } |
|
763 | + |
|
764 | + |
|
765 | + /** |
|
766 | + * @return bool |
|
767 | + * @since $VID:$ |
|
768 | + */ |
|
769 | + private function inValidTransactionError(): bool |
|
770 | + { |
|
771 | + EE_Error::add_error( |
|
772 | + esc_html__( |
|
773 | + 'A valid transaction could not be initiated for processing your registrations.', |
|
774 | + 'event_espresso' |
|
775 | + ), |
|
776 | + __FILE__, |
|
777 | + __FUNCTION__, |
|
778 | + __LINE__ |
|
779 | + ); |
|
780 | + return false; |
|
781 | + } |
|
782 | + |
|
783 | + |
|
784 | + /** |
|
785 | + * @return bool |
|
786 | + * @since $VID:$ |
|
787 | + */ |
|
788 | + private function noRegistrationsError(): bool |
|
789 | + { |
|
790 | + // combine the old translated string with a new one, in order to not break translations |
|
791 | + $error_message = esc_html__( |
|
792 | + 'Your form data could not be applied to any valid registrations.', |
|
793 | + 'event_espresso' |
|
794 | + ); |
|
795 | + $error_message .= sprintf( |
|
796 | + esc_html_x( |
|
797 | + '%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
798 | + '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
799 | + 'event_espresso' |
|
800 | + ), |
|
801 | + '<a href="' . get_post_type_archive_link('espresso_events') . '" >', |
|
802 | + '</a>', |
|
803 | + '<br />' |
|
804 | + ); |
|
805 | + EE_Error::add_error($error_message, __FILE__, __FUNCTION__, __LINE__); |
|
806 | + return false; |
|
807 | + } |
|
808 | + |
|
809 | + |
|
810 | + /** |
|
811 | + * @param int $registrations_processed |
|
812 | + * @return bool |
|
813 | + * @since $VID:$ |
|
814 | + */ |
|
815 | + private function registrationProcessingError(int $registrations_processed): bool |
|
816 | + { |
|
817 | + // generate a correctly translated string for all possible singular/plural combinations |
|
818 | + if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
|
819 | + $error_msg = sprintf( |
|
820 | + esc_html_x( |
|
821 | + 'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed', |
|
822 | + 'There was 1 ticket in the Event Queue, but 2 registrations were processed', |
|
823 | + 'event_espresso' |
|
824 | + ), |
|
825 | + $this->checkout->total_ticket_count, |
|
826 | + $registrations_processed |
|
827 | + ); |
|
828 | + } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) { |
|
829 | + $error_msg = sprintf( |
|
830 | + esc_html_x( |
|
831 | + 'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed', |
|
832 | + 'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed', |
|
833 | + 'event_espresso' |
|
834 | + ), |
|
835 | + $this->checkout->total_ticket_count, |
|
836 | + $registrations_processed |
|
837 | + ); |
|
838 | + } else { |
|
839 | + $error_msg = sprintf( |
|
840 | + esc_html__( |
|
841 | + 'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed', |
|
842 | + 'event_espresso' |
|
843 | + ), |
|
844 | + $this->checkout->total_ticket_count, |
|
845 | + $registrations_processed |
|
846 | + ); |
|
847 | + } |
|
848 | + EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
849 | + return false; |
|
850 | + } |
|
851 | + |
|
852 | + |
|
853 | + /** |
|
854 | + * update_reg_step |
|
855 | + * this is the final step after a user revisits the site to edit their attendee information |
|
856 | + * this gets called AFTER the process_reg_step() method above |
|
857 | + * |
|
858 | + * @return bool |
|
859 | + * @throws EE_Error |
|
860 | + * @throws InvalidArgumentException |
|
861 | + * @throws ReflectionException |
|
862 | + * @throws RuntimeException |
|
863 | + * @throws InvalidDataTypeException |
|
864 | + * @throws InvalidInterfaceException |
|
865 | + */ |
|
866 | + public function update_reg_step(): bool |
|
867 | + { |
|
868 | + // save everything |
|
869 | + if ($this->process_reg_step()) { |
|
870 | + $this->checkout->redirect = true; |
|
871 | + $this->checkout->redirect_url = add_query_arg( |
|
872 | + [ |
|
873 | + 'e_reg_url_link' => $this->checkout->reg_url_link, |
|
874 | + 'revisit' => true, |
|
875 | + ], |
|
876 | + $this->checkout->thank_you_page_url |
|
877 | + ); |
|
878 | + $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
879 | + return true; |
|
880 | + } |
|
881 | + return false; |
|
882 | + } |
|
883 | 883 | } |
@@ -21,1382 +21,1382 @@ |
||
21 | 21 | */ |
22 | 22 | class EED_Core_Rest_Api extends EED_Module |
23 | 23 | { |
24 | - const ee_api_namespace = Domain::API_NAMESPACE; |
|
25 | - |
|
26 | - const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
27 | - |
|
28 | - const saved_routes_option_names = 'ee_core_routes'; |
|
29 | - |
|
30 | - /** |
|
31 | - * string used in _links response bodies to make them globally unique. |
|
32 | - * |
|
33 | - * @see http://v2.wp-api.org/extending/linking/ |
|
34 | - */ |
|
35 | - const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
36 | - |
|
37 | - /** |
|
38 | - * @var CalculatedModelFields |
|
39 | - */ |
|
40 | - protected static $_field_calculator; |
|
41 | - |
|
42 | - |
|
43 | - /** |
|
44 | - * @return EED_Core_Rest_Api|EED_Module |
|
45 | - */ |
|
46 | - public static function instance() |
|
47 | - { |
|
48 | - return parent::get_instance(EED_Core_Rest_Api::class); |
|
49 | - } |
|
50 | - |
|
51 | - |
|
52 | - /** |
|
53 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
54 | - * |
|
55 | - * @access public |
|
56 | - * @return void |
|
57 | - */ |
|
58 | - public static function set_hooks() |
|
59 | - { |
|
60 | - } |
|
61 | - |
|
62 | - |
|
63 | - /** |
|
64 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
65 | - * |
|
66 | - * @access public |
|
67 | - * @return void |
|
68 | - */ |
|
69 | - public static function set_hooks_admin() |
|
70 | - { |
|
71 | - } |
|
72 | - |
|
73 | - |
|
74 | - public static function set_hooks_both() |
|
75 | - { |
|
76 | - add_action('rest_api_init', ['EED_Core_Rest_Api', 'set_hooks_rest_api'], 5); |
|
77 | - add_action('rest_api_init', ['EED_Core_Rest_Api', 'register_routes'], 10); |
|
78 | - add_filter('rest_route_data', ['EED_Core_Rest_Api', 'hide_old_endpoints'], 10, 2); |
|
79 | - add_filter( |
|
80 | - 'rest_index', |
|
81 | - ['EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'] |
|
82 | - ); |
|
83 | - } |
|
84 | - |
|
85 | - |
|
86 | - /** |
|
87 | - * @since $VID:$ |
|
88 | - */ |
|
89 | - public static function loadCalculatedModelFields() |
|
90 | - { |
|
91 | - EED_Core_Rest_Api::$_field_calculator = LoaderFactory::getLoader()->load( |
|
92 | - 'EventEspresso\core\libraries\rest_api\CalculatedModelFields' |
|
93 | - ); |
|
94 | - EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
95 | - } |
|
96 | - |
|
97 | - |
|
98 | - /** |
|
99 | - * sets up hooks which only need to be included as part of REST API requests; |
|
100 | - * other requests like to the frontend or admin etc don't need them |
|
101 | - * |
|
102 | - * @throws EE_Error |
|
103 | - */ |
|
104 | - public static function set_hooks_rest_api() |
|
105 | - { |
|
106 | - // set hooks which account for changes made to the API |
|
107 | - EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
108 | - } |
|
109 | - |
|
110 | - |
|
111 | - /** |
|
112 | - * public wrapper of _set_hooks_for_changes. |
|
113 | - * Loads all the hooks which make requests to old versions of the API |
|
114 | - * appear the same as they always did |
|
115 | - * |
|
116 | - * @throws EE_Error |
|
117 | - */ |
|
118 | - public static function set_hooks_for_changes() |
|
119 | - { |
|
120 | - EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
121 | - } |
|
122 | - |
|
123 | - |
|
124 | - /** |
|
125 | - * Loads all the hooks which make requests to old versions of the API |
|
126 | - * appear the same as they always did |
|
127 | - * |
|
128 | - * @throws EE_Error |
|
129 | - */ |
|
130 | - protected static function _set_hooks_for_changes() |
|
131 | - { |
|
132 | - $folder_contents = EEH_File::get_contents_of_folders([EE_LIBRARIES . 'rest_api/changes'], false); |
|
133 | - foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
134 | - // ignore the base parent class |
|
135 | - // and legacy named classes |
|
136 | - if ( |
|
137 | - $classname_in_namespace === 'ChangesInBase' |
|
138 | - || strpos($classname_in_namespace, 'Changes_In_') === 0 |
|
139 | - ) { |
|
140 | - continue; |
|
141 | - } |
|
142 | - $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
143 | - if (class_exists($full_classname)) { |
|
144 | - $instance_of_class = new $full_classname(); |
|
145 | - if ($instance_of_class instanceof ChangesInBase) { |
|
146 | - $instance_of_class->setHooks(); |
|
147 | - } |
|
148 | - } |
|
149 | - } |
|
150 | - } |
|
151 | - |
|
152 | - |
|
153 | - /** |
|
154 | - * Filters the WP routes to add our EE-related ones. This takes a bit of time |
|
155 | - * so we actually prefer to only do it when an EE plugin is activated or upgraded |
|
156 | - * |
|
157 | - * @throws EE_Error |
|
158 | - * @throws ReflectionException |
|
159 | - */ |
|
160 | - public static function register_routes() |
|
161 | - { |
|
162 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) { |
|
163 | - foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) { |
|
164 | - /** |
|
165 | - * @var array $data_for_multiple_endpoints numerically indexed array |
|
166 | - * but can also contain route options like { |
|
167 | - * @type array $schema { |
|
168 | - * @type callable $schema_callback |
|
169 | - * @type array $callback_args arguments that will be passed to the callback, after the |
|
170 | - * WP_REST_Request of course |
|
171 | - * } |
|
172 | - * } |
|
173 | - */ |
|
174 | - // when registering routes, register all the endpoints' data at the same time |
|
175 | - $multiple_endpoint_args = []; |
|
176 | - foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) { |
|
177 | - /** |
|
178 | - * @var array $data_for_single_endpoint { |
|
179 | - * @type callable $callback |
|
180 | - * @type string methods |
|
181 | - * @type array args |
|
182 | - * @type array _links |
|
183 | - * @type array $callback_args arguments that will be passed to the callback, after the |
|
184 | - * WP_REST_Request of course |
|
185 | - * } |
|
186 | - */ |
|
187 | - // skip route options |
|
188 | - if (! is_numeric($endpoint_key)) { |
|
189 | - continue; |
|
190 | - } |
|
191 | - if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
192 | - throw new EE_Error( |
|
193 | - esc_html__( |
|
194 | - // @codingStandardsIgnoreStart |
|
195 | - 'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).', |
|
196 | - // @codingStandardsIgnoreEnd |
|
197 | - 'event_espresso' |
|
198 | - ) |
|
199 | - ); |
|
200 | - } |
|
201 | - $callback = $data_for_single_endpoint['callback']; |
|
202 | - $single_endpoint_args = [ |
|
203 | - 'methods' => $data_for_single_endpoint['methods'], |
|
204 | - 'args' => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args'] |
|
205 | - : [], |
|
206 | - ]; |
|
207 | - if (isset($data_for_single_endpoint['_links'])) { |
|
208 | - $single_endpoint_args['_links'] = $data_for_single_endpoint['_links']; |
|
209 | - } |
|
210 | - if (isset($data_for_single_endpoint['callback_args'])) { |
|
211 | - $callback_args = $data_for_single_endpoint['callback_args']; |
|
212 | - $single_endpoint_args['callback'] = static function (WP_REST_Request $request) use ( |
|
213 | - $callback, |
|
214 | - $callback_args |
|
215 | - ) { |
|
216 | - array_unshift($callback_args, $request); |
|
217 | - return call_user_func_array( |
|
218 | - $callback, |
|
219 | - $callback_args |
|
220 | - ); |
|
221 | - }; |
|
222 | - } else { |
|
223 | - $single_endpoint_args['callback'] = $data_for_single_endpoint['callback']; |
|
224 | - } |
|
225 | - // As of WordPress 5.5, if a permission_callback is not provided, |
|
226 | - // the REST API will issue a _doing_it_wrong notice. |
|
227 | - // Since the EE REST API defers capabilities to the db model system, |
|
228 | - // we will just use the generic WP callback for public endpoints |
|
229 | - if (! isset($single_endpoint_args['permission_callback'])) { |
|
230 | - $single_endpoint_args['permission_callback'] = '__return_true'; |
|
231 | - } |
|
232 | - $multiple_endpoint_args[] = $single_endpoint_args; |
|
233 | - } |
|
234 | - if (isset($data_for_multiple_endpoints['schema'])) { |
|
235 | - $schema_route_data = $data_for_multiple_endpoints['schema']; |
|
236 | - $schema_callback = $schema_route_data['schema_callback']; |
|
237 | - $callback_args = $schema_route_data['callback_args']; |
|
238 | - $multiple_endpoint_args['schema'] = static function () use ($schema_callback, $callback_args) { |
|
239 | - return call_user_func_array( |
|
240 | - $schema_callback, |
|
241 | - $callback_args |
|
242 | - ); |
|
243 | - }; |
|
244 | - } |
|
245 | - register_rest_route( |
|
246 | - $namespace, |
|
247 | - $relative_route, |
|
248 | - $multiple_endpoint_args |
|
249 | - ); |
|
250 | - } |
|
251 | - } |
|
252 | - } |
|
253 | - |
|
254 | - |
|
255 | - /** |
|
256 | - * Checks if there was a version change or something that merits invalidating the cached |
|
257 | - * route data. If so, invalidates the cached route data so that it gets refreshed |
|
258 | - * next time the WP API is used |
|
259 | - */ |
|
260 | - public static function invalidate_cached_route_data_on_version_change() |
|
261 | - { |
|
262 | - if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) { |
|
263 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
264 | - } |
|
265 | - foreach (EE_Registry::instance()->addons as $addon) { |
|
266 | - if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) { |
|
267 | - EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
268 | - } |
|
269 | - } |
|
270 | - } |
|
271 | - |
|
272 | - |
|
273 | - /** |
|
274 | - * Removes the cached route data so it will get refreshed next time the WP API is used |
|
275 | - */ |
|
276 | - public static function invalidate_cached_route_data() |
|
277 | - { |
|
278 | - // delete the saved EE REST API routes |
|
279 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
|
280 | - delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
281 | - } |
|
282 | - } |
|
283 | - |
|
284 | - |
|
285 | - /** |
|
286 | - * Gets the EE route data |
|
287 | - * |
|
288 | - * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
289 | - * @throws EE_Error |
|
290 | - * @throws ReflectionException |
|
291 | - * @type string|array $callback |
|
292 | - * @type string $methods |
|
293 | - * @type boolean $hidden_endpoint |
|
294 | - * } |
|
295 | - */ |
|
296 | - public static function get_ee_route_data() |
|
297 | - { |
|
298 | - $ee_routes = []; |
|
299 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoints) { |
|
300 | - $ee_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = EED_Core_Rest_Api::_get_ee_route_data_for_version( |
|
301 | - $version, |
|
302 | - $hidden_endpoints |
|
303 | - ); |
|
304 | - } |
|
305 | - return $ee_routes; |
|
306 | - } |
|
307 | - |
|
308 | - |
|
309 | - /** |
|
310 | - * Gets the EE route data from the wp options if it exists already, |
|
311 | - * otherwise re-generates it and saves it to the option |
|
312 | - * |
|
313 | - * @param string $version |
|
314 | - * @param boolean $hidden_endpoints |
|
315 | - * @return array |
|
316 | - * @throws EE_Error |
|
317 | - * @throws ReflectionException |
|
318 | - */ |
|
319 | - protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
320 | - { |
|
321 | - $ee_routes = get_option(EED_Core_Rest_Api::saved_routes_option_names . $version, null); |
|
322 | - if (! $ee_routes || EED_Core_Rest_Api::debugMode()) { |
|
323 | - $ee_routes = EED_Core_Rest_Api::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
324 | - } |
|
325 | - return $ee_routes; |
|
326 | - } |
|
327 | - |
|
328 | - |
|
329 | - /** |
|
330 | - * Saves the EE REST API route data to a wp option and returns it |
|
331 | - * |
|
332 | - * @param string $version |
|
333 | - * @param boolean $hidden_endpoints |
|
334 | - * @return mixed|null |
|
335 | - * @throws EE_Error |
|
336 | - * @throws ReflectionException |
|
337 | - */ |
|
338 | - protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
339 | - { |
|
340 | - $instance = EED_Core_Rest_Api::instance(); |
|
341 | - $routes = apply_filters( |
|
342 | - 'EED_Core_Rest_Api__save_ee_route_data_for_version__routes', |
|
343 | - array_replace_recursive( |
|
344 | - $instance->_get_config_route_data_for_version($version, $hidden_endpoints), |
|
345 | - $instance->_get_meta_route_data_for_version($version, $hidden_endpoints), |
|
346 | - $instance->_get_model_route_data_for_version($version, $hidden_endpoints), |
|
347 | - $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
|
348 | - ) |
|
349 | - ); |
|
350 | - $option_name = EED_Core_Rest_Api::saved_routes_option_names . $version; |
|
351 | - if (get_option($option_name)) { |
|
352 | - update_option($option_name, $routes, true); |
|
353 | - } else { |
|
354 | - add_option($option_name, $routes, null, 'no'); |
|
355 | - } |
|
356 | - return $routes; |
|
357 | - } |
|
358 | - |
|
359 | - |
|
360 | - /** |
|
361 | - * Calculates all the EE routes and saves it to a WordPress option so we don't |
|
362 | - * need to calculate it on every request |
|
363 | - * |
|
364 | - * @return void |
|
365 | - * @deprecated since version 4.9.1 |
|
366 | - */ |
|
367 | - public static function save_ee_routes() |
|
368 | - { |
|
369 | - if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
370 | - $instance = EED_Core_Rest_Api::instance(); |
|
371 | - $routes = apply_filters( |
|
372 | - 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
373 | - array_replace_recursive( |
|
374 | - $instance->_register_config_routes(), |
|
375 | - $instance->_register_meta_routes(), |
|
376 | - $instance->_register_model_routes(), |
|
377 | - $instance->_register_rpc_routes() |
|
378 | - ) |
|
379 | - ); |
|
380 | - update_option(EED_Core_Rest_Api::saved_routes_option_names, $routes, true); |
|
381 | - } |
|
382 | - } |
|
383 | - |
|
384 | - |
|
385 | - /** |
|
386 | - * Gets all the route information relating to EE models |
|
387 | - * |
|
388 | - * @return array @see get_ee_route_data |
|
389 | - * @deprecated since version 4.9.1 |
|
390 | - */ |
|
391 | - protected function _register_model_routes() |
|
392 | - { |
|
393 | - $model_routes = []; |
|
394 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
395 | - $model_routes[ EED_Core_Rest_Api::ee_api_namespace |
|
396 | - . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
397 | - } |
|
398 | - return $model_routes; |
|
399 | - } |
|
400 | - |
|
401 | - |
|
402 | - /** |
|
403 | - * Decides whether or not to add write endpoints for this model. |
|
404 | - * Currently, this defaults to exclude all global tables and models |
|
405 | - * which would allow inserting WP core data (we don't want to duplicate |
|
406 | - * what WP API does, as it's unnecessary, extra work, and potentially extra bugs) |
|
407 | - * |
|
408 | - * @param EEM_Base $model |
|
409 | - * @return bool |
|
410 | - */ |
|
411 | - public static function should_have_write_endpoints(EEM_Base $model) |
|
412 | - { |
|
413 | - if ($model->is_wp_core_model()) { |
|
414 | - return false; |
|
415 | - } |
|
416 | - foreach ($model->get_tables() as $table) { |
|
417 | - if ($table->is_global()) { |
|
418 | - return false; |
|
419 | - } |
|
420 | - } |
|
421 | - return true; |
|
422 | - } |
|
423 | - |
|
424 | - |
|
425 | - /** |
|
426 | - * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`) |
|
427 | - * in this versioned namespace of EE4 |
|
428 | - * |
|
429 | - * @param $version |
|
430 | - * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event') |
|
431 | - */ |
|
432 | - public static function model_names_with_plural_routes($version) |
|
433 | - { |
|
434 | - $model_version_info = new ModelVersionInfo($version); |
|
435 | - $models_to_register = $model_version_info->modelsForRequestedVersion(); |
|
436 | - // let's not bother having endpoints for extra metas |
|
437 | - unset( |
|
438 | - $models_to_register['Extra_Meta'], |
|
439 | - $models_to_register['Extra_Join'], |
|
440 | - $models_to_register['Post_Meta'] |
|
441 | - ); |
|
442 | - return apply_filters( |
|
443 | - 'FHEE__EED_Core_REST_API___register_model_routes', |
|
444 | - $models_to_register |
|
445 | - ); |
|
446 | - } |
|
447 | - |
|
448 | - |
|
449 | - /** |
|
450 | - * Gets the route data for EE models in the specified version |
|
451 | - * |
|
452 | - * @param string $version |
|
453 | - * @param boolean $hidden_endpoint |
|
454 | - * @return array |
|
455 | - * @throws EE_Error |
|
456 | - * @throws ReflectionException |
|
457 | - */ |
|
458 | - protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
459 | - { |
|
460 | - $model_routes = []; |
|
461 | - $model_version_info = new ModelVersionInfo($version); |
|
462 | - foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) { |
|
463 | - $model = EE_Registry::instance()->load_model($model_name); |
|
464 | - // if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
465 | - if (! $model instanceof EEM_Base) { |
|
466 | - continue; |
|
467 | - } |
|
468 | - // yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
469 | - $plural_model_route = EED_Core_Rest_Api::get_collection_route($model); |
|
470 | - $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)'); |
|
471 | - $model_routes[ $plural_model_route ] = [ |
|
472 | - [ |
|
473 | - 'callback' => [ |
|
474 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
475 | - 'handleRequestGetAll', |
|
476 | - ], |
|
477 | - 'callback_args' => [$version, $model_name], |
|
478 | - 'methods' => WP_REST_Server::READABLE, |
|
479 | - 'hidden_endpoint' => $hidden_endpoint, |
|
480 | - 'args' => $this->_get_read_query_params($model, $version), |
|
481 | - '_links' => [ |
|
482 | - 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
483 | - ], |
|
484 | - ], |
|
485 | - 'schema' => [ |
|
486 | - 'schema_callback' => [ |
|
487 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
488 | - 'handleSchemaRequest', |
|
489 | - ], |
|
490 | - 'callback_args' => [$version, $model_name], |
|
491 | - ], |
|
492 | - ]; |
|
493 | - $model_routes[ $singular_model_route ] = [ |
|
494 | - [ |
|
495 | - 'callback' => [ |
|
496 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
497 | - 'handleRequestGetOne', |
|
498 | - ], |
|
499 | - 'callback_args' => [$version, $model_name], |
|
500 | - 'methods' => WP_REST_Server::READABLE, |
|
501 | - 'hidden_endpoint' => $hidden_endpoint, |
|
502 | - 'args' => $this->_get_response_selection_query_params($model, $version, true), |
|
503 | - ], |
|
504 | - ]; |
|
505 | - if ( |
|
506 | - apply_filters( |
|
507 | - 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints', |
|
508 | - EED_Core_Rest_Api::should_have_write_endpoints($model), |
|
509 | - $model |
|
510 | - ) |
|
511 | - ) { |
|
512 | - $model_routes[ $plural_model_route ][] = [ |
|
513 | - 'callback' => [ |
|
514 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
515 | - 'handleRequestInsert', |
|
516 | - ], |
|
517 | - 'callback_args' => [$version, $model_name], |
|
518 | - 'methods' => WP_REST_Server::CREATABLE, |
|
519 | - 'hidden_endpoint' => $hidden_endpoint, |
|
520 | - 'args' => $this->_get_write_params($model_name, $model_version_info, true), |
|
521 | - ]; |
|
522 | - $model_routes[ $singular_model_route ] = array_merge( |
|
523 | - $model_routes[ $singular_model_route ], |
|
524 | - [ |
|
525 | - [ |
|
526 | - 'callback' => [ |
|
527 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
528 | - 'handleRequestUpdate', |
|
529 | - ], |
|
530 | - 'callback_args' => [$version, $model_name], |
|
531 | - 'methods' => WP_REST_Server::EDITABLE, |
|
532 | - 'hidden_endpoint' => $hidden_endpoint, |
|
533 | - 'args' => $this->_get_write_params($model_name, $model_version_info), |
|
534 | - ], |
|
535 | - [ |
|
536 | - 'callback' => [ |
|
537 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
538 | - 'handleRequestDelete', |
|
539 | - ], |
|
540 | - 'callback_args' => [$version, $model_name], |
|
541 | - 'methods' => WP_REST_Server::DELETABLE, |
|
542 | - 'hidden_endpoint' => $hidden_endpoint, |
|
543 | - 'args' => $this->_get_delete_query_params($model, $version), |
|
544 | - ], |
|
545 | - ] |
|
546 | - ); |
|
547 | - } |
|
548 | - foreach ($model->relation_settings() as $relation_name => $relation_obj) { |
|
549 | - $related_route = EED_Core_Rest_Api::get_relation_route_via( |
|
550 | - $model, |
|
551 | - '(?P<id>[^\/]+)', |
|
552 | - $relation_obj |
|
553 | - ); |
|
554 | - $model_routes[ $related_route ] = [ |
|
555 | - [ |
|
556 | - 'callback' => [ |
|
557 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
558 | - 'handleRequestGetRelated', |
|
559 | - ], |
|
560 | - 'callback_args' => [$version, $model_name, $relation_name], |
|
561 | - 'methods' => WP_REST_Server::READABLE, |
|
562 | - 'hidden_endpoint' => $hidden_endpoint, |
|
563 | - 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
564 | - ], |
|
565 | - ]; |
|
566 | - |
|
567 | - $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)'; |
|
568 | - $model_routes[ $related_write_route ] = [ |
|
569 | - [ |
|
570 | - 'callback' => [ |
|
571 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
572 | - 'handleRequestAddRelation', |
|
573 | - ], |
|
574 | - 'callback_args' => [$version, $model_name, $relation_name], |
|
575 | - 'methods' => WP_REST_Server::EDITABLE, |
|
576 | - 'hidden_endpoint' => $hidden_endpoint, |
|
577 | - 'args' => $this->_get_add_relation_query_params( |
|
578 | - $model, |
|
579 | - $relation_obj->get_other_model(), |
|
580 | - $version |
|
581 | - ), |
|
582 | - ], |
|
583 | - [ |
|
584 | - 'callback' => [ |
|
585 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
586 | - 'handleRequestRemoveRelation', |
|
587 | - ], |
|
588 | - 'callback_args' => [$version, $model_name, $relation_name], |
|
589 | - 'methods' => WP_REST_Server::DELETABLE, |
|
590 | - 'hidden_endpoint' => $hidden_endpoint, |
|
591 | - 'args' => [], |
|
592 | - ], |
|
593 | - ]; |
|
594 | - } |
|
595 | - } |
|
596 | - return $model_routes; |
|
597 | - } |
|
598 | - |
|
599 | - |
|
600 | - /** |
|
601 | - * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace, |
|
602 | - * excluding the preceding slash. |
|
603 | - * Eg you pass get_plural_route_to('Event') = 'events' |
|
604 | - * |
|
605 | - * @param EEM_Base $model |
|
606 | - * @return string |
|
607 | - */ |
|
608 | - public static function get_collection_route(EEM_Base $model) |
|
609 | - { |
|
610 | - return EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
611 | - } |
|
612 | - |
|
613 | - |
|
614 | - /** |
|
615 | - * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
616 | - * excluding the preceding slash. |
|
617 | - * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
618 | - * |
|
619 | - * @param EEM_Base $model eg Event or Venue |
|
620 | - * @param string $id |
|
621 | - * @return string |
|
622 | - */ |
|
623 | - public static function get_entity_route($model, $id) |
|
624 | - { |
|
625 | - return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id; |
|
626 | - } |
|
627 | - |
|
628 | - |
|
629 | - /** |
|
630 | - * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
631 | - * excluding the preceding slash. |
|
632 | - * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
633 | - * |
|
634 | - * @param EEM_Base $model eg Event or Venue |
|
635 | - * @param string $id |
|
636 | - * @param EE_Model_Relation_Base $relation_obj |
|
637 | - * @return string |
|
638 | - */ |
|
639 | - public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj) |
|
640 | - { |
|
641 | - $related_model_name_endpoint_part = ModelRead::getRelatedEntityName( |
|
642 | - $relation_obj->get_other_model()->get_this_model_name(), |
|
643 | - $relation_obj |
|
644 | - ); |
|
645 | - return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part; |
|
646 | - } |
|
647 | - |
|
648 | - |
|
649 | - /** |
|
650 | - * Adds onto the $relative_route the EE4 REST API versioned namespace. |
|
651 | - * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events' |
|
652 | - * |
|
653 | - * @param string $relative_route |
|
654 | - * @param string $version |
|
655 | - * @return string |
|
656 | - */ |
|
657 | - public static function get_versioned_route_to($relative_route, $version = '4.8.36') |
|
658 | - { |
|
659 | - return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route; |
|
660 | - } |
|
661 | - |
|
662 | - |
|
663 | - /** |
|
664 | - * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
665 | - * routes that don't conform to the traditional REST CRUD-style). |
|
666 | - * |
|
667 | - * @deprecated since 4.9.1 |
|
668 | - */ |
|
669 | - protected function _register_rpc_routes() |
|
670 | - { |
|
671 | - $routes = []; |
|
672 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
673 | - $routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version( |
|
674 | - $version, |
|
675 | - $hidden_endpoint |
|
676 | - ); |
|
677 | - } |
|
678 | - return $routes; |
|
679 | - } |
|
680 | - |
|
681 | - |
|
682 | - /** |
|
683 | - * @param string $version |
|
684 | - * @param boolean $hidden_endpoint |
|
685 | - * @return array |
|
686 | - */ |
|
687 | - protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
688 | - { |
|
689 | - $this_versions_routes = []; |
|
690 | - // checkin endpoint |
|
691 | - $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = [ |
|
692 | - [ |
|
693 | - 'callback' => [ |
|
694 | - 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
695 | - 'handleRequestToggleCheckin', |
|
696 | - ], |
|
697 | - 'methods' => WP_REST_Server::CREATABLE, |
|
698 | - 'hidden_endpoint' => $hidden_endpoint, |
|
699 | - 'args' => [ |
|
700 | - 'force' => [ |
|
701 | - 'required' => false, |
|
702 | - 'default' => false, |
|
703 | - 'description' => esc_html__( |
|
704 | - // @codingStandardsIgnoreStart |
|
705 | - 'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
706 | - // @codingStandardsIgnoreEnd |
|
707 | - 'event_espresso' |
|
708 | - ), |
|
709 | - ], |
|
710 | - ], |
|
711 | - 'callback_args' => [$version], |
|
712 | - ], |
|
713 | - ]; |
|
714 | - return apply_filters( |
|
715 | - 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
716 | - $this_versions_routes, |
|
717 | - $version, |
|
718 | - $hidden_endpoint |
|
719 | - ); |
|
720 | - } |
|
721 | - |
|
722 | - |
|
723 | - /** |
|
724 | - * Gets the query params that can be used when request one or many |
|
725 | - * |
|
726 | - * @param EEM_Base $model |
|
727 | - * @param string $version |
|
728 | - * @return array |
|
729 | - */ |
|
730 | - protected function _get_response_selection_query_params(EEM_Base $model, $version, $single_only = false) |
|
731 | - { |
|
732 | - EED_Core_Rest_Api::loadCalculatedModelFields(); |
|
733 | - $query_params = [ |
|
734 | - 'include' => [ |
|
735 | - 'required' => false, |
|
736 | - 'default' => '*', |
|
737 | - 'type' => 'string', |
|
738 | - ], |
|
739 | - 'calculate' => [ |
|
740 | - 'required' => false, |
|
741 | - 'default' => '', |
|
742 | - 'enum' => EED_Core_Rest_Api::$_field_calculator->retrieveCalculatedFieldsForModel($model), |
|
743 | - 'type' => 'string', |
|
744 | - // because we accept a CSV list of the enumerated strings, WP core validation and sanitization |
|
745 | - // freaks out. We'll just validate this argument while handling the request |
|
746 | - 'validate_callback' => null, |
|
747 | - 'sanitize_callback' => null, |
|
748 | - ], |
|
749 | - 'password' => [ |
|
750 | - 'required' => false, |
|
751 | - 'default' => '', |
|
752 | - 'type' => 'string', |
|
753 | - ], |
|
754 | - ]; |
|
755 | - return apply_filters( |
|
756 | - 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
757 | - $query_params, |
|
758 | - $model, |
|
759 | - $version |
|
760 | - ); |
|
761 | - } |
|
762 | - |
|
763 | - |
|
764 | - /** |
|
765 | - * Gets the parameters acceptable for delete requests |
|
766 | - * |
|
767 | - * @param EEM_Base $model |
|
768 | - * @param string $version |
|
769 | - * @return array |
|
770 | - */ |
|
771 | - protected function _get_delete_query_params(EEM_Base $model, $version) |
|
772 | - { |
|
773 | - $params_for_delete = [ |
|
774 | - 'allow_blocking' => [ |
|
775 | - 'required' => false, |
|
776 | - 'default' => true, |
|
777 | - 'type' => 'boolean', |
|
778 | - ], |
|
779 | - ]; |
|
780 | - $params_for_delete['force'] = [ |
|
781 | - 'required' => false, |
|
782 | - 'default' => false, |
|
783 | - 'type' => 'boolean', |
|
784 | - ]; |
|
785 | - return apply_filters( |
|
786 | - 'FHEE__EED_Core_Rest_Api___get_delete_query_params', |
|
787 | - $params_for_delete, |
|
788 | - $model, |
|
789 | - $version |
|
790 | - ); |
|
791 | - } |
|
792 | - |
|
793 | - |
|
794 | - /** |
|
795 | - * @param EEM_Base $source_model |
|
796 | - * @param EEM_Base $related_model |
|
797 | - * @param $version |
|
798 | - * @return array |
|
799 | - * @throws EE_Error |
|
800 | - * @since $VID:$ |
|
801 | - */ |
|
802 | - protected function _get_add_relation_query_params(EEM_Base $source_model, EEM_Base $related_model, $version) |
|
803 | - { |
|
804 | - // if they're related through a HABTM relation, check for any non-FKs |
|
805 | - $all_relation_settings = $source_model->relation_settings(); |
|
806 | - $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ]; |
|
807 | - $params = []; |
|
808 | - if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) { |
|
809 | - foreach ($relation_settings->getNonKeyFields() as $field) { |
|
810 | - /* @var $field EE_Model_Field_Base */ |
|
811 | - $params[ $field->get_name() ] = [ |
|
812 | - 'required' => ! $field->is_nullable(), |
|
813 | - 'default' => ModelDataTranslator::prepareFieldValueForJson( |
|
814 | - $field, |
|
815 | - $field->get_default_value(), |
|
816 | - $version |
|
817 | - ), |
|
818 | - 'type' => $field->getSchemaType(), |
|
819 | - 'validate_callback' => null, |
|
820 | - 'sanitize_callback' => null, |
|
821 | - ]; |
|
822 | - } |
|
823 | - } |
|
824 | - return $params; |
|
825 | - } |
|
826 | - |
|
827 | - |
|
828 | - /** |
|
829 | - * Gets info about reading query params that are acceptable |
|
830 | - * |
|
831 | - * @param EEM_Base $model eg 'Event' or 'Venue' |
|
832 | - * @param string $version |
|
833 | - * @return array describing the args acceptable when querying this model |
|
834 | - * @throws EE_Error |
|
835 | - */ |
|
836 | - protected function _get_read_query_params(EEM_Base $model, $version) |
|
837 | - { |
|
838 | - $default_orderby = []; |
|
839 | - foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
840 | - $default_orderby[ $key_field->get_name() ] = 'ASC'; |
|
841 | - } |
|
842 | - return array_merge( |
|
843 | - $this->_get_response_selection_query_params($model, $version), |
|
844 | - [ |
|
845 | - 'where' => [ |
|
846 | - 'required' => false, |
|
847 | - 'default' => [], |
|
848 | - 'type' => 'object', |
|
849 | - // because we accept an almost infinite list of possible where conditions, WP |
|
850 | - // core validation and sanitization freaks out. We'll just validate this argument |
|
851 | - // while handling the request |
|
852 | - 'validate_callback' => null, |
|
853 | - 'sanitize_callback' => null, |
|
854 | - ], |
|
855 | - 'limit' => [ |
|
856 | - 'required' => false, |
|
857 | - 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
858 | - 'type' => [ |
|
859 | - 'array', |
|
860 | - 'string', |
|
861 | - 'integer', |
|
862 | - ], |
|
863 | - // because we accept a variety of types, WP core validation and sanitization |
|
864 | - // freaks out. We'll just validate this argument while handling the request |
|
865 | - 'validate_callback' => null, |
|
866 | - 'sanitize_callback' => null, |
|
867 | - ], |
|
868 | - 'order_by' => [ |
|
869 | - 'required' => false, |
|
870 | - 'default' => $default_orderby, |
|
871 | - 'type' => [ |
|
872 | - 'object', |
|
873 | - 'string', |
|
874 | - ],// because we accept a variety of types, WP core validation and sanitization |
|
875 | - // freaks out. We'll just validate this argument while handling the request |
|
876 | - 'validate_callback' => null, |
|
877 | - 'sanitize_callback' => null, |
|
878 | - ], |
|
879 | - 'group_by' => [ |
|
880 | - 'required' => false, |
|
881 | - 'default' => null, |
|
882 | - 'type' => [ |
|
883 | - 'object', |
|
884 | - 'string', |
|
885 | - ], |
|
886 | - // because we accept an almost infinite list of possible groupings, |
|
887 | - // WP core validation and sanitization |
|
888 | - // freaks out. We'll just validate this argument while handling the request |
|
889 | - 'validate_callback' => null, |
|
890 | - 'sanitize_callback' => null, |
|
891 | - ], |
|
892 | - 'having' => [ |
|
893 | - 'required' => false, |
|
894 | - 'default' => null, |
|
895 | - 'type' => 'object', |
|
896 | - // because we accept an almost infinite list of possible where conditions, WP |
|
897 | - // core validation and sanitization freaks out. We'll just validate this argument |
|
898 | - // while handling the request |
|
899 | - 'validate_callback' => null, |
|
900 | - 'sanitize_callback' => null, |
|
901 | - ], |
|
902 | - 'caps' => [ |
|
903 | - 'required' => false, |
|
904 | - 'default' => EEM_Base::caps_read, |
|
905 | - 'type' => 'string', |
|
906 | - 'enum' => [ |
|
907 | - EEM_Base::caps_read, |
|
908 | - EEM_Base::caps_read_admin, |
|
909 | - EEM_Base::caps_edit, |
|
910 | - EEM_Base::caps_delete, |
|
911 | - ], |
|
912 | - ], |
|
913 | - ] |
|
914 | - ); |
|
915 | - } |
|
916 | - |
|
917 | - |
|
918 | - /** |
|
919 | - * Gets parameter information for a model regarding writing data |
|
920 | - * |
|
921 | - * @param string $model_name |
|
922 | - * @param ModelVersionInfo $model_version_info |
|
923 | - * @param boolean $create whether this is for request to create (in |
|
924 | - * which case we need all required params) or |
|
925 | - * just to update (in which case we don't |
|
926 | - * need those on every request) |
|
927 | - * @return array |
|
928 | - * @throws EE_Error |
|
929 | - * @throws ReflectionException |
|
930 | - */ |
|
931 | - protected function _get_write_params( |
|
932 | - $model_name, |
|
933 | - ModelVersionInfo $model_version_info, |
|
934 | - $create = false |
|
935 | - ) { |
|
936 | - $model = EE_Registry::instance()->load_model($model_name); |
|
937 | - $fields = $model_version_info->fieldsOnModelInThisVersion($model); |
|
938 | - |
|
939 | - // we do our own validation and sanitization within the controller |
|
940 | - $sanitize_callback = function_exists('rest_validate_value_from_schema') |
|
941 | - ? ['EED_Core_Rest_Api', 'default_sanitize_callback'] |
|
942 | - : null; |
|
943 | - $args_info = []; |
|
944 | - foreach ($fields as $field_name => $field_obj) { |
|
945 | - if ($field_obj->is_auto_increment()) { |
|
946 | - // totally ignore auto increment IDs |
|
947 | - continue; |
|
948 | - } |
|
949 | - $arg_info = $field_obj->getSchema(); |
|
950 | - $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null; |
|
951 | - $arg_info['required'] = $required; |
|
952 | - // remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right? |
|
953 | - unset($arg_info['readonly']); |
|
954 | - $schema_properties = $field_obj->getSchemaProperties(); |
|
955 | - if ( |
|
956 | - isset($schema_properties['raw']) |
|
957 | - && $field_obj->getSchemaType() === 'object' |
|
958 | - ) { |
|
959 | - // if there's a "raw" form of this argument, use those properties instead |
|
960 | - $arg_info = array_replace( |
|
961 | - $arg_info, |
|
962 | - $schema_properties['raw'] |
|
963 | - ); |
|
964 | - } |
|
965 | - $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson( |
|
966 | - $field_obj, |
|
967 | - $field_obj->get_default_value(), |
|
968 | - $model_version_info->requestedVersion() |
|
969 | - ); |
|
970 | - $arg_info['sanitize_callback'] = $sanitize_callback; |
|
971 | - $args_info[ $field_name ] = $arg_info; |
|
972 | - if ($field_obj instanceof EE_Datetime_Field) { |
|
973 | - $gmt_arg_info = $arg_info; |
|
974 | - $gmt_arg_info['description'] = sprintf( |
|
975 | - esc_html__( |
|
976 | - '%1$s - the value for this field in UTC. Ignored if %2$s is provided.', |
|
977 | - 'event_espresso' |
|
978 | - ), |
|
979 | - $field_obj->get_nicename(), |
|
980 | - $field_name |
|
981 | - ); |
|
982 | - $args_info[ $field_name . '_gmt' ] = $gmt_arg_info; |
|
983 | - } |
|
984 | - } |
|
985 | - return $args_info; |
|
986 | - } |
|
987 | - |
|
988 | - |
|
989 | - /** |
|
990 | - * Replacement for WP API's 'rest_parse_request_arg'. |
|
991 | - * If the value is blank but not required, don't bother validating it. |
|
992 | - * Also, it uses our email validation instead of WP API's default. |
|
993 | - * |
|
994 | - * @param $value |
|
995 | - * @param WP_REST_Request $request |
|
996 | - * @param $param |
|
997 | - * @return bool|true|WP_Error |
|
998 | - * @throws InvalidArgumentException |
|
999 | - * @throws InvalidInterfaceException |
|
1000 | - * @throws InvalidDataTypeException |
|
1001 | - */ |
|
1002 | - public static function default_sanitize_callback($value, WP_REST_Request $request, $param) |
|
1003 | - { |
|
1004 | - $attributes = $request->get_attributes(); |
|
1005 | - if ( |
|
1006 | - ! isset($attributes['args'][ $param ]) |
|
1007 | - || ! is_array($attributes['args'][ $param ]) |
|
1008 | - ) { |
|
1009 | - $validation_result = true; |
|
1010 | - } else { |
|
1011 | - $args = $attributes['args'][ $param ]; |
|
1012 | - if ( |
|
1013 | - ( |
|
1014 | - $value === '' |
|
1015 | - || $value === null |
|
1016 | - ) |
|
1017 | - && (! isset($args['required']) |
|
1018 | - || $args['required'] === false |
|
1019 | - ) |
|
1020 | - ) { |
|
1021 | - // not required and not provided? that's cool |
|
1022 | - $validation_result = true; |
|
1023 | - } elseif ( |
|
1024 | - isset($args['format']) |
|
1025 | - && $args['format'] === 'email' |
|
1026 | - ) { |
|
1027 | - $validation_result = true; |
|
1028 | - if (! EED_Core_Rest_Api::_validate_email($value)) { |
|
1029 | - $validation_result = new WP_Error( |
|
1030 | - 'rest_invalid_param', |
|
1031 | - esc_html__( |
|
1032 | - 'The email address is not valid or does not exist.', |
|
1033 | - 'event_espresso' |
|
1034 | - ) |
|
1035 | - ); |
|
1036 | - } |
|
1037 | - } else { |
|
1038 | - $validation_result = rest_validate_value_from_schema($value, $args, $param); |
|
1039 | - } |
|
1040 | - } |
|
1041 | - if (is_wp_error($validation_result)) { |
|
1042 | - return $validation_result; |
|
1043 | - } |
|
1044 | - return rest_sanitize_request_arg($value, $request, $param); |
|
1045 | - } |
|
1046 | - |
|
1047 | - |
|
1048 | - /** |
|
1049 | - * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email() |
|
1050 | - * |
|
1051 | - * @param $email |
|
1052 | - * @return bool |
|
1053 | - * @throws InvalidArgumentException |
|
1054 | - * @throws InvalidInterfaceException |
|
1055 | - * @throws InvalidDataTypeException |
|
1056 | - */ |
|
1057 | - protected static function _validate_email($email) |
|
1058 | - { |
|
1059 | - try { |
|
1060 | - EmailAddressFactory::create($email); |
|
1061 | - return true; |
|
1062 | - } catch (EmailValidationException $e) { |
|
1063 | - return false; |
|
1064 | - } |
|
1065 | - } |
|
1066 | - |
|
1067 | - |
|
1068 | - /** |
|
1069 | - * Gets routes for the config |
|
1070 | - * |
|
1071 | - * @return array @see _register_model_routes |
|
1072 | - * @deprecated since version 4.9.1 |
|
1073 | - */ |
|
1074 | - protected function _register_config_routes() |
|
1075 | - { |
|
1076 | - $config_routes = []; |
|
1077 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1078 | - $config_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version( |
|
1079 | - $version, |
|
1080 | - $hidden_endpoint |
|
1081 | - ); |
|
1082 | - } |
|
1083 | - return $config_routes; |
|
1084 | - } |
|
1085 | - |
|
1086 | - |
|
1087 | - /** |
|
1088 | - * Gets routes for the config for the specified version |
|
1089 | - * |
|
1090 | - * @param string $version |
|
1091 | - * @param boolean $hidden_endpoint |
|
1092 | - * @return array |
|
1093 | - */ |
|
1094 | - protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
1095 | - { |
|
1096 | - return [ |
|
1097 | - 'config' => [ |
|
1098 | - [ |
|
1099 | - 'callback' => [ |
|
1100 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1101 | - 'handleRequest', |
|
1102 | - ], |
|
1103 | - 'methods' => WP_REST_Server::READABLE, |
|
1104 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1105 | - 'callback_args' => [$version], |
|
1106 | - ], |
|
1107 | - ], |
|
1108 | - 'site_info' => [ |
|
1109 | - [ |
|
1110 | - 'callback' => [ |
|
1111 | - 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1112 | - 'handleRequestSiteInfo', |
|
1113 | - ], |
|
1114 | - 'methods' => WP_REST_Server::READABLE, |
|
1115 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1116 | - 'callback_args' => [$version], |
|
1117 | - ], |
|
1118 | - ], |
|
1119 | - ]; |
|
1120 | - } |
|
1121 | - |
|
1122 | - |
|
1123 | - /** |
|
1124 | - * Gets the meta info routes |
|
1125 | - * |
|
1126 | - * @return array @see _register_model_routes |
|
1127 | - * @deprecated since version 4.9.1 |
|
1128 | - */ |
|
1129 | - protected function _register_meta_routes() |
|
1130 | - { |
|
1131 | - $meta_routes = []; |
|
1132 | - foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1133 | - $meta_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version( |
|
1134 | - $version, |
|
1135 | - $hidden_endpoint |
|
1136 | - ); |
|
1137 | - } |
|
1138 | - return $meta_routes; |
|
1139 | - } |
|
1140 | - |
|
1141 | - |
|
1142 | - /** |
|
1143 | - * @param string $version |
|
1144 | - * @param boolean $hidden_endpoint |
|
1145 | - * @return array |
|
1146 | - */ |
|
1147 | - protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
1148 | - { |
|
1149 | - return [ |
|
1150 | - 'resources' => [ |
|
1151 | - [ |
|
1152 | - 'callback' => [ |
|
1153 | - 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
1154 | - 'handleRequestModelsMeta', |
|
1155 | - ], |
|
1156 | - 'methods' => WP_REST_Server::READABLE, |
|
1157 | - 'hidden_endpoint' => $hidden_endpoint, |
|
1158 | - 'callback_args' => [$version], |
|
1159 | - ], |
|
1160 | - ], |
|
1161 | - ]; |
|
1162 | - } |
|
1163 | - |
|
1164 | - |
|
1165 | - /** |
|
1166 | - * Tries to hide old 4.6 endpoints from the |
|
1167 | - * |
|
1168 | - * @param array $route_data |
|
1169 | - * @return array |
|
1170 | - * @throws EE_Error |
|
1171 | - * @throws ReflectionException |
|
1172 | - */ |
|
1173 | - public static function hide_old_endpoints($route_data) |
|
1174 | - { |
|
1175 | - // allow API clients to override which endpoints get hidden, in case |
|
1176 | - // they want to discover particular endpoints |
|
1177 | - // also, we don't have access to the request so we have to just grab it from the superglobal |
|
1178 | - $force_show_ee_namespace = ltrim( |
|
1179 | - EED_Core_Rest_Api::getRequest()->getRequestParam('force_show_ee_namespace'), |
|
1180 | - '/' |
|
1181 | - ); |
|
1182 | - foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
1183 | - foreach ($relative_urls as $resource_name => $endpoints) { |
|
1184 | - foreach ($endpoints as $key => $endpoint) { |
|
1185 | - // skip schema and other route options |
|
1186 | - if (! is_numeric($key)) { |
|
1187 | - continue; |
|
1188 | - } |
|
1189 | - // by default, hide "hidden_endpoint"s, unless the request indicates |
|
1190 | - // to $force_show_ee_namespace, in which case only show that one |
|
1191 | - // namespace's endpoints (and hide all others) |
|
1192 | - if ( |
|
1193 | - ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
1194 | - || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
1195 | - ) { |
|
1196 | - $full_route = '/' . ltrim($namespace, '/'); |
|
1197 | - $full_route .= '/' . ltrim($resource_name, '/'); |
|
1198 | - unset($route_data[ $full_route ]); |
|
1199 | - } |
|
1200 | - } |
|
1201 | - } |
|
1202 | - } |
|
1203 | - return $route_data; |
|
1204 | - } |
|
1205 | - |
|
1206 | - |
|
1207 | - /** |
|
1208 | - * Returns an array describing which versions of core support serving requests for. |
|
1209 | - * Keys are core versions' major and minor version, and values are the |
|
1210 | - * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
1211 | - * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
1212 | - * the answers table entirely, in which case it would be very difficult for |
|
1213 | - * it to serve 4.6-style responses. |
|
1214 | - * Versions of core that are missing from this array are unknowns. |
|
1215 | - * previous ver |
|
1216 | - * |
|
1217 | - * @return array |
|
1218 | - */ |
|
1219 | - public static function version_compatibilities() |
|
1220 | - { |
|
1221 | - return apply_filters( |
|
1222 | - 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
1223 | - [ |
|
1224 | - '4.8.29' => '4.8.29', |
|
1225 | - '4.8.33' => '4.8.29', |
|
1226 | - '4.8.34' => '4.8.29', |
|
1227 | - '4.8.36' => '4.8.29', |
|
1228 | - ] |
|
1229 | - ); |
|
1230 | - } |
|
1231 | - |
|
1232 | - |
|
1233 | - /** |
|
1234 | - * Gets the latest API version served. Eg if there |
|
1235 | - * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
1236 | - * we are on core version 4.8.34, it will return the string "4.8.32" |
|
1237 | - * |
|
1238 | - * @return string |
|
1239 | - */ |
|
1240 | - public static function latest_rest_api_version() |
|
1241 | - { |
|
1242 | - $versions_served = EED_Core_Rest_Api::versions_served(); |
|
1243 | - $versions_served_keys = array_keys($versions_served); |
|
1244 | - return end($versions_served_keys); |
|
1245 | - } |
|
1246 | - |
|
1247 | - |
|
1248 | - /** |
|
1249 | - * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
1250 | - * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
1251 | - * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
1252 | - * We also indicate whether or not this version should be put in the index or not |
|
1253 | - * |
|
1254 | - * @return array keys are API version numbers (just major and minor numbers), and values |
|
1255 | - * are whether or not they should be hidden |
|
1256 | - */ |
|
1257 | - public static function versions_served() |
|
1258 | - { |
|
1259 | - $versions_served = []; |
|
1260 | - $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
1261 | - $lowest_compatible_version = end($possibly_served_versions); |
|
1262 | - reset($possibly_served_versions); |
|
1263 | - $versions_served_historically = array_keys($possibly_served_versions); |
|
1264 | - $latest_version = end($versions_served_historically); |
|
1265 | - reset($versions_served_historically); |
|
1266 | - // for each version of core we have ever served: |
|
1267 | - foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
1268 | - // if it's not above the current core version, and it's compatible with the current version of core |
|
1269 | - |
|
1270 | - if ($key_versioned_endpoint === $latest_version) { |
|
1271 | - // don't hide the latest version in the index |
|
1272 | - $versions_served[ $key_versioned_endpoint ] = false; |
|
1273 | - } elseif ( |
|
1274 | - version_compare($key_versioned_endpoint, $lowest_compatible_version, '>=') |
|
1275 | - && version_compare($key_versioned_endpoint, EED_Core_Rest_Api::core_version(), '<') |
|
1276 | - ) { |
|
1277 | - // include, but hide, previous versions which are still supported |
|
1278 | - $versions_served[ $key_versioned_endpoint ] = true; |
|
1279 | - } elseif ( |
|
1280 | - apply_filters( |
|
1281 | - 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
1282 | - false, |
|
1283 | - $possibly_served_versions |
|
1284 | - ) |
|
1285 | - ) { |
|
1286 | - // if a version is no longer supported, don't include it in index or list of versions served |
|
1287 | - $versions_served[ $key_versioned_endpoint ] = true; |
|
1288 | - } |
|
1289 | - } |
|
1290 | - return $versions_served; |
|
1291 | - } |
|
1292 | - |
|
1293 | - |
|
1294 | - /** |
|
1295 | - * Gets the major and minor version of EE core's version string |
|
1296 | - * |
|
1297 | - * @return string |
|
1298 | - */ |
|
1299 | - public static function core_version() |
|
1300 | - { |
|
1301 | - return apply_filters( |
|
1302 | - 'FHEE__EED_Core_REST_API__core_version', |
|
1303 | - implode( |
|
1304 | - '.', |
|
1305 | - array_slice( |
|
1306 | - explode( |
|
1307 | - '.', |
|
1308 | - espresso_version() |
|
1309 | - ), |
|
1310 | - 0, |
|
1311 | - 3 |
|
1312 | - ) |
|
1313 | - ) |
|
1314 | - ); |
|
1315 | - } |
|
1316 | - |
|
1317 | - |
|
1318 | - /** |
|
1319 | - * Gets the default limit that should be used when querying for resources |
|
1320 | - * |
|
1321 | - * @return int |
|
1322 | - */ |
|
1323 | - public static function get_default_query_limit() |
|
1324 | - { |
|
1325 | - // we actually don't use a const because we want folks to always use |
|
1326 | - // this method, not the const directly |
|
1327 | - return apply_filters( |
|
1328 | - 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
1329 | - 50 |
|
1330 | - ); |
|
1331 | - } |
|
1332 | - |
|
1333 | - |
|
1334 | - /** |
|
1335 | - * @param string $version api version string (i.e. '4.8.36') |
|
1336 | - * @return array |
|
1337 | - */ |
|
1338 | - public static function getCollectionRoutesIndexedByModelName($version = '') |
|
1339 | - { |
|
1340 | - $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1341 | - $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1342 | - $collection_routes = []; |
|
1343 | - foreach ($model_names as $model_name => $model_class_name) { |
|
1344 | - $collection_routes[ strtolower($model_name) ] = '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' |
|
1345 | - . EEH_Inflector::pluralize_and_lower($model_name); |
|
1346 | - } |
|
1347 | - return $collection_routes; |
|
1348 | - } |
|
1349 | - |
|
1350 | - |
|
1351 | - /** |
|
1352 | - * Returns an array of primary key names indexed by model names. |
|
1353 | - * |
|
1354 | - * @param string $version |
|
1355 | - * @return array |
|
1356 | - */ |
|
1357 | - public static function getPrimaryKeyNamesIndexedByModelName($version = '') |
|
1358 | - { |
|
1359 | - $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1360 | - $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1361 | - $primary_key_items = []; |
|
1362 | - foreach ($model_names as $model_name => $model_class_name) { |
|
1363 | - $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields(); |
|
1364 | - foreach ($primary_keys as $primary_key_name => $primary_key_field) { |
|
1365 | - if (count($primary_keys) > 1) { |
|
1366 | - $primary_key_items[ strtolower($model_name) ][] = $primary_key_name; |
|
1367 | - } else { |
|
1368 | - $primary_key_items[ strtolower($model_name) ] = $primary_key_name; |
|
1369 | - } |
|
1370 | - } |
|
1371 | - } |
|
1372 | - return $primary_key_items; |
|
1373 | - } |
|
1374 | - |
|
1375 | - |
|
1376 | - /** |
|
1377 | - * Determines the EE REST API debug mode is activated, or not. |
|
1378 | - * |
|
1379 | - * @return bool |
|
1380 | - * @since 4.9.76.p |
|
1381 | - */ |
|
1382 | - public static function debugMode() |
|
1383 | - { |
|
1384 | - static $debug_mode = null; // could be class prop |
|
1385 | - if ($debug_mode === null) { |
|
1386 | - $debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE; |
|
1387 | - } |
|
1388 | - return $debug_mode; |
|
1389 | - } |
|
1390 | - |
|
1391 | - |
|
1392 | - /** |
|
1393 | - * run - initial module setup |
|
1394 | - * |
|
1395 | - * @access public |
|
1396 | - * @param WP $WP |
|
1397 | - * @return void |
|
1398 | - */ |
|
1399 | - public function run($WP) |
|
1400 | - { |
|
1401 | - } |
|
24 | + const ee_api_namespace = Domain::API_NAMESPACE; |
|
25 | + |
|
26 | + const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/'; |
|
27 | + |
|
28 | + const saved_routes_option_names = 'ee_core_routes'; |
|
29 | + |
|
30 | + /** |
|
31 | + * string used in _links response bodies to make them globally unique. |
|
32 | + * |
|
33 | + * @see http://v2.wp-api.org/extending/linking/ |
|
34 | + */ |
|
35 | + const ee_api_link_namespace = 'https://api.eventespresso.com/'; |
|
36 | + |
|
37 | + /** |
|
38 | + * @var CalculatedModelFields |
|
39 | + */ |
|
40 | + protected static $_field_calculator; |
|
41 | + |
|
42 | + |
|
43 | + /** |
|
44 | + * @return EED_Core_Rest_Api|EED_Module |
|
45 | + */ |
|
46 | + public static function instance() |
|
47 | + { |
|
48 | + return parent::get_instance(EED_Core_Rest_Api::class); |
|
49 | + } |
|
50 | + |
|
51 | + |
|
52 | + /** |
|
53 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
54 | + * |
|
55 | + * @access public |
|
56 | + * @return void |
|
57 | + */ |
|
58 | + public static function set_hooks() |
|
59 | + { |
|
60 | + } |
|
61 | + |
|
62 | + |
|
63 | + /** |
|
64 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
65 | + * |
|
66 | + * @access public |
|
67 | + * @return void |
|
68 | + */ |
|
69 | + public static function set_hooks_admin() |
|
70 | + { |
|
71 | + } |
|
72 | + |
|
73 | + |
|
74 | + public static function set_hooks_both() |
|
75 | + { |
|
76 | + add_action('rest_api_init', ['EED_Core_Rest_Api', 'set_hooks_rest_api'], 5); |
|
77 | + add_action('rest_api_init', ['EED_Core_Rest_Api', 'register_routes'], 10); |
|
78 | + add_filter('rest_route_data', ['EED_Core_Rest_Api', 'hide_old_endpoints'], 10, 2); |
|
79 | + add_filter( |
|
80 | + 'rest_index', |
|
81 | + ['EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'] |
|
82 | + ); |
|
83 | + } |
|
84 | + |
|
85 | + |
|
86 | + /** |
|
87 | + * @since $VID:$ |
|
88 | + */ |
|
89 | + public static function loadCalculatedModelFields() |
|
90 | + { |
|
91 | + EED_Core_Rest_Api::$_field_calculator = LoaderFactory::getLoader()->load( |
|
92 | + 'EventEspresso\core\libraries\rest_api\CalculatedModelFields' |
|
93 | + ); |
|
94 | + EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change(); |
|
95 | + } |
|
96 | + |
|
97 | + |
|
98 | + /** |
|
99 | + * sets up hooks which only need to be included as part of REST API requests; |
|
100 | + * other requests like to the frontend or admin etc don't need them |
|
101 | + * |
|
102 | + * @throws EE_Error |
|
103 | + */ |
|
104 | + public static function set_hooks_rest_api() |
|
105 | + { |
|
106 | + // set hooks which account for changes made to the API |
|
107 | + EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
108 | + } |
|
109 | + |
|
110 | + |
|
111 | + /** |
|
112 | + * public wrapper of _set_hooks_for_changes. |
|
113 | + * Loads all the hooks which make requests to old versions of the API |
|
114 | + * appear the same as they always did |
|
115 | + * |
|
116 | + * @throws EE_Error |
|
117 | + */ |
|
118 | + public static function set_hooks_for_changes() |
|
119 | + { |
|
120 | + EED_Core_Rest_Api::_set_hooks_for_changes(); |
|
121 | + } |
|
122 | + |
|
123 | + |
|
124 | + /** |
|
125 | + * Loads all the hooks which make requests to old versions of the API |
|
126 | + * appear the same as they always did |
|
127 | + * |
|
128 | + * @throws EE_Error |
|
129 | + */ |
|
130 | + protected static function _set_hooks_for_changes() |
|
131 | + { |
|
132 | + $folder_contents = EEH_File::get_contents_of_folders([EE_LIBRARIES . 'rest_api/changes'], false); |
|
133 | + foreach ($folder_contents as $classname_in_namespace => $filepath) { |
|
134 | + // ignore the base parent class |
|
135 | + // and legacy named classes |
|
136 | + if ( |
|
137 | + $classname_in_namespace === 'ChangesInBase' |
|
138 | + || strpos($classname_in_namespace, 'Changes_In_') === 0 |
|
139 | + ) { |
|
140 | + continue; |
|
141 | + } |
|
142 | + $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace; |
|
143 | + if (class_exists($full_classname)) { |
|
144 | + $instance_of_class = new $full_classname(); |
|
145 | + if ($instance_of_class instanceof ChangesInBase) { |
|
146 | + $instance_of_class->setHooks(); |
|
147 | + } |
|
148 | + } |
|
149 | + } |
|
150 | + } |
|
151 | + |
|
152 | + |
|
153 | + /** |
|
154 | + * Filters the WP routes to add our EE-related ones. This takes a bit of time |
|
155 | + * so we actually prefer to only do it when an EE plugin is activated or upgraded |
|
156 | + * |
|
157 | + * @throws EE_Error |
|
158 | + * @throws ReflectionException |
|
159 | + */ |
|
160 | + public static function register_routes() |
|
161 | + { |
|
162 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) { |
|
163 | + foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) { |
|
164 | + /** |
|
165 | + * @var array $data_for_multiple_endpoints numerically indexed array |
|
166 | + * but can also contain route options like { |
|
167 | + * @type array $schema { |
|
168 | + * @type callable $schema_callback |
|
169 | + * @type array $callback_args arguments that will be passed to the callback, after the |
|
170 | + * WP_REST_Request of course |
|
171 | + * } |
|
172 | + * } |
|
173 | + */ |
|
174 | + // when registering routes, register all the endpoints' data at the same time |
|
175 | + $multiple_endpoint_args = []; |
|
176 | + foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) { |
|
177 | + /** |
|
178 | + * @var array $data_for_single_endpoint { |
|
179 | + * @type callable $callback |
|
180 | + * @type string methods |
|
181 | + * @type array args |
|
182 | + * @type array _links |
|
183 | + * @type array $callback_args arguments that will be passed to the callback, after the |
|
184 | + * WP_REST_Request of course |
|
185 | + * } |
|
186 | + */ |
|
187 | + // skip route options |
|
188 | + if (! is_numeric($endpoint_key)) { |
|
189 | + continue; |
|
190 | + } |
|
191 | + if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) { |
|
192 | + throw new EE_Error( |
|
193 | + esc_html__( |
|
194 | + // @codingStandardsIgnoreStart |
|
195 | + 'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).', |
|
196 | + // @codingStandardsIgnoreEnd |
|
197 | + 'event_espresso' |
|
198 | + ) |
|
199 | + ); |
|
200 | + } |
|
201 | + $callback = $data_for_single_endpoint['callback']; |
|
202 | + $single_endpoint_args = [ |
|
203 | + 'methods' => $data_for_single_endpoint['methods'], |
|
204 | + 'args' => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args'] |
|
205 | + : [], |
|
206 | + ]; |
|
207 | + if (isset($data_for_single_endpoint['_links'])) { |
|
208 | + $single_endpoint_args['_links'] = $data_for_single_endpoint['_links']; |
|
209 | + } |
|
210 | + if (isset($data_for_single_endpoint['callback_args'])) { |
|
211 | + $callback_args = $data_for_single_endpoint['callback_args']; |
|
212 | + $single_endpoint_args['callback'] = static function (WP_REST_Request $request) use ( |
|
213 | + $callback, |
|
214 | + $callback_args |
|
215 | + ) { |
|
216 | + array_unshift($callback_args, $request); |
|
217 | + return call_user_func_array( |
|
218 | + $callback, |
|
219 | + $callback_args |
|
220 | + ); |
|
221 | + }; |
|
222 | + } else { |
|
223 | + $single_endpoint_args['callback'] = $data_for_single_endpoint['callback']; |
|
224 | + } |
|
225 | + // As of WordPress 5.5, if a permission_callback is not provided, |
|
226 | + // the REST API will issue a _doing_it_wrong notice. |
|
227 | + // Since the EE REST API defers capabilities to the db model system, |
|
228 | + // we will just use the generic WP callback for public endpoints |
|
229 | + if (! isset($single_endpoint_args['permission_callback'])) { |
|
230 | + $single_endpoint_args['permission_callback'] = '__return_true'; |
|
231 | + } |
|
232 | + $multiple_endpoint_args[] = $single_endpoint_args; |
|
233 | + } |
|
234 | + if (isset($data_for_multiple_endpoints['schema'])) { |
|
235 | + $schema_route_data = $data_for_multiple_endpoints['schema']; |
|
236 | + $schema_callback = $schema_route_data['schema_callback']; |
|
237 | + $callback_args = $schema_route_data['callback_args']; |
|
238 | + $multiple_endpoint_args['schema'] = static function () use ($schema_callback, $callback_args) { |
|
239 | + return call_user_func_array( |
|
240 | + $schema_callback, |
|
241 | + $callback_args |
|
242 | + ); |
|
243 | + }; |
|
244 | + } |
|
245 | + register_rest_route( |
|
246 | + $namespace, |
|
247 | + $relative_route, |
|
248 | + $multiple_endpoint_args |
|
249 | + ); |
|
250 | + } |
|
251 | + } |
|
252 | + } |
|
253 | + |
|
254 | + |
|
255 | + /** |
|
256 | + * Checks if there was a version change or something that merits invalidating the cached |
|
257 | + * route data. If so, invalidates the cached route data so that it gets refreshed |
|
258 | + * next time the WP API is used |
|
259 | + */ |
|
260 | + public static function invalidate_cached_route_data_on_version_change() |
|
261 | + { |
|
262 | + if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) { |
|
263 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
264 | + } |
|
265 | + foreach (EE_Registry::instance()->addons as $addon) { |
|
266 | + if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) { |
|
267 | + EED_Core_Rest_Api::invalidate_cached_route_data(); |
|
268 | + } |
|
269 | + } |
|
270 | + } |
|
271 | + |
|
272 | + |
|
273 | + /** |
|
274 | + * Removes the cached route data so it will get refreshed next time the WP API is used |
|
275 | + */ |
|
276 | + public static function invalidate_cached_route_data() |
|
277 | + { |
|
278 | + // delete the saved EE REST API routes |
|
279 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) { |
|
280 | + delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version); |
|
281 | + } |
|
282 | + } |
|
283 | + |
|
284 | + |
|
285 | + /** |
|
286 | + * Gets the EE route data |
|
287 | + * |
|
288 | + * @return array top-level key is the namespace, next-level key is the route and its value is array{ |
|
289 | + * @throws EE_Error |
|
290 | + * @throws ReflectionException |
|
291 | + * @type string|array $callback |
|
292 | + * @type string $methods |
|
293 | + * @type boolean $hidden_endpoint |
|
294 | + * } |
|
295 | + */ |
|
296 | + public static function get_ee_route_data() |
|
297 | + { |
|
298 | + $ee_routes = []; |
|
299 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoints) { |
|
300 | + $ee_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = EED_Core_Rest_Api::_get_ee_route_data_for_version( |
|
301 | + $version, |
|
302 | + $hidden_endpoints |
|
303 | + ); |
|
304 | + } |
|
305 | + return $ee_routes; |
|
306 | + } |
|
307 | + |
|
308 | + |
|
309 | + /** |
|
310 | + * Gets the EE route data from the wp options if it exists already, |
|
311 | + * otherwise re-generates it and saves it to the option |
|
312 | + * |
|
313 | + * @param string $version |
|
314 | + * @param boolean $hidden_endpoints |
|
315 | + * @return array |
|
316 | + * @throws EE_Error |
|
317 | + * @throws ReflectionException |
|
318 | + */ |
|
319 | + protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
320 | + { |
|
321 | + $ee_routes = get_option(EED_Core_Rest_Api::saved_routes_option_names . $version, null); |
|
322 | + if (! $ee_routes || EED_Core_Rest_Api::debugMode()) { |
|
323 | + $ee_routes = EED_Core_Rest_Api::_save_ee_route_data_for_version($version, $hidden_endpoints); |
|
324 | + } |
|
325 | + return $ee_routes; |
|
326 | + } |
|
327 | + |
|
328 | + |
|
329 | + /** |
|
330 | + * Saves the EE REST API route data to a wp option and returns it |
|
331 | + * |
|
332 | + * @param string $version |
|
333 | + * @param boolean $hidden_endpoints |
|
334 | + * @return mixed|null |
|
335 | + * @throws EE_Error |
|
336 | + * @throws ReflectionException |
|
337 | + */ |
|
338 | + protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false) |
|
339 | + { |
|
340 | + $instance = EED_Core_Rest_Api::instance(); |
|
341 | + $routes = apply_filters( |
|
342 | + 'EED_Core_Rest_Api__save_ee_route_data_for_version__routes', |
|
343 | + array_replace_recursive( |
|
344 | + $instance->_get_config_route_data_for_version($version, $hidden_endpoints), |
|
345 | + $instance->_get_meta_route_data_for_version($version, $hidden_endpoints), |
|
346 | + $instance->_get_model_route_data_for_version($version, $hidden_endpoints), |
|
347 | + $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints) |
|
348 | + ) |
|
349 | + ); |
|
350 | + $option_name = EED_Core_Rest_Api::saved_routes_option_names . $version; |
|
351 | + if (get_option($option_name)) { |
|
352 | + update_option($option_name, $routes, true); |
|
353 | + } else { |
|
354 | + add_option($option_name, $routes, null, 'no'); |
|
355 | + } |
|
356 | + return $routes; |
|
357 | + } |
|
358 | + |
|
359 | + |
|
360 | + /** |
|
361 | + * Calculates all the EE routes and saves it to a WordPress option so we don't |
|
362 | + * need to calculate it on every request |
|
363 | + * |
|
364 | + * @return void |
|
365 | + * @deprecated since version 4.9.1 |
|
366 | + */ |
|
367 | + public static function save_ee_routes() |
|
368 | + { |
|
369 | + if (EE_Maintenance_Mode::instance()->models_can_query()) { |
|
370 | + $instance = EED_Core_Rest_Api::instance(); |
|
371 | + $routes = apply_filters( |
|
372 | + 'EED_Core_Rest_Api__save_ee_routes__routes', |
|
373 | + array_replace_recursive( |
|
374 | + $instance->_register_config_routes(), |
|
375 | + $instance->_register_meta_routes(), |
|
376 | + $instance->_register_model_routes(), |
|
377 | + $instance->_register_rpc_routes() |
|
378 | + ) |
|
379 | + ); |
|
380 | + update_option(EED_Core_Rest_Api::saved_routes_option_names, $routes, true); |
|
381 | + } |
|
382 | + } |
|
383 | + |
|
384 | + |
|
385 | + /** |
|
386 | + * Gets all the route information relating to EE models |
|
387 | + * |
|
388 | + * @return array @see get_ee_route_data |
|
389 | + * @deprecated since version 4.9.1 |
|
390 | + */ |
|
391 | + protected function _register_model_routes() |
|
392 | + { |
|
393 | + $model_routes = []; |
|
394 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
395 | + $model_routes[ EED_Core_Rest_Api::ee_api_namespace |
|
396 | + . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint); |
|
397 | + } |
|
398 | + return $model_routes; |
|
399 | + } |
|
400 | + |
|
401 | + |
|
402 | + /** |
|
403 | + * Decides whether or not to add write endpoints for this model. |
|
404 | + * Currently, this defaults to exclude all global tables and models |
|
405 | + * which would allow inserting WP core data (we don't want to duplicate |
|
406 | + * what WP API does, as it's unnecessary, extra work, and potentially extra bugs) |
|
407 | + * |
|
408 | + * @param EEM_Base $model |
|
409 | + * @return bool |
|
410 | + */ |
|
411 | + public static function should_have_write_endpoints(EEM_Base $model) |
|
412 | + { |
|
413 | + if ($model->is_wp_core_model()) { |
|
414 | + return false; |
|
415 | + } |
|
416 | + foreach ($model->get_tables() as $table) { |
|
417 | + if ($table->is_global()) { |
|
418 | + return false; |
|
419 | + } |
|
420 | + } |
|
421 | + return true; |
|
422 | + } |
|
423 | + |
|
424 | + |
|
425 | + /** |
|
426 | + * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`) |
|
427 | + * in this versioned namespace of EE4 |
|
428 | + * |
|
429 | + * @param $version |
|
430 | + * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event') |
|
431 | + */ |
|
432 | + public static function model_names_with_plural_routes($version) |
|
433 | + { |
|
434 | + $model_version_info = new ModelVersionInfo($version); |
|
435 | + $models_to_register = $model_version_info->modelsForRequestedVersion(); |
|
436 | + // let's not bother having endpoints for extra metas |
|
437 | + unset( |
|
438 | + $models_to_register['Extra_Meta'], |
|
439 | + $models_to_register['Extra_Join'], |
|
440 | + $models_to_register['Post_Meta'] |
|
441 | + ); |
|
442 | + return apply_filters( |
|
443 | + 'FHEE__EED_Core_REST_API___register_model_routes', |
|
444 | + $models_to_register |
|
445 | + ); |
|
446 | + } |
|
447 | + |
|
448 | + |
|
449 | + /** |
|
450 | + * Gets the route data for EE models in the specified version |
|
451 | + * |
|
452 | + * @param string $version |
|
453 | + * @param boolean $hidden_endpoint |
|
454 | + * @return array |
|
455 | + * @throws EE_Error |
|
456 | + * @throws ReflectionException |
|
457 | + */ |
|
458 | + protected function _get_model_route_data_for_version($version, $hidden_endpoint = false) |
|
459 | + { |
|
460 | + $model_routes = []; |
|
461 | + $model_version_info = new ModelVersionInfo($version); |
|
462 | + foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) { |
|
463 | + $model = EE_Registry::instance()->load_model($model_name); |
|
464 | + // if this isn't a valid model then let's skip iterate to the next item in the loop. |
|
465 | + if (! $model instanceof EEM_Base) { |
|
466 | + continue; |
|
467 | + } |
|
468 | + // yes we could just register one route for ALL models, but then they wouldn't show up in the index |
|
469 | + $plural_model_route = EED_Core_Rest_Api::get_collection_route($model); |
|
470 | + $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)'); |
|
471 | + $model_routes[ $plural_model_route ] = [ |
|
472 | + [ |
|
473 | + 'callback' => [ |
|
474 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
475 | + 'handleRequestGetAll', |
|
476 | + ], |
|
477 | + 'callback_args' => [$version, $model_name], |
|
478 | + 'methods' => WP_REST_Server::READABLE, |
|
479 | + 'hidden_endpoint' => $hidden_endpoint, |
|
480 | + 'args' => $this->_get_read_query_params($model, $version), |
|
481 | + '_links' => [ |
|
482 | + 'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route), |
|
483 | + ], |
|
484 | + ], |
|
485 | + 'schema' => [ |
|
486 | + 'schema_callback' => [ |
|
487 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
488 | + 'handleSchemaRequest', |
|
489 | + ], |
|
490 | + 'callback_args' => [$version, $model_name], |
|
491 | + ], |
|
492 | + ]; |
|
493 | + $model_routes[ $singular_model_route ] = [ |
|
494 | + [ |
|
495 | + 'callback' => [ |
|
496 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
497 | + 'handleRequestGetOne', |
|
498 | + ], |
|
499 | + 'callback_args' => [$version, $model_name], |
|
500 | + 'methods' => WP_REST_Server::READABLE, |
|
501 | + 'hidden_endpoint' => $hidden_endpoint, |
|
502 | + 'args' => $this->_get_response_selection_query_params($model, $version, true), |
|
503 | + ], |
|
504 | + ]; |
|
505 | + if ( |
|
506 | + apply_filters( |
|
507 | + 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints', |
|
508 | + EED_Core_Rest_Api::should_have_write_endpoints($model), |
|
509 | + $model |
|
510 | + ) |
|
511 | + ) { |
|
512 | + $model_routes[ $plural_model_route ][] = [ |
|
513 | + 'callback' => [ |
|
514 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
515 | + 'handleRequestInsert', |
|
516 | + ], |
|
517 | + 'callback_args' => [$version, $model_name], |
|
518 | + 'methods' => WP_REST_Server::CREATABLE, |
|
519 | + 'hidden_endpoint' => $hidden_endpoint, |
|
520 | + 'args' => $this->_get_write_params($model_name, $model_version_info, true), |
|
521 | + ]; |
|
522 | + $model_routes[ $singular_model_route ] = array_merge( |
|
523 | + $model_routes[ $singular_model_route ], |
|
524 | + [ |
|
525 | + [ |
|
526 | + 'callback' => [ |
|
527 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
528 | + 'handleRequestUpdate', |
|
529 | + ], |
|
530 | + 'callback_args' => [$version, $model_name], |
|
531 | + 'methods' => WP_REST_Server::EDITABLE, |
|
532 | + 'hidden_endpoint' => $hidden_endpoint, |
|
533 | + 'args' => $this->_get_write_params($model_name, $model_version_info), |
|
534 | + ], |
|
535 | + [ |
|
536 | + 'callback' => [ |
|
537 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
538 | + 'handleRequestDelete', |
|
539 | + ], |
|
540 | + 'callback_args' => [$version, $model_name], |
|
541 | + 'methods' => WP_REST_Server::DELETABLE, |
|
542 | + 'hidden_endpoint' => $hidden_endpoint, |
|
543 | + 'args' => $this->_get_delete_query_params($model, $version), |
|
544 | + ], |
|
545 | + ] |
|
546 | + ); |
|
547 | + } |
|
548 | + foreach ($model->relation_settings() as $relation_name => $relation_obj) { |
|
549 | + $related_route = EED_Core_Rest_Api::get_relation_route_via( |
|
550 | + $model, |
|
551 | + '(?P<id>[^\/]+)', |
|
552 | + $relation_obj |
|
553 | + ); |
|
554 | + $model_routes[ $related_route ] = [ |
|
555 | + [ |
|
556 | + 'callback' => [ |
|
557 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Read', |
|
558 | + 'handleRequestGetRelated', |
|
559 | + ], |
|
560 | + 'callback_args' => [$version, $model_name, $relation_name], |
|
561 | + 'methods' => WP_REST_Server::READABLE, |
|
562 | + 'hidden_endpoint' => $hidden_endpoint, |
|
563 | + 'args' => $this->_get_read_query_params($relation_obj->get_other_model(), $version), |
|
564 | + ], |
|
565 | + ]; |
|
566 | + |
|
567 | + $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)'; |
|
568 | + $model_routes[ $related_write_route ] = [ |
|
569 | + [ |
|
570 | + 'callback' => [ |
|
571 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
572 | + 'handleRequestAddRelation', |
|
573 | + ], |
|
574 | + 'callback_args' => [$version, $model_name, $relation_name], |
|
575 | + 'methods' => WP_REST_Server::EDITABLE, |
|
576 | + 'hidden_endpoint' => $hidden_endpoint, |
|
577 | + 'args' => $this->_get_add_relation_query_params( |
|
578 | + $model, |
|
579 | + $relation_obj->get_other_model(), |
|
580 | + $version |
|
581 | + ), |
|
582 | + ], |
|
583 | + [ |
|
584 | + 'callback' => [ |
|
585 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Write', |
|
586 | + 'handleRequestRemoveRelation', |
|
587 | + ], |
|
588 | + 'callback_args' => [$version, $model_name, $relation_name], |
|
589 | + 'methods' => WP_REST_Server::DELETABLE, |
|
590 | + 'hidden_endpoint' => $hidden_endpoint, |
|
591 | + 'args' => [], |
|
592 | + ], |
|
593 | + ]; |
|
594 | + } |
|
595 | + } |
|
596 | + return $model_routes; |
|
597 | + } |
|
598 | + |
|
599 | + |
|
600 | + /** |
|
601 | + * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace, |
|
602 | + * excluding the preceding slash. |
|
603 | + * Eg you pass get_plural_route_to('Event') = 'events' |
|
604 | + * |
|
605 | + * @param EEM_Base $model |
|
606 | + * @return string |
|
607 | + */ |
|
608 | + public static function get_collection_route(EEM_Base $model) |
|
609 | + { |
|
610 | + return EEH_Inflector::pluralize_and_lower($model->get_this_model_name()); |
|
611 | + } |
|
612 | + |
|
613 | + |
|
614 | + /** |
|
615 | + * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
616 | + * excluding the preceding slash. |
|
617 | + * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
618 | + * |
|
619 | + * @param EEM_Base $model eg Event or Venue |
|
620 | + * @param string $id |
|
621 | + * @return string |
|
622 | + */ |
|
623 | + public static function get_entity_route($model, $id) |
|
624 | + { |
|
625 | + return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id; |
|
626 | + } |
|
627 | + |
|
628 | + |
|
629 | + /** |
|
630 | + * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace, |
|
631 | + * excluding the preceding slash. |
|
632 | + * Eg you pass get_plural_route_to('Event', 12) = 'events/12' |
|
633 | + * |
|
634 | + * @param EEM_Base $model eg Event or Venue |
|
635 | + * @param string $id |
|
636 | + * @param EE_Model_Relation_Base $relation_obj |
|
637 | + * @return string |
|
638 | + */ |
|
639 | + public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj) |
|
640 | + { |
|
641 | + $related_model_name_endpoint_part = ModelRead::getRelatedEntityName( |
|
642 | + $relation_obj->get_other_model()->get_this_model_name(), |
|
643 | + $relation_obj |
|
644 | + ); |
|
645 | + return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part; |
|
646 | + } |
|
647 | + |
|
648 | + |
|
649 | + /** |
|
650 | + * Adds onto the $relative_route the EE4 REST API versioned namespace. |
|
651 | + * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events' |
|
652 | + * |
|
653 | + * @param string $relative_route |
|
654 | + * @param string $version |
|
655 | + * @return string |
|
656 | + */ |
|
657 | + public static function get_versioned_route_to($relative_route, $version = '4.8.36') |
|
658 | + { |
|
659 | + return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route; |
|
660 | + } |
|
661 | + |
|
662 | + |
|
663 | + /** |
|
664 | + * Adds all the RPC-style routes (remote procedure call-like routes, ie |
|
665 | + * routes that don't conform to the traditional REST CRUD-style). |
|
666 | + * |
|
667 | + * @deprecated since 4.9.1 |
|
668 | + */ |
|
669 | + protected function _register_rpc_routes() |
|
670 | + { |
|
671 | + $routes = []; |
|
672 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
673 | + $routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version( |
|
674 | + $version, |
|
675 | + $hidden_endpoint |
|
676 | + ); |
|
677 | + } |
|
678 | + return $routes; |
|
679 | + } |
|
680 | + |
|
681 | + |
|
682 | + /** |
|
683 | + * @param string $version |
|
684 | + * @param boolean $hidden_endpoint |
|
685 | + * @return array |
|
686 | + */ |
|
687 | + protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false) |
|
688 | + { |
|
689 | + $this_versions_routes = []; |
|
690 | + // checkin endpoint |
|
691 | + $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = [ |
|
692 | + [ |
|
693 | + 'callback' => [ |
|
694 | + 'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin', |
|
695 | + 'handleRequestToggleCheckin', |
|
696 | + ], |
|
697 | + 'methods' => WP_REST_Server::CREATABLE, |
|
698 | + 'hidden_endpoint' => $hidden_endpoint, |
|
699 | + 'args' => [ |
|
700 | + 'force' => [ |
|
701 | + 'required' => false, |
|
702 | + 'default' => false, |
|
703 | + 'description' => esc_html__( |
|
704 | + // @codingStandardsIgnoreStart |
|
705 | + 'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses', |
|
706 | + // @codingStandardsIgnoreEnd |
|
707 | + 'event_espresso' |
|
708 | + ), |
|
709 | + ], |
|
710 | + ], |
|
711 | + 'callback_args' => [$version], |
|
712 | + ], |
|
713 | + ]; |
|
714 | + return apply_filters( |
|
715 | + 'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes', |
|
716 | + $this_versions_routes, |
|
717 | + $version, |
|
718 | + $hidden_endpoint |
|
719 | + ); |
|
720 | + } |
|
721 | + |
|
722 | + |
|
723 | + /** |
|
724 | + * Gets the query params that can be used when request one or many |
|
725 | + * |
|
726 | + * @param EEM_Base $model |
|
727 | + * @param string $version |
|
728 | + * @return array |
|
729 | + */ |
|
730 | + protected function _get_response_selection_query_params(EEM_Base $model, $version, $single_only = false) |
|
731 | + { |
|
732 | + EED_Core_Rest_Api::loadCalculatedModelFields(); |
|
733 | + $query_params = [ |
|
734 | + 'include' => [ |
|
735 | + 'required' => false, |
|
736 | + 'default' => '*', |
|
737 | + 'type' => 'string', |
|
738 | + ], |
|
739 | + 'calculate' => [ |
|
740 | + 'required' => false, |
|
741 | + 'default' => '', |
|
742 | + 'enum' => EED_Core_Rest_Api::$_field_calculator->retrieveCalculatedFieldsForModel($model), |
|
743 | + 'type' => 'string', |
|
744 | + // because we accept a CSV list of the enumerated strings, WP core validation and sanitization |
|
745 | + // freaks out. We'll just validate this argument while handling the request |
|
746 | + 'validate_callback' => null, |
|
747 | + 'sanitize_callback' => null, |
|
748 | + ], |
|
749 | + 'password' => [ |
|
750 | + 'required' => false, |
|
751 | + 'default' => '', |
|
752 | + 'type' => 'string', |
|
753 | + ], |
|
754 | + ]; |
|
755 | + return apply_filters( |
|
756 | + 'FHEE__EED_Core_Rest_Api___get_response_selection_query_params', |
|
757 | + $query_params, |
|
758 | + $model, |
|
759 | + $version |
|
760 | + ); |
|
761 | + } |
|
762 | + |
|
763 | + |
|
764 | + /** |
|
765 | + * Gets the parameters acceptable for delete requests |
|
766 | + * |
|
767 | + * @param EEM_Base $model |
|
768 | + * @param string $version |
|
769 | + * @return array |
|
770 | + */ |
|
771 | + protected function _get_delete_query_params(EEM_Base $model, $version) |
|
772 | + { |
|
773 | + $params_for_delete = [ |
|
774 | + 'allow_blocking' => [ |
|
775 | + 'required' => false, |
|
776 | + 'default' => true, |
|
777 | + 'type' => 'boolean', |
|
778 | + ], |
|
779 | + ]; |
|
780 | + $params_for_delete['force'] = [ |
|
781 | + 'required' => false, |
|
782 | + 'default' => false, |
|
783 | + 'type' => 'boolean', |
|
784 | + ]; |
|
785 | + return apply_filters( |
|
786 | + 'FHEE__EED_Core_Rest_Api___get_delete_query_params', |
|
787 | + $params_for_delete, |
|
788 | + $model, |
|
789 | + $version |
|
790 | + ); |
|
791 | + } |
|
792 | + |
|
793 | + |
|
794 | + /** |
|
795 | + * @param EEM_Base $source_model |
|
796 | + * @param EEM_Base $related_model |
|
797 | + * @param $version |
|
798 | + * @return array |
|
799 | + * @throws EE_Error |
|
800 | + * @since $VID:$ |
|
801 | + */ |
|
802 | + protected function _get_add_relation_query_params(EEM_Base $source_model, EEM_Base $related_model, $version) |
|
803 | + { |
|
804 | + // if they're related through a HABTM relation, check for any non-FKs |
|
805 | + $all_relation_settings = $source_model->relation_settings(); |
|
806 | + $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ]; |
|
807 | + $params = []; |
|
808 | + if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) { |
|
809 | + foreach ($relation_settings->getNonKeyFields() as $field) { |
|
810 | + /* @var $field EE_Model_Field_Base */ |
|
811 | + $params[ $field->get_name() ] = [ |
|
812 | + 'required' => ! $field->is_nullable(), |
|
813 | + 'default' => ModelDataTranslator::prepareFieldValueForJson( |
|
814 | + $field, |
|
815 | + $field->get_default_value(), |
|
816 | + $version |
|
817 | + ), |
|
818 | + 'type' => $field->getSchemaType(), |
|
819 | + 'validate_callback' => null, |
|
820 | + 'sanitize_callback' => null, |
|
821 | + ]; |
|
822 | + } |
|
823 | + } |
|
824 | + return $params; |
|
825 | + } |
|
826 | + |
|
827 | + |
|
828 | + /** |
|
829 | + * Gets info about reading query params that are acceptable |
|
830 | + * |
|
831 | + * @param EEM_Base $model eg 'Event' or 'Venue' |
|
832 | + * @param string $version |
|
833 | + * @return array describing the args acceptable when querying this model |
|
834 | + * @throws EE_Error |
|
835 | + */ |
|
836 | + protected function _get_read_query_params(EEM_Base $model, $version) |
|
837 | + { |
|
838 | + $default_orderby = []; |
|
839 | + foreach ($model->get_combined_primary_key_fields() as $key_field) { |
|
840 | + $default_orderby[ $key_field->get_name() ] = 'ASC'; |
|
841 | + } |
|
842 | + return array_merge( |
|
843 | + $this->_get_response_selection_query_params($model, $version), |
|
844 | + [ |
|
845 | + 'where' => [ |
|
846 | + 'required' => false, |
|
847 | + 'default' => [], |
|
848 | + 'type' => 'object', |
|
849 | + // because we accept an almost infinite list of possible where conditions, WP |
|
850 | + // core validation and sanitization freaks out. We'll just validate this argument |
|
851 | + // while handling the request |
|
852 | + 'validate_callback' => null, |
|
853 | + 'sanitize_callback' => null, |
|
854 | + ], |
|
855 | + 'limit' => [ |
|
856 | + 'required' => false, |
|
857 | + 'default' => EED_Core_Rest_Api::get_default_query_limit(), |
|
858 | + 'type' => [ |
|
859 | + 'array', |
|
860 | + 'string', |
|
861 | + 'integer', |
|
862 | + ], |
|
863 | + // because we accept a variety of types, WP core validation and sanitization |
|
864 | + // freaks out. We'll just validate this argument while handling the request |
|
865 | + 'validate_callback' => null, |
|
866 | + 'sanitize_callback' => null, |
|
867 | + ], |
|
868 | + 'order_by' => [ |
|
869 | + 'required' => false, |
|
870 | + 'default' => $default_orderby, |
|
871 | + 'type' => [ |
|
872 | + 'object', |
|
873 | + 'string', |
|
874 | + ],// because we accept a variety of types, WP core validation and sanitization |
|
875 | + // freaks out. We'll just validate this argument while handling the request |
|
876 | + 'validate_callback' => null, |
|
877 | + 'sanitize_callback' => null, |
|
878 | + ], |
|
879 | + 'group_by' => [ |
|
880 | + 'required' => false, |
|
881 | + 'default' => null, |
|
882 | + 'type' => [ |
|
883 | + 'object', |
|
884 | + 'string', |
|
885 | + ], |
|
886 | + // because we accept an almost infinite list of possible groupings, |
|
887 | + // WP core validation and sanitization |
|
888 | + // freaks out. We'll just validate this argument while handling the request |
|
889 | + 'validate_callback' => null, |
|
890 | + 'sanitize_callback' => null, |
|
891 | + ], |
|
892 | + 'having' => [ |
|
893 | + 'required' => false, |
|
894 | + 'default' => null, |
|
895 | + 'type' => 'object', |
|
896 | + // because we accept an almost infinite list of possible where conditions, WP |
|
897 | + // core validation and sanitization freaks out. We'll just validate this argument |
|
898 | + // while handling the request |
|
899 | + 'validate_callback' => null, |
|
900 | + 'sanitize_callback' => null, |
|
901 | + ], |
|
902 | + 'caps' => [ |
|
903 | + 'required' => false, |
|
904 | + 'default' => EEM_Base::caps_read, |
|
905 | + 'type' => 'string', |
|
906 | + 'enum' => [ |
|
907 | + EEM_Base::caps_read, |
|
908 | + EEM_Base::caps_read_admin, |
|
909 | + EEM_Base::caps_edit, |
|
910 | + EEM_Base::caps_delete, |
|
911 | + ], |
|
912 | + ], |
|
913 | + ] |
|
914 | + ); |
|
915 | + } |
|
916 | + |
|
917 | + |
|
918 | + /** |
|
919 | + * Gets parameter information for a model regarding writing data |
|
920 | + * |
|
921 | + * @param string $model_name |
|
922 | + * @param ModelVersionInfo $model_version_info |
|
923 | + * @param boolean $create whether this is for request to create (in |
|
924 | + * which case we need all required params) or |
|
925 | + * just to update (in which case we don't |
|
926 | + * need those on every request) |
|
927 | + * @return array |
|
928 | + * @throws EE_Error |
|
929 | + * @throws ReflectionException |
|
930 | + */ |
|
931 | + protected function _get_write_params( |
|
932 | + $model_name, |
|
933 | + ModelVersionInfo $model_version_info, |
|
934 | + $create = false |
|
935 | + ) { |
|
936 | + $model = EE_Registry::instance()->load_model($model_name); |
|
937 | + $fields = $model_version_info->fieldsOnModelInThisVersion($model); |
|
938 | + |
|
939 | + // we do our own validation and sanitization within the controller |
|
940 | + $sanitize_callback = function_exists('rest_validate_value_from_schema') |
|
941 | + ? ['EED_Core_Rest_Api', 'default_sanitize_callback'] |
|
942 | + : null; |
|
943 | + $args_info = []; |
|
944 | + foreach ($fields as $field_name => $field_obj) { |
|
945 | + if ($field_obj->is_auto_increment()) { |
|
946 | + // totally ignore auto increment IDs |
|
947 | + continue; |
|
948 | + } |
|
949 | + $arg_info = $field_obj->getSchema(); |
|
950 | + $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null; |
|
951 | + $arg_info['required'] = $required; |
|
952 | + // remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right? |
|
953 | + unset($arg_info['readonly']); |
|
954 | + $schema_properties = $field_obj->getSchemaProperties(); |
|
955 | + if ( |
|
956 | + isset($schema_properties['raw']) |
|
957 | + && $field_obj->getSchemaType() === 'object' |
|
958 | + ) { |
|
959 | + // if there's a "raw" form of this argument, use those properties instead |
|
960 | + $arg_info = array_replace( |
|
961 | + $arg_info, |
|
962 | + $schema_properties['raw'] |
|
963 | + ); |
|
964 | + } |
|
965 | + $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson( |
|
966 | + $field_obj, |
|
967 | + $field_obj->get_default_value(), |
|
968 | + $model_version_info->requestedVersion() |
|
969 | + ); |
|
970 | + $arg_info['sanitize_callback'] = $sanitize_callback; |
|
971 | + $args_info[ $field_name ] = $arg_info; |
|
972 | + if ($field_obj instanceof EE_Datetime_Field) { |
|
973 | + $gmt_arg_info = $arg_info; |
|
974 | + $gmt_arg_info['description'] = sprintf( |
|
975 | + esc_html__( |
|
976 | + '%1$s - the value for this field in UTC. Ignored if %2$s is provided.', |
|
977 | + 'event_espresso' |
|
978 | + ), |
|
979 | + $field_obj->get_nicename(), |
|
980 | + $field_name |
|
981 | + ); |
|
982 | + $args_info[ $field_name . '_gmt' ] = $gmt_arg_info; |
|
983 | + } |
|
984 | + } |
|
985 | + return $args_info; |
|
986 | + } |
|
987 | + |
|
988 | + |
|
989 | + /** |
|
990 | + * Replacement for WP API's 'rest_parse_request_arg'. |
|
991 | + * If the value is blank but not required, don't bother validating it. |
|
992 | + * Also, it uses our email validation instead of WP API's default. |
|
993 | + * |
|
994 | + * @param $value |
|
995 | + * @param WP_REST_Request $request |
|
996 | + * @param $param |
|
997 | + * @return bool|true|WP_Error |
|
998 | + * @throws InvalidArgumentException |
|
999 | + * @throws InvalidInterfaceException |
|
1000 | + * @throws InvalidDataTypeException |
|
1001 | + */ |
|
1002 | + public static function default_sanitize_callback($value, WP_REST_Request $request, $param) |
|
1003 | + { |
|
1004 | + $attributes = $request->get_attributes(); |
|
1005 | + if ( |
|
1006 | + ! isset($attributes['args'][ $param ]) |
|
1007 | + || ! is_array($attributes['args'][ $param ]) |
|
1008 | + ) { |
|
1009 | + $validation_result = true; |
|
1010 | + } else { |
|
1011 | + $args = $attributes['args'][ $param ]; |
|
1012 | + if ( |
|
1013 | + ( |
|
1014 | + $value === '' |
|
1015 | + || $value === null |
|
1016 | + ) |
|
1017 | + && (! isset($args['required']) |
|
1018 | + || $args['required'] === false |
|
1019 | + ) |
|
1020 | + ) { |
|
1021 | + // not required and not provided? that's cool |
|
1022 | + $validation_result = true; |
|
1023 | + } elseif ( |
|
1024 | + isset($args['format']) |
|
1025 | + && $args['format'] === 'email' |
|
1026 | + ) { |
|
1027 | + $validation_result = true; |
|
1028 | + if (! EED_Core_Rest_Api::_validate_email($value)) { |
|
1029 | + $validation_result = new WP_Error( |
|
1030 | + 'rest_invalid_param', |
|
1031 | + esc_html__( |
|
1032 | + 'The email address is not valid or does not exist.', |
|
1033 | + 'event_espresso' |
|
1034 | + ) |
|
1035 | + ); |
|
1036 | + } |
|
1037 | + } else { |
|
1038 | + $validation_result = rest_validate_value_from_schema($value, $args, $param); |
|
1039 | + } |
|
1040 | + } |
|
1041 | + if (is_wp_error($validation_result)) { |
|
1042 | + return $validation_result; |
|
1043 | + } |
|
1044 | + return rest_sanitize_request_arg($value, $request, $param); |
|
1045 | + } |
|
1046 | + |
|
1047 | + |
|
1048 | + /** |
|
1049 | + * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email() |
|
1050 | + * |
|
1051 | + * @param $email |
|
1052 | + * @return bool |
|
1053 | + * @throws InvalidArgumentException |
|
1054 | + * @throws InvalidInterfaceException |
|
1055 | + * @throws InvalidDataTypeException |
|
1056 | + */ |
|
1057 | + protected static function _validate_email($email) |
|
1058 | + { |
|
1059 | + try { |
|
1060 | + EmailAddressFactory::create($email); |
|
1061 | + return true; |
|
1062 | + } catch (EmailValidationException $e) { |
|
1063 | + return false; |
|
1064 | + } |
|
1065 | + } |
|
1066 | + |
|
1067 | + |
|
1068 | + /** |
|
1069 | + * Gets routes for the config |
|
1070 | + * |
|
1071 | + * @return array @see _register_model_routes |
|
1072 | + * @deprecated since version 4.9.1 |
|
1073 | + */ |
|
1074 | + protected function _register_config_routes() |
|
1075 | + { |
|
1076 | + $config_routes = []; |
|
1077 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1078 | + $config_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version( |
|
1079 | + $version, |
|
1080 | + $hidden_endpoint |
|
1081 | + ); |
|
1082 | + } |
|
1083 | + return $config_routes; |
|
1084 | + } |
|
1085 | + |
|
1086 | + |
|
1087 | + /** |
|
1088 | + * Gets routes for the config for the specified version |
|
1089 | + * |
|
1090 | + * @param string $version |
|
1091 | + * @param boolean $hidden_endpoint |
|
1092 | + * @return array |
|
1093 | + */ |
|
1094 | + protected function _get_config_route_data_for_version($version, $hidden_endpoint) |
|
1095 | + { |
|
1096 | + return [ |
|
1097 | + 'config' => [ |
|
1098 | + [ |
|
1099 | + 'callback' => [ |
|
1100 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1101 | + 'handleRequest', |
|
1102 | + ], |
|
1103 | + 'methods' => WP_REST_Server::READABLE, |
|
1104 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1105 | + 'callback_args' => [$version], |
|
1106 | + ], |
|
1107 | + ], |
|
1108 | + 'site_info' => [ |
|
1109 | + [ |
|
1110 | + 'callback' => [ |
|
1111 | + 'EventEspresso\core\libraries\rest_api\controllers\config\Read', |
|
1112 | + 'handleRequestSiteInfo', |
|
1113 | + ], |
|
1114 | + 'methods' => WP_REST_Server::READABLE, |
|
1115 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1116 | + 'callback_args' => [$version], |
|
1117 | + ], |
|
1118 | + ], |
|
1119 | + ]; |
|
1120 | + } |
|
1121 | + |
|
1122 | + |
|
1123 | + /** |
|
1124 | + * Gets the meta info routes |
|
1125 | + * |
|
1126 | + * @return array @see _register_model_routes |
|
1127 | + * @deprecated since version 4.9.1 |
|
1128 | + */ |
|
1129 | + protected function _register_meta_routes() |
|
1130 | + { |
|
1131 | + $meta_routes = []; |
|
1132 | + foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden_endpoint) { |
|
1133 | + $meta_routes[ EED_Core_Rest_Api::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version( |
|
1134 | + $version, |
|
1135 | + $hidden_endpoint |
|
1136 | + ); |
|
1137 | + } |
|
1138 | + return $meta_routes; |
|
1139 | + } |
|
1140 | + |
|
1141 | + |
|
1142 | + /** |
|
1143 | + * @param string $version |
|
1144 | + * @param boolean $hidden_endpoint |
|
1145 | + * @return array |
|
1146 | + */ |
|
1147 | + protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false) |
|
1148 | + { |
|
1149 | + return [ |
|
1150 | + 'resources' => [ |
|
1151 | + [ |
|
1152 | + 'callback' => [ |
|
1153 | + 'EventEspresso\core\libraries\rest_api\controllers\model\Meta', |
|
1154 | + 'handleRequestModelsMeta', |
|
1155 | + ], |
|
1156 | + 'methods' => WP_REST_Server::READABLE, |
|
1157 | + 'hidden_endpoint' => $hidden_endpoint, |
|
1158 | + 'callback_args' => [$version], |
|
1159 | + ], |
|
1160 | + ], |
|
1161 | + ]; |
|
1162 | + } |
|
1163 | + |
|
1164 | + |
|
1165 | + /** |
|
1166 | + * Tries to hide old 4.6 endpoints from the |
|
1167 | + * |
|
1168 | + * @param array $route_data |
|
1169 | + * @return array |
|
1170 | + * @throws EE_Error |
|
1171 | + * @throws ReflectionException |
|
1172 | + */ |
|
1173 | + public static function hide_old_endpoints($route_data) |
|
1174 | + { |
|
1175 | + // allow API clients to override which endpoints get hidden, in case |
|
1176 | + // they want to discover particular endpoints |
|
1177 | + // also, we don't have access to the request so we have to just grab it from the superglobal |
|
1178 | + $force_show_ee_namespace = ltrim( |
|
1179 | + EED_Core_Rest_Api::getRequest()->getRequestParam('force_show_ee_namespace'), |
|
1180 | + '/' |
|
1181 | + ); |
|
1182 | + foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) { |
|
1183 | + foreach ($relative_urls as $resource_name => $endpoints) { |
|
1184 | + foreach ($endpoints as $key => $endpoint) { |
|
1185 | + // skip schema and other route options |
|
1186 | + if (! is_numeric($key)) { |
|
1187 | + continue; |
|
1188 | + } |
|
1189 | + // by default, hide "hidden_endpoint"s, unless the request indicates |
|
1190 | + // to $force_show_ee_namespace, in which case only show that one |
|
1191 | + // namespace's endpoints (and hide all others) |
|
1192 | + if ( |
|
1193 | + ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace) |
|
1194 | + || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '') |
|
1195 | + ) { |
|
1196 | + $full_route = '/' . ltrim($namespace, '/'); |
|
1197 | + $full_route .= '/' . ltrim($resource_name, '/'); |
|
1198 | + unset($route_data[ $full_route ]); |
|
1199 | + } |
|
1200 | + } |
|
1201 | + } |
|
1202 | + } |
|
1203 | + return $route_data; |
|
1204 | + } |
|
1205 | + |
|
1206 | + |
|
1207 | + /** |
|
1208 | + * Returns an array describing which versions of core support serving requests for. |
|
1209 | + * Keys are core versions' major and minor version, and values are the |
|
1210 | + * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like |
|
1211 | + * data by just removing a few models and fields from the responses. However, 4.15 might remove |
|
1212 | + * the answers table entirely, in which case it would be very difficult for |
|
1213 | + * it to serve 4.6-style responses. |
|
1214 | + * Versions of core that are missing from this array are unknowns. |
|
1215 | + * previous ver |
|
1216 | + * |
|
1217 | + * @return array |
|
1218 | + */ |
|
1219 | + public static function version_compatibilities() |
|
1220 | + { |
|
1221 | + return apply_filters( |
|
1222 | + 'FHEE__EED_Core_REST_API__version_compatibilities', |
|
1223 | + [ |
|
1224 | + '4.8.29' => '4.8.29', |
|
1225 | + '4.8.33' => '4.8.29', |
|
1226 | + '4.8.34' => '4.8.29', |
|
1227 | + '4.8.36' => '4.8.29', |
|
1228 | + ] |
|
1229 | + ); |
|
1230 | + } |
|
1231 | + |
|
1232 | + |
|
1233 | + /** |
|
1234 | + * Gets the latest API version served. Eg if there |
|
1235 | + * are two versions served of the API, 4.8.29 and 4.8.32, and |
|
1236 | + * we are on core version 4.8.34, it will return the string "4.8.32" |
|
1237 | + * |
|
1238 | + * @return string |
|
1239 | + */ |
|
1240 | + public static function latest_rest_api_version() |
|
1241 | + { |
|
1242 | + $versions_served = EED_Core_Rest_Api::versions_served(); |
|
1243 | + $versions_served_keys = array_keys($versions_served); |
|
1244 | + return end($versions_served_keys); |
|
1245 | + } |
|
1246 | + |
|
1247 | + |
|
1248 | + /** |
|
1249 | + * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of |
|
1250 | + * EE the API can serve requests for. Eg, if we are on 4.15 of core, and |
|
1251 | + * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ). |
|
1252 | + * We also indicate whether or not this version should be put in the index or not |
|
1253 | + * |
|
1254 | + * @return array keys are API version numbers (just major and minor numbers), and values |
|
1255 | + * are whether or not they should be hidden |
|
1256 | + */ |
|
1257 | + public static function versions_served() |
|
1258 | + { |
|
1259 | + $versions_served = []; |
|
1260 | + $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities(); |
|
1261 | + $lowest_compatible_version = end($possibly_served_versions); |
|
1262 | + reset($possibly_served_versions); |
|
1263 | + $versions_served_historically = array_keys($possibly_served_versions); |
|
1264 | + $latest_version = end($versions_served_historically); |
|
1265 | + reset($versions_served_historically); |
|
1266 | + // for each version of core we have ever served: |
|
1267 | + foreach ($versions_served_historically as $key_versioned_endpoint) { |
|
1268 | + // if it's not above the current core version, and it's compatible with the current version of core |
|
1269 | + |
|
1270 | + if ($key_versioned_endpoint === $latest_version) { |
|
1271 | + // don't hide the latest version in the index |
|
1272 | + $versions_served[ $key_versioned_endpoint ] = false; |
|
1273 | + } elseif ( |
|
1274 | + version_compare($key_versioned_endpoint, $lowest_compatible_version, '>=') |
|
1275 | + && version_compare($key_versioned_endpoint, EED_Core_Rest_Api::core_version(), '<') |
|
1276 | + ) { |
|
1277 | + // include, but hide, previous versions which are still supported |
|
1278 | + $versions_served[ $key_versioned_endpoint ] = true; |
|
1279 | + } elseif ( |
|
1280 | + apply_filters( |
|
1281 | + 'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions', |
|
1282 | + false, |
|
1283 | + $possibly_served_versions |
|
1284 | + ) |
|
1285 | + ) { |
|
1286 | + // if a version is no longer supported, don't include it in index or list of versions served |
|
1287 | + $versions_served[ $key_versioned_endpoint ] = true; |
|
1288 | + } |
|
1289 | + } |
|
1290 | + return $versions_served; |
|
1291 | + } |
|
1292 | + |
|
1293 | + |
|
1294 | + /** |
|
1295 | + * Gets the major and minor version of EE core's version string |
|
1296 | + * |
|
1297 | + * @return string |
|
1298 | + */ |
|
1299 | + public static function core_version() |
|
1300 | + { |
|
1301 | + return apply_filters( |
|
1302 | + 'FHEE__EED_Core_REST_API__core_version', |
|
1303 | + implode( |
|
1304 | + '.', |
|
1305 | + array_slice( |
|
1306 | + explode( |
|
1307 | + '.', |
|
1308 | + espresso_version() |
|
1309 | + ), |
|
1310 | + 0, |
|
1311 | + 3 |
|
1312 | + ) |
|
1313 | + ) |
|
1314 | + ); |
|
1315 | + } |
|
1316 | + |
|
1317 | + |
|
1318 | + /** |
|
1319 | + * Gets the default limit that should be used when querying for resources |
|
1320 | + * |
|
1321 | + * @return int |
|
1322 | + */ |
|
1323 | + public static function get_default_query_limit() |
|
1324 | + { |
|
1325 | + // we actually don't use a const because we want folks to always use |
|
1326 | + // this method, not the const directly |
|
1327 | + return apply_filters( |
|
1328 | + 'FHEE__EED_Core_Rest_Api__get_default_query_limit', |
|
1329 | + 50 |
|
1330 | + ); |
|
1331 | + } |
|
1332 | + |
|
1333 | + |
|
1334 | + /** |
|
1335 | + * @param string $version api version string (i.e. '4.8.36') |
|
1336 | + * @return array |
|
1337 | + */ |
|
1338 | + public static function getCollectionRoutesIndexedByModelName($version = '') |
|
1339 | + { |
|
1340 | + $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1341 | + $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1342 | + $collection_routes = []; |
|
1343 | + foreach ($model_names as $model_name => $model_class_name) { |
|
1344 | + $collection_routes[ strtolower($model_name) ] = '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' |
|
1345 | + . EEH_Inflector::pluralize_and_lower($model_name); |
|
1346 | + } |
|
1347 | + return $collection_routes; |
|
1348 | + } |
|
1349 | + |
|
1350 | + |
|
1351 | + /** |
|
1352 | + * Returns an array of primary key names indexed by model names. |
|
1353 | + * |
|
1354 | + * @param string $version |
|
1355 | + * @return array |
|
1356 | + */ |
|
1357 | + public static function getPrimaryKeyNamesIndexedByModelName($version = '') |
|
1358 | + { |
|
1359 | + $version = empty($version) ? EED_Core_Rest_Api::latest_rest_api_version() : $version; |
|
1360 | + $model_names = EED_Core_Rest_Api::model_names_with_plural_routes($version); |
|
1361 | + $primary_key_items = []; |
|
1362 | + foreach ($model_names as $model_name => $model_class_name) { |
|
1363 | + $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields(); |
|
1364 | + foreach ($primary_keys as $primary_key_name => $primary_key_field) { |
|
1365 | + if (count($primary_keys) > 1) { |
|
1366 | + $primary_key_items[ strtolower($model_name) ][] = $primary_key_name; |
|
1367 | + } else { |
|
1368 | + $primary_key_items[ strtolower($model_name) ] = $primary_key_name; |
|
1369 | + } |
|
1370 | + } |
|
1371 | + } |
|
1372 | + return $primary_key_items; |
|
1373 | + } |
|
1374 | + |
|
1375 | + |
|
1376 | + /** |
|
1377 | + * Determines the EE REST API debug mode is activated, or not. |
|
1378 | + * |
|
1379 | + * @return bool |
|
1380 | + * @since 4.9.76.p |
|
1381 | + */ |
|
1382 | + public static function debugMode() |
|
1383 | + { |
|
1384 | + static $debug_mode = null; // could be class prop |
|
1385 | + if ($debug_mode === null) { |
|
1386 | + $debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE; |
|
1387 | + } |
|
1388 | + return $debug_mode; |
|
1389 | + } |
|
1390 | + |
|
1391 | + |
|
1392 | + /** |
|
1393 | + * run - initial module setup |
|
1394 | + * |
|
1395 | + * @access public |
|
1396 | + * @param WP $WP |
|
1397 | + * @return void |
|
1398 | + */ |
|
1399 | + public function run($WP) |
|
1400 | + { |
|
1401 | + } |
|
1402 | 1402 | } |
@@ -10,236 +10,236 @@ |
||
10 | 10 | */ |
11 | 11 | class EEH_Money extends EEH_Base |
12 | 12 | { |
13 | - /** |
|
14 | - * This removes all localized money formatting from the incoming value |
|
15 | - * Note: uses this site's currency settings for deciding what is considered a |
|
16 | - * "thousands separator" (usually the character "," ) |
|
17 | - * and what is a "decimal mark" (usually the character ".") |
|
18 | - * |
|
19 | - * @param int|float|string $money_value |
|
20 | - * @param string|null $CNT_ISO |
|
21 | - * @return float |
|
22 | - * @throws EE_Error |
|
23 | - * @throws ReflectionException |
|
24 | - */ |
|
25 | - public static function strip_localized_money_formatting($money_value, ?string $CNT_ISO = ''): float |
|
26 | - { |
|
27 | - $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
28 | - $money_value = str_replace( |
|
29 | - [ |
|
30 | - $currency_config->thsnds, |
|
31 | - $currency_config->dec_mrk, |
|
32 | - ], |
|
33 | - [ |
|
34 | - '', // remove thousands separator |
|
35 | - '.', // convert decimal mark to what PHP expects |
|
36 | - ], |
|
37 | - $money_value |
|
38 | - ); |
|
39 | - return (float) filter_var( |
|
40 | - $money_value, |
|
41 | - FILTER_SANITIZE_NUMBER_FLOAT, |
|
42 | - FILTER_FLAG_ALLOW_FRACTION |
|
43 | - ); |
|
44 | - } |
|
13 | + /** |
|
14 | + * This removes all localized money formatting from the incoming value |
|
15 | + * Note: uses this site's currency settings for deciding what is considered a |
|
16 | + * "thousands separator" (usually the character "," ) |
|
17 | + * and what is a "decimal mark" (usually the character ".") |
|
18 | + * |
|
19 | + * @param int|float|string $money_value |
|
20 | + * @param string|null $CNT_ISO |
|
21 | + * @return float |
|
22 | + * @throws EE_Error |
|
23 | + * @throws ReflectionException |
|
24 | + */ |
|
25 | + public static function strip_localized_money_formatting($money_value, ?string $CNT_ISO = ''): float |
|
26 | + { |
|
27 | + $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
28 | + $money_value = str_replace( |
|
29 | + [ |
|
30 | + $currency_config->thsnds, |
|
31 | + $currency_config->dec_mrk, |
|
32 | + ], |
|
33 | + [ |
|
34 | + '', // remove thousands separator |
|
35 | + '.', // convert decimal mark to what PHP expects |
|
36 | + ], |
|
37 | + $money_value |
|
38 | + ); |
|
39 | + return (float) filter_var( |
|
40 | + $money_value, |
|
41 | + FILTER_SANITIZE_NUMBER_FLOAT, |
|
42 | + FILTER_FLAG_ALLOW_FRACTION |
|
43 | + ); |
|
44 | + } |
|
45 | 45 | |
46 | 46 | |
47 | - /** |
|
48 | - * This converts an incoming localized money value into a standard float item (to three decimal places) |
|
49 | - * Only use this if you know the $money_value follows your currency configuration's |
|
50 | - * settings. Note: this uses this site's currency settings for deciding what is considered a |
|
51 | - * "thousands separator" (usually the character "," ) |
|
52 | - * and what is a "decimal mark" (usually the character ".") |
|
53 | - * |
|
54 | - * @param int|float|string $money_value |
|
55 | - * @return float |
|
56 | - * @throws EE_Error |
|
57 | - * @throws ReflectionException |
|
58 | - */ |
|
59 | - public static function convert_to_float_from_localized_money($money_value): float |
|
60 | - { |
|
61 | - // float it! and round to three decimal places |
|
62 | - return round(EEH_Money::strip_localized_money_formatting($money_value), 3); |
|
63 | - } |
|
47 | + /** |
|
48 | + * This converts an incoming localized money value into a standard float item (to three decimal places) |
|
49 | + * Only use this if you know the $money_value follows your currency configuration's |
|
50 | + * settings. Note: this uses this site's currency settings for deciding what is considered a |
|
51 | + * "thousands separator" (usually the character "," ) |
|
52 | + * and what is a "decimal mark" (usually the character ".") |
|
53 | + * |
|
54 | + * @param int|float|string $money_value |
|
55 | + * @return float |
|
56 | + * @throws EE_Error |
|
57 | + * @throws ReflectionException |
|
58 | + */ |
|
59 | + public static function convert_to_float_from_localized_money($money_value): float |
|
60 | + { |
|
61 | + // float it! and round to three decimal places |
|
62 | + return round(EEH_Money::strip_localized_money_formatting($money_value), 3); |
|
63 | + } |
|
64 | 64 | |
65 | 65 | |
66 | - /** |
|
67 | - * For comparing floats. Default operator is '=', but see the $operator below for all options. |
|
68 | - * This should be used to compare floats instead of normal '==' because floats |
|
69 | - * are inherently imprecise, and so you can sometimes have two floats that appear to be identical |
|
70 | - * but actually differ by 0.00000001. |
|
71 | - * |
|
72 | - * @see http://biostall.com/php-function-to-compare-floating-point-numbers |
|
73 | - * @param int|float|string $float1 |
|
74 | - * @param int|float|string $float2 |
|
75 | - * @param string|null $operator The operator. Valid options are =, <=, <, >=, >, <>, eq, lt, lte, gt, gte, ne |
|
76 | - * @return bool whether the equation is true or false |
|
77 | - * @throws EE_Error |
|
78 | - */ |
|
79 | - public static function compare_floats($float1, $float2, ?string $operator = '='): bool |
|
80 | - { |
|
81 | - // Check numbers to 5 digits of precision |
|
82 | - $epsilon = 0.00001; |
|
83 | - $float1 = (float) $float1; |
|
84 | - $float2 = (float) $float2; |
|
85 | - switch ($operator) { |
|
86 | - // equal |
|
87 | - case '=': |
|
88 | - case '==': |
|
89 | - case '===': |
|
90 | - case 'eq': |
|
91 | - if (abs($float1 - $float2) < $epsilon) { |
|
92 | - return true; |
|
93 | - } |
|
94 | - break; |
|
95 | - // less than |
|
96 | - case '<': |
|
97 | - case 'lt': |
|
98 | - if (abs($float1 - $float2) < $epsilon) { |
|
99 | - return false; |
|
100 | - } |
|
101 | - if ($float1 < $float2) { |
|
102 | - return true; |
|
103 | - } |
|
104 | - break; |
|
105 | - // less than or equal |
|
106 | - case '<=': |
|
107 | - case 'lte': |
|
108 | - if ( |
|
109 | - self::compare_floats($float1, $float2, '<') |
|
110 | - || self::compare_floats($float1, $float2) |
|
111 | - ) { |
|
112 | - return true; |
|
113 | - } |
|
114 | - break; |
|
115 | - // greater than |
|
116 | - case '>': |
|
117 | - case 'gt': |
|
118 | - if (abs($float1 - $float2) < $epsilon) { |
|
119 | - return false; |
|
120 | - } |
|
121 | - if ($float1 > $float2) { |
|
122 | - return true; |
|
123 | - } |
|
124 | - break; |
|
125 | - // greater than or equal |
|
126 | - case '>=': |
|
127 | - case 'gte': |
|
128 | - if ( |
|
129 | - self::compare_floats($float1, $float2, '>') |
|
130 | - || self::compare_floats($float1, $float2) |
|
131 | - ) { |
|
132 | - return true; |
|
133 | - } |
|
134 | - break; |
|
135 | - case '<>': |
|
136 | - case '!=': |
|
137 | - case '!==': |
|
138 | - case 'ne': |
|
139 | - if (abs($float1 - $float2) > $epsilon) { |
|
140 | - return true; |
|
141 | - } |
|
142 | - break; |
|
143 | - default: |
|
144 | - throw new EE_Error( |
|
145 | - sprintf( |
|
146 | - esc_html__( |
|
147 | - "Unknown operator %s in EEH_Money::compare_floats()", |
|
148 | - 'event_espresso' |
|
149 | - ), |
|
150 | - $operator |
|
151 | - ) |
|
152 | - ); |
|
153 | - } |
|
154 | - return false; |
|
155 | - } |
|
66 | + /** |
|
67 | + * For comparing floats. Default operator is '=', but see the $operator below for all options. |
|
68 | + * This should be used to compare floats instead of normal '==' because floats |
|
69 | + * are inherently imprecise, and so you can sometimes have two floats that appear to be identical |
|
70 | + * but actually differ by 0.00000001. |
|
71 | + * |
|
72 | + * @see http://biostall.com/php-function-to-compare-floating-point-numbers |
|
73 | + * @param int|float|string $float1 |
|
74 | + * @param int|float|string $float2 |
|
75 | + * @param string|null $operator The operator. Valid options are =, <=, <, >=, >, <>, eq, lt, lte, gt, gte, ne |
|
76 | + * @return bool whether the equation is true or false |
|
77 | + * @throws EE_Error |
|
78 | + */ |
|
79 | + public static function compare_floats($float1, $float2, ?string $operator = '='): bool |
|
80 | + { |
|
81 | + // Check numbers to 5 digits of precision |
|
82 | + $epsilon = 0.00001; |
|
83 | + $float1 = (float) $float1; |
|
84 | + $float2 = (float) $float2; |
|
85 | + switch ($operator) { |
|
86 | + // equal |
|
87 | + case '=': |
|
88 | + case '==': |
|
89 | + case '===': |
|
90 | + case 'eq': |
|
91 | + if (abs($float1 - $float2) < $epsilon) { |
|
92 | + return true; |
|
93 | + } |
|
94 | + break; |
|
95 | + // less than |
|
96 | + case '<': |
|
97 | + case 'lt': |
|
98 | + if (abs($float1 - $float2) < $epsilon) { |
|
99 | + return false; |
|
100 | + } |
|
101 | + if ($float1 < $float2) { |
|
102 | + return true; |
|
103 | + } |
|
104 | + break; |
|
105 | + // less than or equal |
|
106 | + case '<=': |
|
107 | + case 'lte': |
|
108 | + if ( |
|
109 | + self::compare_floats($float1, $float2, '<') |
|
110 | + || self::compare_floats($float1, $float2) |
|
111 | + ) { |
|
112 | + return true; |
|
113 | + } |
|
114 | + break; |
|
115 | + // greater than |
|
116 | + case '>': |
|
117 | + case 'gt': |
|
118 | + if (abs($float1 - $float2) < $epsilon) { |
|
119 | + return false; |
|
120 | + } |
|
121 | + if ($float1 > $float2) { |
|
122 | + return true; |
|
123 | + } |
|
124 | + break; |
|
125 | + // greater than or equal |
|
126 | + case '>=': |
|
127 | + case 'gte': |
|
128 | + if ( |
|
129 | + self::compare_floats($float1, $float2, '>') |
|
130 | + || self::compare_floats($float1, $float2) |
|
131 | + ) { |
|
132 | + return true; |
|
133 | + } |
|
134 | + break; |
|
135 | + case '<>': |
|
136 | + case '!=': |
|
137 | + case '!==': |
|
138 | + case 'ne': |
|
139 | + if (abs($float1 - $float2) > $epsilon) { |
|
140 | + return true; |
|
141 | + } |
|
142 | + break; |
|
143 | + default: |
|
144 | + throw new EE_Error( |
|
145 | + sprintf( |
|
146 | + esc_html__( |
|
147 | + "Unknown operator %s in EEH_Money::compare_floats()", |
|
148 | + 'event_espresso' |
|
149 | + ), |
|
150 | + $operator |
|
151 | + ) |
|
152 | + ); |
|
153 | + } |
|
154 | + return false; |
|
155 | + } |
|
156 | 156 | |
157 | 157 | |
158 | - /** |
|
159 | - * This returns a localized format string suitable for jQplot. |
|
160 | - * |
|
161 | - * @param string|null $CNT_ISO If this is provided, then will attempt to get the currency settings for the country. |
|
162 | - * Otherwise will use currency settings for current active country on site. |
|
163 | - * @return string |
|
164 | - * @throws EE_Error |
|
165 | - * @throws ReflectionException |
|
166 | - */ |
|
167 | - public static function get_format_for_jqplot(?string $CNT_ISO = ''): string |
|
168 | - { |
|
169 | - // default format |
|
170 | - $format = 'f'; |
|
171 | - $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
172 | - // first get the decimal place and number of places |
|
173 | - $format = "%'." . $currency_config->dec_plc . $format; |
|
174 | - // currency symbol on right side. |
|
175 | - return $currency_config->sign_b4 ? $currency_config->sign . $format : $format . $currency_config->sign; |
|
176 | - } |
|
158 | + /** |
|
159 | + * This returns a localized format string suitable for jQplot. |
|
160 | + * |
|
161 | + * @param string|null $CNT_ISO If this is provided, then will attempt to get the currency settings for the country. |
|
162 | + * Otherwise will use currency settings for current active country on site. |
|
163 | + * @return string |
|
164 | + * @throws EE_Error |
|
165 | + * @throws ReflectionException |
|
166 | + */ |
|
167 | + public static function get_format_for_jqplot(?string $CNT_ISO = ''): string |
|
168 | + { |
|
169 | + // default format |
|
170 | + $format = 'f'; |
|
171 | + $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
172 | + // first get the decimal place and number of places |
|
173 | + $format = "%'." . $currency_config->dec_plc . $format; |
|
174 | + // currency symbol on right side. |
|
175 | + return $currency_config->sign_b4 ? $currency_config->sign . $format : $format . $currency_config->sign; |
|
176 | + } |
|
177 | 177 | |
178 | 178 | |
179 | - /** |
|
180 | - * This returns a localized format string suitable for usage with the Google Charts API format param. |
|
181 | - * |
|
182 | - * @param string|null $CNT_ISO If this is provided, then will attempt to get the currency settings for the country. |
|
183 | - * Otherwise will use currency settings for current active country on site. |
|
184 | - * Note: GoogleCharts uses ICU pattern set |
|
185 | - * (@return array |
|
186 | - * @return array |
|
187 | - * @throws EE_Error |
|
188 | - * @throws ReflectionException |
|
189 | - * @see http://icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) |
|
190 | - */ |
|
191 | - public static function get_format_for_google_charts(?string $CNT_ISO = ''): array |
|
192 | - { |
|
193 | - $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
194 | - $decimal_places_placeholder = str_pad('', $currency_config->dec_plc, '0'); |
|
195 | - // first get the decimal place and number of places |
|
196 | - $format = '#,##0.' . $decimal_places_placeholder; |
|
197 | - // currency symbol on right side. |
|
198 | - $format = $currency_config->sign_b4 |
|
199 | - ? $currency_config->sign . $format |
|
200 | - : $format |
|
201 | - . $currency_config->sign; |
|
202 | - $formatterObject = [ |
|
203 | - 'decimalSymbol' => $currency_config->dec_mrk, |
|
204 | - 'groupingSymbol' => $currency_config->thsnds, |
|
205 | - 'fractionDigits' => $currency_config->dec_plc, |
|
206 | - ]; |
|
207 | - if ($currency_config->sign_b4) { |
|
208 | - $formatterObject['prefix'] = $currency_config->sign; |
|
209 | - } else { |
|
210 | - $formatterObject['suffix'] = $currency_config->sign; |
|
211 | - } |
|
212 | - return [ |
|
213 | - 'format' => $format, |
|
214 | - 'formatterObject' => $formatterObject, |
|
215 | - ]; |
|
216 | - } |
|
179 | + /** |
|
180 | + * This returns a localized format string suitable for usage with the Google Charts API format param. |
|
181 | + * |
|
182 | + * @param string|null $CNT_ISO If this is provided, then will attempt to get the currency settings for the country. |
|
183 | + * Otherwise will use currency settings for current active country on site. |
|
184 | + * Note: GoogleCharts uses ICU pattern set |
|
185 | + * (@return array |
|
186 | + * @return array |
|
187 | + * @throws EE_Error |
|
188 | + * @throws ReflectionException |
|
189 | + * @see http://icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) |
|
190 | + */ |
|
191 | + public static function get_format_for_google_charts(?string $CNT_ISO = ''): array |
|
192 | + { |
|
193 | + $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
194 | + $decimal_places_placeholder = str_pad('', $currency_config->dec_plc, '0'); |
|
195 | + // first get the decimal place and number of places |
|
196 | + $format = '#,##0.' . $decimal_places_placeholder; |
|
197 | + // currency symbol on right side. |
|
198 | + $format = $currency_config->sign_b4 |
|
199 | + ? $currency_config->sign . $format |
|
200 | + : $format |
|
201 | + . $currency_config->sign; |
|
202 | + $formatterObject = [ |
|
203 | + 'decimalSymbol' => $currency_config->dec_mrk, |
|
204 | + 'groupingSymbol' => $currency_config->thsnds, |
|
205 | + 'fractionDigits' => $currency_config->dec_plc, |
|
206 | + ]; |
|
207 | + if ($currency_config->sign_b4) { |
|
208 | + $formatterObject['prefix'] = $currency_config->sign; |
|
209 | + } else { |
|
210 | + $formatterObject['suffix'] = $currency_config->sign; |
|
211 | + } |
|
212 | + return [ |
|
213 | + 'format' => $format, |
|
214 | + 'formatterObject' => $formatterObject, |
|
215 | + ]; |
|
216 | + } |
|
217 | 217 | |
218 | 218 | |
219 | - /** |
|
220 | - * @param string|null $CNT_ISO |
|
221 | - * @return EE_Currency_Config |
|
222 | - * @throws EE_Error |
|
223 | - * @throws ReflectionException |
|
224 | - */ |
|
225 | - public static function get_currency_config(?string $CNT_ISO = ''): EE_Currency_Config |
|
226 | - { |
|
227 | - return EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
228 | - } |
|
219 | + /** |
|
220 | + * @param string|null $CNT_ISO |
|
221 | + * @return EE_Currency_Config |
|
222 | + * @throws EE_Error |
|
223 | + * @throws ReflectionException |
|
224 | + */ |
|
225 | + public static function get_currency_config(?string $CNT_ISO = ''): EE_Currency_Config |
|
226 | + { |
|
227 | + return EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
228 | + } |
|
229 | 229 | |
230 | 230 | |
231 | - /** |
|
232 | - * @param string|null $CNT_ISO |
|
233 | - * @param bool $as_decimal if false [default] will return the number of decimal places ex: 1, 2, 3 |
|
234 | - * if true, will return the subunits as a decimal fraction ex: .1, .01, .001 |
|
235 | - * @return float |
|
236 | - * @throws EE_Error |
|
237 | - * @throws ReflectionException |
|
238 | - * @since $VID:$ |
|
239 | - */ |
|
240 | - public static function getCurrencySubUnits(?string $CNT_ISO = '', bool $as_decimal = false): float |
|
241 | - { |
|
242 | - $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
243 | - return $as_decimal ? pow(10, ($currency_config->dec_plc * -1)) : $currency_config->dec_plc; |
|
244 | - } |
|
231 | + /** |
|
232 | + * @param string|null $CNT_ISO |
|
233 | + * @param bool $as_decimal if false [default] will return the number of decimal places ex: 1, 2, 3 |
|
234 | + * if true, will return the subunits as a decimal fraction ex: .1, .01, .001 |
|
235 | + * @return float |
|
236 | + * @throws EE_Error |
|
237 | + * @throws ReflectionException |
|
238 | + * @since $VID:$ |
|
239 | + */ |
|
240 | + public static function getCurrencySubUnits(?string $CNT_ISO = '', bool $as_decimal = false): float |
|
241 | + { |
|
242 | + $currency_config = EE_Currency_Config::getCurrencyConfig($CNT_ISO); |
|
243 | + return $as_decimal ? pow(10, ($currency_config->dec_plc * -1)) : $currency_config->dec_plc; |
|
244 | + } |
|
245 | 245 | } |
@@ -12,842 +12,842 @@ |
||
12 | 12 | */ |
13 | 13 | class EEM_Datetime extends EEM_Soft_Delete_Base |
14 | 14 | { |
15 | - /** |
|
16 | - * @var EEM_Datetime $_instance |
|
17 | - */ |
|
18 | - protected static $_instance; |
|
19 | - |
|
20 | - |
|
21 | - /** |
|
22 | - * private constructor to prevent direct creation |
|
23 | - * |
|
24 | - * @param string $timezone A string representing the timezone we want to set for returned Date Time Strings |
|
25 | - * (and any incoming timezone data that gets saved). |
|
26 | - * Note this just sends the timezone info to the date time model field objects. |
|
27 | - * Default is NULL |
|
28 | - * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
29 | - * @throws EE_Error |
|
30 | - * @throws InvalidArgumentException |
|
31 | - * @throws InvalidArgumentException |
|
32 | - */ |
|
33 | - protected function __construct($timezone) |
|
34 | - { |
|
35 | - $this->singular_item = esc_html__('Datetime', 'event_espresso'); |
|
36 | - $this->plural_item = esc_html__('Datetimes', 'event_espresso'); |
|
37 | - $this->_tables = [ |
|
38 | - 'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'), |
|
39 | - ]; |
|
40 | - $this->_fields = [ |
|
41 | - 'Datetime' => [ |
|
42 | - 'DTT_ID' => new EE_Primary_Key_Int_Field( |
|
43 | - 'DTT_ID', |
|
44 | - esc_html__('Datetime ID', 'event_espresso') |
|
45 | - ), |
|
46 | - 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
47 | - 'EVT_ID', |
|
48 | - esc_html__('Event ID', 'event_espresso'), |
|
49 | - false, |
|
50 | - 0, |
|
51 | - 'Event' |
|
52 | - ), |
|
53 | - 'VNU_ID' => new EE_Foreign_Key_Int_Field( |
|
54 | - 'VNU_ID', |
|
55 | - __('Venue ID', 'event_espresso'), |
|
56 | - false, |
|
57 | - 0, |
|
58 | - 'Venue' |
|
59 | - ), |
|
60 | - 'DTT_name' => new EE_Plain_Text_Field( |
|
61 | - 'DTT_name', |
|
62 | - esc_html__('Datetime Name', 'event_espresso'), |
|
63 | - false, |
|
64 | - '' |
|
65 | - ), |
|
66 | - 'DTT_description' => new EE_Post_Content_Field( |
|
67 | - 'DTT_description', |
|
68 | - esc_html__('Description for Datetime', 'event_espresso'), |
|
69 | - false, |
|
70 | - '' |
|
71 | - ), |
|
72 | - 'DTT_EVT_start' => new EE_Datetime_Field( |
|
73 | - 'DTT_EVT_start', |
|
74 | - esc_html__('Start time/date of Event', 'event_espresso'), |
|
75 | - false, |
|
76 | - EE_Datetime_Field::now, |
|
77 | - $timezone |
|
78 | - ), |
|
79 | - 'DTT_EVT_end' => new EE_Datetime_Field( |
|
80 | - 'DTT_EVT_end', |
|
81 | - esc_html__('End time/date of Event', 'event_espresso'), |
|
82 | - false, |
|
83 | - EE_Datetime_Field::now, |
|
84 | - $timezone |
|
85 | - ), |
|
86 | - 'DTT_reg_limit' => new EE_Infinite_Integer_Field( |
|
87 | - 'DTT_reg_limit', |
|
88 | - esc_html__('Registration Limit for this time', 'event_espresso'), |
|
89 | - true, |
|
90 | - EE_INF |
|
91 | - ), |
|
92 | - 'DTT_sold' => new EE_Integer_Field( |
|
93 | - 'DTT_sold', |
|
94 | - esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'), |
|
95 | - true, |
|
96 | - 0 |
|
97 | - ), |
|
98 | - 'DTT_reserved' => new EE_Integer_Field( |
|
99 | - 'DTT_reserved', |
|
100 | - esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'), |
|
101 | - false, |
|
102 | - 0 |
|
103 | - ), |
|
104 | - 'DTT_is_primary' => new EE_Boolean_Field( |
|
105 | - 'DTT_is_primary', |
|
106 | - esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'), |
|
107 | - false, |
|
108 | - false |
|
109 | - ), |
|
110 | - 'DTT_order' => new EE_Integer_Field( |
|
111 | - 'DTT_order', |
|
112 | - esc_html__('The order in which the Datetime is displayed', 'event_espresso'), |
|
113 | - false, |
|
114 | - 0 |
|
115 | - ), |
|
116 | - 'DTT_parent' => new EE_Integer_Field( |
|
117 | - 'DTT_parent', |
|
118 | - esc_html__('Indicates what DTT_ID is the parent of this DTT_ID', 'event_espresso'), |
|
119 | - true, |
|
120 | - 0 |
|
121 | - ), |
|
122 | - 'DTT_deleted' => new EE_Trashed_Flag_Field( |
|
123 | - 'DTT_deleted', |
|
124 | - esc_html__('Flag indicating datetime is archived', 'event_espresso'), |
|
125 | - false, |
|
126 | - false |
|
127 | - ), |
|
128 | - ], |
|
129 | - ]; |
|
130 | - $this->_model_relations = [ |
|
131 | - 'Ticket' => new EE_HABTM_Relation('Datetime_Ticket'), |
|
132 | - 'Event' => new EE_Belongs_To_Relation(), |
|
133 | - 'Checkin' => new EE_Has_Many_Relation(), |
|
134 | - 'Datetime_Ticket' => new EE_Has_Many_Relation(), |
|
135 | - 'Venue' => new EE_Belongs_To_Relation(), |
|
136 | - ]; |
|
137 | - $path_to_event_model = 'Event'; |
|
138 | - $this->model_chain_to_password = $path_to_event_model; |
|
139 | - $this->_model_chain_to_wp_user = $path_to_event_model; |
|
140 | - // this model is generally available for reading |
|
141 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = |
|
142 | - new EE_Restriction_Generator_Event_Related_Public( |
|
143 | - $path_to_event_model |
|
144 | - ); |
|
145 | - $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
146 | - new EE_Restriction_Generator_Event_Related_Protected( |
|
147 | - $path_to_event_model |
|
148 | - ); |
|
149 | - $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = |
|
150 | - new EE_Restriction_Generator_Event_Related_Protected( |
|
151 | - $path_to_event_model |
|
152 | - ); |
|
153 | - $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
154 | - new EE_Restriction_Generator_Event_Related_Protected( |
|
155 | - $path_to_event_model, |
|
156 | - EEM_Base::caps_edit |
|
157 | - ); |
|
158 | - parent::__construct($timezone); |
|
159 | - } |
|
160 | - |
|
161 | - |
|
162 | - /** |
|
163 | - * create new blank datetime |
|
164 | - * |
|
165 | - * @access public |
|
166 | - * @return EE_Datetime[] array on success, FALSE on fail |
|
167 | - * @throws EE_Error |
|
168 | - * @throws InvalidArgumentException |
|
169 | - * @throws InvalidDataTypeException |
|
170 | - * @throws ReflectionException |
|
171 | - * @throws InvalidInterfaceException |
|
172 | - */ |
|
173 | - public function create_new_blank_datetime() |
|
174 | - { |
|
175 | - // makes sure timezone is always set. |
|
176 | - $timezone_string = $this->get_timezone(); |
|
177 | - /** |
|
178 | - * Filters the initial start date for the new datetime. |
|
179 | - * Any time included in this value will be overridden later so use additional filters to modify the time. |
|
180 | - * |
|
181 | - * @param int $start_date Unix timestamp representing now + 30 days in seconds. |
|
182 | - * @return int Unix timestamp |
|
183 | - */ |
|
184 | - $start_date = apply_filters( |
|
185 | - 'FHEE__EEM_Datetime__create_new_blank_datetime__start_date', |
|
186 | - $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS |
|
187 | - ); |
|
188 | - /** |
|
189 | - * Filters the initial end date for the new datetime. |
|
190 | - * Any time included in this value will be overridden later so use additional filters to modify the time. |
|
191 | - * |
|
192 | - * @param int $end_data Unix timestamp representing now + 30 days in seconds. |
|
193 | - * @return int Unix timestamp |
|
194 | - */ |
|
195 | - $end_date = apply_filters( |
|
196 | - 'FHEE__EEM_Datetime__create_new_blank_datetime__end_date', |
|
197 | - $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS |
|
198 | - ); |
|
199 | - $blank_datetime = EE_Datetime::new_instance( |
|
200 | - [ |
|
201 | - 'DTT_EVT_start' => $start_date, |
|
202 | - 'DTT_EVT_end' => $end_date, |
|
203 | - 'DTT_order' => 1, |
|
204 | - 'DTT_reg_limit' => EE_INF, |
|
205 | - ], |
|
206 | - $timezone_string |
|
207 | - ); |
|
208 | - /** |
|
209 | - * Filters the initial start time and format for the new EE_Datetime instance. |
|
210 | - * |
|
211 | - * @param array $start_time An array having size 2. First element is the time, second element is the time |
|
212 | - * format. |
|
213 | - * @return array |
|
214 | - */ |
|
215 | - $start_time = apply_filters( |
|
216 | - 'FHEE__EEM_Datetime__create_new_blank_datetime__start_time', |
|
217 | - ['8am', 'ga'] |
|
218 | - ); |
|
219 | - /** |
|
220 | - * Filters the initial end time and format for the new EE_Datetime instance. |
|
221 | - * |
|
222 | - * @param array $end_time An array having size 2. First element is the time, second element is the time |
|
223 | - * format |
|
224 | - * @return array |
|
225 | - */ |
|
226 | - $end_time = apply_filters( |
|
227 | - 'FHEE__EEM_Datetime__create_new_blank_datetime__end_time', |
|
228 | - ['5pm', 'ga'] |
|
229 | - ); |
|
230 | - $this->validateStartAndEndTimeForBlankDate($start_time, $end_time); |
|
231 | - $blank_datetime->set_start_time( |
|
232 | - $this->convert_datetime_for_query( |
|
233 | - 'DTT_EVT_start', |
|
234 | - $start_time[0], |
|
235 | - $start_time[1], |
|
236 | - $timezone_string |
|
237 | - ) |
|
238 | - ); |
|
239 | - $blank_datetime->set_end_time( |
|
240 | - $this->convert_datetime_for_query( |
|
241 | - 'DTT_EVT_end', |
|
242 | - $end_time[0], |
|
243 | - $end_time[1], |
|
244 | - $timezone_string |
|
245 | - ) |
|
246 | - ); |
|
247 | - return [$blank_datetime]; |
|
248 | - } |
|
249 | - |
|
250 | - |
|
251 | - /** |
|
252 | - * Validates whether the start_time and end_time are in the expected format. |
|
253 | - * |
|
254 | - * @param array $start_time |
|
255 | - * @param array $end_time |
|
256 | - * @throws InvalidArgumentException |
|
257 | - * @throws InvalidDataTypeException |
|
258 | - */ |
|
259 | - private function validateStartAndEndTimeForBlankDate(array $start_time, array $end_time) |
|
260 | - { |
|
261 | - if (! is_array($start_time)) { |
|
262 | - throw new InvalidDataTypeException('start_time', $start_time, 'array'); |
|
263 | - } |
|
264 | - if (! is_array($end_time)) { |
|
265 | - throw new InvalidDataTypeException('end_time', $end_time, 'array'); |
|
266 | - } |
|
267 | - if (count($start_time) !== 2) { |
|
268 | - throw new InvalidArgumentException( |
|
269 | - sprintf( |
|
270 | - 'The variable %1$s is expected to be an array with two elements. The first item in the ' |
|
271 | - . 'array should be a valid time string, the second item in the array should be a valid time format', |
|
272 | - '$start_time' |
|
273 | - ) |
|
274 | - ); |
|
275 | - } |
|
276 | - if (count($end_time) !== 2) { |
|
277 | - throw new InvalidArgumentException( |
|
278 | - sprintf( |
|
279 | - 'The variable %1$s is expected to be an array with two elements. The first item in the ' |
|
280 | - . 'array should be a valid time string, the second item in the array should be a valid time format', |
|
281 | - '$end_time' |
|
282 | - ) |
|
283 | - ); |
|
284 | - } |
|
285 | - } |
|
286 | - |
|
287 | - |
|
288 | - /** |
|
289 | - * get event start date from db |
|
290 | - * |
|
291 | - * @access public |
|
292 | - * @param int $EVT_ID |
|
293 | - * @return EE_Datetime[] array on success, FALSE on fail |
|
294 | - * @throws EE_Error |
|
295 | - * @throws ReflectionException |
|
296 | - */ |
|
297 | - public function get_all_event_dates($EVT_ID = 0) |
|
298 | - { |
|
299 | - if (! $EVT_ID) { // on add_new_event event_id gets set to 0 |
|
300 | - return $this->create_new_blank_datetime(); |
|
301 | - } |
|
302 | - $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID); |
|
303 | - if (empty($results)) { |
|
304 | - return $this->create_new_blank_datetime(); |
|
305 | - } |
|
306 | - return $results; |
|
307 | - } |
|
308 | - |
|
309 | - |
|
310 | - /** |
|
311 | - * get all datetimes attached to an event ordered by the DTT_order field |
|
312 | - * |
|
313 | - * @public |
|
314 | - * @param int $EVT_ID event id |
|
315 | - * @param boolean $include_expired |
|
316 | - * @param boolean $include_deleted |
|
317 | - * @param int $limit If included then limit the count of results by |
|
318 | - * the given number |
|
319 | - * @return EE_Datetime[] |
|
320 | - * @throws EE_Error |
|
321 | - */ |
|
322 | - public function get_datetimes_for_event_ordered_by_DTT_order( |
|
323 | - int $EVT_ID, |
|
324 | - bool $include_expired = true, |
|
325 | - bool $include_deleted = true, |
|
326 | - $limit = 0 |
|
327 | - ) { |
|
328 | - $prev_data_prep_value = $this->prepModelForQuery(); |
|
329 | - $where_params = ['Event.EVT_ID' => absint($EVT_ID)]; |
|
330 | - $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
331 | - $query_params = $this->addDefaultWhereConditions($query_params); |
|
332 | - $query_params = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order'); |
|
333 | - return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
334 | - } |
|
335 | - |
|
336 | - |
|
337 | - /** |
|
338 | - * Gets the datetimes for the event (with the given limit), and orders them by "importance". |
|
339 | - * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW), |
|
340 | - * and then the earlier datetimes are the most important. |
|
341 | - * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet. |
|
342 | - * |
|
343 | - * @param int $EVT_ID |
|
344 | - * @param int $limit |
|
345 | - * @return EE_Datetime[]|EE_Base_Class[] |
|
346 | - * @throws EE_Error |
|
347 | - */ |
|
348 | - public function get_datetimes_for_event_ordered_by_importance(int $EVT_ID, $limit = 0) |
|
349 | - { |
|
350 | - $query_params[0] = ['Event.EVT_ID' => absint($EVT_ID)]; |
|
351 | - $query_params = $this->addDefaultWhereConditions($query_params); |
|
352 | - $query_params = $this->addDefaultQueryParams($query_params, $limit); |
|
353 | - return $this->get_all($query_params); |
|
354 | - } |
|
355 | - |
|
356 | - |
|
357 | - /** |
|
358 | - * @param int $EVT_ID |
|
359 | - * @param boolean $include_expired |
|
360 | - * @param boolean $include_deleted |
|
361 | - * @return EE_Datetime |
|
362 | - * @throws EE_Error |
|
363 | - */ |
|
364 | - public function get_oldest_datetime_for_event( |
|
365 | - int $EVT_ID, |
|
366 | - bool $include_expired = false, |
|
367 | - bool $include_deleted = false |
|
368 | - ) { |
|
369 | - $results = $this->get_datetimes_for_event_ordered_by_start_time( |
|
370 | - $EVT_ID, |
|
371 | - $include_expired, |
|
372 | - $include_deleted, |
|
373 | - 1 |
|
374 | - ); |
|
375 | - if ($results) { |
|
376 | - return array_shift($results); |
|
377 | - } |
|
378 | - return null; |
|
379 | - } |
|
380 | - |
|
381 | - |
|
382 | - /** |
|
383 | - * Gets the 'primary' datetime for an event. |
|
384 | - * |
|
385 | - * @param int $EVT_ID |
|
386 | - * @param bool $try_to_exclude_expired |
|
387 | - * @param bool $try_to_exclude_deleted |
|
388 | - * @return EE_Datetime |
|
389 | - * @throws EE_Error |
|
390 | - */ |
|
391 | - public function get_primary_datetime_for_event( |
|
392 | - int $EVT_ID, |
|
393 | - bool $try_to_exclude_expired = true, |
|
394 | - bool $try_to_exclude_deleted = true |
|
395 | - ) { |
|
396 | - if ($try_to_exclude_expired) { |
|
397 | - $non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false); |
|
398 | - if ($non_expired) { |
|
399 | - return $non_expired; |
|
400 | - } |
|
401 | - } |
|
402 | - if ($try_to_exclude_deleted) { |
|
403 | - $expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true); |
|
404 | - if ($expired_even) { |
|
405 | - return $expired_even; |
|
406 | - } |
|
407 | - } |
|
408 | - return $this->get_oldest_datetime_for_event($EVT_ID, true, true); |
|
409 | - } |
|
410 | - |
|
411 | - |
|
412 | - /** |
|
413 | - * Gets ALL the datetimes for an event (including trashed ones, for now), ordered |
|
414 | - * only by start date |
|
415 | - * |
|
416 | - * @param int $EVT_ID |
|
417 | - * @param boolean $include_expired |
|
418 | - * @param boolean $include_deleted |
|
419 | - * @param int $limit |
|
420 | - * @return EE_Datetime[] |
|
421 | - * @throws EE_Error |
|
422 | - */ |
|
423 | - public function get_datetimes_for_event_ordered_by_start_time( |
|
424 | - int $EVT_ID, |
|
425 | - bool $include_expired = true, |
|
426 | - bool $include_deleted = true, |
|
427 | - $limit = 0 |
|
428 | - ) { |
|
429 | - $prev_data_prep_value = $this->prepModelForQuery(); |
|
430 | - $where_params = ['Event.EVT_ID' => absint($EVT_ID)]; |
|
431 | - $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
432 | - $query_params = $this->addDefaultWhereConditions( |
|
433 | - $query_params, |
|
434 | - EEM_Base::default_where_conditions_this_only |
|
435 | - ); |
|
436 | - $query_params = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order'); |
|
437 | - return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
438 | - } |
|
439 | - |
|
440 | - |
|
441 | - /** |
|
442 | - * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered |
|
443 | - * only by start date |
|
444 | - * |
|
445 | - * @param int $TKT_ID |
|
446 | - * @param boolean $include_expired |
|
447 | - * @param boolean $include_deleted |
|
448 | - * @param int $limit |
|
449 | - * @return EE_Datetime[] |
|
450 | - * @throws EE_Error |
|
451 | - */ |
|
452 | - public function get_datetimes_for_ticket_ordered_by_start_time( |
|
453 | - int $TKT_ID, |
|
454 | - bool $include_expired = true, |
|
455 | - bool $include_deleted = true, |
|
456 | - $limit = 0 |
|
457 | - ) { |
|
458 | - $prev_data_prep_value = $this->prepModelForQuery(); |
|
459 | - $where_params = ['Ticket.TKT_ID' => absint($TKT_ID)]; |
|
460 | - $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
461 | - $query_params = $this->addDefaultQueryParams($query_params, $limit); |
|
462 | - return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
463 | - } |
|
464 | - |
|
465 | - |
|
466 | - /** |
|
467 | - * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the |
|
468 | - * datetimes. |
|
469 | - * |
|
470 | - * @param int $TKT_ID ID of ticket to retrieve the datetimes for |
|
471 | - * @param boolean $include_expired whether to include expired datetimes or not |
|
472 | - * @param boolean $include_deleted whether to include trashed datetimes or not. |
|
473 | - * @param int|null $limit if null, no limit, if int then limit results by |
|
474 | - * that number |
|
475 | - * @return EE_Datetime[] |
|
476 | - * @throws EE_Error |
|
477 | - */ |
|
478 | - public function get_datetimes_for_ticket_ordered_by_DTT_order( |
|
479 | - int $TKT_ID, |
|
480 | - bool $include_expired = true, |
|
481 | - bool $include_deleted = true, |
|
482 | - $limit = 0 |
|
483 | - ) { |
|
484 | - $prev_data_prep_value = $this->prepModelForQuery(); |
|
485 | - $where_params = ['Ticket.TKT_ID' => absint($TKT_ID)]; |
|
486 | - $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
487 | - $query_params = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order'); |
|
488 | - return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
489 | - } |
|
490 | - |
|
491 | - |
|
492 | - /** |
|
493 | - * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK |
|
494 | - * reason it doesn't exist, we consider the earliest event the most important) |
|
495 | - * |
|
496 | - * @param int $EVT_ID |
|
497 | - * @return EE_Datetime |
|
498 | - * @throws EE_Error |
|
499 | - */ |
|
500 | - public function get_most_important_datetime_for_event(int $EVT_ID) |
|
501 | - { |
|
502 | - $results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1); |
|
503 | - if ($results) { |
|
504 | - return array_shift($results); |
|
505 | - } |
|
506 | - return null; |
|
507 | - } |
|
508 | - |
|
509 | - |
|
510 | - /** |
|
511 | - * This returns a wpdb->results Array of all DTT month and years matching the incoming query params and |
|
512 | - * grouped by month and year. |
|
513 | - * |
|
514 | - * @param array $where_params @see |
|
515 | - * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
516 | - * @param string $evt_active_status A string representing the evt active status to filter the months by. |
|
517 | - * Can be: |
|
518 | - * - '' = no filter |
|
519 | - * - upcoming = Published events with at least one upcoming datetime. |
|
520 | - * - expired = Events with all datetimes expired. |
|
521 | - * - active = Events that are published and have at least one datetime that |
|
522 | - * starts before now and ends after now. |
|
523 | - * - inactive = Events that are either not published. |
|
524 | - * @return stdClass[] |
|
525 | - * @throws EE_Error |
|
526 | - * @throws InvalidArgumentException |
|
527 | - * @throws InvalidArgumentException |
|
528 | - */ |
|
529 | - public function get_dtt_months_and_years(array $where_params, $evt_active_status = '') |
|
530 | - { |
|
531 | - $current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start'); |
|
532 | - $current_time_for_DTT_EVT_end = $this->current_time_for_query('DTT_EVT_end'); |
|
533 | - switch ($evt_active_status) { |
|
534 | - case 'upcoming': |
|
535 | - $where_params['Event.status'] = 'publish'; |
|
536 | - // if there are already query_params matching DTT_EVT_start then we need to modify that to add them. |
|
537 | - if (isset($where_params['DTT_EVT_start'])) { |
|
538 | - $where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start']; |
|
539 | - } |
|
540 | - $where_params['DTT_EVT_start'] = ['>', $current_time_for_DTT_EVT_start]; |
|
541 | - break; |
|
542 | - case 'expired': |
|
543 | - if (isset($where_params['Event.status'])) { |
|
544 | - unset($where_params['Event.status']); |
|
545 | - } |
|
546 | - // get events to exclude |
|
547 | - $exclude_query[0] = array_merge( |
|
548 | - $where_params, |
|
549 | - ['DTT_EVT_end' => ['>', $current_time_for_DTT_EVT_end]] |
|
550 | - ); |
|
551 | - // first get all events that have datetimes where its not expired. |
|
552 | - $event_ids = $this->_get_all_wpdb_results( |
|
553 | - $exclude_query, |
|
554 | - OBJECT_K, |
|
555 | - 'Datetime.EVT_ID' |
|
556 | - ); |
|
557 | - $event_ids = array_keys($event_ids); |
|
558 | - if (isset($where_params['DTT_EVT_end'])) { |
|
559 | - $where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end']; |
|
560 | - } |
|
561 | - $where_params['DTT_EVT_end'] = ['<', $current_time_for_DTT_EVT_end]; |
|
562 | - $where_params['Event.EVT_ID'] = ['NOT IN', $event_ids]; |
|
563 | - break; |
|
564 | - case 'active': |
|
565 | - $where_params['Event.status'] = 'publish'; |
|
566 | - if (isset($where_params['DTT_EVT_start'])) { |
|
567 | - $where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start']; |
|
568 | - } |
|
569 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
570 | - $where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end']; |
|
571 | - } |
|
572 | - $where_params['DTT_EVT_start'] = ['<', $current_time_for_DTT_EVT_start]; |
|
573 | - $where_params['DTT_EVT_end'] = ['>', $current_time_for_DTT_EVT_end]; |
|
574 | - break; |
|
575 | - case 'inactive': |
|
576 | - if (isset($where_params['Event.status'])) { |
|
577 | - unset($where_params['Event.status']); |
|
578 | - } |
|
579 | - if (isset($where_params['OR'])) { |
|
580 | - $where_params['AND']['OR'] = $where_params['OR']; |
|
581 | - } |
|
582 | - if (isset($where_params['DTT_EVT_end'])) { |
|
583 | - $where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end']; |
|
584 | - unset($where_params['DTT_EVT_end']); |
|
585 | - } |
|
586 | - if (isset($where_params['DTT_EVT_start'])) { |
|
587 | - $where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start']; |
|
588 | - unset($where_params['DTT_EVT_start']); |
|
589 | - } |
|
590 | - $where_params['AND']['Event.status'] = ['!=', 'publish']; |
|
591 | - break; |
|
592 | - } |
|
593 | - $query_params[0] = $where_params; |
|
594 | - $query_params['group_by'] = ['dtt_year', 'dtt_month']; |
|
595 | - $query_params = $this->addOrderByQueryParams($query_params, 'DTT_EVT_start', 'DESC'); |
|
596 | - |
|
597 | - $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset( |
|
598 | - $this->get_timezone(), |
|
599 | - 'DTT_EVT_start' |
|
600 | - ); |
|
601 | - $columns_to_select = [ |
|
602 | - 'dtt_year' => ['YEAR(' . $query_interval . ')', '%s'], |
|
603 | - 'dtt_month' => ['MONTHNAME(' . $query_interval . ')', '%s'], |
|
604 | - 'dtt_month_num' => ['MONTH(' . $query_interval . ')', '%s'], |
|
605 | - ]; |
|
606 | - return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select); |
|
607 | - } |
|
608 | - |
|
609 | - |
|
610 | - /** |
|
611 | - * Updates the DTT_sold attribute on each datetime (based on the registrations |
|
612 | - * for the tickets for each datetime) |
|
613 | - * |
|
614 | - * @param EE_Base_Class[]|EE_Datetime[] $datetimes |
|
615 | - * @throws EE_Error |
|
616 | - * @throws ReflectionException |
|
617 | - */ |
|
618 | - public function update_sold(array $datetimes) |
|
619 | - { |
|
620 | - EE_Error::doing_it_wrong( |
|
621 | - __FUNCTION__, |
|
622 | - esc_html__( |
|
623 | - 'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.', |
|
624 | - 'event_espresso' |
|
625 | - ), |
|
626 | - '4.9.32.rc.005' |
|
627 | - ); |
|
628 | - foreach ($datetimes as $datetime) { |
|
629 | - $datetime->update_sold(); |
|
630 | - } |
|
631 | - } |
|
632 | - |
|
633 | - |
|
634 | - /** |
|
635 | - * Gets the total number of tickets available at a particular datetime |
|
636 | - * (does NOT take into account the datetime's spaces available) |
|
637 | - * |
|
638 | - * @param int $DTT_ID |
|
639 | - * @param array $query_params |
|
640 | - * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF, IF there are NO |
|
641 | - * tickets attached to datetime then FALSE is returned. |
|
642 | - * @throws EE_Error |
|
643 | - * @throws ReflectionException |
|
644 | - */ |
|
645 | - public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = []) |
|
646 | - { |
|
647 | - $datetime = $this->get_one_by_ID($DTT_ID); |
|
648 | - if ($datetime instanceof EE_Datetime) { |
|
649 | - return $datetime->tickets_remaining($query_params); |
|
650 | - } |
|
651 | - return 0; |
|
652 | - } |
|
653 | - |
|
654 | - |
|
655 | - /** |
|
656 | - * This returns an array of counts of datetimes in the database for each Datetime status that can be queried. |
|
657 | - * |
|
658 | - * @param array $stati_to_include If included you can restrict the statuses we return counts for by including the |
|
659 | - * stati you want counts for as values in the array. An empty array returns counts |
|
660 | - * for all valid stati. |
|
661 | - * @param array $query_params If included can be used to refine the conditions for returning the count (i.e. |
|
662 | - * only for Datetimes connected to a specific event, or specific ticket. |
|
663 | - * @return array The value returned is an array indexed by Datetime Status and the values are the counts. The |
|
664 | - * @throws EE_Error |
|
665 | - * stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming |
|
666 | - * EE_Datetime::expired |
|
667 | - */ |
|
668 | - public function get_datetime_counts_by_status(array $stati_to_include = [], array $query_params = []) |
|
669 | - { |
|
670 | - // only accept where conditions for this query. |
|
671 | - $_where = isset($query_params[0]) ? $query_params[0] : []; |
|
672 | - $status_query_args = [ |
|
673 | - EE_Datetime::active => array_merge( |
|
674 | - $_where, |
|
675 | - ['DTT_EVT_start' => ['<', time()], 'DTT_EVT_end' => ['>', time()]] |
|
676 | - ), |
|
677 | - EE_Datetime::upcoming => array_merge( |
|
678 | - $_where, |
|
679 | - ['DTT_EVT_start' => ['>', time()]] |
|
680 | - ), |
|
681 | - EE_Datetime::expired => array_merge( |
|
682 | - $_where, |
|
683 | - ['DTT_EVT_end' => ['<', time()]] |
|
684 | - ), |
|
685 | - ]; |
|
686 | - if (! empty($stati_to_include)) { |
|
687 | - foreach (array_keys($status_query_args) as $status) { |
|
688 | - if (! in_array($status, $stati_to_include, true)) { |
|
689 | - unset($status_query_args[ $status ]); |
|
690 | - } |
|
691 | - } |
|
692 | - } |
|
693 | - // loop through and query counts for each stati. |
|
694 | - $status_query_results = []; |
|
695 | - foreach ($status_query_args as $status => $status_where_conditions) { |
|
696 | - $status_query_results[ $status ] = EEM_Datetime::count( |
|
697 | - [$status_where_conditions], |
|
698 | - 'DTT_ID', |
|
699 | - true |
|
700 | - ); |
|
701 | - } |
|
702 | - return $status_query_results; |
|
703 | - } |
|
704 | - |
|
705 | - |
|
706 | - /** |
|
707 | - * Returns the specific count for a given Datetime status matching any given query_params. |
|
708 | - * |
|
709 | - * @param string $status Valid string representation for Datetime status requested. (Defaults to Active). |
|
710 | - * @param array $query_params |
|
711 | - * @return int |
|
712 | - * @throws EE_Error |
|
713 | - */ |
|
714 | - public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = []) |
|
715 | - { |
|
716 | - $count = $this->get_datetime_counts_by_status([$status], $query_params); |
|
717 | - return ! empty($count[ $status ]) ? $count[ $status ] : 0; |
|
718 | - } |
|
719 | - |
|
720 | - |
|
721 | - /** |
|
722 | - * @return bool|int |
|
723 | - * @since $VID:$ |
|
724 | - */ |
|
725 | - private function prepModelForQuery() |
|
726 | - { |
|
727 | - $prev_data_prep_value = $this->get_assumption_concerning_values_already_prepared_by_model_object(); |
|
728 | - $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db); |
|
729 | - return $prev_data_prep_value; |
|
730 | - } |
|
731 | - |
|
732 | - |
|
733 | - /** |
|
734 | - * @param array $query_params |
|
735 | - * @param bool|int $prev_data_prep_value |
|
736 | - * @return EE_Base_Class[]|EE_Datetime[] |
|
737 | - * @throws EE_Error |
|
738 | - * @since $VID:$ |
|
739 | - */ |
|
740 | - private function getDatetimesAndRestoreModel(array $query_params, $prev_data_prep_value) |
|
741 | - { |
|
742 | - $result = $this->get_all($query_params); |
|
743 | - $this->assume_values_already_prepared_by_model_object($prev_data_prep_value); |
|
744 | - return $result; |
|
745 | - } |
|
746 | - |
|
747 | - |
|
748 | - /** |
|
749 | - * @param array $query_params |
|
750 | - * @param int $limit |
|
751 | - * @param string $order_by |
|
752 | - * @param string $order |
|
753 | - * @return array |
|
754 | - * @since $VID:$ |
|
755 | - */ |
|
756 | - private function addDefaultQueryParams(array $query_params, $limit = 0, $order_by = 'DTT_EVT_start', $order = 'ASC') |
|
757 | - { |
|
758 | - $query_params = $this->addOrderByQueryParams($query_params, $order_by, $order); |
|
759 | - $query_params = $this->addLimitQueryParams($query_params, $limit); |
|
760 | - return $query_params; |
|
761 | - } |
|
762 | - |
|
763 | - |
|
764 | - /** |
|
765 | - * @param array $query_params |
|
766 | - * @param string $default_where_conditions |
|
767 | - * @return array |
|
768 | - * @since $VID:$ |
|
769 | - */ |
|
770 | - private function addDefaultWhereConditions( |
|
771 | - array $query_params, |
|
772 | - $default_where_conditions = EEM_Base::default_where_conditions_none |
|
773 | - ) { |
|
774 | - $query_params['default_where_conditions'] = $default_where_conditions; |
|
775 | - return $query_params; |
|
776 | - } |
|
777 | - |
|
778 | - |
|
779 | - /** |
|
780 | - * @param array $where_params |
|
781 | - * @param bool $include_deleted |
|
782 | - * @param bool $include_expired |
|
783 | - * @return array |
|
784 | - * @since $VID:$ |
|
785 | - */ |
|
786 | - private function addDefaultWhereParams(array $where_params, bool $include_deleted = true, bool $include_expired = true) |
|
787 | - { |
|
788 | - $where_params = $this->addExpiredWhereParams($where_params, $include_expired); |
|
789 | - $where_params = $this->addDeletedWhereParams($where_params, $include_deleted); |
|
790 | - return $where_params; |
|
791 | - } |
|
792 | - |
|
793 | - |
|
794 | - /** |
|
795 | - * @param array $where_params |
|
796 | - * @param bool $include_deleted |
|
797 | - * @return array |
|
798 | - * @since $VID:$ |
|
799 | - */ |
|
800 | - private function addDeletedWhereParams(array $where_params, bool $include_deleted = true) |
|
801 | - { |
|
802 | - $deleted = $include_deleted ? [true, false] : [false]; |
|
803 | - $where_params['DTT_deleted'] = ['IN', $deleted]; |
|
804 | - return $where_params; |
|
805 | - } |
|
806 | - |
|
807 | - |
|
808 | - /** |
|
809 | - * @param array $where_params |
|
810 | - * @param bool $include_expired |
|
811 | - * @return array |
|
812 | - * @since $VID:$ |
|
813 | - */ |
|
814 | - private function addExpiredWhereParams(array $where_params, bool $include_expired = true) |
|
815 | - { |
|
816 | - if (! $include_expired) { |
|
817 | - $where_params['DTT_EVT_end'] = ['>=', current_time('mysql', true)]; |
|
818 | - } |
|
819 | - return $where_params; |
|
820 | - } |
|
821 | - |
|
822 | - |
|
823 | - /** |
|
824 | - * @param array $query_params |
|
825 | - * @param int $limit |
|
826 | - * @return array |
|
827 | - * @since $VID:$ |
|
828 | - */ |
|
829 | - private function addLimitQueryParams(array $query_params, $limit = 0) |
|
830 | - { |
|
831 | - if ($limit) { |
|
832 | - $query_params['limit'] = $limit; |
|
833 | - } |
|
834 | - return $query_params; |
|
835 | - } |
|
836 | - |
|
837 | - |
|
838 | - /** |
|
839 | - * @param array $query_params |
|
840 | - * @param string $order_by |
|
841 | - * @param string $order |
|
842 | - * @return array |
|
843 | - * @since $VID:$ |
|
844 | - */ |
|
845 | - private function addOrderByQueryParams(array $query_params, $order_by = 'DTT_EVT_start', $order = 'ASC') |
|
846 | - { |
|
847 | - $order = $order === 'ASC' ? 'ASC' : 'DESC'; |
|
848 | - $valid_order_columns = ['DTT_ID', 'DTT_EVT_start', 'DTT_EVT_end', 'DTT_order']; |
|
849 | - $order_by = in_array($order_by, $valid_order_columns, true) ? $order_by : 'DTT_EVT_start'; |
|
850 | - $query_params['order_by'] = [$order_by => $order]; |
|
851 | - return $query_params; |
|
852 | - } |
|
15 | + /** |
|
16 | + * @var EEM_Datetime $_instance |
|
17 | + */ |
|
18 | + protected static $_instance; |
|
19 | + |
|
20 | + |
|
21 | + /** |
|
22 | + * private constructor to prevent direct creation |
|
23 | + * |
|
24 | + * @param string $timezone A string representing the timezone we want to set for returned Date Time Strings |
|
25 | + * (and any incoming timezone data that gets saved). |
|
26 | + * Note this just sends the timezone info to the date time model field objects. |
|
27 | + * Default is NULL |
|
28 | + * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
29 | + * @throws EE_Error |
|
30 | + * @throws InvalidArgumentException |
|
31 | + * @throws InvalidArgumentException |
|
32 | + */ |
|
33 | + protected function __construct($timezone) |
|
34 | + { |
|
35 | + $this->singular_item = esc_html__('Datetime', 'event_espresso'); |
|
36 | + $this->plural_item = esc_html__('Datetimes', 'event_espresso'); |
|
37 | + $this->_tables = [ |
|
38 | + 'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'), |
|
39 | + ]; |
|
40 | + $this->_fields = [ |
|
41 | + 'Datetime' => [ |
|
42 | + 'DTT_ID' => new EE_Primary_Key_Int_Field( |
|
43 | + 'DTT_ID', |
|
44 | + esc_html__('Datetime ID', 'event_espresso') |
|
45 | + ), |
|
46 | + 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
47 | + 'EVT_ID', |
|
48 | + esc_html__('Event ID', 'event_espresso'), |
|
49 | + false, |
|
50 | + 0, |
|
51 | + 'Event' |
|
52 | + ), |
|
53 | + 'VNU_ID' => new EE_Foreign_Key_Int_Field( |
|
54 | + 'VNU_ID', |
|
55 | + __('Venue ID', 'event_espresso'), |
|
56 | + false, |
|
57 | + 0, |
|
58 | + 'Venue' |
|
59 | + ), |
|
60 | + 'DTT_name' => new EE_Plain_Text_Field( |
|
61 | + 'DTT_name', |
|
62 | + esc_html__('Datetime Name', 'event_espresso'), |
|
63 | + false, |
|
64 | + '' |
|
65 | + ), |
|
66 | + 'DTT_description' => new EE_Post_Content_Field( |
|
67 | + 'DTT_description', |
|
68 | + esc_html__('Description for Datetime', 'event_espresso'), |
|
69 | + false, |
|
70 | + '' |
|
71 | + ), |
|
72 | + 'DTT_EVT_start' => new EE_Datetime_Field( |
|
73 | + 'DTT_EVT_start', |
|
74 | + esc_html__('Start time/date of Event', 'event_espresso'), |
|
75 | + false, |
|
76 | + EE_Datetime_Field::now, |
|
77 | + $timezone |
|
78 | + ), |
|
79 | + 'DTT_EVT_end' => new EE_Datetime_Field( |
|
80 | + 'DTT_EVT_end', |
|
81 | + esc_html__('End time/date of Event', 'event_espresso'), |
|
82 | + false, |
|
83 | + EE_Datetime_Field::now, |
|
84 | + $timezone |
|
85 | + ), |
|
86 | + 'DTT_reg_limit' => new EE_Infinite_Integer_Field( |
|
87 | + 'DTT_reg_limit', |
|
88 | + esc_html__('Registration Limit for this time', 'event_espresso'), |
|
89 | + true, |
|
90 | + EE_INF |
|
91 | + ), |
|
92 | + 'DTT_sold' => new EE_Integer_Field( |
|
93 | + 'DTT_sold', |
|
94 | + esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'), |
|
95 | + true, |
|
96 | + 0 |
|
97 | + ), |
|
98 | + 'DTT_reserved' => new EE_Integer_Field( |
|
99 | + 'DTT_reserved', |
|
100 | + esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'), |
|
101 | + false, |
|
102 | + 0 |
|
103 | + ), |
|
104 | + 'DTT_is_primary' => new EE_Boolean_Field( |
|
105 | + 'DTT_is_primary', |
|
106 | + esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'), |
|
107 | + false, |
|
108 | + false |
|
109 | + ), |
|
110 | + 'DTT_order' => new EE_Integer_Field( |
|
111 | + 'DTT_order', |
|
112 | + esc_html__('The order in which the Datetime is displayed', 'event_espresso'), |
|
113 | + false, |
|
114 | + 0 |
|
115 | + ), |
|
116 | + 'DTT_parent' => new EE_Integer_Field( |
|
117 | + 'DTT_parent', |
|
118 | + esc_html__('Indicates what DTT_ID is the parent of this DTT_ID', 'event_espresso'), |
|
119 | + true, |
|
120 | + 0 |
|
121 | + ), |
|
122 | + 'DTT_deleted' => new EE_Trashed_Flag_Field( |
|
123 | + 'DTT_deleted', |
|
124 | + esc_html__('Flag indicating datetime is archived', 'event_espresso'), |
|
125 | + false, |
|
126 | + false |
|
127 | + ), |
|
128 | + ], |
|
129 | + ]; |
|
130 | + $this->_model_relations = [ |
|
131 | + 'Ticket' => new EE_HABTM_Relation('Datetime_Ticket'), |
|
132 | + 'Event' => new EE_Belongs_To_Relation(), |
|
133 | + 'Checkin' => new EE_Has_Many_Relation(), |
|
134 | + 'Datetime_Ticket' => new EE_Has_Many_Relation(), |
|
135 | + 'Venue' => new EE_Belongs_To_Relation(), |
|
136 | + ]; |
|
137 | + $path_to_event_model = 'Event'; |
|
138 | + $this->model_chain_to_password = $path_to_event_model; |
|
139 | + $this->_model_chain_to_wp_user = $path_to_event_model; |
|
140 | + // this model is generally available for reading |
|
141 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = |
|
142 | + new EE_Restriction_Generator_Event_Related_Public( |
|
143 | + $path_to_event_model |
|
144 | + ); |
|
145 | + $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
146 | + new EE_Restriction_Generator_Event_Related_Protected( |
|
147 | + $path_to_event_model |
|
148 | + ); |
|
149 | + $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = |
|
150 | + new EE_Restriction_Generator_Event_Related_Protected( |
|
151 | + $path_to_event_model |
|
152 | + ); |
|
153 | + $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
154 | + new EE_Restriction_Generator_Event_Related_Protected( |
|
155 | + $path_to_event_model, |
|
156 | + EEM_Base::caps_edit |
|
157 | + ); |
|
158 | + parent::__construct($timezone); |
|
159 | + } |
|
160 | + |
|
161 | + |
|
162 | + /** |
|
163 | + * create new blank datetime |
|
164 | + * |
|
165 | + * @access public |
|
166 | + * @return EE_Datetime[] array on success, FALSE on fail |
|
167 | + * @throws EE_Error |
|
168 | + * @throws InvalidArgumentException |
|
169 | + * @throws InvalidDataTypeException |
|
170 | + * @throws ReflectionException |
|
171 | + * @throws InvalidInterfaceException |
|
172 | + */ |
|
173 | + public function create_new_blank_datetime() |
|
174 | + { |
|
175 | + // makes sure timezone is always set. |
|
176 | + $timezone_string = $this->get_timezone(); |
|
177 | + /** |
|
178 | + * Filters the initial start date for the new datetime. |
|
179 | + * Any time included in this value will be overridden later so use additional filters to modify the time. |
|
180 | + * |
|
181 | + * @param int $start_date Unix timestamp representing now + 30 days in seconds. |
|
182 | + * @return int Unix timestamp |
|
183 | + */ |
|
184 | + $start_date = apply_filters( |
|
185 | + 'FHEE__EEM_Datetime__create_new_blank_datetime__start_date', |
|
186 | + $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS |
|
187 | + ); |
|
188 | + /** |
|
189 | + * Filters the initial end date for the new datetime. |
|
190 | + * Any time included in this value will be overridden later so use additional filters to modify the time. |
|
191 | + * |
|
192 | + * @param int $end_data Unix timestamp representing now + 30 days in seconds. |
|
193 | + * @return int Unix timestamp |
|
194 | + */ |
|
195 | + $end_date = apply_filters( |
|
196 | + 'FHEE__EEM_Datetime__create_new_blank_datetime__end_date', |
|
197 | + $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS |
|
198 | + ); |
|
199 | + $blank_datetime = EE_Datetime::new_instance( |
|
200 | + [ |
|
201 | + 'DTT_EVT_start' => $start_date, |
|
202 | + 'DTT_EVT_end' => $end_date, |
|
203 | + 'DTT_order' => 1, |
|
204 | + 'DTT_reg_limit' => EE_INF, |
|
205 | + ], |
|
206 | + $timezone_string |
|
207 | + ); |
|
208 | + /** |
|
209 | + * Filters the initial start time and format for the new EE_Datetime instance. |
|
210 | + * |
|
211 | + * @param array $start_time An array having size 2. First element is the time, second element is the time |
|
212 | + * format. |
|
213 | + * @return array |
|
214 | + */ |
|
215 | + $start_time = apply_filters( |
|
216 | + 'FHEE__EEM_Datetime__create_new_blank_datetime__start_time', |
|
217 | + ['8am', 'ga'] |
|
218 | + ); |
|
219 | + /** |
|
220 | + * Filters the initial end time and format for the new EE_Datetime instance. |
|
221 | + * |
|
222 | + * @param array $end_time An array having size 2. First element is the time, second element is the time |
|
223 | + * format |
|
224 | + * @return array |
|
225 | + */ |
|
226 | + $end_time = apply_filters( |
|
227 | + 'FHEE__EEM_Datetime__create_new_blank_datetime__end_time', |
|
228 | + ['5pm', 'ga'] |
|
229 | + ); |
|
230 | + $this->validateStartAndEndTimeForBlankDate($start_time, $end_time); |
|
231 | + $blank_datetime->set_start_time( |
|
232 | + $this->convert_datetime_for_query( |
|
233 | + 'DTT_EVT_start', |
|
234 | + $start_time[0], |
|
235 | + $start_time[1], |
|
236 | + $timezone_string |
|
237 | + ) |
|
238 | + ); |
|
239 | + $blank_datetime->set_end_time( |
|
240 | + $this->convert_datetime_for_query( |
|
241 | + 'DTT_EVT_end', |
|
242 | + $end_time[0], |
|
243 | + $end_time[1], |
|
244 | + $timezone_string |
|
245 | + ) |
|
246 | + ); |
|
247 | + return [$blank_datetime]; |
|
248 | + } |
|
249 | + |
|
250 | + |
|
251 | + /** |
|
252 | + * Validates whether the start_time and end_time are in the expected format. |
|
253 | + * |
|
254 | + * @param array $start_time |
|
255 | + * @param array $end_time |
|
256 | + * @throws InvalidArgumentException |
|
257 | + * @throws InvalidDataTypeException |
|
258 | + */ |
|
259 | + private function validateStartAndEndTimeForBlankDate(array $start_time, array $end_time) |
|
260 | + { |
|
261 | + if (! is_array($start_time)) { |
|
262 | + throw new InvalidDataTypeException('start_time', $start_time, 'array'); |
|
263 | + } |
|
264 | + if (! is_array($end_time)) { |
|
265 | + throw new InvalidDataTypeException('end_time', $end_time, 'array'); |
|
266 | + } |
|
267 | + if (count($start_time) !== 2) { |
|
268 | + throw new InvalidArgumentException( |
|
269 | + sprintf( |
|
270 | + 'The variable %1$s is expected to be an array with two elements. The first item in the ' |
|
271 | + . 'array should be a valid time string, the second item in the array should be a valid time format', |
|
272 | + '$start_time' |
|
273 | + ) |
|
274 | + ); |
|
275 | + } |
|
276 | + if (count($end_time) !== 2) { |
|
277 | + throw new InvalidArgumentException( |
|
278 | + sprintf( |
|
279 | + 'The variable %1$s is expected to be an array with two elements. The first item in the ' |
|
280 | + . 'array should be a valid time string, the second item in the array should be a valid time format', |
|
281 | + '$end_time' |
|
282 | + ) |
|
283 | + ); |
|
284 | + } |
|
285 | + } |
|
286 | + |
|
287 | + |
|
288 | + /** |
|
289 | + * get event start date from db |
|
290 | + * |
|
291 | + * @access public |
|
292 | + * @param int $EVT_ID |
|
293 | + * @return EE_Datetime[] array on success, FALSE on fail |
|
294 | + * @throws EE_Error |
|
295 | + * @throws ReflectionException |
|
296 | + */ |
|
297 | + public function get_all_event_dates($EVT_ID = 0) |
|
298 | + { |
|
299 | + if (! $EVT_ID) { // on add_new_event event_id gets set to 0 |
|
300 | + return $this->create_new_blank_datetime(); |
|
301 | + } |
|
302 | + $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID); |
|
303 | + if (empty($results)) { |
|
304 | + return $this->create_new_blank_datetime(); |
|
305 | + } |
|
306 | + return $results; |
|
307 | + } |
|
308 | + |
|
309 | + |
|
310 | + /** |
|
311 | + * get all datetimes attached to an event ordered by the DTT_order field |
|
312 | + * |
|
313 | + * @public |
|
314 | + * @param int $EVT_ID event id |
|
315 | + * @param boolean $include_expired |
|
316 | + * @param boolean $include_deleted |
|
317 | + * @param int $limit If included then limit the count of results by |
|
318 | + * the given number |
|
319 | + * @return EE_Datetime[] |
|
320 | + * @throws EE_Error |
|
321 | + */ |
|
322 | + public function get_datetimes_for_event_ordered_by_DTT_order( |
|
323 | + int $EVT_ID, |
|
324 | + bool $include_expired = true, |
|
325 | + bool $include_deleted = true, |
|
326 | + $limit = 0 |
|
327 | + ) { |
|
328 | + $prev_data_prep_value = $this->prepModelForQuery(); |
|
329 | + $where_params = ['Event.EVT_ID' => absint($EVT_ID)]; |
|
330 | + $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
331 | + $query_params = $this->addDefaultWhereConditions($query_params); |
|
332 | + $query_params = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order'); |
|
333 | + return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
334 | + } |
|
335 | + |
|
336 | + |
|
337 | + /** |
|
338 | + * Gets the datetimes for the event (with the given limit), and orders them by "importance". |
|
339 | + * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW), |
|
340 | + * and then the earlier datetimes are the most important. |
|
341 | + * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet. |
|
342 | + * |
|
343 | + * @param int $EVT_ID |
|
344 | + * @param int $limit |
|
345 | + * @return EE_Datetime[]|EE_Base_Class[] |
|
346 | + * @throws EE_Error |
|
347 | + */ |
|
348 | + public function get_datetimes_for_event_ordered_by_importance(int $EVT_ID, $limit = 0) |
|
349 | + { |
|
350 | + $query_params[0] = ['Event.EVT_ID' => absint($EVT_ID)]; |
|
351 | + $query_params = $this->addDefaultWhereConditions($query_params); |
|
352 | + $query_params = $this->addDefaultQueryParams($query_params, $limit); |
|
353 | + return $this->get_all($query_params); |
|
354 | + } |
|
355 | + |
|
356 | + |
|
357 | + /** |
|
358 | + * @param int $EVT_ID |
|
359 | + * @param boolean $include_expired |
|
360 | + * @param boolean $include_deleted |
|
361 | + * @return EE_Datetime |
|
362 | + * @throws EE_Error |
|
363 | + */ |
|
364 | + public function get_oldest_datetime_for_event( |
|
365 | + int $EVT_ID, |
|
366 | + bool $include_expired = false, |
|
367 | + bool $include_deleted = false |
|
368 | + ) { |
|
369 | + $results = $this->get_datetimes_for_event_ordered_by_start_time( |
|
370 | + $EVT_ID, |
|
371 | + $include_expired, |
|
372 | + $include_deleted, |
|
373 | + 1 |
|
374 | + ); |
|
375 | + if ($results) { |
|
376 | + return array_shift($results); |
|
377 | + } |
|
378 | + return null; |
|
379 | + } |
|
380 | + |
|
381 | + |
|
382 | + /** |
|
383 | + * Gets the 'primary' datetime for an event. |
|
384 | + * |
|
385 | + * @param int $EVT_ID |
|
386 | + * @param bool $try_to_exclude_expired |
|
387 | + * @param bool $try_to_exclude_deleted |
|
388 | + * @return EE_Datetime |
|
389 | + * @throws EE_Error |
|
390 | + */ |
|
391 | + public function get_primary_datetime_for_event( |
|
392 | + int $EVT_ID, |
|
393 | + bool $try_to_exclude_expired = true, |
|
394 | + bool $try_to_exclude_deleted = true |
|
395 | + ) { |
|
396 | + if ($try_to_exclude_expired) { |
|
397 | + $non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false); |
|
398 | + if ($non_expired) { |
|
399 | + return $non_expired; |
|
400 | + } |
|
401 | + } |
|
402 | + if ($try_to_exclude_deleted) { |
|
403 | + $expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true); |
|
404 | + if ($expired_even) { |
|
405 | + return $expired_even; |
|
406 | + } |
|
407 | + } |
|
408 | + return $this->get_oldest_datetime_for_event($EVT_ID, true, true); |
|
409 | + } |
|
410 | + |
|
411 | + |
|
412 | + /** |
|
413 | + * Gets ALL the datetimes for an event (including trashed ones, for now), ordered |
|
414 | + * only by start date |
|
415 | + * |
|
416 | + * @param int $EVT_ID |
|
417 | + * @param boolean $include_expired |
|
418 | + * @param boolean $include_deleted |
|
419 | + * @param int $limit |
|
420 | + * @return EE_Datetime[] |
|
421 | + * @throws EE_Error |
|
422 | + */ |
|
423 | + public function get_datetimes_for_event_ordered_by_start_time( |
|
424 | + int $EVT_ID, |
|
425 | + bool $include_expired = true, |
|
426 | + bool $include_deleted = true, |
|
427 | + $limit = 0 |
|
428 | + ) { |
|
429 | + $prev_data_prep_value = $this->prepModelForQuery(); |
|
430 | + $where_params = ['Event.EVT_ID' => absint($EVT_ID)]; |
|
431 | + $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
432 | + $query_params = $this->addDefaultWhereConditions( |
|
433 | + $query_params, |
|
434 | + EEM_Base::default_where_conditions_this_only |
|
435 | + ); |
|
436 | + $query_params = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order'); |
|
437 | + return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
438 | + } |
|
439 | + |
|
440 | + |
|
441 | + /** |
|
442 | + * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered |
|
443 | + * only by start date |
|
444 | + * |
|
445 | + * @param int $TKT_ID |
|
446 | + * @param boolean $include_expired |
|
447 | + * @param boolean $include_deleted |
|
448 | + * @param int $limit |
|
449 | + * @return EE_Datetime[] |
|
450 | + * @throws EE_Error |
|
451 | + */ |
|
452 | + public function get_datetimes_for_ticket_ordered_by_start_time( |
|
453 | + int $TKT_ID, |
|
454 | + bool $include_expired = true, |
|
455 | + bool $include_deleted = true, |
|
456 | + $limit = 0 |
|
457 | + ) { |
|
458 | + $prev_data_prep_value = $this->prepModelForQuery(); |
|
459 | + $where_params = ['Ticket.TKT_ID' => absint($TKT_ID)]; |
|
460 | + $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
461 | + $query_params = $this->addDefaultQueryParams($query_params, $limit); |
|
462 | + return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
463 | + } |
|
464 | + |
|
465 | + |
|
466 | + /** |
|
467 | + * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the |
|
468 | + * datetimes. |
|
469 | + * |
|
470 | + * @param int $TKT_ID ID of ticket to retrieve the datetimes for |
|
471 | + * @param boolean $include_expired whether to include expired datetimes or not |
|
472 | + * @param boolean $include_deleted whether to include trashed datetimes or not. |
|
473 | + * @param int|null $limit if null, no limit, if int then limit results by |
|
474 | + * that number |
|
475 | + * @return EE_Datetime[] |
|
476 | + * @throws EE_Error |
|
477 | + */ |
|
478 | + public function get_datetimes_for_ticket_ordered_by_DTT_order( |
|
479 | + int $TKT_ID, |
|
480 | + bool $include_expired = true, |
|
481 | + bool $include_deleted = true, |
|
482 | + $limit = 0 |
|
483 | + ) { |
|
484 | + $prev_data_prep_value = $this->prepModelForQuery(); |
|
485 | + $where_params = ['Ticket.TKT_ID' => absint($TKT_ID)]; |
|
486 | + $query_params[0] = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired); |
|
487 | + $query_params = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order'); |
|
488 | + return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value); |
|
489 | + } |
|
490 | + |
|
491 | + |
|
492 | + /** |
|
493 | + * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK |
|
494 | + * reason it doesn't exist, we consider the earliest event the most important) |
|
495 | + * |
|
496 | + * @param int $EVT_ID |
|
497 | + * @return EE_Datetime |
|
498 | + * @throws EE_Error |
|
499 | + */ |
|
500 | + public function get_most_important_datetime_for_event(int $EVT_ID) |
|
501 | + { |
|
502 | + $results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1); |
|
503 | + if ($results) { |
|
504 | + return array_shift($results); |
|
505 | + } |
|
506 | + return null; |
|
507 | + } |
|
508 | + |
|
509 | + |
|
510 | + /** |
|
511 | + * This returns a wpdb->results Array of all DTT month and years matching the incoming query params and |
|
512 | + * grouped by month and year. |
|
513 | + * |
|
514 | + * @param array $where_params @see |
|
515 | + * https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
516 | + * @param string $evt_active_status A string representing the evt active status to filter the months by. |
|
517 | + * Can be: |
|
518 | + * - '' = no filter |
|
519 | + * - upcoming = Published events with at least one upcoming datetime. |
|
520 | + * - expired = Events with all datetimes expired. |
|
521 | + * - active = Events that are published and have at least one datetime that |
|
522 | + * starts before now and ends after now. |
|
523 | + * - inactive = Events that are either not published. |
|
524 | + * @return stdClass[] |
|
525 | + * @throws EE_Error |
|
526 | + * @throws InvalidArgumentException |
|
527 | + * @throws InvalidArgumentException |
|
528 | + */ |
|
529 | + public function get_dtt_months_and_years(array $where_params, $evt_active_status = '') |
|
530 | + { |
|
531 | + $current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start'); |
|
532 | + $current_time_for_DTT_EVT_end = $this->current_time_for_query('DTT_EVT_end'); |
|
533 | + switch ($evt_active_status) { |
|
534 | + case 'upcoming': |
|
535 | + $where_params['Event.status'] = 'publish'; |
|
536 | + // if there are already query_params matching DTT_EVT_start then we need to modify that to add them. |
|
537 | + if (isset($where_params['DTT_EVT_start'])) { |
|
538 | + $where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start']; |
|
539 | + } |
|
540 | + $where_params['DTT_EVT_start'] = ['>', $current_time_for_DTT_EVT_start]; |
|
541 | + break; |
|
542 | + case 'expired': |
|
543 | + if (isset($where_params['Event.status'])) { |
|
544 | + unset($where_params['Event.status']); |
|
545 | + } |
|
546 | + // get events to exclude |
|
547 | + $exclude_query[0] = array_merge( |
|
548 | + $where_params, |
|
549 | + ['DTT_EVT_end' => ['>', $current_time_for_DTT_EVT_end]] |
|
550 | + ); |
|
551 | + // first get all events that have datetimes where its not expired. |
|
552 | + $event_ids = $this->_get_all_wpdb_results( |
|
553 | + $exclude_query, |
|
554 | + OBJECT_K, |
|
555 | + 'Datetime.EVT_ID' |
|
556 | + ); |
|
557 | + $event_ids = array_keys($event_ids); |
|
558 | + if (isset($where_params['DTT_EVT_end'])) { |
|
559 | + $where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end']; |
|
560 | + } |
|
561 | + $where_params['DTT_EVT_end'] = ['<', $current_time_for_DTT_EVT_end]; |
|
562 | + $where_params['Event.EVT_ID'] = ['NOT IN', $event_ids]; |
|
563 | + break; |
|
564 | + case 'active': |
|
565 | + $where_params['Event.status'] = 'publish'; |
|
566 | + if (isset($where_params['DTT_EVT_start'])) { |
|
567 | + $where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start']; |
|
568 | + } |
|
569 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
570 | + $where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end']; |
|
571 | + } |
|
572 | + $where_params['DTT_EVT_start'] = ['<', $current_time_for_DTT_EVT_start]; |
|
573 | + $where_params['DTT_EVT_end'] = ['>', $current_time_for_DTT_EVT_end]; |
|
574 | + break; |
|
575 | + case 'inactive': |
|
576 | + if (isset($where_params['Event.status'])) { |
|
577 | + unset($where_params['Event.status']); |
|
578 | + } |
|
579 | + if (isset($where_params['OR'])) { |
|
580 | + $where_params['AND']['OR'] = $where_params['OR']; |
|
581 | + } |
|
582 | + if (isset($where_params['DTT_EVT_end'])) { |
|
583 | + $where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end']; |
|
584 | + unset($where_params['DTT_EVT_end']); |
|
585 | + } |
|
586 | + if (isset($where_params['DTT_EVT_start'])) { |
|
587 | + $where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start']; |
|
588 | + unset($where_params['DTT_EVT_start']); |
|
589 | + } |
|
590 | + $where_params['AND']['Event.status'] = ['!=', 'publish']; |
|
591 | + break; |
|
592 | + } |
|
593 | + $query_params[0] = $where_params; |
|
594 | + $query_params['group_by'] = ['dtt_year', 'dtt_month']; |
|
595 | + $query_params = $this->addOrderByQueryParams($query_params, 'DTT_EVT_start', 'DESC'); |
|
596 | + |
|
597 | + $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset( |
|
598 | + $this->get_timezone(), |
|
599 | + 'DTT_EVT_start' |
|
600 | + ); |
|
601 | + $columns_to_select = [ |
|
602 | + 'dtt_year' => ['YEAR(' . $query_interval . ')', '%s'], |
|
603 | + 'dtt_month' => ['MONTHNAME(' . $query_interval . ')', '%s'], |
|
604 | + 'dtt_month_num' => ['MONTH(' . $query_interval . ')', '%s'], |
|
605 | + ]; |
|
606 | + return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select); |
|
607 | + } |
|
608 | + |
|
609 | + |
|
610 | + /** |
|
611 | + * Updates the DTT_sold attribute on each datetime (based on the registrations |
|
612 | + * for the tickets for each datetime) |
|
613 | + * |
|
614 | + * @param EE_Base_Class[]|EE_Datetime[] $datetimes |
|
615 | + * @throws EE_Error |
|
616 | + * @throws ReflectionException |
|
617 | + */ |
|
618 | + public function update_sold(array $datetimes) |
|
619 | + { |
|
620 | + EE_Error::doing_it_wrong( |
|
621 | + __FUNCTION__, |
|
622 | + esc_html__( |
|
623 | + 'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.', |
|
624 | + 'event_espresso' |
|
625 | + ), |
|
626 | + '4.9.32.rc.005' |
|
627 | + ); |
|
628 | + foreach ($datetimes as $datetime) { |
|
629 | + $datetime->update_sold(); |
|
630 | + } |
|
631 | + } |
|
632 | + |
|
633 | + |
|
634 | + /** |
|
635 | + * Gets the total number of tickets available at a particular datetime |
|
636 | + * (does NOT take into account the datetime's spaces available) |
|
637 | + * |
|
638 | + * @param int $DTT_ID |
|
639 | + * @param array $query_params |
|
640 | + * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF, IF there are NO |
|
641 | + * tickets attached to datetime then FALSE is returned. |
|
642 | + * @throws EE_Error |
|
643 | + * @throws ReflectionException |
|
644 | + */ |
|
645 | + public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = []) |
|
646 | + { |
|
647 | + $datetime = $this->get_one_by_ID($DTT_ID); |
|
648 | + if ($datetime instanceof EE_Datetime) { |
|
649 | + return $datetime->tickets_remaining($query_params); |
|
650 | + } |
|
651 | + return 0; |
|
652 | + } |
|
653 | + |
|
654 | + |
|
655 | + /** |
|
656 | + * This returns an array of counts of datetimes in the database for each Datetime status that can be queried. |
|
657 | + * |
|
658 | + * @param array $stati_to_include If included you can restrict the statuses we return counts for by including the |
|
659 | + * stati you want counts for as values in the array. An empty array returns counts |
|
660 | + * for all valid stati. |
|
661 | + * @param array $query_params If included can be used to refine the conditions for returning the count (i.e. |
|
662 | + * only for Datetimes connected to a specific event, or specific ticket. |
|
663 | + * @return array The value returned is an array indexed by Datetime Status and the values are the counts. The |
|
664 | + * @throws EE_Error |
|
665 | + * stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming |
|
666 | + * EE_Datetime::expired |
|
667 | + */ |
|
668 | + public function get_datetime_counts_by_status(array $stati_to_include = [], array $query_params = []) |
|
669 | + { |
|
670 | + // only accept where conditions for this query. |
|
671 | + $_where = isset($query_params[0]) ? $query_params[0] : []; |
|
672 | + $status_query_args = [ |
|
673 | + EE_Datetime::active => array_merge( |
|
674 | + $_where, |
|
675 | + ['DTT_EVT_start' => ['<', time()], 'DTT_EVT_end' => ['>', time()]] |
|
676 | + ), |
|
677 | + EE_Datetime::upcoming => array_merge( |
|
678 | + $_where, |
|
679 | + ['DTT_EVT_start' => ['>', time()]] |
|
680 | + ), |
|
681 | + EE_Datetime::expired => array_merge( |
|
682 | + $_where, |
|
683 | + ['DTT_EVT_end' => ['<', time()]] |
|
684 | + ), |
|
685 | + ]; |
|
686 | + if (! empty($stati_to_include)) { |
|
687 | + foreach (array_keys($status_query_args) as $status) { |
|
688 | + if (! in_array($status, $stati_to_include, true)) { |
|
689 | + unset($status_query_args[ $status ]); |
|
690 | + } |
|
691 | + } |
|
692 | + } |
|
693 | + // loop through and query counts for each stati. |
|
694 | + $status_query_results = []; |
|
695 | + foreach ($status_query_args as $status => $status_where_conditions) { |
|
696 | + $status_query_results[ $status ] = EEM_Datetime::count( |
|
697 | + [$status_where_conditions], |
|
698 | + 'DTT_ID', |
|
699 | + true |
|
700 | + ); |
|
701 | + } |
|
702 | + return $status_query_results; |
|
703 | + } |
|
704 | + |
|
705 | + |
|
706 | + /** |
|
707 | + * Returns the specific count for a given Datetime status matching any given query_params. |
|
708 | + * |
|
709 | + * @param string $status Valid string representation for Datetime status requested. (Defaults to Active). |
|
710 | + * @param array $query_params |
|
711 | + * @return int |
|
712 | + * @throws EE_Error |
|
713 | + */ |
|
714 | + public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = []) |
|
715 | + { |
|
716 | + $count = $this->get_datetime_counts_by_status([$status], $query_params); |
|
717 | + return ! empty($count[ $status ]) ? $count[ $status ] : 0; |
|
718 | + } |
|
719 | + |
|
720 | + |
|
721 | + /** |
|
722 | + * @return bool|int |
|
723 | + * @since $VID:$ |
|
724 | + */ |
|
725 | + private function prepModelForQuery() |
|
726 | + { |
|
727 | + $prev_data_prep_value = $this->get_assumption_concerning_values_already_prepared_by_model_object(); |
|
728 | + $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db); |
|
729 | + return $prev_data_prep_value; |
|
730 | + } |
|
731 | + |
|
732 | + |
|
733 | + /** |
|
734 | + * @param array $query_params |
|
735 | + * @param bool|int $prev_data_prep_value |
|
736 | + * @return EE_Base_Class[]|EE_Datetime[] |
|
737 | + * @throws EE_Error |
|
738 | + * @since $VID:$ |
|
739 | + */ |
|
740 | + private function getDatetimesAndRestoreModel(array $query_params, $prev_data_prep_value) |
|
741 | + { |
|
742 | + $result = $this->get_all($query_params); |
|
743 | + $this->assume_values_already_prepared_by_model_object($prev_data_prep_value); |
|
744 | + return $result; |
|
745 | + } |
|
746 | + |
|
747 | + |
|
748 | + /** |
|
749 | + * @param array $query_params |
|
750 | + * @param int $limit |
|
751 | + * @param string $order_by |
|
752 | + * @param string $order |
|
753 | + * @return array |
|
754 | + * @since $VID:$ |
|
755 | + */ |
|
756 | + private function addDefaultQueryParams(array $query_params, $limit = 0, $order_by = 'DTT_EVT_start', $order = 'ASC') |
|
757 | + { |
|
758 | + $query_params = $this->addOrderByQueryParams($query_params, $order_by, $order); |
|
759 | + $query_params = $this->addLimitQueryParams($query_params, $limit); |
|
760 | + return $query_params; |
|
761 | + } |
|
762 | + |
|
763 | + |
|
764 | + /** |
|
765 | + * @param array $query_params |
|
766 | + * @param string $default_where_conditions |
|
767 | + * @return array |
|
768 | + * @since $VID:$ |
|
769 | + */ |
|
770 | + private function addDefaultWhereConditions( |
|
771 | + array $query_params, |
|
772 | + $default_where_conditions = EEM_Base::default_where_conditions_none |
|
773 | + ) { |
|
774 | + $query_params['default_where_conditions'] = $default_where_conditions; |
|
775 | + return $query_params; |
|
776 | + } |
|
777 | + |
|
778 | + |
|
779 | + /** |
|
780 | + * @param array $where_params |
|
781 | + * @param bool $include_deleted |
|
782 | + * @param bool $include_expired |
|
783 | + * @return array |
|
784 | + * @since $VID:$ |
|
785 | + */ |
|
786 | + private function addDefaultWhereParams(array $where_params, bool $include_deleted = true, bool $include_expired = true) |
|
787 | + { |
|
788 | + $where_params = $this->addExpiredWhereParams($where_params, $include_expired); |
|
789 | + $where_params = $this->addDeletedWhereParams($where_params, $include_deleted); |
|
790 | + return $where_params; |
|
791 | + } |
|
792 | + |
|
793 | + |
|
794 | + /** |
|
795 | + * @param array $where_params |
|
796 | + * @param bool $include_deleted |
|
797 | + * @return array |
|
798 | + * @since $VID:$ |
|
799 | + */ |
|
800 | + private function addDeletedWhereParams(array $where_params, bool $include_deleted = true) |
|
801 | + { |
|
802 | + $deleted = $include_deleted ? [true, false] : [false]; |
|
803 | + $where_params['DTT_deleted'] = ['IN', $deleted]; |
|
804 | + return $where_params; |
|
805 | + } |
|
806 | + |
|
807 | + |
|
808 | + /** |
|
809 | + * @param array $where_params |
|
810 | + * @param bool $include_expired |
|
811 | + * @return array |
|
812 | + * @since $VID:$ |
|
813 | + */ |
|
814 | + private function addExpiredWhereParams(array $where_params, bool $include_expired = true) |
|
815 | + { |
|
816 | + if (! $include_expired) { |
|
817 | + $where_params['DTT_EVT_end'] = ['>=', current_time('mysql', true)]; |
|
818 | + } |
|
819 | + return $where_params; |
|
820 | + } |
|
821 | + |
|
822 | + |
|
823 | + /** |
|
824 | + * @param array $query_params |
|
825 | + * @param int $limit |
|
826 | + * @return array |
|
827 | + * @since $VID:$ |
|
828 | + */ |
|
829 | + private function addLimitQueryParams(array $query_params, $limit = 0) |
|
830 | + { |
|
831 | + if ($limit) { |
|
832 | + $query_params['limit'] = $limit; |
|
833 | + } |
|
834 | + return $query_params; |
|
835 | + } |
|
836 | + |
|
837 | + |
|
838 | + /** |
|
839 | + * @param array $query_params |
|
840 | + * @param string $order_by |
|
841 | + * @param string $order |
|
842 | + * @return array |
|
843 | + * @since $VID:$ |
|
844 | + */ |
|
845 | + private function addOrderByQueryParams(array $query_params, $order_by = 'DTT_EVT_start', $order = 'ASC') |
|
846 | + { |
|
847 | + $order = $order === 'ASC' ? 'ASC' : 'DESC'; |
|
848 | + $valid_order_columns = ['DTT_ID', 'DTT_EVT_start', 'DTT_EVT_end', 'DTT_order']; |
|
849 | + $order_by = in_array($order_by, $valid_order_columns, true) ? $order_by : 'DTT_EVT_start'; |
|
850 | + $query_params['order_by'] = [$order_by => $order]; |
|
851 | + return $query_params; |
|
852 | + } |
|
853 | 853 | } |
@@ -14,164 +14,164 @@ |
||
14 | 14 | */ |
15 | 15 | class EE_Restriction_Generator_Default_Protected extends EE_Restriction_Generator_Base |
16 | 16 | { |
17 | - /** |
|
18 | - * Name of the field on this model (or a related model, including the model chain to it) |
|
19 | - * that is a boolean indicating whether or not a model object is considered "Default" or not |
|
20 | - * |
|
21 | - * @var string |
|
22 | - */ |
|
23 | - protected $_default_field_name; |
|
24 | - |
|
25 | - /** |
|
26 | - * The model chain to follow to get to the event model, including the event model itself. |
|
27 | - * Eg 'Ticket.Datetime.Event' |
|
28 | - * |
|
29 | - * @var string |
|
30 | - */ |
|
31 | - protected $_path_to_event_model; |
|
32 | - |
|
33 | - |
|
34 | - /** |
|
35 | - * @param string $default_field_name the name of the field Name of the field on this model |
|
36 | - * (or a related model, including the model chain to it) |
|
37 | - * that is a boolean indicating whether or not a model object |
|
38 | - * is considered "Default" or not |
|
39 | - * @param string $path_to_event_model The model chain to follow to get to the event model, |
|
40 | - * including the event model itself. Eg 'Ticket.Datetime.Event' |
|
41 | - */ |
|
42 | - public function __construct(string $default_field_name, string $path_to_event_model) |
|
43 | - { |
|
44 | - $this->_default_field_name = $default_field_name; |
|
45 | - $this->_path_to_event_model = rtrim($path_to_event_model, '.') . '.'; |
|
46 | - } |
|
47 | - |
|
48 | - |
|
49 | - /** |
|
50 | - * @return EE_Default_Where_Conditions[]|EE_Return_None_Where_Conditions[] |
|
51 | - * @throws EE_Error |
|
52 | - */ |
|
53 | - protected function _generate_restrictions(): array |
|
54 | - { |
|
55 | - // if there are no standard caps for this model, then for now |
|
56 | - // all we know is if they need the default cap to access this |
|
57 | - if (! $this->model()->cap_slug()) { |
|
58 | - return [ |
|
59 | - self::get_default_restrictions_cap() => new EE_Return_None_Where_Conditions(), |
|
60 | - ]; |
|
61 | - } |
|
62 | - |
|
63 | - $action = $this->action(); |
|
64 | - $others = "{$action}_others"; |
|
65 | - $private = "{$action}_private"; |
|
66 | - $default = "{$action}_default"; |
|
67 | - $others_default = "{$action}_others_default"; |
|
68 | - $event_model = EEM_Event::instance(); |
|
69 | - |
|
70 | - $restrictions = [ |
|
71 | - // first: access to non-defaults is essentially controlled by which events are accessible |
|
72 | - // if they don't have the basic event cap, they can't access ANY non-default items |
|
73 | - $this->getCapKey($event_model, $action) => $this->nonDefaultRestrictions(true), |
|
74 | - // if they don't have the others event cap, they can't access others' non-default items |
|
75 | - $this->getCapKey($event_model, $others) => $this->othersNonDefaultRestrictions($event_model, $others), |
|
76 | - // if they have basic and others, but not private, they can't access others' private non-default items |
|
77 | - $this->getCapKey($event_model, $private) => $this->privateRestrictions($event_model, $private), |
|
78 | - // second: access to defaults is controlled by the default capabilities |
|
79 | - // if they don't have the default capability, restrict access to only non-default items |
|
80 | - $this->getCapKey($this->model(), $default) => $this->nonDefaultRestrictions(false), |
|
81 | - ]; |
|
82 | - // if they don't have the "others" default capability, |
|
83 | - // restrict access to only their default ones, and non-default ones |
|
84 | - if (EE_Restriction_Generator_Base::is_cap($this->model(), $others_default)) { |
|
85 | - $restrictions[ $this->getCapKey($this->model(), $others_default) ] = $this->othersDefaultRestrictions( |
|
86 | - $others_default |
|
87 | - ); |
|
88 | - } |
|
89 | - return $restrictions; |
|
90 | - } |
|
91 | - |
|
92 | - |
|
93 | - /** |
|
94 | - * @param EEM_Base $model |
|
95 | - * @param string $action |
|
96 | - * @return string |
|
97 | - * @since $VID:$ |
|
98 | - */ |
|
99 | - private function getCapKey(EEM_Base $model, string $action): string |
|
100 | - { |
|
101 | - return EE_Restriction_Generator_Base::get_cap_name($model, $action); |
|
102 | - } |
|
103 | - |
|
104 | - |
|
105 | - /** |
|
106 | - * @param bool $use_default_field_name |
|
107 | - * @return EE_Default_Where_Conditions |
|
108 | - * @since $VID:$ |
|
109 | - */ |
|
110 | - private function nonDefaultRestrictions(bool $use_default_field_name): EE_Default_Where_Conditions |
|
111 | - { |
|
112 | - return new EE_Default_Where_Conditions([$this->_default_field_name => $use_default_field_name]); |
|
113 | - } |
|
114 | - |
|
115 | - |
|
116 | - /** |
|
117 | - * @param string $action |
|
118 | - * @return EE_Default_Where_Conditions |
|
119 | - * @throws EE_Error |
|
120 | - * @since $VID:$ |
|
121 | - */ |
|
122 | - private function othersDefaultRestrictions(string $action): EE_Default_Where_Conditions |
|
123 | - { |
|
124 | - return new EE_Default_Where_Conditions( |
|
125 | - [ |
|
126 | - // if they don't have the others default cap, they can't access others default items |
|
127 | - // (but they can access their own default items, and non-default items) |
|
128 | - 'OR*no_' . $this->getCapKey($this->model(), $action) => [ |
|
129 | - 'AND' => [ |
|
130 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_QUERY_PLACEHOLDER_CURRENT_USER, |
|
131 | - $this->_default_field_name => true, |
|
132 | - ], |
|
133 | - $this->_default_field_name => false, |
|
134 | - ], |
|
135 | - ] |
|
136 | - ); |
|
137 | - } |
|
138 | - |
|
139 | - |
|
140 | - /** |
|
141 | - * @param EEM_Event $event_model |
|
142 | - * @param string $action |
|
143 | - * @return EE_Default_Where_Conditions |
|
144 | - * @since $VID:$ |
|
145 | - */ |
|
146 | - private function othersNonDefaultRestrictions(EEM_Event $event_model, string $action): EE_Default_Where_Conditions |
|
147 | - { |
|
148 | - return new EE_Default_Where_Conditions( |
|
149 | - [ |
|
150 | - 'OR*no_' . $this->getCapKey($event_model, $action) => [ |
|
151 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_QUERY_PLACEHOLDER_CURRENT_USER, |
|
152 | - ], |
|
153 | - $this->_default_field_name => true, |
|
154 | - ] |
|
155 | - ); |
|
156 | - } |
|
157 | - |
|
158 | - |
|
159 | - /** |
|
160 | - * @param EEM_Event $event_model |
|
161 | - * @param string $action |
|
162 | - * @return EE_Default_Where_Conditions |
|
163 | - * @since $VID:$ |
|
164 | - */ |
|
165 | - private function privateRestrictions(EEM_Event $event_model, string $action): EE_Default_Where_Conditions |
|
166 | - { |
|
167 | - return new EE_Default_Where_Conditions( |
|
168 | - [ |
|
169 | - 'OR*no_' . $this->getCapKey($event_model, $action) => [ |
|
170 | - $this->_path_to_event_model . 'EVT_wp_user' => EE_QUERY_PLACEHOLDER_CURRENT_USER, |
|
171 | - $this->_path_to_event_model . 'status' => ['!=', 'private'], |
|
172 | - $this->_default_field_name => true, |
|
173 | - ], |
|
174 | - ] |
|
175 | - ); |
|
176 | - } |
|
17 | + /** |
|
18 | + * Name of the field on this model (or a related model, including the model chain to it) |
|
19 | + * that is a boolean indicating whether or not a model object is considered "Default" or not |
|
20 | + * |
|
21 | + * @var string |
|
22 | + */ |
|
23 | + protected $_default_field_name; |
|
24 | + |
|
25 | + /** |
|
26 | + * The model chain to follow to get to the event model, including the event model itself. |
|
27 | + * Eg 'Ticket.Datetime.Event' |
|
28 | + * |
|
29 | + * @var string |
|
30 | + */ |
|
31 | + protected $_path_to_event_model; |
|
32 | + |
|
33 | + |
|
34 | + /** |
|
35 | + * @param string $default_field_name the name of the field Name of the field on this model |
|
36 | + * (or a related model, including the model chain to it) |
|
37 | + * that is a boolean indicating whether or not a model object |
|
38 | + * is considered "Default" or not |
|
39 | + * @param string $path_to_event_model The model chain to follow to get to the event model, |
|
40 | + * including the event model itself. Eg 'Ticket.Datetime.Event' |
|
41 | + */ |
|
42 | + public function __construct(string $default_field_name, string $path_to_event_model) |
|
43 | + { |
|
44 | + $this->_default_field_name = $default_field_name; |
|
45 | + $this->_path_to_event_model = rtrim($path_to_event_model, '.') . '.'; |
|
46 | + } |
|
47 | + |
|
48 | + |
|
49 | + /** |
|
50 | + * @return EE_Default_Where_Conditions[]|EE_Return_None_Where_Conditions[] |
|
51 | + * @throws EE_Error |
|
52 | + */ |
|
53 | + protected function _generate_restrictions(): array |
|
54 | + { |
|
55 | + // if there are no standard caps for this model, then for now |
|
56 | + // all we know is if they need the default cap to access this |
|
57 | + if (! $this->model()->cap_slug()) { |
|
58 | + return [ |
|
59 | + self::get_default_restrictions_cap() => new EE_Return_None_Where_Conditions(), |
|
60 | + ]; |
|
61 | + } |
|
62 | + |
|
63 | + $action = $this->action(); |
|
64 | + $others = "{$action}_others"; |
|
65 | + $private = "{$action}_private"; |
|
66 | + $default = "{$action}_default"; |
|
67 | + $others_default = "{$action}_others_default"; |
|
68 | + $event_model = EEM_Event::instance(); |
|
69 | + |
|
70 | + $restrictions = [ |
|
71 | + // first: access to non-defaults is essentially controlled by which events are accessible |
|
72 | + // if they don't have the basic event cap, they can't access ANY non-default items |
|
73 | + $this->getCapKey($event_model, $action) => $this->nonDefaultRestrictions(true), |
|
74 | + // if they don't have the others event cap, they can't access others' non-default items |
|
75 | + $this->getCapKey($event_model, $others) => $this->othersNonDefaultRestrictions($event_model, $others), |
|
76 | + // if they have basic and others, but not private, they can't access others' private non-default items |
|
77 | + $this->getCapKey($event_model, $private) => $this->privateRestrictions($event_model, $private), |
|
78 | + // second: access to defaults is controlled by the default capabilities |
|
79 | + // if they don't have the default capability, restrict access to only non-default items |
|
80 | + $this->getCapKey($this->model(), $default) => $this->nonDefaultRestrictions(false), |
|
81 | + ]; |
|
82 | + // if they don't have the "others" default capability, |
|
83 | + // restrict access to only their default ones, and non-default ones |
|
84 | + if (EE_Restriction_Generator_Base::is_cap($this->model(), $others_default)) { |
|
85 | + $restrictions[ $this->getCapKey($this->model(), $others_default) ] = $this->othersDefaultRestrictions( |
|
86 | + $others_default |
|
87 | + ); |
|
88 | + } |
|
89 | + return $restrictions; |
|
90 | + } |
|
91 | + |
|
92 | + |
|
93 | + /** |
|
94 | + * @param EEM_Base $model |
|
95 | + * @param string $action |
|
96 | + * @return string |
|
97 | + * @since $VID:$ |
|
98 | + */ |
|
99 | + private function getCapKey(EEM_Base $model, string $action): string |
|
100 | + { |
|
101 | + return EE_Restriction_Generator_Base::get_cap_name($model, $action); |
|
102 | + } |
|
103 | + |
|
104 | + |
|
105 | + /** |
|
106 | + * @param bool $use_default_field_name |
|
107 | + * @return EE_Default_Where_Conditions |
|
108 | + * @since $VID:$ |
|
109 | + */ |
|
110 | + private function nonDefaultRestrictions(bool $use_default_field_name): EE_Default_Where_Conditions |
|
111 | + { |
|
112 | + return new EE_Default_Where_Conditions([$this->_default_field_name => $use_default_field_name]); |
|
113 | + } |
|
114 | + |
|
115 | + |
|
116 | + /** |
|
117 | + * @param string $action |
|
118 | + * @return EE_Default_Where_Conditions |
|
119 | + * @throws EE_Error |
|
120 | + * @since $VID:$ |
|
121 | + */ |
|
122 | + private function othersDefaultRestrictions(string $action): EE_Default_Where_Conditions |
|
123 | + { |
|
124 | + return new EE_Default_Where_Conditions( |
|
125 | + [ |
|
126 | + // if they don't have the others default cap, they can't access others default items |
|
127 | + // (but they can access their own default items, and non-default items) |
|
128 | + 'OR*no_' . $this->getCapKey($this->model(), $action) => [ |
|
129 | + 'AND' => [ |
|
130 | + $this->_path_to_event_model . 'EVT_wp_user' => EE_QUERY_PLACEHOLDER_CURRENT_USER, |
|
131 | + $this->_default_field_name => true, |
|
132 | + ], |
|
133 | + $this->_default_field_name => false, |
|
134 | + ], |
|
135 | + ] |
|
136 | + ); |
|
137 | + } |
|
138 | + |
|
139 | + |
|
140 | + /** |
|
141 | + * @param EEM_Event $event_model |
|
142 | + * @param string $action |
|
143 | + * @return EE_Default_Where_Conditions |
|
144 | + * @since $VID:$ |
|
145 | + */ |
|
146 | + private function othersNonDefaultRestrictions(EEM_Event $event_model, string $action): EE_Default_Where_Conditions |
|
147 | + { |
|
148 | + return new EE_Default_Where_Conditions( |
|
149 | + [ |
|
150 | + 'OR*no_' . $this->getCapKey($event_model, $action) => [ |
|
151 | + $this->_path_to_event_model . 'EVT_wp_user' => EE_QUERY_PLACEHOLDER_CURRENT_USER, |
|
152 | + ], |
|
153 | + $this->_default_field_name => true, |
|
154 | + ] |
|
155 | + ); |
|
156 | + } |
|
157 | + |
|
158 | + |
|
159 | + /** |
|
160 | + * @param EEM_Event $event_model |
|
161 | + * @param string $action |
|
162 | + * @return EE_Default_Where_Conditions |
|
163 | + * @since $VID:$ |
|
164 | + */ |
|
165 | + private function privateRestrictions(EEM_Event $event_model, string $action): EE_Default_Where_Conditions |
|
166 | + { |
|
167 | + return new EE_Default_Where_Conditions( |
|
168 | + [ |
|
169 | + 'OR*no_' . $this->getCapKey($event_model, $action) => [ |
|
170 | + $this->_path_to_event_model . 'EVT_wp_user' => EE_QUERY_PLACEHOLDER_CURRENT_USER, |
|
171 | + $this->_path_to_event_model . 'status' => ['!=', 'private'], |
|
172 | + $this->_default_field_name => true, |
|
173 | + ], |
|
174 | + ] |
|
175 | + ); |
|
176 | + } |
|
177 | 177 | } |
@@ -12,368 +12,368 @@ |
||
12 | 12 | */ |
13 | 13 | class EEM_Price extends EEM_Soft_Delete_Base |
14 | 14 | { |
15 | - // private instance of the EEM_Price object |
|
16 | - protected static $_instance; |
|
15 | + // private instance of the EEM_Price object |
|
16 | + protected static $_instance; |
|
17 | 17 | |
18 | 18 | |
19 | - /** |
|
20 | - * private constructor to prevent direct creation |
|
21 | - * |
|
22 | - * @Constructor |
|
23 | - * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
24 | - * (and any incoming timezone data that gets saved). |
|
25 | - * Note this just sends the timezone info to the date time model field objects. |
|
26 | - * Default is NULL |
|
27 | - * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
28 | - */ |
|
29 | - protected function __construct($timezone) |
|
30 | - { |
|
31 | - $this->singular_item = __('Price', 'event_espresso'); |
|
32 | - $this->plural_item = __('Prices', 'event_espresso'); |
|
19 | + /** |
|
20 | + * private constructor to prevent direct creation |
|
21 | + * |
|
22 | + * @Constructor |
|
23 | + * @param string $timezone string representing the timezone we want to set for returned Date Time Strings |
|
24 | + * (and any incoming timezone data that gets saved). |
|
25 | + * Note this just sends the timezone info to the date time model field objects. |
|
26 | + * Default is NULL |
|
27 | + * (and will be assumed using the set timezone in the 'timezone_string' wp option) |
|
28 | + */ |
|
29 | + protected function __construct($timezone) |
|
30 | + { |
|
31 | + $this->singular_item = __('Price', 'event_espresso'); |
|
32 | + $this->plural_item = __('Prices', 'event_espresso'); |
|
33 | 33 | |
34 | - $this->_tables = [ |
|
35 | - 'Price' => new EE_Primary_Table('esp_price', 'PRC_ID'), |
|
36 | - ]; |
|
37 | - $this->_fields = [ |
|
38 | - 'Price' => [ |
|
39 | - 'PRC_ID' => new EE_Primary_Key_Int_Field( |
|
40 | - 'PRC_ID', |
|
41 | - 'Price ID' |
|
42 | - ), |
|
43 | - 'PRT_ID' => new EE_Foreign_Key_Int_Field( |
|
44 | - 'PRT_ID', |
|
45 | - esc_html__('Price type Id', 'event_espresso'), |
|
46 | - false, |
|
47 | - null, |
|
48 | - 'Price_Type' |
|
49 | - ), |
|
50 | - 'PRC_amount' => new EE_Money_Field( |
|
51 | - 'PRC_amount', |
|
52 | - esc_html__('Price Amount', 'event_espresso'), |
|
53 | - false, |
|
54 | - 0 |
|
55 | - ), |
|
56 | - 'PRC_name' => new EE_Plain_Text_Field( |
|
57 | - 'PRC_name', |
|
58 | - esc_html__('Name of Price', 'event_espresso'), |
|
59 | - false, |
|
60 | - '' |
|
61 | - ), |
|
62 | - 'PRC_desc' => new EE_Post_Content_Field( |
|
63 | - 'PRC_desc', |
|
64 | - esc_html__('Price Description', 'event_espresso'), |
|
65 | - false, |
|
66 | - '' |
|
67 | - ), |
|
68 | - 'PRC_is_default' => new EE_Boolean_Field( |
|
69 | - 'PRC_is_default', |
|
70 | - esc_html__('Flag indicating whether price is a default price', 'event_espresso'), |
|
71 | - false, |
|
72 | - false |
|
73 | - ), |
|
74 | - 'PRC_overrides' => new EE_Integer_Field( |
|
75 | - 'PRC_overrides', |
|
76 | - esc_html__( |
|
77 | - 'Price ID for a global Price that will be overridden by this Price ( for replacing default prices )', |
|
78 | - 'event_espresso' |
|
79 | - ), |
|
80 | - true, |
|
81 | - 0 |
|
82 | - ), |
|
83 | - 'PRC_order' => new EE_Integer_Field( |
|
84 | - 'PRC_order', |
|
85 | - esc_html__( |
|
86 | - 'Order of Application of Price (lower numbers apply first?)', |
|
87 | - 'event_espresso' |
|
88 | - ), |
|
89 | - false, |
|
90 | - 1 |
|
91 | - ), |
|
92 | - 'PRC_deleted' => new EE_Trashed_Flag_Field( |
|
93 | - 'PRC_deleted', |
|
94 | - esc_html__('Flag Indicating if this has been deleted or not', 'event_espresso'), |
|
95 | - false, |
|
96 | - false |
|
97 | - ), |
|
98 | - 'PRC_parent' => new EE_Integer_Field( |
|
99 | - 'PRC_parent', |
|
100 | - esc_html__('Indicates what PRC_ID is the parent of this PRC_ID', 'event_espresso'), |
|
101 | - true, |
|
102 | - 0 |
|
103 | - ), |
|
104 | - 'PRC_wp_user' => new EE_WP_User_Field( |
|
105 | - 'PRC_wp_user', |
|
106 | - esc_html__('Price Creator ID', 'event_espresso'), |
|
107 | - false |
|
108 | - ), |
|
109 | - ], |
|
110 | - ]; |
|
111 | - $this->_model_relations = [ |
|
112 | - 'Ticket' => new EE_HABTM_Relation('Ticket_Price'), |
|
113 | - 'Price_Type' => new EE_Belongs_To_Relation(), |
|
114 | - 'WP_User' => new EE_Belongs_To_Relation(), |
|
115 | - ]; |
|
116 | - // this model is generally available for reading |
|
117 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = |
|
118 | - new EE_Restriction_Generator_Default_Public( |
|
119 | - 'PRC_is_default', |
|
120 | - 'Ticket.Datetime.Event' |
|
121 | - ); |
|
122 | - // account for default tickets in the caps |
|
123 | - $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
124 | - new EE_Restriction_Generator_Default_Protected( |
|
125 | - 'PRC_is_default', |
|
126 | - 'Ticket.Datetime.Event' |
|
127 | - ); |
|
128 | - $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = |
|
129 | - new EE_Restriction_Generator_Default_Protected( |
|
130 | - 'PRC_is_default', |
|
131 | - 'Ticket.Datetime.Event' |
|
132 | - ); |
|
133 | - $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
134 | - new EE_Restriction_Generator_Default_Protected( |
|
135 | - 'PRC_is_default', |
|
136 | - 'Ticket.Datetime.Event' |
|
137 | - ); |
|
138 | - parent::__construct($timezone); |
|
139 | - } |
|
34 | + $this->_tables = [ |
|
35 | + 'Price' => new EE_Primary_Table('esp_price', 'PRC_ID'), |
|
36 | + ]; |
|
37 | + $this->_fields = [ |
|
38 | + 'Price' => [ |
|
39 | + 'PRC_ID' => new EE_Primary_Key_Int_Field( |
|
40 | + 'PRC_ID', |
|
41 | + 'Price ID' |
|
42 | + ), |
|
43 | + 'PRT_ID' => new EE_Foreign_Key_Int_Field( |
|
44 | + 'PRT_ID', |
|
45 | + esc_html__('Price type Id', 'event_espresso'), |
|
46 | + false, |
|
47 | + null, |
|
48 | + 'Price_Type' |
|
49 | + ), |
|
50 | + 'PRC_amount' => new EE_Money_Field( |
|
51 | + 'PRC_amount', |
|
52 | + esc_html__('Price Amount', 'event_espresso'), |
|
53 | + false, |
|
54 | + 0 |
|
55 | + ), |
|
56 | + 'PRC_name' => new EE_Plain_Text_Field( |
|
57 | + 'PRC_name', |
|
58 | + esc_html__('Name of Price', 'event_espresso'), |
|
59 | + false, |
|
60 | + '' |
|
61 | + ), |
|
62 | + 'PRC_desc' => new EE_Post_Content_Field( |
|
63 | + 'PRC_desc', |
|
64 | + esc_html__('Price Description', 'event_espresso'), |
|
65 | + false, |
|
66 | + '' |
|
67 | + ), |
|
68 | + 'PRC_is_default' => new EE_Boolean_Field( |
|
69 | + 'PRC_is_default', |
|
70 | + esc_html__('Flag indicating whether price is a default price', 'event_espresso'), |
|
71 | + false, |
|
72 | + false |
|
73 | + ), |
|
74 | + 'PRC_overrides' => new EE_Integer_Field( |
|
75 | + 'PRC_overrides', |
|
76 | + esc_html__( |
|
77 | + 'Price ID for a global Price that will be overridden by this Price ( for replacing default prices )', |
|
78 | + 'event_espresso' |
|
79 | + ), |
|
80 | + true, |
|
81 | + 0 |
|
82 | + ), |
|
83 | + 'PRC_order' => new EE_Integer_Field( |
|
84 | + 'PRC_order', |
|
85 | + esc_html__( |
|
86 | + 'Order of Application of Price (lower numbers apply first?)', |
|
87 | + 'event_espresso' |
|
88 | + ), |
|
89 | + false, |
|
90 | + 1 |
|
91 | + ), |
|
92 | + 'PRC_deleted' => new EE_Trashed_Flag_Field( |
|
93 | + 'PRC_deleted', |
|
94 | + esc_html__('Flag Indicating if this has been deleted or not', 'event_espresso'), |
|
95 | + false, |
|
96 | + false |
|
97 | + ), |
|
98 | + 'PRC_parent' => new EE_Integer_Field( |
|
99 | + 'PRC_parent', |
|
100 | + esc_html__('Indicates what PRC_ID is the parent of this PRC_ID', 'event_espresso'), |
|
101 | + true, |
|
102 | + 0 |
|
103 | + ), |
|
104 | + 'PRC_wp_user' => new EE_WP_User_Field( |
|
105 | + 'PRC_wp_user', |
|
106 | + esc_html__('Price Creator ID', 'event_espresso'), |
|
107 | + false |
|
108 | + ), |
|
109 | + ], |
|
110 | + ]; |
|
111 | + $this->_model_relations = [ |
|
112 | + 'Ticket' => new EE_HABTM_Relation('Ticket_Price'), |
|
113 | + 'Price_Type' => new EE_Belongs_To_Relation(), |
|
114 | + 'WP_User' => new EE_Belongs_To_Relation(), |
|
115 | + ]; |
|
116 | + // this model is generally available for reading |
|
117 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = |
|
118 | + new EE_Restriction_Generator_Default_Public( |
|
119 | + 'PRC_is_default', |
|
120 | + 'Ticket.Datetime.Event' |
|
121 | + ); |
|
122 | + // account for default tickets in the caps |
|
123 | + $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = |
|
124 | + new EE_Restriction_Generator_Default_Protected( |
|
125 | + 'PRC_is_default', |
|
126 | + 'Ticket.Datetime.Event' |
|
127 | + ); |
|
128 | + $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = |
|
129 | + new EE_Restriction_Generator_Default_Protected( |
|
130 | + 'PRC_is_default', |
|
131 | + 'Ticket.Datetime.Event' |
|
132 | + ); |
|
133 | + $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = |
|
134 | + new EE_Restriction_Generator_Default_Protected( |
|
135 | + 'PRC_is_default', |
|
136 | + 'Ticket.Datetime.Event' |
|
137 | + ); |
|
138 | + parent::__construct($timezone); |
|
139 | + } |
|
140 | 140 | |
141 | 141 | |
142 | - /** |
|
143 | - * instantiate a new price object with blank/empty properties |
|
144 | - * |
|
145 | - * @return mixed array on success, FALSE on fail |
|
146 | - */ |
|
147 | - public function get_new_price() |
|
148 | - { |
|
149 | - return $this->create_default_object(); |
|
150 | - } |
|
142 | + /** |
|
143 | + * instantiate a new price object with blank/empty properties |
|
144 | + * |
|
145 | + * @return mixed array on success, FALSE on fail |
|
146 | + */ |
|
147 | + public function get_new_price() |
|
148 | + { |
|
149 | + return $this->create_default_object(); |
|
150 | + } |
|
151 | 151 | |
152 | 152 | |
153 | - /** |
|
154 | - * retrieve ALL prices from db |
|
155 | - * |
|
156 | - * @return EE_Base_Class[]|EE_PRice[] |
|
157 | - * @throws EE_Error |
|
158 | - */ |
|
159 | - public function get_all_prices() |
|
160 | - { |
|
161 | - // retrieve all prices |
|
162 | - return $this->get_all(['order_by' => ['PRC_amount' => 'ASC']]); |
|
163 | - } |
|
153 | + /** |
|
154 | + * retrieve ALL prices from db |
|
155 | + * |
|
156 | + * @return EE_Base_Class[]|EE_PRice[] |
|
157 | + * @throws EE_Error |
|
158 | + */ |
|
159 | + public function get_all_prices() |
|
160 | + { |
|
161 | + // retrieve all prices |
|
162 | + return $this->get_all(['order_by' => ['PRC_amount' => 'ASC']]); |
|
163 | + } |
|
164 | 164 | |
165 | 165 | |
166 | - /** |
|
167 | - * retrieve all active prices for a particular event |
|
168 | - * |
|
169 | - * @param int $EVT_ID |
|
170 | - * @return array on success |
|
171 | - * @throws EE_Error |
|
172 | - */ |
|
173 | - public function get_all_event_prices($EVT_ID = 0) |
|
174 | - { |
|
175 | - return $this->get_all( |
|
176 | - [ |
|
177 | - [ |
|
178 | - 'EVT_ID' => $EVT_ID, |
|
179 | - 'Price_Type.PBT_ID' => ['!=', EEM_Price_Type::base_type_tax], |
|
180 | - ], |
|
181 | - 'order_by' => $this->_order_by_array_for_get_all_method(), |
|
182 | - ] |
|
183 | - ); |
|
184 | - } |
|
166 | + /** |
|
167 | + * retrieve all active prices for a particular event |
|
168 | + * |
|
169 | + * @param int $EVT_ID |
|
170 | + * @return array on success |
|
171 | + * @throws EE_Error |
|
172 | + */ |
|
173 | + public function get_all_event_prices($EVT_ID = 0) |
|
174 | + { |
|
175 | + return $this->get_all( |
|
176 | + [ |
|
177 | + [ |
|
178 | + 'EVT_ID' => $EVT_ID, |
|
179 | + 'Price_Type.PBT_ID' => ['!=', EEM_Price_Type::base_type_tax], |
|
180 | + ], |
|
181 | + 'order_by' => $this->_order_by_array_for_get_all_method(), |
|
182 | + ] |
|
183 | + ); |
|
184 | + } |
|
185 | 185 | |
186 | 186 | |
187 | - /** |
|
188 | - * retrieve all active global prices (that are not taxes (PBT_ID=4)) for a particular event |
|
189 | - * |
|
190 | - * @param boolean $count return count |
|
191 | - * @param bool $include_taxes |
|
192 | - * @return bool|EE_Base_Class[]|EE_PRice[] |
|
193 | - * @throws EE_Error |
|
194 | - */ |
|
195 | - public function get_all_default_prices($count = false, $include_taxes = false) |
|
196 | - { |
|
197 | - $_where = [ |
|
198 | - 'PRC_deleted' => 0, |
|
199 | - 'PRC_is_default' => 1, |
|
200 | - ]; |
|
201 | - if (! $include_taxes) { |
|
202 | - $_where['Price_Type.PBT_ID'] = ['!=', 4]; |
|
203 | - } |
|
204 | - $_query_params = [ |
|
205 | - $_where, |
|
206 | - 'order_by' => $this->_order_by_array_for_get_all_method(), |
|
207 | - ]; |
|
208 | - return $count ? $this->count([$_where]) : $this->get_all($_query_params); |
|
209 | - } |
|
187 | + /** |
|
188 | + * retrieve all active global prices (that are not taxes (PBT_ID=4)) for a particular event |
|
189 | + * |
|
190 | + * @param boolean $count return count |
|
191 | + * @param bool $include_taxes |
|
192 | + * @return bool|EE_Base_Class[]|EE_PRice[] |
|
193 | + * @throws EE_Error |
|
194 | + */ |
|
195 | + public function get_all_default_prices($count = false, $include_taxes = false) |
|
196 | + { |
|
197 | + $_where = [ |
|
198 | + 'PRC_deleted' => 0, |
|
199 | + 'PRC_is_default' => 1, |
|
200 | + ]; |
|
201 | + if (! $include_taxes) { |
|
202 | + $_where['Price_Type.PBT_ID'] = ['!=', 4]; |
|
203 | + } |
|
204 | + $_query_params = [ |
|
205 | + $_where, |
|
206 | + 'order_by' => $this->_order_by_array_for_get_all_method(), |
|
207 | + ]; |
|
208 | + return $count ? $this->count([$_where]) : $this->get_all($_query_params); |
|
209 | + } |
|
210 | 210 | |
211 | 211 | |
212 | - /** |
|
213 | - * retrieve all active global prices that are taxes |
|
214 | - * |
|
215 | - * @return bool|EE_Base_Class[]|EE_PRice[] |
|
216 | - * @throws EE_Error |
|
217 | - * @since $VID:$ |
|
218 | - */ |
|
219 | - public function getAllDefaultTaxes() |
|
220 | - { |
|
221 | - return $this->get_all( |
|
222 | - [ |
|
223 | - [ |
|
224 | - 'PRC_deleted' => 0, |
|
225 | - 'PRC_is_default' => 1, |
|
226 | - 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax |
|
227 | - ], |
|
228 | - 'order_by' => [ |
|
229 | - 'Price_Type.PRT_order' => 'ASC', |
|
230 | - 'PRC_order' => 'ASC' |
|
231 | - ], |
|
232 | - ] |
|
233 | - ); |
|
234 | - } |
|
212 | + /** |
|
213 | + * retrieve all active global prices that are taxes |
|
214 | + * |
|
215 | + * @return bool|EE_Base_Class[]|EE_PRice[] |
|
216 | + * @throws EE_Error |
|
217 | + * @since $VID:$ |
|
218 | + */ |
|
219 | + public function getAllDefaultTaxes() |
|
220 | + { |
|
221 | + return $this->get_all( |
|
222 | + [ |
|
223 | + [ |
|
224 | + 'PRC_deleted' => 0, |
|
225 | + 'PRC_is_default' => 1, |
|
226 | + 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax |
|
227 | + ], |
|
228 | + 'order_by' => [ |
|
229 | + 'Price_Type.PRT_order' => 'ASC', |
|
230 | + 'PRC_order' => 'ASC' |
|
231 | + ], |
|
232 | + ] |
|
233 | + ); |
|
234 | + } |
|
235 | 235 | |
236 | 236 | |
237 | - /** |
|
238 | - * retrieve all prices that are taxes |
|
239 | - * |
|
240 | - * @return EE_Base_Class[]|EE_PRice[] |
|
241 | - * @throws EE_Error |
|
242 | - * @throws InvalidArgumentException |
|
243 | - * @throws ReflectionException |
|
244 | - * @throws InvalidDataTypeException |
|
245 | - * @throws InvalidInterfaceException |
|
246 | - */ |
|
247 | - public function get_all_prices_that_are_taxes() |
|
248 | - { |
|
249 | - $taxes = []; |
|
250 | - $all_taxes = $this->get_all( |
|
251 | - [ |
|
252 | - ['Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax, 'PRC_is_default' => 1], |
|
253 | - 'order_by' => ['Price_Type.PRT_order' => 'ASC', 'PRC_order' => 'ASC'], |
|
254 | - ] |
|
255 | - ); |
|
256 | - foreach ($all_taxes as $tax) { |
|
257 | - if ($tax instanceof EE_Price) { |
|
258 | - $taxes[ $tax->order() ][ $tax->ID() ] = $tax; |
|
259 | - } |
|
260 | - } |
|
261 | - return $taxes; |
|
262 | - } |
|
237 | + /** |
|
238 | + * retrieve all prices that are taxes |
|
239 | + * |
|
240 | + * @return EE_Base_Class[]|EE_PRice[] |
|
241 | + * @throws EE_Error |
|
242 | + * @throws InvalidArgumentException |
|
243 | + * @throws ReflectionException |
|
244 | + * @throws InvalidDataTypeException |
|
245 | + * @throws InvalidInterfaceException |
|
246 | + */ |
|
247 | + public function get_all_prices_that_are_taxes() |
|
248 | + { |
|
249 | + $taxes = []; |
|
250 | + $all_taxes = $this->get_all( |
|
251 | + [ |
|
252 | + ['Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax, 'PRC_is_default' => 1], |
|
253 | + 'order_by' => ['Price_Type.PRT_order' => 'ASC', 'PRC_order' => 'ASC'], |
|
254 | + ] |
|
255 | + ); |
|
256 | + foreach ($all_taxes as $tax) { |
|
257 | + if ($tax instanceof EE_Price) { |
|
258 | + $taxes[ $tax->order() ][ $tax->ID() ] = $tax; |
|
259 | + } |
|
260 | + } |
|
261 | + return $taxes; |
|
262 | + } |
|
263 | 263 | |
264 | 264 | |
265 | - /** |
|
266 | - * retrieve all prices for an ticket plus default global prices, but not taxes |
|
267 | - * |
|
268 | - * @param int $TKT_ID the id of the event. If not included then we assume that this is a new ticket. |
|
269 | - * @return EE_Base_Class[]|EE_PRice[]|boolean |
|
270 | - * @throws EE_Error |
|
271 | - */ |
|
272 | - public function get_all_ticket_prices_for_admin($TKT_ID = 0) |
|
273 | - { |
|
274 | - $array_of_price_objects = []; |
|
275 | - if (empty($TKT_ID)) { |
|
276 | - // if there is no tkt, get prices with no tkt ID, are global, are not a tax, and are active |
|
277 | - // return that list |
|
278 | - $default_prices = $this->get_all_default_prices(); |
|
265 | + /** |
|
266 | + * retrieve all prices for an ticket plus default global prices, but not taxes |
|
267 | + * |
|
268 | + * @param int $TKT_ID the id of the event. If not included then we assume that this is a new ticket. |
|
269 | + * @return EE_Base_Class[]|EE_PRice[]|boolean |
|
270 | + * @throws EE_Error |
|
271 | + */ |
|
272 | + public function get_all_ticket_prices_for_admin($TKT_ID = 0) |
|
273 | + { |
|
274 | + $array_of_price_objects = []; |
|
275 | + if (empty($TKT_ID)) { |
|
276 | + // if there is no tkt, get prices with no tkt ID, are global, are not a tax, and are active |
|
277 | + // return that list |
|
278 | + $default_prices = $this->get_all_default_prices(); |
|
279 | 279 | |
280 | - if ($default_prices) { |
|
281 | - foreach ($default_prices as $price) { |
|
282 | - if ($price instanceof EE_Price) { |
|
283 | - $array_of_price_objects[ $price->type() ][] = $price; |
|
284 | - } |
|
285 | - } |
|
286 | - return $array_of_price_objects; |
|
287 | - } |
|
288 | - return []; |
|
289 | - } |
|
290 | - $ticket_prices = $this->get_all( |
|
291 | - [ |
|
292 | - [ |
|
293 | - 'TKT_ID' => $TKT_ID, |
|
294 | - 'PRC_deleted' => 0, |
|
295 | - ], |
|
296 | - 'order_by' => ['PRC_order' => 'ASC'], |
|
297 | - ] |
|
298 | - ); |
|
280 | + if ($default_prices) { |
|
281 | + foreach ($default_prices as $price) { |
|
282 | + if ($price instanceof EE_Price) { |
|
283 | + $array_of_price_objects[ $price->type() ][] = $price; |
|
284 | + } |
|
285 | + } |
|
286 | + return $array_of_price_objects; |
|
287 | + } |
|
288 | + return []; |
|
289 | + } |
|
290 | + $ticket_prices = $this->get_all( |
|
291 | + [ |
|
292 | + [ |
|
293 | + 'TKT_ID' => $TKT_ID, |
|
294 | + 'PRC_deleted' => 0, |
|
295 | + ], |
|
296 | + 'order_by' => ['PRC_order' => 'ASC'], |
|
297 | + ] |
|
298 | + ); |
|
299 | 299 | |
300 | - if (! empty($ticket_prices)) { |
|
301 | - foreach ($ticket_prices as $price) { |
|
302 | - if ($price instanceof EE_Price) { |
|
303 | - $array_of_price_objects[ $price->type() ][] = $price; |
|
304 | - } |
|
305 | - } |
|
306 | - return $array_of_price_objects; |
|
307 | - } |
|
308 | - return false; |
|
309 | - } |
|
300 | + if (! empty($ticket_prices)) { |
|
301 | + foreach ($ticket_prices as $price) { |
|
302 | + if ($price instanceof EE_Price) { |
|
303 | + $array_of_price_objects[ $price->type() ][] = $price; |
|
304 | + } |
|
305 | + } |
|
306 | + return $array_of_price_objects; |
|
307 | + } |
|
308 | + return false; |
|
309 | + } |
|
310 | 310 | |
311 | 311 | |
312 | - /** |
|
313 | - * _sort_event_prices_by_type |
|
314 | - * |
|
315 | - * @param EE_Price $price_a |
|
316 | - * @param EE_Price $price_b |
|
317 | - * @return bool false on fail |
|
318 | - */ |
|
319 | - public function _sort_event_prices_by_type(EE_Price $price_a, EE_Price $price_b) |
|
320 | - { |
|
321 | - if ($price_a->type_obj()->order() === $price_b->type_obj()->order()) { |
|
322 | - return $this->_sort_event_prices_by_order($price_a, $price_b); |
|
323 | - } |
|
324 | - return $price_a->type_obj()->order() < $price_b->type_obj()->order() ? -1 : 1; |
|
325 | - } |
|
312 | + /** |
|
313 | + * _sort_event_prices_by_type |
|
314 | + * |
|
315 | + * @param EE_Price $price_a |
|
316 | + * @param EE_Price $price_b |
|
317 | + * @return bool false on fail |
|
318 | + */ |
|
319 | + public function _sort_event_prices_by_type(EE_Price $price_a, EE_Price $price_b) |
|
320 | + { |
|
321 | + if ($price_a->type_obj()->order() === $price_b->type_obj()->order()) { |
|
322 | + return $this->_sort_event_prices_by_order($price_a, $price_b); |
|
323 | + } |
|
324 | + return $price_a->type_obj()->order() < $price_b->type_obj()->order() ? -1 : 1; |
|
325 | + } |
|
326 | 326 | |
327 | 327 | |
328 | - /** |
|
329 | - * _sort_event_prices_by_order |
|
330 | - * |
|
331 | - * @param EE_Price $price_a |
|
332 | - * @param EE_Price $price_b |
|
333 | - * @return bool false on fail |
|
334 | - */ |
|
335 | - public function _sort_event_prices_by_order(EE_Price $price_a, EE_Price $price_b) |
|
336 | - { |
|
337 | - if ($price_a->order() === $price_b->order()) { |
|
338 | - return 0; |
|
339 | - } |
|
340 | - return $price_a->order() < $price_b->order() ? -1 : 1; |
|
341 | - } |
|
328 | + /** |
|
329 | + * _sort_event_prices_by_order |
|
330 | + * |
|
331 | + * @param EE_Price $price_a |
|
332 | + * @param EE_Price $price_b |
|
333 | + * @return bool false on fail |
|
334 | + */ |
|
335 | + public function _sort_event_prices_by_order(EE_Price $price_a, EE_Price $price_b) |
|
336 | + { |
|
337 | + if ($price_a->order() === $price_b->order()) { |
|
338 | + return 0; |
|
339 | + } |
|
340 | + return $price_a->order() < $price_b->order() ? -1 : 1; |
|
341 | + } |
|
342 | 342 | |
343 | 343 | |
344 | - /** |
|
345 | - * get all prices of a specific type |
|
346 | - * |
|
347 | - * @param int $type - PRT_ID |
|
348 | - * @return EE_Base_Class[]|EE_PRice[] |
|
349 | - * @throws EE_Error |
|
350 | - */ |
|
351 | - public function get_all_prices_that_are_type($type = 0) |
|
352 | - { |
|
353 | - return $this->get_all( |
|
354 | - [ |
|
355 | - [ |
|
356 | - 'PRT_ID' => $type, |
|
357 | - ], |
|
358 | - 'order_by' => $this->_order_by_array_for_get_all_method(), |
|
359 | - ] |
|
360 | - ); |
|
361 | - } |
|
344 | + /** |
|
345 | + * get all prices of a specific type |
|
346 | + * |
|
347 | + * @param int $type - PRT_ID |
|
348 | + * @return EE_Base_Class[]|EE_PRice[] |
|
349 | + * @throws EE_Error |
|
350 | + */ |
|
351 | + public function get_all_prices_that_are_type($type = 0) |
|
352 | + { |
|
353 | + return $this->get_all( |
|
354 | + [ |
|
355 | + [ |
|
356 | + 'PRT_ID' => $type, |
|
357 | + ], |
|
358 | + 'order_by' => $this->_order_by_array_for_get_all_method(), |
|
359 | + ] |
|
360 | + ); |
|
361 | + } |
|
362 | 362 | |
363 | 363 | |
364 | - /** |
|
365 | - * Returns an array of the normal 'order_by' query parameter provided to the get_all query. |
|
366 | - * Of course you don't have to use it, but this is the order we usually want to sort prices by |
|
367 | - * |
|
368 | - * @return array which can be used like so: $this->get_all(array(array(...where |
|
369 | - * stuff...),'order_by'=>$this->_order_by_array_for_get_all_method())); |
|
370 | - */ |
|
371 | - public function _order_by_array_for_get_all_method() |
|
372 | - { |
|
373 | - return [ |
|
374 | - 'PRC_order' => 'ASC', |
|
375 | - 'Price_Type.PRT_order' => 'ASC', |
|
376 | - 'PRC_ID' => 'ASC', |
|
377 | - ]; |
|
378 | - } |
|
364 | + /** |
|
365 | + * Returns an array of the normal 'order_by' query parameter provided to the get_all query. |
|
366 | + * Of course you don't have to use it, but this is the order we usually want to sort prices by |
|
367 | + * |
|
368 | + * @return array which can be used like so: $this->get_all(array(array(...where |
|
369 | + * stuff...),'order_by'=>$this->_order_by_array_for_get_all_method())); |
|
370 | + */ |
|
371 | + public function _order_by_array_for_get_all_method() |
|
372 | + { |
|
373 | + return [ |
|
374 | + 'PRC_order' => 'ASC', |
|
375 | + 'Price_Type.PRT_order' => 'ASC', |
|
376 | + 'PRC_ID' => 'ASC', |
|
377 | + ]; |
|
378 | + } |
|
379 | 379 | } |
@@ -11,134 +11,134 @@ |
||
11 | 11 | */ |
12 | 12 | class EEM_Event_Message_Template extends EEM_Base |
13 | 13 | { |
14 | - // private instance of the EEM_Event_Message_Template object |
|
15 | - protected static $_instance = null; |
|
14 | + // private instance of the EEM_Event_Message_Template object |
|
15 | + protected static $_instance = null; |
|
16 | 16 | |
17 | 17 | |
18 | - /** |
|
19 | - * protected constructor to prevent direct creation |
|
20 | - * |
|
21 | - * @param null $timezone |
|
22 | - * @throws EE_Error |
|
23 | - */ |
|
24 | - protected function __construct($timezone = null) |
|
25 | - { |
|
26 | - $this->singular_item = esc_html__('Event Message Template', 'event_espresso'); |
|
27 | - $this->plural_item = esc_html__('Event Message Templates', 'event_espresso'); |
|
18 | + /** |
|
19 | + * protected constructor to prevent direct creation |
|
20 | + * |
|
21 | + * @param null $timezone |
|
22 | + * @throws EE_Error |
|
23 | + */ |
|
24 | + protected function __construct($timezone = null) |
|
25 | + { |
|
26 | + $this->singular_item = esc_html__('Event Message Template', 'event_espresso'); |
|
27 | + $this->plural_item = esc_html__('Event Message Templates', 'event_espresso'); |
|
28 | 28 | |
29 | - $this->_tables = [ |
|
30 | - 'Event_Message_Template' => new EE_Primary_Table('esp_event_message_template', 'EMT_ID'), |
|
31 | - ]; |
|
32 | - $this->_fields = [ |
|
33 | - 'Event_Message_Template' => [ |
|
34 | - 'EMT_ID' => new EE_Primary_Key_Int_Field( |
|
35 | - 'EMT_ID', |
|
36 | - esc_html__('Event Message Template ID', 'event_espresso') |
|
37 | - ), |
|
38 | - 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
39 | - 'EVT_ID', |
|
40 | - esc_html__('The ID to the Event', 'event_espresso'), |
|
41 | - false, |
|
42 | - 0, |
|
43 | - 'Event' |
|
44 | - ), |
|
45 | - 'GRP_ID' => new EE_Foreign_Key_Int_Field( |
|
46 | - 'GRP_ID', |
|
47 | - esc_html__('The ID to the Message Template Group', 'event_espresso'), |
|
48 | - false, |
|
49 | - 0, |
|
50 | - 'Message_Template_Group' |
|
51 | - ), |
|
52 | - ], |
|
53 | - ]; |
|
54 | - $this->_model_relations = [ |
|
55 | - 'Event' => new EE_Belongs_To_Relation(), |
|
56 | - 'Message_Template_Group' => new EE_Belongs_To_Relation(), |
|
57 | - ]; |
|
58 | - $path_to_event = 'Event'; |
|
59 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Event_Related_Public( |
|
60 | - $path_to_event |
|
61 | - ); |
|
62 | - $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
63 | - $path_to_event |
|
64 | - ); |
|
65 | - $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
66 | - $path_to_event |
|
67 | - ); |
|
68 | - $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
69 | - $path_to_event, |
|
70 | - EEM_Base::caps_edit |
|
71 | - ); |
|
72 | - parent::__construct($timezone); |
|
73 | - } |
|
29 | + $this->_tables = [ |
|
30 | + 'Event_Message_Template' => new EE_Primary_Table('esp_event_message_template', 'EMT_ID'), |
|
31 | + ]; |
|
32 | + $this->_fields = [ |
|
33 | + 'Event_Message_Template' => [ |
|
34 | + 'EMT_ID' => new EE_Primary_Key_Int_Field( |
|
35 | + 'EMT_ID', |
|
36 | + esc_html__('Event Message Template ID', 'event_espresso') |
|
37 | + ), |
|
38 | + 'EVT_ID' => new EE_Foreign_Key_Int_Field( |
|
39 | + 'EVT_ID', |
|
40 | + esc_html__('The ID to the Event', 'event_espresso'), |
|
41 | + false, |
|
42 | + 0, |
|
43 | + 'Event' |
|
44 | + ), |
|
45 | + 'GRP_ID' => new EE_Foreign_Key_Int_Field( |
|
46 | + 'GRP_ID', |
|
47 | + esc_html__('The ID to the Message Template Group', 'event_espresso'), |
|
48 | + false, |
|
49 | + 0, |
|
50 | + 'Message_Template_Group' |
|
51 | + ), |
|
52 | + ], |
|
53 | + ]; |
|
54 | + $this->_model_relations = [ |
|
55 | + 'Event' => new EE_Belongs_To_Relation(), |
|
56 | + 'Message_Template_Group' => new EE_Belongs_To_Relation(), |
|
57 | + ]; |
|
58 | + $path_to_event = 'Event'; |
|
59 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Event_Related_Public( |
|
60 | + $path_to_event |
|
61 | + ); |
|
62 | + $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
63 | + $path_to_event |
|
64 | + ); |
|
65 | + $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
66 | + $path_to_event |
|
67 | + ); |
|
68 | + $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Event_Related_Protected( |
|
69 | + $path_to_event, |
|
70 | + EEM_Base::caps_edit |
|
71 | + ); |
|
72 | + parent::__construct($timezone); |
|
73 | + } |
|
74 | 74 | |
75 | 75 | |
76 | - /** |
|
77 | - * helper method to simply return an array of event ids for events attached to the given |
|
78 | - * message template group. |
|
79 | - * |
|
80 | - * @param int $GRP_ID The MTP group we want attached events for. |
|
81 | - * @return array An array of event ids. |
|
82 | - * @throws EE_Error |
|
83 | - * @since 4.3.0 |
|
84 | - */ |
|
85 | - public function get_attached_event_ids($GRP_ID) |
|
86 | - { |
|
87 | - $event_ids = $this->_get_all_wpdb_results([['GRP_ID' => $GRP_ID]], ARRAY_N, 'EVT_ID'); |
|
88 | - $event_ids = call_user_func_array('array_merge', $event_ids); |
|
89 | - return $event_ids; |
|
90 | - } |
|
76 | + /** |
|
77 | + * helper method to simply return an array of event ids for events attached to the given |
|
78 | + * message template group. |
|
79 | + * |
|
80 | + * @param int $GRP_ID The MTP group we want attached events for. |
|
81 | + * @return array An array of event ids. |
|
82 | + * @throws EE_Error |
|
83 | + * @since 4.3.0 |
|
84 | + */ |
|
85 | + public function get_attached_event_ids($GRP_ID) |
|
86 | + { |
|
87 | + $event_ids = $this->_get_all_wpdb_results([['GRP_ID' => $GRP_ID]], ARRAY_N, 'EVT_ID'); |
|
88 | + $event_ids = call_user_func_array('array_merge', $event_ids); |
|
89 | + return $event_ids; |
|
90 | + } |
|
91 | 91 | |
92 | 92 | |
93 | - /** |
|
94 | - * helper method for clearing event/group relations for the given event ids and grp ids. |
|
95 | - * |
|
96 | - * @param array $GRP_IDs An array of GRP_IDs. Optional. If empty then there must be EVT IDs. |
|
97 | - * @param array $EVT_IDs An array of EVT_IDs. Optional. If empty then there must be GRP IDs. |
|
98 | - * @return int How many rows were deleted. |
|
99 | - * @throws EE_Error |
|
100 | - * @throws EE_Error |
|
101 | - */ |
|
102 | - public function delete_event_group_relations($GRP_IDs = [], $EVT_IDs = []) |
|
103 | - { |
|
104 | - if (empty($GRP_IDs) && empty($EVT_IDs)) { |
|
105 | - throw new EE_Error( |
|
106 | - sprintf( |
|
107 | - esc_html__( |
|
108 | - '%s requires either an array of GRP_IDs or EVT_IDs or both, but both cannot be empty.', |
|
109 | - 'event_espresso' |
|
110 | - ), |
|
111 | - __METHOD__ |
|
112 | - ) |
|
113 | - ); |
|
114 | - } |
|
93 | + /** |
|
94 | + * helper method for clearing event/group relations for the given event ids and grp ids. |
|
95 | + * |
|
96 | + * @param array $GRP_IDs An array of GRP_IDs. Optional. If empty then there must be EVT IDs. |
|
97 | + * @param array $EVT_IDs An array of EVT_IDs. Optional. If empty then there must be GRP IDs. |
|
98 | + * @return int How many rows were deleted. |
|
99 | + * @throws EE_Error |
|
100 | + * @throws EE_Error |
|
101 | + */ |
|
102 | + public function delete_event_group_relations($GRP_IDs = [], $EVT_IDs = []) |
|
103 | + { |
|
104 | + if (empty($GRP_IDs) && empty($EVT_IDs)) { |
|
105 | + throw new EE_Error( |
|
106 | + sprintf( |
|
107 | + esc_html__( |
|
108 | + '%s requires either an array of GRP_IDs or EVT_IDs or both, but both cannot be empty.', |
|
109 | + 'event_espresso' |
|
110 | + ), |
|
111 | + __METHOD__ |
|
112 | + ) |
|
113 | + ); |
|
114 | + } |
|
115 | 115 | |
116 | - $where = []; |
|
117 | - if (! empty($GRP_IDs)) { |
|
118 | - $where['GRP_ID'] = ['IN', (array) $GRP_IDs]; |
|
119 | - } |
|
120 | - if (! empty($EVT_IDs)) { |
|
121 | - $where['EVT_ID'] = ['IN', (array) $EVT_IDs]; |
|
122 | - } |
|
116 | + $where = []; |
|
117 | + if (! empty($GRP_IDs)) { |
|
118 | + $where['GRP_ID'] = ['IN', (array) $GRP_IDs]; |
|
119 | + } |
|
120 | + if (! empty($EVT_IDs)) { |
|
121 | + $where['EVT_ID'] = ['IN', (array) $EVT_IDs]; |
|
122 | + } |
|
123 | 123 | |
124 | - return $this->delete([$where], false); |
|
125 | - } |
|
124 | + return $this->delete([$where], false); |
|
125 | + } |
|
126 | 126 | |
127 | 127 | |
128 | - /** |
|
129 | - * returns a numerically indexed array |
|
130 | - * with values that correspond to the 'GRP_ID' column |
|
131 | - * where the 'EVT_ID' column matches that of the supplied event |
|
132 | - * |
|
133 | - * @param EE_Event $event |
|
134 | - * @return array |
|
135 | - * @throws EE_Error |
|
136 | - * @throws ReflectionException |
|
137 | - * @since $VID:$ |
|
138 | - */ |
|
139 | - public function messageTemplateGroupIDsForEvent(EE_Event $event): array |
|
140 | - { |
|
141 | - $results = $this->get_col([['EVT_ID' => $event->ID()]], 'GRP_ID'); |
|
142 | - return $results !== false ? $results : []; |
|
143 | - } |
|
128 | + /** |
|
129 | + * returns a numerically indexed array |
|
130 | + * with values that correspond to the 'GRP_ID' column |
|
131 | + * where the 'EVT_ID' column matches that of the supplied event |
|
132 | + * |
|
133 | + * @param EE_Event $event |
|
134 | + * @return array |
|
135 | + * @throws EE_Error |
|
136 | + * @throws ReflectionException |
|
137 | + * @since $VID:$ |
|
138 | + */ |
|
139 | + public function messageTemplateGroupIDsForEvent(EE_Event $event): array |
|
140 | + { |
|
141 | + $results = $this->get_col([['EVT_ID' => $event->ID()]], 'GRP_ID'); |
|
142 | + return $results !== false ? $results : []; |
|
143 | + } |
|
144 | 144 | } |
@@ -14,74 +14,74 @@ |
||
14 | 14 | */ |
15 | 15 | abstract class GraphQLData implements GraphQLDataInterface |
16 | 16 | { |
17 | - /** |
|
18 | - * @var string $namespace The graphql namespace/prefix. |
|
19 | - */ |
|
20 | - protected $namespace = 'Espresso'; |
|
17 | + /** |
|
18 | + * @var string $namespace The graphql namespace/prefix. |
|
19 | + */ |
|
20 | + protected $namespace = 'Espresso'; |
|
21 | 21 | |
22 | - /** |
|
23 | - * @var array $params |
|
24 | - */ |
|
25 | - private $params = []; |
|
22 | + /** |
|
23 | + * @var array $params |
|
24 | + */ |
|
25 | + private $params = []; |
|
26 | 26 | |
27 | 27 | |
28 | - /** |
|
29 | - * @param array $params |
|
30 | - */ |
|
31 | - public function setParams(array $params) |
|
32 | - { |
|
33 | - $this->params = $params; |
|
34 | - } |
|
28 | + /** |
|
29 | + * @param array $params |
|
30 | + */ |
|
31 | + public function setParams(array $params) |
|
32 | + { |
|
33 | + $this->params = $params; |
|
34 | + } |
|
35 | 35 | |
36 | 36 | |
37 | 37 | |
38 | - /** |
|
39 | - * @param string $field_key |
|
40 | - * @param array $where_params |
|
41 | - * @return mixed|null |
|
42 | - * @since $VID:$ |
|
43 | - */ |
|
44 | - protected function getQueryResponse(string $field_key, array $where_params = []) |
|
45 | - { |
|
46 | - if (! empty($where_params)) { |
|
47 | - if (! array_key_exists('variables', $this->params)) { |
|
48 | - $this->params['variables'] = []; |
|
49 | - } |
|
50 | - $this->params['variables']['where'] = $where_params; |
|
51 | - } |
|
38 | + /** |
|
39 | + * @param string $field_key |
|
40 | + * @param array $where_params |
|
41 | + * @return mixed|null |
|
42 | + * @since $VID:$ |
|
43 | + */ |
|
44 | + protected function getQueryResponse(string $field_key, array $where_params = []) |
|
45 | + { |
|
46 | + if (! empty($where_params)) { |
|
47 | + if (! array_key_exists('variables', $this->params)) { |
|
48 | + $this->params['variables'] = []; |
|
49 | + } |
|
50 | + $this->params['variables']['where'] = $where_params; |
|
51 | + } |
|
52 | 52 | |
53 | - $responseData = $this->makeGraphQLRequest($this->params); |
|
54 | - return ! empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null; |
|
55 | - } |
|
53 | + $responseData = $this->makeGraphQLRequest($this->params); |
|
54 | + return ! empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null; |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | - /** |
|
59 | - * @param array $data |
|
60 | - * @return array|null |
|
61 | - * @since $VID:$ |
|
62 | - */ |
|
63 | - protected function makeGraphQLRequest(array $data) |
|
64 | - { |
|
65 | - $error = ''; |
|
66 | - try { |
|
67 | - $response = graphql($data); |
|
68 | - if (! empty($response['data'])) { |
|
69 | - return $response['data']; |
|
70 | - } |
|
71 | - $error = ! empty($response['errors']) |
|
72 | - ? print_r($response['errors'], true) |
|
73 | - : esc_html__( |
|
74 | - 'An unknown error has occurred during the GraphQL request and no data was found to return.', |
|
75 | - 'event_espresso' |
|
76 | - ); |
|
77 | - } catch (Exception $e) { |
|
78 | - if (defined('GRAPHQL_DEBUG') && GRAPHQL_DEBUG) { |
|
79 | - $error = $e->getMessage(); |
|
80 | - } |
|
81 | - } |
|
82 | - if ($error !== '') { |
|
83 | - error_log($error); |
|
84 | - } |
|
85 | - return null; |
|
86 | - } |
|
58 | + /** |
|
59 | + * @param array $data |
|
60 | + * @return array|null |
|
61 | + * @since $VID:$ |
|
62 | + */ |
|
63 | + protected function makeGraphQLRequest(array $data) |
|
64 | + { |
|
65 | + $error = ''; |
|
66 | + try { |
|
67 | + $response = graphql($data); |
|
68 | + if (! empty($response['data'])) { |
|
69 | + return $response['data']; |
|
70 | + } |
|
71 | + $error = ! empty($response['errors']) |
|
72 | + ? print_r($response['errors'], true) |
|
73 | + : esc_html__( |
|
74 | + 'An unknown error has occurred during the GraphQL request and no data was found to return.', |
|
75 | + 'event_espresso' |
|
76 | + ); |
|
77 | + } catch (Exception $e) { |
|
78 | + if (defined('GRAPHQL_DEBUG') && GRAPHQL_DEBUG) { |
|
79 | + $error = $e->getMessage(); |
|
80 | + } |
|
81 | + } |
|
82 | + if ($error !== '') { |
|
83 | + error_log($error); |
|
84 | + } |
|
85 | + return null; |
|
86 | + } |
|
87 | 87 | } |