@@ -15,983 +15,983 @@ |
||
15 | 15 | */ |
16 | 16 | class EE_Messages_Generator |
17 | 17 | { |
18 | - protected EE_Messages_Data_Handler_Collection $_data_handler_collection; |
|
19 | - |
|
20 | - protected EE_Message_Template_Group_Collection $_template_collection; |
|
21 | - |
|
22 | - /** |
|
23 | - * This will hold the data handler for the current EE_Message being generated. |
|
24 | - */ |
|
25 | - protected ?EE_Messages_incoming_data $_current_data_handler = null; |
|
26 | - |
|
27 | - /** |
|
28 | - * This holds the EE_Messages_Queue that contains the messages to generate. |
|
29 | - */ |
|
30 | - protected EE_Messages_Queue $_generation_queue; |
|
31 | - |
|
32 | - /** |
|
33 | - * This holds the EE_Messages_Queue that will store the generated EE_Message objects. |
|
34 | - */ |
|
35 | - protected EE_Messages_Queue $_ready_queue; |
|
36 | - |
|
37 | - /** |
|
38 | - * This is a container for any error messages that get created through the generation |
|
39 | - * process. |
|
40 | - */ |
|
41 | - protected array $_error_msg = []; |
|
42 | - |
|
43 | - /** |
|
44 | - * Flag used to set when the current EE_Message in the generation queue has been verified. |
|
45 | - */ |
|
46 | - protected bool $_verified = false; |
|
47 | - |
|
48 | - /** |
|
49 | - * This will hold the current messenger object corresponding with the current EE_Message in the generation queue. |
|
50 | - */ |
|
51 | - protected ?EE_messenger $_current_messenger = null; |
|
52 | - |
|
53 | - /** |
|
54 | - * This will hold the current message type object corresponding with the current EE_Message in the generation queue. |
|
55 | - */ |
|
56 | - protected ?EE_message_type $_current_message_type = null; |
|
57 | - |
|
58 | - protected EEH_Parse_Shortcodes $_shortcode_parser; |
|
59 | - |
|
60 | - |
|
61 | - /** |
|
62 | - * @param EE_Messages_Queue $generation_queue |
|
63 | - * @param EE_Messages_Queue $ready_queue |
|
64 | - * @param EE_Messages_Data_Handler_Collection $data_handler_collection |
|
65 | - * @param EE_Message_Template_Group_Collection $template_collection |
|
66 | - * @param EEH_Parse_Shortcodes $shortcode_parser |
|
67 | - */ |
|
68 | - public function __construct( |
|
69 | - EE_Messages_Queue $generation_queue, |
|
70 | - EE_Messages_Queue $ready_queue, |
|
71 | - EE_Messages_Data_Handler_Collection $data_handler_collection, |
|
72 | - EE_Message_Template_Group_Collection $template_collection, |
|
73 | - EEH_Parse_Shortcodes $shortcode_parser |
|
74 | - ) { |
|
75 | - $this->_generation_queue = $generation_queue; |
|
76 | - $this->_ready_queue = $ready_queue; |
|
77 | - $this->_data_handler_collection = $data_handler_collection; |
|
78 | - $this->_template_collection = $template_collection; |
|
79 | - $this->_shortcode_parser = $shortcode_parser; |
|
80 | - } |
|
81 | - |
|
82 | - |
|
83 | - /** |
|
84 | - * @return EE_Messages_Queue |
|
85 | - */ |
|
86 | - public function generation_queue(): EE_Messages_Queue |
|
87 | - { |
|
88 | - return $this->_generation_queue; |
|
89 | - } |
|
90 | - |
|
91 | - |
|
92 | - /** |
|
93 | - * This iterates through the provided queue and generates the EE_Message objects. |
|
94 | - * When iterating through the queue, the queued item that served as the base for generating other EE_Message |
|
95 | - * objects gets removed and the new EE_Message objects get added to a NEW queue. The NEW queue is then returned |
|
96 | - * for the caller to decide what to do with it. |
|
97 | - * |
|
98 | - * @param bool $save Whether to save the EE_Message objects in the new queue or just return. |
|
99 | - * @return EE_Messages_Queue The new queue for holding generated EE_Message objects. |
|
100 | - * @throws EE_Error |
|
101 | - * @throws InvalidArgumentException |
|
102 | - * @throws InvalidDataTypeException |
|
103 | - * @throws InvalidInterfaceException |
|
104 | - * @throws ReflectionException |
|
105 | - */ |
|
106 | - public function generate(bool $save = true): EE_Messages_Queue |
|
107 | - { |
|
108 | - // iterate through the messages in the queue, generate, and add to new queue. |
|
109 | - $this->_generation_queue->get_message_repository()->rewind(); |
|
110 | - |
|
111 | - while ($this->_generation_queue->get_message_repository()->valid()) { |
|
112 | - // reset "current" properties |
|
113 | - $this->_reset_current_properties(); |
|
114 | - |
|
115 | - $msg = $this->_generation_queue->get_message_repository()->current(); |
|
116 | - |
|
117 | - /** |
|
118 | - * need to get the next object and capture it for setting manually after deletes. The reason is that when |
|
119 | - * an object is removed from the repo then valid for the next object will fail. |
|
120 | - */ |
|
121 | - $this->_generation_queue->get_message_repository()->next(); |
|
122 | - $next_msg = $this->_generation_queue->get_message_repository()->valid() |
|
123 | - ? $this->_generation_queue->get_message_repository()->current() |
|
124 | - : null; |
|
125 | - // restore pointer to current item |
|
126 | - $this->_generation_queue->get_message_repository()->set_current($msg); |
|
127 | - |
|
128 | - // skip and delete if the current $msg is NOT incomplete (queued for generation) |
|
129 | - if ($msg->STS_ID() !== EEM_Message::status_incomplete) { |
|
130 | - // we keep this item in the db just remove from the repo. |
|
131 | - $this->_generation_queue->get_message_repository()->remove($msg); |
|
132 | - // next item |
|
133 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
134 | - continue; |
|
135 | - } |
|
136 | - |
|
137 | - if ($this->_verify()) { |
|
138 | - // let's get generating! |
|
139 | - $this->_generate(); |
|
140 | - } |
|
141 | - |
|
142 | - // don't persist debug_only messages if the messages system is not in debug mode. |
|
143 | - if ( |
|
144 | - $msg->STS_ID() === EEM_Message::status_debug_only |
|
145 | - && ! EEM_Message::debug() |
|
146 | - ) { |
|
147 | - do_action( |
|
148 | - 'AHEE__EE_Messages_Generator__generate__before_debug_delete', |
|
149 | - $msg, |
|
150 | - $this->_error_msg, |
|
151 | - $this->_current_messenger, |
|
152 | - $this->_current_message_type, |
|
153 | - $this->_current_data_handler |
|
154 | - ); |
|
155 | - $this->_generation_queue->get_message_repository()->delete(); |
|
156 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
157 | - continue; |
|
158 | - } |
|
159 | - |
|
160 | - // if there are error messages then let's set the status and the error message. |
|
161 | - if ($this->_error_msg) { |
|
162 | - // if the status is already debug only, then let's leave it at that. |
|
163 | - if ($msg->STS_ID() !== EEM_Message::status_debug_only) { |
|
164 | - $msg->set_STS_ID(EEM_Message::status_failed); |
|
165 | - } |
|
166 | - do_action( |
|
167 | - 'AHEE__EE_Messages_Generator__generate__processing_failed_message', |
|
168 | - $msg, |
|
169 | - $this->_error_msg, |
|
170 | - $this->_current_messenger, |
|
171 | - $this->_current_message_type, |
|
172 | - $this->_current_data_handler |
|
173 | - ); |
|
174 | - $msg->set_error_message( |
|
175 | - esc_html__('Message failed to generate for the following reasons: ', 'event_espresso') |
|
176 | - . "\n" |
|
177 | - . implode("\n", $this->_error_msg) |
|
178 | - ); |
|
179 | - $msg->set_modified(time()); |
|
180 | - } else { |
|
181 | - do_action( |
|
182 | - 'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete', |
|
183 | - $msg, |
|
184 | - $this->_error_msg, |
|
185 | - $this->_current_messenger, |
|
186 | - $this->_current_message_type, |
|
187 | - $this->_current_data_handler |
|
188 | - ); |
|
189 | - // remove from db |
|
190 | - $this->_generation_queue->get_message_repository()->delete(); |
|
191 | - } |
|
192 | - // next item |
|
193 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
194 | - } |
|
195 | - |
|
196 | - // generation queue is ALWAYS saved to record any errors in the generation process. |
|
197 | - $this->_generation_queue->save(); |
|
198 | - |
|
199 | - /** |
|
200 | - * save _ready_queue if flag set. |
|
201 | - * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method. This |
|
202 | - * means if a field was added that is not a valid database column. The EE_Message was already saved to the db |
|
203 | - * so a EE_Extra_Meta entry could be created and attached to the EE_Message. In those cases the save flag is |
|
204 | - * irrelevant. |
|
205 | - */ |
|
206 | - if ($save) { |
|
207 | - $this->_ready_queue->save(); |
|
208 | - } |
|
209 | - |
|
210 | - // final reset of properties |
|
211 | - $this->_reset_current_properties(); |
|
212 | - |
|
213 | - return $this->_ready_queue; |
|
214 | - } |
|
215 | - |
|
216 | - |
|
217 | - /** |
|
218 | - * This resets all the properties used for holding "current" values corresponding to the current EE_Message object |
|
219 | - * in the generation queue. |
|
220 | - */ |
|
221 | - protected function _reset_current_properties() |
|
222 | - { |
|
223 | - $this->_verified = false; |
|
224 | - // make sure any _data value in the current message type is reset |
|
225 | - if ($this->_current_message_type instanceof EE_message_type) { |
|
226 | - $this->_current_message_type->reset_data(); |
|
227 | - } |
|
228 | - $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null; |
|
229 | - } |
|
230 | - |
|
231 | - |
|
232 | - /** |
|
233 | - * This proceeds with the actual generation of a message. By the time this is called, there should already be a |
|
234 | - * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the |
|
235 | - * _generating_queue. |
|
236 | - * |
|
237 | - * @return bool Whether the message was successfully generated or not. |
|
238 | - * @throws EE_Error |
|
239 | - * @throws InvalidArgumentException |
|
240 | - * @throws InvalidDataTypeException |
|
241 | - * @throws InvalidInterfaceException |
|
242 | - * @throws ReflectionException |
|
243 | - */ |
|
244 | - protected function _generate(): bool |
|
245 | - { |
|
246 | - // double check verification has run and that everything is ready to work with (saves us having to validate |
|
247 | - // everything again). |
|
248 | - if (! $this->_verified) { |
|
249 | - return false; // get out because we don't have a valid setup to work with. |
|
250 | - } |
|
251 | - |
|
252 | - |
|
253 | - try { |
|
254 | - $addressees = $this->_current_message_type->get_addressees( |
|
255 | - $this->_current_data_handler, |
|
256 | - $this->_generation_queue->get_message_repository()->current()->context() |
|
257 | - ); |
|
258 | - } catch (EE_Error $e) { |
|
259 | - $this->_error_msg[] = $e->getMessage(); |
|
260 | - return false; |
|
261 | - } |
|
262 | - |
|
263 | - |
|
264 | - // if no addressees then get out because there is nothing to generation (possible bad data). |
|
265 | - if (! $this->_valid_addressees($addressees)) { |
|
266 | - do_action( |
|
267 | - 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
|
268 | - $this->_generation_queue->get_message_repository()->current(), |
|
269 | - $addressees, |
|
270 | - $this->_current_messenger, |
|
271 | - $this->_current_message_type, |
|
272 | - $this->_current_data_handler |
|
273 | - ); |
|
274 | - $this->_generation_queue->get_message_repository()->current()->set_STS_ID( |
|
275 | - EEM_Message::status_debug_only |
|
276 | - ); |
|
277 | - $this->_error_msg[] = esc_html__( |
|
278 | - 'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects. There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.', |
|
279 | - 'event_espresso' |
|
280 | - ); |
|
281 | - return false; |
|
282 | - } |
|
283 | - |
|
284 | - $message_template_group = $this->_get_message_template_group(); |
|
285 | - |
|
286 | - // in the unlikely event there is no EE_Message_Template_Group available, get out! |
|
287 | - if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
288 | - $this->_error_msg[] = esc_html__( |
|
289 | - 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
|
290 | - 'event_espresso' |
|
291 | - ); |
|
292 | - return false; |
|
293 | - } |
|
294 | - |
|
295 | - // get formatted templates for using to parse and setup EE_Message objects. |
|
296 | - $templates = $this->_get_templates($message_template_group); |
|
297 | - |
|
298 | - |
|
299 | - // setup new EE_Message objects (and add to _ready_queue) |
|
300 | - return $this->_assemble_messages($addressees, $templates, $message_template_group); |
|
301 | - } |
|
302 | - |
|
303 | - |
|
304 | - /** |
|
305 | - * Retrieves the message template group being used for generating messages. |
|
306 | - * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times. |
|
307 | - * |
|
308 | - * @return EE_Message_Template_Group|null |
|
309 | - * @throws EE_Error |
|
310 | - * @throws InvalidArgumentException |
|
311 | - * @throws InvalidDataTypeException |
|
312 | - * @throws InvalidInterfaceException |
|
313 | - * @throws ReflectionException |
|
314 | - */ |
|
315 | - protected function _get_message_template_group(): ?EE_Message_Template_Group |
|
316 | - { |
|
317 | - // first see if there is a specific message template group requested |
|
318 | - // (current message in the queue has a specific GRP_ID) |
|
319 | - $message_template_group = $this->_specific_message_template_group_from_queue(); |
|
320 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
321 | - return $message_template_group; |
|
322 | - } |
|
323 | - |
|
324 | - // get event_ids from the data handler so we can check to see |
|
325 | - // if there's already a message template group for them in the collection. |
|
326 | - $event_ids = $this->_get_event_ids_from_current_data_handler(); |
|
327 | - $message_template_group = $this->_template_collection->get_by_key( |
|
328 | - $this->_template_collection->getKey( |
|
329 | - $this->_current_messenger->name, |
|
330 | - $this->_current_message_type->name, |
|
331 | - $event_ids |
|
332 | - ) |
|
333 | - ); |
|
334 | - |
|
335 | - // if we have a message template group then no need to hit the database, just return it. |
|
336 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
337 | - return $message_template_group; |
|
338 | - } |
|
339 | - |
|
340 | - // get the global group first for this messenger and message type |
|
341 | - // to ensure there is no override set. |
|
342 | - $global_message_template_group = |
|
343 | - $this->_get_global_message_template_group_for_current_messenger_and_message_type(); |
|
344 | - |
|
345 | - if ( |
|
346 | - $global_message_template_group instanceof EE_Message_Template_Group |
|
347 | - && $global_message_template_group->get('MTP_is_override') |
|
348 | - ) { |
|
349 | - return $global_message_template_group; |
|
350 | - } |
|
351 | - |
|
352 | - // if we're still here, that means there was no message template group for the events in the collection and |
|
353 | - // the global message template group for the messenger and message type is not set for override. So next step |
|
354 | - // is to see if there is a common shared custom message template group for this set of events. |
|
355 | - $message_template_group = $this->_get_shared_message_template_for_events($event_ids); |
|
356 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
357 | - return $message_template_group; |
|
358 | - } |
|
359 | - |
|
360 | - // STILL here? Okay that means the fallback is to just use the global message template group for this event |
|
361 | - // set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this |
|
362 | - // request) and return it. |
|
363 | - if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
364 | - $this->_template_collection->add( |
|
365 | - $global_message_template_group, |
|
366 | - $event_ids |
|
367 | - ); |
|
368 | - return $global_message_template_group; |
|
369 | - } |
|
370 | - |
|
371 | - // if we land here that means there's NO active message template group for this set. |
|
372 | - // TODO this will be a good target for some optimization down the road. Whenever there is no active message |
|
373 | - // template group for a given event set then cache that result so we don't repeat the logic. However, for now, |
|
374 | - // this should likely bit hit rarely enough that it's not a significant issue. |
|
375 | - return null; |
|
376 | - } |
|
377 | - |
|
378 | - |
|
379 | - /** |
|
380 | - * This checks the current message in the queue and determines if there is a specific Message Template Group |
|
381 | - * requested for that message. |
|
382 | - * |
|
383 | - * @return EE_Message_Template_Group|null |
|
384 | - * @throws EE_Error |
|
385 | - * @throws InvalidArgumentException |
|
386 | - * @throws InvalidDataTypeException |
|
387 | - * @throws InvalidInterfaceException |
|
388 | - * @throws ReflectionException |
|
389 | - */ |
|
390 | - protected function _specific_message_template_group_from_queue(): ?EE_Message_Template_Group |
|
391 | - { |
|
392 | - // is there a GRP_ID already on the EE_Message object? If there is, then a specific template has been requested |
|
393 | - // so let's use that. |
|
394 | - $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID(); |
|
395 | - |
|
396 | - if ($GRP_ID) { |
|
397 | - // attempt to retrieve from repo first |
|
398 | - $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
|
399 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
400 | - return $message_template_group; // got it! |
|
401 | - } |
|
402 | - |
|
403 | - // nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
|
404 | - // is not valid, so we'll continue on in the code assuming there's NO GRP_ID. |
|
405 | - $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID); |
|
406 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
407 | - $this->_template_collection->add($message_template_group); |
|
408 | - return $message_template_group; |
|
409 | - } |
|
410 | - } |
|
411 | - return null; |
|
412 | - } |
|
413 | - |
|
414 | - |
|
415 | - /** |
|
416 | - * Returns whether the event ids passed in all share the same message template group for the current message type |
|
417 | - * and messenger. |
|
418 | - * |
|
419 | - * @param array $event_ids |
|
420 | - * @return bool true means they DO share the same message template group, false means they don't. |
|
421 | - * @throws EE_Error |
|
422 | - * @throws InvalidArgumentException |
|
423 | - * @throws InvalidDataTypeException |
|
424 | - * @throws InvalidInterfaceException |
|
425 | - * @throws ReflectionException |
|
426 | - */ |
|
427 | - protected function _queue_shares_same_message_template_group_for_events(array $event_ids): bool |
|
428 | - { |
|
429 | - foreach ($this->_current_data_handler->events as $event) { |
|
430 | - $event_ids[ $event['ID'] ] = $event['ID']; |
|
431 | - } |
|
432 | - $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count( |
|
433 | - [ |
|
434 | - [ |
|
435 | - 'Event.EVT_ID' => ['IN', $event_ids], |
|
436 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
437 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
438 | - ], |
|
439 | - ], |
|
440 | - 'GRP_ID', |
|
441 | - true |
|
442 | - ); |
|
443 | - return $count_of_message_template_groups === 1; |
|
444 | - } |
|
445 | - |
|
446 | - |
|
447 | - /** |
|
448 | - * This will get the shared message template group for events that are in the current data handler but ONLY if |
|
449 | - * there's a single shared message template group among all the events. Otherwise it returns null. |
|
450 | - * |
|
451 | - * @param array $event_ids |
|
452 | - * @return EE_Message_Template_Group|null |
|
453 | - * @throws EE_Error |
|
454 | - * @throws InvalidArgumentException |
|
455 | - * @throws InvalidDataTypeException |
|
456 | - * @throws InvalidInterfaceException |
|
457 | - * @throws ReflectionException |
|
458 | - */ |
|
459 | - protected function _get_shared_message_template_for_events(array $event_ids): ?EE_Message_Template_Group |
|
460 | - { |
|
461 | - $message_template_group = null; |
|
462 | - if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) { |
|
463 | - $message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
464 | - [ |
|
465 | - [ |
|
466 | - 'Event.EVT_ID' => ['IN', $event_ids], |
|
467 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
468 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
469 | - 'MTP_is_active' => true, |
|
470 | - ], |
|
471 | - 'group_by' => 'GRP_ID', |
|
472 | - ] |
|
473 | - ); |
|
474 | - // store this in the collection if its valid |
|
475 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
476 | - $this->_template_collection->add( |
|
477 | - $message_template_group, |
|
478 | - $event_ids |
|
479 | - ); |
|
480 | - } |
|
481 | - } |
|
482 | - return $message_template_group; |
|
483 | - } |
|
484 | - |
|
485 | - |
|
486 | - /** |
|
487 | - * Retrieves the global message template group for the current messenger and message type. |
|
488 | - * |
|
489 | - * @return EE_Message_Template_Group|null |
|
490 | - * @throws EE_Error |
|
491 | - * @throws InvalidArgumentException |
|
492 | - * @throws InvalidDataTypeException |
|
493 | - * @throws InvalidInterfaceException |
|
494 | - * @throws ReflectionException |
|
495 | - */ |
|
496 | - protected function _get_global_message_template_group_for_current_messenger_and_message_type(): ?EE_Message_Template_Group |
|
497 | - { |
|
498 | - // first check the collection (we use an array with 0 in it to represent global groups). |
|
499 | - $global_message_template_group = $this->_template_collection->get_by_key( |
|
500 | - $this->_template_collection->getKey( |
|
501 | - $this->_current_messenger->name, |
|
502 | - $this->_current_message_type->name, |
|
503 | - [0] |
|
504 | - ) |
|
505 | - ); |
|
506 | - |
|
507 | - // if we don't have a group lets hit the db. |
|
508 | - if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
509 | - $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
510 | - [ |
|
511 | - [ |
|
512 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
513 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
514 | - 'MTP_is_active' => true, |
|
515 | - 'MTP_is_global' => true, |
|
516 | - ], |
|
517 | - ] |
|
518 | - ); |
|
519 | - // if we have a group, add it to the collection. |
|
520 | - if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
521 | - $this->_template_collection->add( |
|
522 | - $global_message_template_group, |
|
523 | - [0] |
|
524 | - ); |
|
525 | - } |
|
526 | - } |
|
527 | - return $global_message_template_group; |
|
528 | - } |
|
529 | - |
|
530 | - |
|
531 | - /** |
|
532 | - * Returns an array of event ids for all the events within the current data handler. |
|
533 | - * |
|
534 | - * @return array |
|
535 | - */ |
|
536 | - protected function _get_event_ids_from_current_data_handler(): array |
|
537 | - { |
|
538 | - $event_ids = []; |
|
539 | - foreach ($this->_current_data_handler->events as $event) { |
|
540 | - $event_ids[ $event['ID'] ] = $event['ID']; |
|
541 | - } |
|
542 | - return $event_ids; |
|
543 | - } |
|
544 | - |
|
545 | - |
|
546 | - /** |
|
547 | - * Retrieves formatted array of template information for each context specific to the given |
|
548 | - * EE_Message_Template_Group |
|
549 | - * |
|
550 | - * @param EE_Message_Template_Group $message_template_group |
|
551 | - * @return array The returned array is in this structure: |
|
552 | - * array( |
|
553 | - * 'field_name' => array( |
|
554 | - * 'context' => 'content' |
|
555 | - * ) |
|
556 | - * ) |
|
557 | - * @throws EE_Error |
|
558 | - * @throws InvalidArgumentException |
|
559 | - * @throws InvalidDataTypeException |
|
560 | - * @throws InvalidInterfaceException |
|
561 | - * @throws ReflectionException |
|
562 | - */ |
|
563 | - protected function _get_templates(EE_Message_Template_Group $message_template_group): array |
|
564 | - { |
|
565 | - $templates = []; |
|
566 | - $context_templates = $message_template_group->context_templates(); |
|
567 | - foreach ($context_templates as $context => $template_fields) { |
|
568 | - foreach ($template_fields as $template_field => $template_obj) { |
|
569 | - if (! $template_obj instanceof EE_Message_Template) { |
|
570 | - continue; |
|
571 | - } |
|
572 | - $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content'); |
|
573 | - } |
|
574 | - } |
|
575 | - return $templates; |
|
576 | - } |
|
577 | - |
|
578 | - |
|
579 | - /** |
|
580 | - * Assembles new fully generated EE_Message objects and adds to _ready_queue |
|
581 | - * |
|
582 | - * @param array $addressees Array of EE_Messages_Addressee objects indexed by message type |
|
583 | - * context. |
|
584 | - * @param array $templates formatted array of templates used for parsing data. |
|
585 | - * @param EE_Message_Template_Group $message_template_group |
|
586 | - * @return bool true if message generation went a-ok. false if some sort of exception occurred. Note: The |
|
587 | - * method will attempt to generate ALL EE_Message objects and add to |
|
588 | - * the _ready_queue. Successfully generated messages get added to the |
|
589 | - * queue with EEM_Message::status_idle, unsuccessfully generated |
|
590 | - * messages will get added to the queue as EEM_Message::status_failed. |
|
591 | - * Very rarely should "false" be returned from this method. |
|
592 | - * @throws EE_Error |
|
593 | - * @throws InvalidArgumentException |
|
594 | - * @throws InvalidDataTypeException |
|
595 | - * @throws InvalidIdentifierException |
|
596 | - * @throws InvalidInterfaceException |
|
597 | - * @throws ReflectionException |
|
598 | - */ |
|
599 | - protected function _assemble_messages( |
|
600 | - array $addressees, |
|
601 | - array $templates, |
|
602 | - EE_Message_Template_Group $message_template_group |
|
603 | - ): bool { |
|
604 | - // if templates are empty then get out because we can't generate anything. |
|
605 | - if (! $templates) { |
|
606 | - $this->_error_msg[] = esc_html__( |
|
607 | - 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
|
608 | - 'event_espresso' |
|
609 | - ); |
|
610 | - return false; |
|
611 | - } |
|
612 | - |
|
613 | - // We use this as the counter for generated messages because don't forget we may be executing this inside of a |
|
614 | - // generation_queue. So _ready_queue may have generated EE_Message objects already. |
|
615 | - $generated_count = 0; |
|
616 | - foreach ($addressees as $context => $recipients) { |
|
617 | - foreach ($recipients as $recipient) { |
|
618 | - $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group); |
|
619 | - if ($message instanceof EE_Message) { |
|
620 | - $this->_ready_queue->add( |
|
621 | - $message, |
|
622 | - [], |
|
623 | - $this->_generation_queue->get_message_repository()->is_preview(), |
|
624 | - $this->_generation_queue->get_message_repository()->is_test_send() |
|
625 | - ); |
|
626 | - $generated_count++; |
|
627 | - } |
|
628 | - |
|
629 | - // if the current MSG being generated is for a test send then we'll only use ONE message in the |
|
630 | - // generation. |
|
631 | - if ($this->_generation_queue->get_message_repository()->is_test_send()) { |
|
632 | - break 2; |
|
633 | - } |
|
634 | - } |
|
635 | - } |
|
636 | - |
|
637 | - // if there are no generated messages then something else fatal went wrong. |
|
638 | - return $generated_count > 0; |
|
639 | - } |
|
640 | - |
|
641 | - |
|
642 | - /** |
|
643 | - * @param string $context The context for the generated message. |
|
644 | - * @param EE_Messages_Addressee $recipient |
|
645 | - * @param array $templates formatted array of templates used for parsing data. |
|
646 | - * @param EE_Message_Template_Group $message_template_group |
|
647 | - * @return bool|EE_Message |
|
648 | - * @throws EE_Error |
|
649 | - * @throws InvalidArgumentException |
|
650 | - * @throws InvalidDataTypeException |
|
651 | - * @throws InvalidInterfaceException |
|
652 | - * @throws ReflectionException |
|
653 | - * @throws InvalidIdentifierException |
|
654 | - */ |
|
655 | - protected function _setup_message_object( |
|
656 | - string $context, |
|
657 | - EE_Messages_Addressee $recipient, |
|
658 | - array $templates, |
|
659 | - EE_Message_Template_Group $message_template_group |
|
660 | - ) { |
|
661 | - // stuff we already know |
|
662 | - $transaction_id = $recipient->txn instanceof EE_Transaction |
|
663 | - ? $recipient->txn->ID() |
|
664 | - : 0; |
|
665 | - $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction |
|
666 | - ? $this->_current_data_handler->txn->ID() |
|
667 | - : $transaction_id; |
|
668 | - $message_fields = [ |
|
669 | - 'GRP_ID' => $message_template_group->ID(), |
|
670 | - 'TXN_ID' => $transaction_id, |
|
671 | - 'MSG_messenger' => $this->_current_messenger->name, |
|
672 | - 'MSG_message_type' => $this->_current_message_type->name, |
|
673 | - 'MSG_context' => $context, |
|
674 | - ]; |
|
675 | - |
|
676 | - // recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab |
|
677 | - // the info from the att_obj found in the EE_Messages_Addressee object. |
|
678 | - if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) { |
|
679 | - $message_fields['MSG_recipient_ID'] = $recipient->att_obj instanceof EE_Attendee |
|
680 | - ? $recipient->att_obj->ID() |
|
681 | - : 0; |
|
682 | - $message_fields['MSG_recipient_type'] = 'Attendee'; |
|
683 | - } else { |
|
684 | - $message_fields['MSG_recipient_ID'] = $recipient->recipient_id; |
|
685 | - $message_fields['MSG_recipient_type'] = $recipient->recipient_type; |
|
686 | - } |
|
687 | - $message = EE_Message_Factory::create($message_fields); |
|
688 | - |
|
689 | - // grab valid shortcodes for shortcode parser |
|
690 | - $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes(); |
|
691 | - $m_shortcodes = $this->_current_messenger->get_valid_shortcodes(); |
|
692 | - |
|
693 | - // if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing |
|
694 | - if ( |
|
695 | - ! $this->_generation_queue->get_message_repository()->is_preview() |
|
696 | - && ( |
|
697 | - (empty($templates['to'][ $context ]) && ! $this->_current_messenger->allow_empty_to_field()) |
|
698 | - || ! $message_template_group->is_context_active($context) |
|
699 | - ) |
|
700 | - ) { |
|
701 | - // we silently exit here and do NOT record a fail because the message is "turned off" by having no "to" |
|
702 | - // field. |
|
703 | - return false; |
|
704 | - } |
|
705 | - $error_msg = []; |
|
706 | - foreach ($templates as $field => $field_context) { |
|
707 | - $error_msg = []; |
|
708 | - // let's setup the valid shortcodes for the incoming context. |
|
709 | - $valid_shortcodes = $mt_shortcodes[ $context ]; |
|
710 | - // merge in valid shortcodes for the field. |
|
711 | - $shortcodes = $m_shortcodes[ $field ] ?? $valid_shortcodes; |
|
712 | - if (isset($field_context[ $context ])) { |
|
713 | - // prefix field. |
|
714 | - $column_name = 'MSG_' . $field; |
|
715 | - try { |
|
716 | - $content = $this->_shortcode_parser->parse_message_template( |
|
717 | - $field_context[ $context ], |
|
718 | - $recipient, |
|
719 | - $shortcodes, |
|
720 | - $this->_current_message_type, |
|
721 | - $this->_current_messenger, |
|
722 | - $message |
|
723 | - ); |
|
724 | - // the model field removes slashes when setting (usually necessary when the input is from the |
|
725 | - // request) but this value is from another model and has no slashes. So add them so it matches |
|
726 | - // what the field expected (otherwise slashes will have been stripped from this an extra time) |
|
727 | - $message->set_field_or_extra_meta($column_name, addslashes($content)); |
|
728 | - } catch (EE_Error $e) { |
|
729 | - $error_msg[] = sprintf( |
|
730 | - /* Translators: First place holder is message model field name. |
|
18 | + protected EE_Messages_Data_Handler_Collection $_data_handler_collection; |
|
19 | + |
|
20 | + protected EE_Message_Template_Group_Collection $_template_collection; |
|
21 | + |
|
22 | + /** |
|
23 | + * This will hold the data handler for the current EE_Message being generated. |
|
24 | + */ |
|
25 | + protected ?EE_Messages_incoming_data $_current_data_handler = null; |
|
26 | + |
|
27 | + /** |
|
28 | + * This holds the EE_Messages_Queue that contains the messages to generate. |
|
29 | + */ |
|
30 | + protected EE_Messages_Queue $_generation_queue; |
|
31 | + |
|
32 | + /** |
|
33 | + * This holds the EE_Messages_Queue that will store the generated EE_Message objects. |
|
34 | + */ |
|
35 | + protected EE_Messages_Queue $_ready_queue; |
|
36 | + |
|
37 | + /** |
|
38 | + * This is a container for any error messages that get created through the generation |
|
39 | + * process. |
|
40 | + */ |
|
41 | + protected array $_error_msg = []; |
|
42 | + |
|
43 | + /** |
|
44 | + * Flag used to set when the current EE_Message in the generation queue has been verified. |
|
45 | + */ |
|
46 | + protected bool $_verified = false; |
|
47 | + |
|
48 | + /** |
|
49 | + * This will hold the current messenger object corresponding with the current EE_Message in the generation queue. |
|
50 | + */ |
|
51 | + protected ?EE_messenger $_current_messenger = null; |
|
52 | + |
|
53 | + /** |
|
54 | + * This will hold the current message type object corresponding with the current EE_Message in the generation queue. |
|
55 | + */ |
|
56 | + protected ?EE_message_type $_current_message_type = null; |
|
57 | + |
|
58 | + protected EEH_Parse_Shortcodes $_shortcode_parser; |
|
59 | + |
|
60 | + |
|
61 | + /** |
|
62 | + * @param EE_Messages_Queue $generation_queue |
|
63 | + * @param EE_Messages_Queue $ready_queue |
|
64 | + * @param EE_Messages_Data_Handler_Collection $data_handler_collection |
|
65 | + * @param EE_Message_Template_Group_Collection $template_collection |
|
66 | + * @param EEH_Parse_Shortcodes $shortcode_parser |
|
67 | + */ |
|
68 | + public function __construct( |
|
69 | + EE_Messages_Queue $generation_queue, |
|
70 | + EE_Messages_Queue $ready_queue, |
|
71 | + EE_Messages_Data_Handler_Collection $data_handler_collection, |
|
72 | + EE_Message_Template_Group_Collection $template_collection, |
|
73 | + EEH_Parse_Shortcodes $shortcode_parser |
|
74 | + ) { |
|
75 | + $this->_generation_queue = $generation_queue; |
|
76 | + $this->_ready_queue = $ready_queue; |
|
77 | + $this->_data_handler_collection = $data_handler_collection; |
|
78 | + $this->_template_collection = $template_collection; |
|
79 | + $this->_shortcode_parser = $shortcode_parser; |
|
80 | + } |
|
81 | + |
|
82 | + |
|
83 | + /** |
|
84 | + * @return EE_Messages_Queue |
|
85 | + */ |
|
86 | + public function generation_queue(): EE_Messages_Queue |
|
87 | + { |
|
88 | + return $this->_generation_queue; |
|
89 | + } |
|
90 | + |
|
91 | + |
|
92 | + /** |
|
93 | + * This iterates through the provided queue and generates the EE_Message objects. |
|
94 | + * When iterating through the queue, the queued item that served as the base for generating other EE_Message |
|
95 | + * objects gets removed and the new EE_Message objects get added to a NEW queue. The NEW queue is then returned |
|
96 | + * for the caller to decide what to do with it. |
|
97 | + * |
|
98 | + * @param bool $save Whether to save the EE_Message objects in the new queue or just return. |
|
99 | + * @return EE_Messages_Queue The new queue for holding generated EE_Message objects. |
|
100 | + * @throws EE_Error |
|
101 | + * @throws InvalidArgumentException |
|
102 | + * @throws InvalidDataTypeException |
|
103 | + * @throws InvalidInterfaceException |
|
104 | + * @throws ReflectionException |
|
105 | + */ |
|
106 | + public function generate(bool $save = true): EE_Messages_Queue |
|
107 | + { |
|
108 | + // iterate through the messages in the queue, generate, and add to new queue. |
|
109 | + $this->_generation_queue->get_message_repository()->rewind(); |
|
110 | + |
|
111 | + while ($this->_generation_queue->get_message_repository()->valid()) { |
|
112 | + // reset "current" properties |
|
113 | + $this->_reset_current_properties(); |
|
114 | + |
|
115 | + $msg = $this->_generation_queue->get_message_repository()->current(); |
|
116 | + |
|
117 | + /** |
|
118 | + * need to get the next object and capture it for setting manually after deletes. The reason is that when |
|
119 | + * an object is removed from the repo then valid for the next object will fail. |
|
120 | + */ |
|
121 | + $this->_generation_queue->get_message_repository()->next(); |
|
122 | + $next_msg = $this->_generation_queue->get_message_repository()->valid() |
|
123 | + ? $this->_generation_queue->get_message_repository()->current() |
|
124 | + : null; |
|
125 | + // restore pointer to current item |
|
126 | + $this->_generation_queue->get_message_repository()->set_current($msg); |
|
127 | + |
|
128 | + // skip and delete if the current $msg is NOT incomplete (queued for generation) |
|
129 | + if ($msg->STS_ID() !== EEM_Message::status_incomplete) { |
|
130 | + // we keep this item in the db just remove from the repo. |
|
131 | + $this->_generation_queue->get_message_repository()->remove($msg); |
|
132 | + // next item |
|
133 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
134 | + continue; |
|
135 | + } |
|
136 | + |
|
137 | + if ($this->_verify()) { |
|
138 | + // let's get generating! |
|
139 | + $this->_generate(); |
|
140 | + } |
|
141 | + |
|
142 | + // don't persist debug_only messages if the messages system is not in debug mode. |
|
143 | + if ( |
|
144 | + $msg->STS_ID() === EEM_Message::status_debug_only |
|
145 | + && ! EEM_Message::debug() |
|
146 | + ) { |
|
147 | + do_action( |
|
148 | + 'AHEE__EE_Messages_Generator__generate__before_debug_delete', |
|
149 | + $msg, |
|
150 | + $this->_error_msg, |
|
151 | + $this->_current_messenger, |
|
152 | + $this->_current_message_type, |
|
153 | + $this->_current_data_handler |
|
154 | + ); |
|
155 | + $this->_generation_queue->get_message_repository()->delete(); |
|
156 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
157 | + continue; |
|
158 | + } |
|
159 | + |
|
160 | + // if there are error messages then let's set the status and the error message. |
|
161 | + if ($this->_error_msg) { |
|
162 | + // if the status is already debug only, then let's leave it at that. |
|
163 | + if ($msg->STS_ID() !== EEM_Message::status_debug_only) { |
|
164 | + $msg->set_STS_ID(EEM_Message::status_failed); |
|
165 | + } |
|
166 | + do_action( |
|
167 | + 'AHEE__EE_Messages_Generator__generate__processing_failed_message', |
|
168 | + $msg, |
|
169 | + $this->_error_msg, |
|
170 | + $this->_current_messenger, |
|
171 | + $this->_current_message_type, |
|
172 | + $this->_current_data_handler |
|
173 | + ); |
|
174 | + $msg->set_error_message( |
|
175 | + esc_html__('Message failed to generate for the following reasons: ', 'event_espresso') |
|
176 | + . "\n" |
|
177 | + . implode("\n", $this->_error_msg) |
|
178 | + ); |
|
179 | + $msg->set_modified(time()); |
|
180 | + } else { |
|
181 | + do_action( |
|
182 | + 'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete', |
|
183 | + $msg, |
|
184 | + $this->_error_msg, |
|
185 | + $this->_current_messenger, |
|
186 | + $this->_current_message_type, |
|
187 | + $this->_current_data_handler |
|
188 | + ); |
|
189 | + // remove from db |
|
190 | + $this->_generation_queue->get_message_repository()->delete(); |
|
191 | + } |
|
192 | + // next item |
|
193 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
194 | + } |
|
195 | + |
|
196 | + // generation queue is ALWAYS saved to record any errors in the generation process. |
|
197 | + $this->_generation_queue->save(); |
|
198 | + |
|
199 | + /** |
|
200 | + * save _ready_queue if flag set. |
|
201 | + * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method. This |
|
202 | + * means if a field was added that is not a valid database column. The EE_Message was already saved to the db |
|
203 | + * so a EE_Extra_Meta entry could be created and attached to the EE_Message. In those cases the save flag is |
|
204 | + * irrelevant. |
|
205 | + */ |
|
206 | + if ($save) { |
|
207 | + $this->_ready_queue->save(); |
|
208 | + } |
|
209 | + |
|
210 | + // final reset of properties |
|
211 | + $this->_reset_current_properties(); |
|
212 | + |
|
213 | + return $this->_ready_queue; |
|
214 | + } |
|
215 | + |
|
216 | + |
|
217 | + /** |
|
218 | + * This resets all the properties used for holding "current" values corresponding to the current EE_Message object |
|
219 | + * in the generation queue. |
|
220 | + */ |
|
221 | + protected function _reset_current_properties() |
|
222 | + { |
|
223 | + $this->_verified = false; |
|
224 | + // make sure any _data value in the current message type is reset |
|
225 | + if ($this->_current_message_type instanceof EE_message_type) { |
|
226 | + $this->_current_message_type->reset_data(); |
|
227 | + } |
|
228 | + $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null; |
|
229 | + } |
|
230 | + |
|
231 | + |
|
232 | + /** |
|
233 | + * This proceeds with the actual generation of a message. By the time this is called, there should already be a |
|
234 | + * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the |
|
235 | + * _generating_queue. |
|
236 | + * |
|
237 | + * @return bool Whether the message was successfully generated or not. |
|
238 | + * @throws EE_Error |
|
239 | + * @throws InvalidArgumentException |
|
240 | + * @throws InvalidDataTypeException |
|
241 | + * @throws InvalidInterfaceException |
|
242 | + * @throws ReflectionException |
|
243 | + */ |
|
244 | + protected function _generate(): bool |
|
245 | + { |
|
246 | + // double check verification has run and that everything is ready to work with (saves us having to validate |
|
247 | + // everything again). |
|
248 | + if (! $this->_verified) { |
|
249 | + return false; // get out because we don't have a valid setup to work with. |
|
250 | + } |
|
251 | + |
|
252 | + |
|
253 | + try { |
|
254 | + $addressees = $this->_current_message_type->get_addressees( |
|
255 | + $this->_current_data_handler, |
|
256 | + $this->_generation_queue->get_message_repository()->current()->context() |
|
257 | + ); |
|
258 | + } catch (EE_Error $e) { |
|
259 | + $this->_error_msg[] = $e->getMessage(); |
|
260 | + return false; |
|
261 | + } |
|
262 | + |
|
263 | + |
|
264 | + // if no addressees then get out because there is nothing to generation (possible bad data). |
|
265 | + if (! $this->_valid_addressees($addressees)) { |
|
266 | + do_action( |
|
267 | + 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
|
268 | + $this->_generation_queue->get_message_repository()->current(), |
|
269 | + $addressees, |
|
270 | + $this->_current_messenger, |
|
271 | + $this->_current_message_type, |
|
272 | + $this->_current_data_handler |
|
273 | + ); |
|
274 | + $this->_generation_queue->get_message_repository()->current()->set_STS_ID( |
|
275 | + EEM_Message::status_debug_only |
|
276 | + ); |
|
277 | + $this->_error_msg[] = esc_html__( |
|
278 | + 'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects. There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.', |
|
279 | + 'event_espresso' |
|
280 | + ); |
|
281 | + return false; |
|
282 | + } |
|
283 | + |
|
284 | + $message_template_group = $this->_get_message_template_group(); |
|
285 | + |
|
286 | + // in the unlikely event there is no EE_Message_Template_Group available, get out! |
|
287 | + if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
288 | + $this->_error_msg[] = esc_html__( |
|
289 | + 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
|
290 | + 'event_espresso' |
|
291 | + ); |
|
292 | + return false; |
|
293 | + } |
|
294 | + |
|
295 | + // get formatted templates for using to parse and setup EE_Message objects. |
|
296 | + $templates = $this->_get_templates($message_template_group); |
|
297 | + |
|
298 | + |
|
299 | + // setup new EE_Message objects (and add to _ready_queue) |
|
300 | + return $this->_assemble_messages($addressees, $templates, $message_template_group); |
|
301 | + } |
|
302 | + |
|
303 | + |
|
304 | + /** |
|
305 | + * Retrieves the message template group being used for generating messages. |
|
306 | + * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times. |
|
307 | + * |
|
308 | + * @return EE_Message_Template_Group|null |
|
309 | + * @throws EE_Error |
|
310 | + * @throws InvalidArgumentException |
|
311 | + * @throws InvalidDataTypeException |
|
312 | + * @throws InvalidInterfaceException |
|
313 | + * @throws ReflectionException |
|
314 | + */ |
|
315 | + protected function _get_message_template_group(): ?EE_Message_Template_Group |
|
316 | + { |
|
317 | + // first see if there is a specific message template group requested |
|
318 | + // (current message in the queue has a specific GRP_ID) |
|
319 | + $message_template_group = $this->_specific_message_template_group_from_queue(); |
|
320 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
321 | + return $message_template_group; |
|
322 | + } |
|
323 | + |
|
324 | + // get event_ids from the data handler so we can check to see |
|
325 | + // if there's already a message template group for them in the collection. |
|
326 | + $event_ids = $this->_get_event_ids_from_current_data_handler(); |
|
327 | + $message_template_group = $this->_template_collection->get_by_key( |
|
328 | + $this->_template_collection->getKey( |
|
329 | + $this->_current_messenger->name, |
|
330 | + $this->_current_message_type->name, |
|
331 | + $event_ids |
|
332 | + ) |
|
333 | + ); |
|
334 | + |
|
335 | + // if we have a message template group then no need to hit the database, just return it. |
|
336 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
337 | + return $message_template_group; |
|
338 | + } |
|
339 | + |
|
340 | + // get the global group first for this messenger and message type |
|
341 | + // to ensure there is no override set. |
|
342 | + $global_message_template_group = |
|
343 | + $this->_get_global_message_template_group_for_current_messenger_and_message_type(); |
|
344 | + |
|
345 | + if ( |
|
346 | + $global_message_template_group instanceof EE_Message_Template_Group |
|
347 | + && $global_message_template_group->get('MTP_is_override') |
|
348 | + ) { |
|
349 | + return $global_message_template_group; |
|
350 | + } |
|
351 | + |
|
352 | + // if we're still here, that means there was no message template group for the events in the collection and |
|
353 | + // the global message template group for the messenger and message type is not set for override. So next step |
|
354 | + // is to see if there is a common shared custom message template group for this set of events. |
|
355 | + $message_template_group = $this->_get_shared_message_template_for_events($event_ids); |
|
356 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
357 | + return $message_template_group; |
|
358 | + } |
|
359 | + |
|
360 | + // STILL here? Okay that means the fallback is to just use the global message template group for this event |
|
361 | + // set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this |
|
362 | + // request) and return it. |
|
363 | + if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
364 | + $this->_template_collection->add( |
|
365 | + $global_message_template_group, |
|
366 | + $event_ids |
|
367 | + ); |
|
368 | + return $global_message_template_group; |
|
369 | + } |
|
370 | + |
|
371 | + // if we land here that means there's NO active message template group for this set. |
|
372 | + // TODO this will be a good target for some optimization down the road. Whenever there is no active message |
|
373 | + // template group for a given event set then cache that result so we don't repeat the logic. However, for now, |
|
374 | + // this should likely bit hit rarely enough that it's not a significant issue. |
|
375 | + return null; |
|
376 | + } |
|
377 | + |
|
378 | + |
|
379 | + /** |
|
380 | + * This checks the current message in the queue and determines if there is a specific Message Template Group |
|
381 | + * requested for that message. |
|
382 | + * |
|
383 | + * @return EE_Message_Template_Group|null |
|
384 | + * @throws EE_Error |
|
385 | + * @throws InvalidArgumentException |
|
386 | + * @throws InvalidDataTypeException |
|
387 | + * @throws InvalidInterfaceException |
|
388 | + * @throws ReflectionException |
|
389 | + */ |
|
390 | + protected function _specific_message_template_group_from_queue(): ?EE_Message_Template_Group |
|
391 | + { |
|
392 | + // is there a GRP_ID already on the EE_Message object? If there is, then a specific template has been requested |
|
393 | + // so let's use that. |
|
394 | + $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID(); |
|
395 | + |
|
396 | + if ($GRP_ID) { |
|
397 | + // attempt to retrieve from repo first |
|
398 | + $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
|
399 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
400 | + return $message_template_group; // got it! |
|
401 | + } |
|
402 | + |
|
403 | + // nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
|
404 | + // is not valid, so we'll continue on in the code assuming there's NO GRP_ID. |
|
405 | + $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID); |
|
406 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
407 | + $this->_template_collection->add($message_template_group); |
|
408 | + return $message_template_group; |
|
409 | + } |
|
410 | + } |
|
411 | + return null; |
|
412 | + } |
|
413 | + |
|
414 | + |
|
415 | + /** |
|
416 | + * Returns whether the event ids passed in all share the same message template group for the current message type |
|
417 | + * and messenger. |
|
418 | + * |
|
419 | + * @param array $event_ids |
|
420 | + * @return bool true means they DO share the same message template group, false means they don't. |
|
421 | + * @throws EE_Error |
|
422 | + * @throws InvalidArgumentException |
|
423 | + * @throws InvalidDataTypeException |
|
424 | + * @throws InvalidInterfaceException |
|
425 | + * @throws ReflectionException |
|
426 | + */ |
|
427 | + protected function _queue_shares_same_message_template_group_for_events(array $event_ids): bool |
|
428 | + { |
|
429 | + foreach ($this->_current_data_handler->events as $event) { |
|
430 | + $event_ids[ $event['ID'] ] = $event['ID']; |
|
431 | + } |
|
432 | + $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count( |
|
433 | + [ |
|
434 | + [ |
|
435 | + 'Event.EVT_ID' => ['IN', $event_ids], |
|
436 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
437 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
438 | + ], |
|
439 | + ], |
|
440 | + 'GRP_ID', |
|
441 | + true |
|
442 | + ); |
|
443 | + return $count_of_message_template_groups === 1; |
|
444 | + } |
|
445 | + |
|
446 | + |
|
447 | + /** |
|
448 | + * This will get the shared message template group for events that are in the current data handler but ONLY if |
|
449 | + * there's a single shared message template group among all the events. Otherwise it returns null. |
|
450 | + * |
|
451 | + * @param array $event_ids |
|
452 | + * @return EE_Message_Template_Group|null |
|
453 | + * @throws EE_Error |
|
454 | + * @throws InvalidArgumentException |
|
455 | + * @throws InvalidDataTypeException |
|
456 | + * @throws InvalidInterfaceException |
|
457 | + * @throws ReflectionException |
|
458 | + */ |
|
459 | + protected function _get_shared_message_template_for_events(array $event_ids): ?EE_Message_Template_Group |
|
460 | + { |
|
461 | + $message_template_group = null; |
|
462 | + if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) { |
|
463 | + $message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
464 | + [ |
|
465 | + [ |
|
466 | + 'Event.EVT_ID' => ['IN', $event_ids], |
|
467 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
468 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
469 | + 'MTP_is_active' => true, |
|
470 | + ], |
|
471 | + 'group_by' => 'GRP_ID', |
|
472 | + ] |
|
473 | + ); |
|
474 | + // store this in the collection if its valid |
|
475 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
476 | + $this->_template_collection->add( |
|
477 | + $message_template_group, |
|
478 | + $event_ids |
|
479 | + ); |
|
480 | + } |
|
481 | + } |
|
482 | + return $message_template_group; |
|
483 | + } |
|
484 | + |
|
485 | + |
|
486 | + /** |
|
487 | + * Retrieves the global message template group for the current messenger and message type. |
|
488 | + * |
|
489 | + * @return EE_Message_Template_Group|null |
|
490 | + * @throws EE_Error |
|
491 | + * @throws InvalidArgumentException |
|
492 | + * @throws InvalidDataTypeException |
|
493 | + * @throws InvalidInterfaceException |
|
494 | + * @throws ReflectionException |
|
495 | + */ |
|
496 | + protected function _get_global_message_template_group_for_current_messenger_and_message_type(): ?EE_Message_Template_Group |
|
497 | + { |
|
498 | + // first check the collection (we use an array with 0 in it to represent global groups). |
|
499 | + $global_message_template_group = $this->_template_collection->get_by_key( |
|
500 | + $this->_template_collection->getKey( |
|
501 | + $this->_current_messenger->name, |
|
502 | + $this->_current_message_type->name, |
|
503 | + [0] |
|
504 | + ) |
|
505 | + ); |
|
506 | + |
|
507 | + // if we don't have a group lets hit the db. |
|
508 | + if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
509 | + $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
510 | + [ |
|
511 | + [ |
|
512 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
513 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
514 | + 'MTP_is_active' => true, |
|
515 | + 'MTP_is_global' => true, |
|
516 | + ], |
|
517 | + ] |
|
518 | + ); |
|
519 | + // if we have a group, add it to the collection. |
|
520 | + if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
521 | + $this->_template_collection->add( |
|
522 | + $global_message_template_group, |
|
523 | + [0] |
|
524 | + ); |
|
525 | + } |
|
526 | + } |
|
527 | + return $global_message_template_group; |
|
528 | + } |
|
529 | + |
|
530 | + |
|
531 | + /** |
|
532 | + * Returns an array of event ids for all the events within the current data handler. |
|
533 | + * |
|
534 | + * @return array |
|
535 | + */ |
|
536 | + protected function _get_event_ids_from_current_data_handler(): array |
|
537 | + { |
|
538 | + $event_ids = []; |
|
539 | + foreach ($this->_current_data_handler->events as $event) { |
|
540 | + $event_ids[ $event['ID'] ] = $event['ID']; |
|
541 | + } |
|
542 | + return $event_ids; |
|
543 | + } |
|
544 | + |
|
545 | + |
|
546 | + /** |
|
547 | + * Retrieves formatted array of template information for each context specific to the given |
|
548 | + * EE_Message_Template_Group |
|
549 | + * |
|
550 | + * @param EE_Message_Template_Group $message_template_group |
|
551 | + * @return array The returned array is in this structure: |
|
552 | + * array( |
|
553 | + * 'field_name' => array( |
|
554 | + * 'context' => 'content' |
|
555 | + * ) |
|
556 | + * ) |
|
557 | + * @throws EE_Error |
|
558 | + * @throws InvalidArgumentException |
|
559 | + * @throws InvalidDataTypeException |
|
560 | + * @throws InvalidInterfaceException |
|
561 | + * @throws ReflectionException |
|
562 | + */ |
|
563 | + protected function _get_templates(EE_Message_Template_Group $message_template_group): array |
|
564 | + { |
|
565 | + $templates = []; |
|
566 | + $context_templates = $message_template_group->context_templates(); |
|
567 | + foreach ($context_templates as $context => $template_fields) { |
|
568 | + foreach ($template_fields as $template_field => $template_obj) { |
|
569 | + if (! $template_obj instanceof EE_Message_Template) { |
|
570 | + continue; |
|
571 | + } |
|
572 | + $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content'); |
|
573 | + } |
|
574 | + } |
|
575 | + return $templates; |
|
576 | + } |
|
577 | + |
|
578 | + |
|
579 | + /** |
|
580 | + * Assembles new fully generated EE_Message objects and adds to _ready_queue |
|
581 | + * |
|
582 | + * @param array $addressees Array of EE_Messages_Addressee objects indexed by message type |
|
583 | + * context. |
|
584 | + * @param array $templates formatted array of templates used for parsing data. |
|
585 | + * @param EE_Message_Template_Group $message_template_group |
|
586 | + * @return bool true if message generation went a-ok. false if some sort of exception occurred. Note: The |
|
587 | + * method will attempt to generate ALL EE_Message objects and add to |
|
588 | + * the _ready_queue. Successfully generated messages get added to the |
|
589 | + * queue with EEM_Message::status_idle, unsuccessfully generated |
|
590 | + * messages will get added to the queue as EEM_Message::status_failed. |
|
591 | + * Very rarely should "false" be returned from this method. |
|
592 | + * @throws EE_Error |
|
593 | + * @throws InvalidArgumentException |
|
594 | + * @throws InvalidDataTypeException |
|
595 | + * @throws InvalidIdentifierException |
|
596 | + * @throws InvalidInterfaceException |
|
597 | + * @throws ReflectionException |
|
598 | + */ |
|
599 | + protected function _assemble_messages( |
|
600 | + array $addressees, |
|
601 | + array $templates, |
|
602 | + EE_Message_Template_Group $message_template_group |
|
603 | + ): bool { |
|
604 | + // if templates are empty then get out because we can't generate anything. |
|
605 | + if (! $templates) { |
|
606 | + $this->_error_msg[] = esc_html__( |
|
607 | + 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
|
608 | + 'event_espresso' |
|
609 | + ); |
|
610 | + return false; |
|
611 | + } |
|
612 | + |
|
613 | + // We use this as the counter for generated messages because don't forget we may be executing this inside of a |
|
614 | + // generation_queue. So _ready_queue may have generated EE_Message objects already. |
|
615 | + $generated_count = 0; |
|
616 | + foreach ($addressees as $context => $recipients) { |
|
617 | + foreach ($recipients as $recipient) { |
|
618 | + $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group); |
|
619 | + if ($message instanceof EE_Message) { |
|
620 | + $this->_ready_queue->add( |
|
621 | + $message, |
|
622 | + [], |
|
623 | + $this->_generation_queue->get_message_repository()->is_preview(), |
|
624 | + $this->_generation_queue->get_message_repository()->is_test_send() |
|
625 | + ); |
|
626 | + $generated_count++; |
|
627 | + } |
|
628 | + |
|
629 | + // if the current MSG being generated is for a test send then we'll only use ONE message in the |
|
630 | + // generation. |
|
631 | + if ($this->_generation_queue->get_message_repository()->is_test_send()) { |
|
632 | + break 2; |
|
633 | + } |
|
634 | + } |
|
635 | + } |
|
636 | + |
|
637 | + // if there are no generated messages then something else fatal went wrong. |
|
638 | + return $generated_count > 0; |
|
639 | + } |
|
640 | + |
|
641 | + |
|
642 | + /** |
|
643 | + * @param string $context The context for the generated message. |
|
644 | + * @param EE_Messages_Addressee $recipient |
|
645 | + * @param array $templates formatted array of templates used for parsing data. |
|
646 | + * @param EE_Message_Template_Group $message_template_group |
|
647 | + * @return bool|EE_Message |
|
648 | + * @throws EE_Error |
|
649 | + * @throws InvalidArgumentException |
|
650 | + * @throws InvalidDataTypeException |
|
651 | + * @throws InvalidInterfaceException |
|
652 | + * @throws ReflectionException |
|
653 | + * @throws InvalidIdentifierException |
|
654 | + */ |
|
655 | + protected function _setup_message_object( |
|
656 | + string $context, |
|
657 | + EE_Messages_Addressee $recipient, |
|
658 | + array $templates, |
|
659 | + EE_Message_Template_Group $message_template_group |
|
660 | + ) { |
|
661 | + // stuff we already know |
|
662 | + $transaction_id = $recipient->txn instanceof EE_Transaction |
|
663 | + ? $recipient->txn->ID() |
|
664 | + : 0; |
|
665 | + $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction |
|
666 | + ? $this->_current_data_handler->txn->ID() |
|
667 | + : $transaction_id; |
|
668 | + $message_fields = [ |
|
669 | + 'GRP_ID' => $message_template_group->ID(), |
|
670 | + 'TXN_ID' => $transaction_id, |
|
671 | + 'MSG_messenger' => $this->_current_messenger->name, |
|
672 | + 'MSG_message_type' => $this->_current_message_type->name, |
|
673 | + 'MSG_context' => $context, |
|
674 | + ]; |
|
675 | + |
|
676 | + // recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab |
|
677 | + // the info from the att_obj found in the EE_Messages_Addressee object. |
|
678 | + if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) { |
|
679 | + $message_fields['MSG_recipient_ID'] = $recipient->att_obj instanceof EE_Attendee |
|
680 | + ? $recipient->att_obj->ID() |
|
681 | + : 0; |
|
682 | + $message_fields['MSG_recipient_type'] = 'Attendee'; |
|
683 | + } else { |
|
684 | + $message_fields['MSG_recipient_ID'] = $recipient->recipient_id; |
|
685 | + $message_fields['MSG_recipient_type'] = $recipient->recipient_type; |
|
686 | + } |
|
687 | + $message = EE_Message_Factory::create($message_fields); |
|
688 | + |
|
689 | + // grab valid shortcodes for shortcode parser |
|
690 | + $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes(); |
|
691 | + $m_shortcodes = $this->_current_messenger->get_valid_shortcodes(); |
|
692 | + |
|
693 | + // if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing |
|
694 | + if ( |
|
695 | + ! $this->_generation_queue->get_message_repository()->is_preview() |
|
696 | + && ( |
|
697 | + (empty($templates['to'][ $context ]) && ! $this->_current_messenger->allow_empty_to_field()) |
|
698 | + || ! $message_template_group->is_context_active($context) |
|
699 | + ) |
|
700 | + ) { |
|
701 | + // we silently exit here and do NOT record a fail because the message is "turned off" by having no "to" |
|
702 | + // field. |
|
703 | + return false; |
|
704 | + } |
|
705 | + $error_msg = []; |
|
706 | + foreach ($templates as $field => $field_context) { |
|
707 | + $error_msg = []; |
|
708 | + // let's setup the valid shortcodes for the incoming context. |
|
709 | + $valid_shortcodes = $mt_shortcodes[ $context ]; |
|
710 | + // merge in valid shortcodes for the field. |
|
711 | + $shortcodes = $m_shortcodes[ $field ] ?? $valid_shortcodes; |
|
712 | + if (isset($field_context[ $context ])) { |
|
713 | + // prefix field. |
|
714 | + $column_name = 'MSG_' . $field; |
|
715 | + try { |
|
716 | + $content = $this->_shortcode_parser->parse_message_template( |
|
717 | + $field_context[ $context ], |
|
718 | + $recipient, |
|
719 | + $shortcodes, |
|
720 | + $this->_current_message_type, |
|
721 | + $this->_current_messenger, |
|
722 | + $message |
|
723 | + ); |
|
724 | + // the model field removes slashes when setting (usually necessary when the input is from the |
|
725 | + // request) but this value is from another model and has no slashes. So add them so it matches |
|
726 | + // what the field expected (otherwise slashes will have been stripped from this an extra time) |
|
727 | + $message->set_field_or_extra_meta($column_name, addslashes($content)); |
|
728 | + } catch (EE_Error $e) { |
|
729 | + $error_msg[] = sprintf( |
|
730 | + /* Translators: First place holder is message model field name. |
|
731 | 731 | * Second placeholder is exception error message */ |
732 | - esc_html__( |
|
733 | - 'There was a problem generating the content for the field %s: %s', |
|
734 | - 'event_espresso' |
|
735 | - ), |
|
736 | - $field, |
|
737 | - $e->getMessage() |
|
738 | - ); |
|
739 | - $message->set_STS_ID(EEM_Message::status_failed); |
|
740 | - } |
|
741 | - } |
|
742 | - } |
|
743 | - |
|
744 | - if ($message->STS_ID() === EEM_Message::status_failed) { |
|
745 | - $error_msg = esc_html__('There were problems generating this message:', 'event_espresso') |
|
746 | - . "\n" |
|
747 | - . implode("\n", $error_msg); |
|
748 | - $message->set_error_message($error_msg); |
|
749 | - } else { |
|
750 | - $message->set_STS_ID(EEM_Message::status_idle); |
|
751 | - } |
|
752 | - return $message; |
|
753 | - } |
|
754 | - |
|
755 | - |
|
756 | - /** |
|
757 | - * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate |
|
758 | - * error message if either is missing. |
|
759 | - * |
|
760 | - * @return bool true means there were no errors, false means there were errors. |
|
761 | - */ |
|
762 | - protected function _verify(): bool |
|
763 | - { |
|
764 | - // reset error message to an empty array. |
|
765 | - $this->_error_msg = []; |
|
766 | - // set the verified flag so we know everything has been validated. |
|
767 | - $this->_verified = $this->_validate_messenger_and_message_type() && $this->_validate_and_setup_data(); |
|
768 | - return $this->_verified; |
|
769 | - } |
|
770 | - |
|
771 | - |
|
772 | - /** |
|
773 | - * This accepts an array and validates that it is an array indexed by context with each value being an array of |
|
774 | - * EE_Messages_Addressee objects. |
|
775 | - * |
|
776 | - * @param array|null $addressees Keys correspond to contexts for the message type and values are |
|
777 | - * EE_Messages_Addressee[] |
|
778 | - * @return bool |
|
779 | - */ |
|
780 | - protected function _valid_addressees(?array $addressees): bool |
|
781 | - { |
|
782 | - if (! $addressees || ! is_array($addressees)) { |
|
783 | - return false; |
|
784 | - } |
|
785 | - |
|
786 | - foreach ($addressees as $addressee_array) { |
|
787 | - foreach ($addressee_array as $addressee) { |
|
788 | - if (! $addressee instanceof EE_Messages_Addressee) { |
|
789 | - return false; |
|
790 | - } |
|
791 | - } |
|
792 | - } |
|
793 | - return true; |
|
794 | - } |
|
795 | - |
|
796 | - |
|
797 | - /** |
|
798 | - * This validates the messenger, message type, and presences of generation data for the current EE_Message in the |
|
799 | - * queue. This process sets error messages if something is wrong. |
|
800 | - * |
|
801 | - * @return bool true is if there are no errors. false is if there is. |
|
802 | - */ |
|
803 | - protected function _validate_messenger_and_message_type(): bool |
|
804 | - { |
|
805 | - // first are there any existing error messages? If so then return. |
|
806 | - if ($this->_error_msg) { |
|
807 | - return false; |
|
808 | - } |
|
809 | - $message = $this->_generation_queue->get_message_repository()->current(); |
|
810 | - try { |
|
811 | - $this->_current_messenger = $message->valid_messenger(true) |
|
812 | - ? $message->messenger_object() |
|
813 | - : null; |
|
814 | - } catch (Exception $e) { |
|
815 | - $this->_error_msg[] = $e->getMessage(); |
|
816 | - } |
|
817 | - try { |
|
818 | - $this->_current_message_type = $message->valid_message_type(true) |
|
819 | - ? $message->message_type_object() |
|
820 | - : null; |
|
821 | - } catch (Exception $e) { |
|
822 | - $this->_error_msg[] = $e->getMessage(); |
|
823 | - } |
|
824 | - |
|
825 | - /** |
|
826 | - * Check if there is any generation data, but only if this is not for a preview. |
|
827 | - */ |
|
828 | - if ( |
|
829 | - ! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
830 | - && ( |
|
831 | - ! $this->_generation_queue->get_message_repository()->is_preview() |
|
832 | - && $this->_generation_queue->get_message_repository()->get_data_handler() |
|
833 | - !== 'EE_Messages_Preview_incoming_data' |
|
834 | - ) |
|
835 | - ) { |
|
836 | - $this->_error_msg[] = esc_html__( |
|
837 | - 'There is no generation data for this message. Unable to generate.', |
|
838 | - 'event_espresso' |
|
839 | - ); |
|
840 | - } |
|
841 | - |
|
842 | - return empty($this->_error_msg); |
|
843 | - } |
|
844 | - |
|
845 | - |
|
846 | - /** |
|
847 | - * This method retrieves the expected data handler for the message type and validates the generation data for that |
|
848 | - * data handler. |
|
849 | - * |
|
850 | - * @return bool true means there are no errors. false means there were errors (and handler did not get setup). |
|
851 | - */ |
|
852 | - protected function _validate_and_setup_data(): bool |
|
853 | - { |
|
854 | - // First, are there any existing error messages? If so, return because if there were errors elsewhere this |
|
855 | - // can't be used anyways. |
|
856 | - if ($this->_error_msg) { |
|
857 | - return false; |
|
858 | - } |
|
859 | - |
|
860 | - $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data(); |
|
861 | - |
|
862 | - /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */ |
|
863 | - $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
|
864 | - ? $this->_generation_queue->get_message_repository()->get_data_handler() |
|
865 | - : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
866 | - |
|
867 | - // If this EE_Message is for a preview, then let's switch out to the preview data handler. |
|
868 | - if ($this->_generation_queue->get_message_repository()->is_preview()) { |
|
869 | - $data_handler_class_name = 'EE_Messages_Preview_incoming_data'; |
|
870 | - } |
|
871 | - |
|
872 | - // First get the class name for the data handler (and also verifies it exists. |
|
873 | - if (! class_exists($data_handler_class_name)) { |
|
874 | - $this->_error_msg[] = sprintf( |
|
875 | - /* Translators: Both placeholders are the names of php classes. */ |
|
876 | - esc_html__( |
|
877 | - 'The included data handler class name does not match any valid, accessible, "%1$s" classes. Looking for %2$s.', |
|
878 | - 'event_espresso' |
|
879 | - ), |
|
880 | - 'EE_Messages_incoming_data', |
|
881 | - $data_handler_class_name |
|
882 | - ); |
|
883 | - return false; |
|
884 | - } |
|
885 | - |
|
886 | - // convert generation_data for data_handler_instantiation. |
|
887 | - $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data); |
|
888 | - |
|
889 | - // note, this may set error messages as well. |
|
890 | - $this->_set_data_handler($generation_data, $data_handler_class_name); |
|
891 | - |
|
892 | - return empty($this->_error_msg); |
|
893 | - } |
|
894 | - |
|
895 | - |
|
896 | - /** |
|
897 | - * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and |
|
898 | - * adds it to the _data repository. |
|
899 | - * |
|
900 | - * @param mixed $generating_data This is data expected by the instantiated data handler. |
|
901 | - * @param string $data_handler_class_name This is the reference string indicating what data handler is being |
|
902 | - * instantiated. |
|
903 | - */ |
|
904 | - protected function _set_data_handler($generating_data, string $data_handler_class_name) |
|
905 | - { |
|
906 | - // valid classname for the data handler. Now let's setup the key for the data handler repository to see if |
|
907 | - // there is already a ready data handler in the repository. |
|
908 | - $this->_current_data_handler = $this->_data_handler_collection->get_by_key( |
|
909 | - $this->_data_handler_collection->get_key( |
|
910 | - $data_handler_class_name, |
|
911 | - $generating_data |
|
912 | - ) |
|
913 | - ); |
|
914 | - if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
915 | - // no saved data_handler in the repo so let's set one up and add it to the repo. |
|
916 | - try { |
|
917 | - $this->_current_data_handler = new $data_handler_class_name($generating_data); |
|
918 | - $this->_data_handler_collection->add($this->_current_data_handler, $generating_data); |
|
919 | - } catch (Exception $e) { |
|
920 | - $this->_error_msg[] = $e->getMessage(); |
|
921 | - } |
|
922 | - } |
|
923 | - } |
|
924 | - |
|
925 | - |
|
926 | - /** |
|
927 | - * The queued EE_Message for generation does not save the data used for generation as objects |
|
928 | - * because serialization of those objects could be problematic if the data is saved to the db. |
|
929 | - * So this method calls the static method on the associated data_handler for the given message_type |
|
930 | - * and that preps the data for later instantiation when generating. |
|
931 | - * |
|
932 | - * @param EE_Message_To_Generate $message_to_generate |
|
933 | - * @param bool $preview Indicate whether this is being used for a preview or not. |
|
934 | - * @return mixed Prepped data for persisting to the queue. false is returned if unable to prep data. |
|
935 | - */ |
|
936 | - protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, bool $preview) |
|
937 | - { |
|
938 | - if (! $message_to_generate->valid()) { |
|
939 | - return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
|
940 | - } |
|
941 | - /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
|
942 | - $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
|
943 | - return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
|
944 | - } |
|
945 | - |
|
946 | - |
|
947 | - /** |
|
948 | - * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue. |
|
949 | - * |
|
950 | - * @param EE_Message_To_Generate $message_to_generate |
|
951 | - * @param bool $test_send Whether this is just a test send or not. Typically used for previews. |
|
952 | - * @return bool |
|
953 | - * @throws InvalidArgumentException |
|
954 | - * @throws InvalidDataTypeException |
|
955 | - * @throws InvalidInterfaceException |
|
956 | - */ |
|
957 | - public function create_and_add_message_to_queue( |
|
958 | - EE_Message_To_Generate $message_to_generate, |
|
959 | - bool $test_send = false |
|
960 | - ): bool { |
|
961 | - // prep data |
|
962 | - $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview()); |
|
963 | - $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface'); |
|
964 | - |
|
965 | - $message = $message_to_generate->get_EE_Message(); |
|
966 | - $GRP_ID = $request->getRequestParam('GRP_ID', 0, 'int'); |
|
967 | - |
|
968 | - $GRP_ID = apply_filters( |
|
969 | - 'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID', |
|
970 | - $GRP_ID > 0 |
|
971 | - ? $GRP_ID |
|
972 | - : $message->GRP_ID(), |
|
973 | - $message, |
|
974 | - $message_to_generate, |
|
975 | - $test_send |
|
976 | - ); |
|
977 | - |
|
978 | - if ($GRP_ID > 0) { |
|
979 | - $message->set_GRP_ID($GRP_ID); |
|
980 | - } |
|
981 | - |
|
982 | - if ($data === false) { |
|
983 | - $message->set_STS_ID(EEM_Message::status_failed); |
|
984 | - $message->set_error_message( |
|
985 | - esc_html__( |
|
986 | - 'Unable to prepare data for persistence to the database.', |
|
987 | - 'event_espresso' |
|
988 | - ) |
|
989 | - ); |
|
990 | - } else { |
|
991 | - // make sure that the data handler is cached on the message as well |
|
992 | - $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name(); |
|
993 | - } |
|
994 | - |
|
995 | - return $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send); |
|
996 | - } |
|
732 | + esc_html__( |
|
733 | + 'There was a problem generating the content for the field %s: %s', |
|
734 | + 'event_espresso' |
|
735 | + ), |
|
736 | + $field, |
|
737 | + $e->getMessage() |
|
738 | + ); |
|
739 | + $message->set_STS_ID(EEM_Message::status_failed); |
|
740 | + } |
|
741 | + } |
|
742 | + } |
|
743 | + |
|
744 | + if ($message->STS_ID() === EEM_Message::status_failed) { |
|
745 | + $error_msg = esc_html__('There were problems generating this message:', 'event_espresso') |
|
746 | + . "\n" |
|
747 | + . implode("\n", $error_msg); |
|
748 | + $message->set_error_message($error_msg); |
|
749 | + } else { |
|
750 | + $message->set_STS_ID(EEM_Message::status_idle); |
|
751 | + } |
|
752 | + return $message; |
|
753 | + } |
|
754 | + |
|
755 | + |
|
756 | + /** |
|
757 | + * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate |
|
758 | + * error message if either is missing. |
|
759 | + * |
|
760 | + * @return bool true means there were no errors, false means there were errors. |
|
761 | + */ |
|
762 | + protected function _verify(): bool |
|
763 | + { |
|
764 | + // reset error message to an empty array. |
|
765 | + $this->_error_msg = []; |
|
766 | + // set the verified flag so we know everything has been validated. |
|
767 | + $this->_verified = $this->_validate_messenger_and_message_type() && $this->_validate_and_setup_data(); |
|
768 | + return $this->_verified; |
|
769 | + } |
|
770 | + |
|
771 | + |
|
772 | + /** |
|
773 | + * This accepts an array and validates that it is an array indexed by context with each value being an array of |
|
774 | + * EE_Messages_Addressee objects. |
|
775 | + * |
|
776 | + * @param array|null $addressees Keys correspond to contexts for the message type and values are |
|
777 | + * EE_Messages_Addressee[] |
|
778 | + * @return bool |
|
779 | + */ |
|
780 | + protected function _valid_addressees(?array $addressees): bool |
|
781 | + { |
|
782 | + if (! $addressees || ! is_array($addressees)) { |
|
783 | + return false; |
|
784 | + } |
|
785 | + |
|
786 | + foreach ($addressees as $addressee_array) { |
|
787 | + foreach ($addressee_array as $addressee) { |
|
788 | + if (! $addressee instanceof EE_Messages_Addressee) { |
|
789 | + return false; |
|
790 | + } |
|
791 | + } |
|
792 | + } |
|
793 | + return true; |
|
794 | + } |
|
795 | + |
|
796 | + |
|
797 | + /** |
|
798 | + * This validates the messenger, message type, and presences of generation data for the current EE_Message in the |
|
799 | + * queue. This process sets error messages if something is wrong. |
|
800 | + * |
|
801 | + * @return bool true is if there are no errors. false is if there is. |
|
802 | + */ |
|
803 | + protected function _validate_messenger_and_message_type(): bool |
|
804 | + { |
|
805 | + // first are there any existing error messages? If so then return. |
|
806 | + if ($this->_error_msg) { |
|
807 | + return false; |
|
808 | + } |
|
809 | + $message = $this->_generation_queue->get_message_repository()->current(); |
|
810 | + try { |
|
811 | + $this->_current_messenger = $message->valid_messenger(true) |
|
812 | + ? $message->messenger_object() |
|
813 | + : null; |
|
814 | + } catch (Exception $e) { |
|
815 | + $this->_error_msg[] = $e->getMessage(); |
|
816 | + } |
|
817 | + try { |
|
818 | + $this->_current_message_type = $message->valid_message_type(true) |
|
819 | + ? $message->message_type_object() |
|
820 | + : null; |
|
821 | + } catch (Exception $e) { |
|
822 | + $this->_error_msg[] = $e->getMessage(); |
|
823 | + } |
|
824 | + |
|
825 | + /** |
|
826 | + * Check if there is any generation data, but only if this is not for a preview. |
|
827 | + */ |
|
828 | + if ( |
|
829 | + ! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
830 | + && ( |
|
831 | + ! $this->_generation_queue->get_message_repository()->is_preview() |
|
832 | + && $this->_generation_queue->get_message_repository()->get_data_handler() |
|
833 | + !== 'EE_Messages_Preview_incoming_data' |
|
834 | + ) |
|
835 | + ) { |
|
836 | + $this->_error_msg[] = esc_html__( |
|
837 | + 'There is no generation data for this message. Unable to generate.', |
|
838 | + 'event_espresso' |
|
839 | + ); |
|
840 | + } |
|
841 | + |
|
842 | + return empty($this->_error_msg); |
|
843 | + } |
|
844 | + |
|
845 | + |
|
846 | + /** |
|
847 | + * This method retrieves the expected data handler for the message type and validates the generation data for that |
|
848 | + * data handler. |
|
849 | + * |
|
850 | + * @return bool true means there are no errors. false means there were errors (and handler did not get setup). |
|
851 | + */ |
|
852 | + protected function _validate_and_setup_data(): bool |
|
853 | + { |
|
854 | + // First, are there any existing error messages? If so, return because if there were errors elsewhere this |
|
855 | + // can't be used anyways. |
|
856 | + if ($this->_error_msg) { |
|
857 | + return false; |
|
858 | + } |
|
859 | + |
|
860 | + $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data(); |
|
861 | + |
|
862 | + /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */ |
|
863 | + $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
|
864 | + ? $this->_generation_queue->get_message_repository()->get_data_handler() |
|
865 | + : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
866 | + |
|
867 | + // If this EE_Message is for a preview, then let's switch out to the preview data handler. |
|
868 | + if ($this->_generation_queue->get_message_repository()->is_preview()) { |
|
869 | + $data_handler_class_name = 'EE_Messages_Preview_incoming_data'; |
|
870 | + } |
|
871 | + |
|
872 | + // First get the class name for the data handler (and also verifies it exists. |
|
873 | + if (! class_exists($data_handler_class_name)) { |
|
874 | + $this->_error_msg[] = sprintf( |
|
875 | + /* Translators: Both placeholders are the names of php classes. */ |
|
876 | + esc_html__( |
|
877 | + 'The included data handler class name does not match any valid, accessible, "%1$s" classes. Looking for %2$s.', |
|
878 | + 'event_espresso' |
|
879 | + ), |
|
880 | + 'EE_Messages_incoming_data', |
|
881 | + $data_handler_class_name |
|
882 | + ); |
|
883 | + return false; |
|
884 | + } |
|
885 | + |
|
886 | + // convert generation_data for data_handler_instantiation. |
|
887 | + $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data); |
|
888 | + |
|
889 | + // note, this may set error messages as well. |
|
890 | + $this->_set_data_handler($generation_data, $data_handler_class_name); |
|
891 | + |
|
892 | + return empty($this->_error_msg); |
|
893 | + } |
|
894 | + |
|
895 | + |
|
896 | + /** |
|
897 | + * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and |
|
898 | + * adds it to the _data repository. |
|
899 | + * |
|
900 | + * @param mixed $generating_data This is data expected by the instantiated data handler. |
|
901 | + * @param string $data_handler_class_name This is the reference string indicating what data handler is being |
|
902 | + * instantiated. |
|
903 | + */ |
|
904 | + protected function _set_data_handler($generating_data, string $data_handler_class_name) |
|
905 | + { |
|
906 | + // valid classname for the data handler. Now let's setup the key for the data handler repository to see if |
|
907 | + // there is already a ready data handler in the repository. |
|
908 | + $this->_current_data_handler = $this->_data_handler_collection->get_by_key( |
|
909 | + $this->_data_handler_collection->get_key( |
|
910 | + $data_handler_class_name, |
|
911 | + $generating_data |
|
912 | + ) |
|
913 | + ); |
|
914 | + if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
915 | + // no saved data_handler in the repo so let's set one up and add it to the repo. |
|
916 | + try { |
|
917 | + $this->_current_data_handler = new $data_handler_class_name($generating_data); |
|
918 | + $this->_data_handler_collection->add($this->_current_data_handler, $generating_data); |
|
919 | + } catch (Exception $e) { |
|
920 | + $this->_error_msg[] = $e->getMessage(); |
|
921 | + } |
|
922 | + } |
|
923 | + } |
|
924 | + |
|
925 | + |
|
926 | + /** |
|
927 | + * The queued EE_Message for generation does not save the data used for generation as objects |
|
928 | + * because serialization of those objects could be problematic if the data is saved to the db. |
|
929 | + * So this method calls the static method on the associated data_handler for the given message_type |
|
930 | + * and that preps the data for later instantiation when generating. |
|
931 | + * |
|
932 | + * @param EE_Message_To_Generate $message_to_generate |
|
933 | + * @param bool $preview Indicate whether this is being used for a preview or not. |
|
934 | + * @return mixed Prepped data for persisting to the queue. false is returned if unable to prep data. |
|
935 | + */ |
|
936 | + protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, bool $preview) |
|
937 | + { |
|
938 | + if (! $message_to_generate->valid()) { |
|
939 | + return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
|
940 | + } |
|
941 | + /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
|
942 | + $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
|
943 | + return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
|
944 | + } |
|
945 | + |
|
946 | + |
|
947 | + /** |
|
948 | + * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue. |
|
949 | + * |
|
950 | + * @param EE_Message_To_Generate $message_to_generate |
|
951 | + * @param bool $test_send Whether this is just a test send or not. Typically used for previews. |
|
952 | + * @return bool |
|
953 | + * @throws InvalidArgumentException |
|
954 | + * @throws InvalidDataTypeException |
|
955 | + * @throws InvalidInterfaceException |
|
956 | + */ |
|
957 | + public function create_and_add_message_to_queue( |
|
958 | + EE_Message_To_Generate $message_to_generate, |
|
959 | + bool $test_send = false |
|
960 | + ): bool { |
|
961 | + // prep data |
|
962 | + $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview()); |
|
963 | + $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface'); |
|
964 | + |
|
965 | + $message = $message_to_generate->get_EE_Message(); |
|
966 | + $GRP_ID = $request->getRequestParam('GRP_ID', 0, 'int'); |
|
967 | + |
|
968 | + $GRP_ID = apply_filters( |
|
969 | + 'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID', |
|
970 | + $GRP_ID > 0 |
|
971 | + ? $GRP_ID |
|
972 | + : $message->GRP_ID(), |
|
973 | + $message, |
|
974 | + $message_to_generate, |
|
975 | + $test_send |
|
976 | + ); |
|
977 | + |
|
978 | + if ($GRP_ID > 0) { |
|
979 | + $message->set_GRP_ID($GRP_ID); |
|
980 | + } |
|
981 | + |
|
982 | + if ($data === false) { |
|
983 | + $message->set_STS_ID(EEM_Message::status_failed); |
|
984 | + $message->set_error_message( |
|
985 | + esc_html__( |
|
986 | + 'Unable to prepare data for persistence to the database.', |
|
987 | + 'event_espresso' |
|
988 | + ) |
|
989 | + ); |
|
990 | + } else { |
|
991 | + // make sure that the data handler is cached on the message as well |
|
992 | + $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name(); |
|
993 | + } |
|
994 | + |
|
995 | + return $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send); |
|
996 | + } |
|
997 | 997 | } |
@@ -11,231 +11,231 @@ |
||
11 | 11 | */ |
12 | 12 | class EE_Messages_Template_Defaults extends EE_Base |
13 | 13 | { |
14 | - /** |
|
15 | - * Used for holding the EE_Message_Template GRP_ID field value. |
|
16 | - * |
|
17 | - * @var [type] |
|
18 | - */ |
|
19 | - protected $_GRP_ID; |
|
20 | - |
|
21 | - /** |
|
22 | - * holds the messenger object |
|
23 | - * |
|
24 | - * @var EE_messenger |
|
25 | - */ |
|
26 | - protected $_messenger; |
|
27 | - |
|
28 | - /** |
|
29 | - * holds the message type object |
|
30 | - * |
|
31 | - * @var EE_message_type |
|
32 | - */ |
|
33 | - protected $_message_type; |
|
34 | - |
|
35 | - /** |
|
36 | - * holds the fields used (this is retrieved from the messenger) |
|
37 | - * |
|
38 | - * @var array |
|
39 | - */ |
|
40 | - protected $_fields; |
|
41 | - |
|
42 | - /** |
|
43 | - * holds the assembled template (with defaults) for creation in the database |
|
44 | - * |
|
45 | - * @var array |
|
46 | - */ |
|
47 | - protected $_templates; |
|
48 | - |
|
49 | - /** |
|
50 | - * holds the contexts used (this is retrieved from the message type) |
|
51 | - * |
|
52 | - * @var array |
|
53 | - */ |
|
54 | - protected $_contexts; |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * @var EEM_Message_Template_Group |
|
59 | - */ |
|
60 | - protected $_message_template_group_model; |
|
61 | - |
|
62 | - |
|
63 | - /** |
|
64 | - * @var EEM_Message_Template |
|
65 | - */ |
|
66 | - protected $_message_template_model; |
|
67 | - |
|
68 | - |
|
69 | - /** |
|
70 | - * EE_Messages_Template_Defaults constructor. |
|
71 | - * |
|
72 | - * @param EE_messenger $messenger |
|
73 | - * @param EE_message_type $message_type |
|
74 | - * @param int|null $GRP_ID Optional. If included then we're just |
|
75 | - * regenerating the template fields for the given |
|
76 | - * group not the message template group itself |
|
77 | - * @param EEM_Message_Template_Group|null $message_template_group_model |
|
78 | - * @param EEM_Message_Template|null $message_template_model |
|
79 | - * @throws EE_Error |
|
80 | - */ |
|
81 | - public function __construct( |
|
82 | - EE_messenger $messenger, |
|
83 | - EE_message_type $message_type, |
|
84 | - ?int $GRP_ID, |
|
85 | - ?EEM_Message_Template_Group $message_template_group_model, |
|
86 | - ?EEM_Message_Template $message_template_model |
|
87 | - ) { |
|
88 | - $this->_messenger = $messenger; |
|
89 | - $this->_message_type = $message_type; |
|
90 | - $this->_GRP_ID = $GRP_ID ?? 0; |
|
91 | - // set the model object |
|
92 | - $this->_message_template_group_model = $message_template_group_model ?? EEM_Message_Template_Group::instance(); |
|
93 | - $this->_message_template_model = $message_template_model ?? EEM_Message_Template::instance(); |
|
94 | - $this->_fields = $this->_messenger->get_template_fields(); |
|
95 | - $this->_contexts = $this->_message_type->get_contexts(); |
|
96 | - } |
|
97 | - |
|
98 | - |
|
99 | - /** |
|
100 | - * Setup the _template_data property. |
|
101 | - * This method sets the _templates property array before templates are created. |
|
102 | - * |
|
103 | - * @param string $template_pack This corresponds to a template pack class reference which will contain information |
|
104 | - * about where to obtain the templates. |
|
105 | - * |
|
106 | - */ |
|
107 | - private function _set_templates(string $template_pack) |
|
108 | - { |
|
109 | - // get the corresponding template pack object (if present. If not then we just load the default and add a |
|
110 | - // notice). The class name should be something like 'EE_Messages_Template_Pack_Default' where "default' would be |
|
111 | - // the incoming template pack reference. |
|
112 | - $class_name = |
|
113 | - 'EE_Messages_Template_Pack_' . str_replace(' ', '_', ucwords(str_replace('_', ' ', $template_pack))); |
|
114 | - |
|
115 | - if (! class_exists($class_name)) { |
|
116 | - EE_Error::add_error( |
|
117 | - sprintf( |
|
118 | - esc_html__( |
|
119 | - 'The template pack represented by a class corresponding to "%1$s" does not exist. Likely the autoloader for this class has the wrong path or the incoming reference is misspelled. The default template pack has been used to generate the templates instead.', |
|
120 | - 'event_espresso' |
|
121 | - ), |
|
122 | - $class_name |
|
123 | - ), |
|
124 | - __FILE__, |
|
125 | - __FUNCTION__, |
|
126 | - __LINE__ |
|
127 | - ); |
|
128 | - $class_name = 'EE_Messages_Template_Pack_Default'; |
|
129 | - } |
|
130 | - /** @type EE_Messages_Template_Pack $template_pack */ |
|
131 | - $template_pack = new $class_name(); |
|
132 | - |
|
133 | - // get all the templates from the template pack. |
|
134 | - $this->_templates = $template_pack->get_templates($this->_messenger, $this->_message_type); |
|
135 | - } |
|
136 | - |
|
137 | - |
|
138 | - /** |
|
139 | - * Return the contexts for the message type as cached on this instance. |
|
140 | - * |
|
141 | - * @return array |
|
142 | - */ |
|
143 | - public function get_contexts(): array |
|
144 | - { |
|
145 | - return $this->_contexts; |
|
146 | - } |
|
147 | - |
|
148 | - |
|
149 | - /** |
|
150 | - * public facing create new templates method |
|
151 | - * |
|
152 | - * @return array|false|int|string success array or false. |
|
153 | - * @throws EE_Error |
|
154 | - * @throws ReflectionException |
|
155 | - */ |
|
156 | - public function create_new_templates() |
|
157 | - { |
|
158 | - $template_pack = 'default'; |
|
159 | - // if we have the GRP_ID then let's use that to see if there is a set template pack and use that for the new templates. |
|
160 | - if (! empty($this->_GRP_ID)) { |
|
161 | - $message_template_group = $this->_message_template_group_model->get_one_by_ID($this->_GRP_ID); |
|
162 | - $template_pack = $message_template_group instanceof EE_Message_Template_Group |
|
163 | - ? $message_template_group->get_template_pack_name() |
|
164 | - : 'default'; |
|
165 | - // we also need to reset the template variation to default |
|
166 | - $message_template_group->set_template_pack_variation('default'); |
|
167 | - } |
|
168 | - return $this->_create_new_templates($template_pack); |
|
169 | - } |
|
170 | - |
|
171 | - |
|
172 | - /** |
|
173 | - * Handles creating new default templates. |
|
174 | - * |
|
175 | - * @param string $template_pack This corresponds to a template pack class reference |
|
176 | - * which will contain information about where to obtain the templates. |
|
177 | - * @return array|bool success array or false. |
|
178 | - * @throws EE_Error |
|
179 | - * @throws ReflectionException |
|
180 | - */ |
|
181 | - protected function _create_new_templates(string $template_pack) |
|
182 | - { |
|
183 | - $this->_set_templates($template_pack); |
|
184 | - |
|
185 | - // necessary properties are set, let's save the default templates |
|
186 | - if (empty($this->_GRP_ID)) { |
|
187 | - $main_template_data = [ |
|
188 | - 'MTP_messenger' => $this->_messenger->name, |
|
189 | - 'MTP_message_type' => $this->_message_type->name, |
|
190 | - 'MTP_is_override' => 0, |
|
191 | - 'MTP_deleted' => 0, |
|
192 | - 'MTP_is_global' => 1, |
|
193 | - 'MTP_user_id' => EEH_Activation::get_default_creator_id(), |
|
194 | - 'MTP_is_active' => 1, |
|
195 | - ]; |
|
196 | - // let's insert the above and get our GRP_ID, then reset the template data array to just include the GRP_ID |
|
197 | - $grp_id = $this->_message_template_group_model->insert($main_template_data); |
|
198 | - if (empty($grp_id)) { |
|
199 | - return $grp_id; |
|
200 | - } |
|
201 | - $this->_GRP_ID = $grp_id; |
|
202 | - } |
|
203 | - |
|
204 | - $template_data = ['GRP_ID' => $this->_GRP_ID]; |
|
205 | - |
|
206 | - foreach ($this->_contexts as $context => $details) { |
|
207 | - foreach ($this->_fields as $field => $field_type) { |
|
208 | - if ($field != 'extra') { |
|
209 | - $template_data['MTP_context'] = $context; |
|
210 | - $template_data['MTP_template_field'] = $field; |
|
211 | - $template_data['MTP_content'] = $this->_templates[ $context ][ $field ]; |
|
212 | - |
|
213 | - $MTP = $this->_message_template_model->insert($template_data); |
|
214 | - if (! $MTP) { |
|
215 | - EE_Error::add_error( |
|
216 | - sprintf( |
|
217 | - esc_html__( |
|
218 | - 'There was an error in saving new template data for %1$s messenger, %2$s message type, %3$s context and %4$s template field.', |
|
219 | - 'event_espresso' |
|
220 | - ), |
|
221 | - $this->_messenger->name, |
|
222 | - $this->_message_type->name, |
|
223 | - $context, |
|
224 | - $field |
|
225 | - ), |
|
226 | - __FILE__, |
|
227 | - __FUNCTION__, |
|
228 | - __LINE__ |
|
229 | - ); |
|
230 | - return false; |
|
231 | - } |
|
232 | - } |
|
233 | - } |
|
234 | - } |
|
235 | - |
|
236 | - return [ |
|
237 | - 'GRP_ID' => $this->_GRP_ID, |
|
238 | - 'MTP_context' => key($this->_contexts), |
|
239 | - ]; |
|
240 | - } |
|
14 | + /** |
|
15 | + * Used for holding the EE_Message_Template GRP_ID field value. |
|
16 | + * |
|
17 | + * @var [type] |
|
18 | + */ |
|
19 | + protected $_GRP_ID; |
|
20 | + |
|
21 | + /** |
|
22 | + * holds the messenger object |
|
23 | + * |
|
24 | + * @var EE_messenger |
|
25 | + */ |
|
26 | + protected $_messenger; |
|
27 | + |
|
28 | + /** |
|
29 | + * holds the message type object |
|
30 | + * |
|
31 | + * @var EE_message_type |
|
32 | + */ |
|
33 | + protected $_message_type; |
|
34 | + |
|
35 | + /** |
|
36 | + * holds the fields used (this is retrieved from the messenger) |
|
37 | + * |
|
38 | + * @var array |
|
39 | + */ |
|
40 | + protected $_fields; |
|
41 | + |
|
42 | + /** |
|
43 | + * holds the assembled template (with defaults) for creation in the database |
|
44 | + * |
|
45 | + * @var array |
|
46 | + */ |
|
47 | + protected $_templates; |
|
48 | + |
|
49 | + /** |
|
50 | + * holds the contexts used (this is retrieved from the message type) |
|
51 | + * |
|
52 | + * @var array |
|
53 | + */ |
|
54 | + protected $_contexts; |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * @var EEM_Message_Template_Group |
|
59 | + */ |
|
60 | + protected $_message_template_group_model; |
|
61 | + |
|
62 | + |
|
63 | + /** |
|
64 | + * @var EEM_Message_Template |
|
65 | + */ |
|
66 | + protected $_message_template_model; |
|
67 | + |
|
68 | + |
|
69 | + /** |
|
70 | + * EE_Messages_Template_Defaults constructor. |
|
71 | + * |
|
72 | + * @param EE_messenger $messenger |
|
73 | + * @param EE_message_type $message_type |
|
74 | + * @param int|null $GRP_ID Optional. If included then we're just |
|
75 | + * regenerating the template fields for the given |
|
76 | + * group not the message template group itself |
|
77 | + * @param EEM_Message_Template_Group|null $message_template_group_model |
|
78 | + * @param EEM_Message_Template|null $message_template_model |
|
79 | + * @throws EE_Error |
|
80 | + */ |
|
81 | + public function __construct( |
|
82 | + EE_messenger $messenger, |
|
83 | + EE_message_type $message_type, |
|
84 | + ?int $GRP_ID, |
|
85 | + ?EEM_Message_Template_Group $message_template_group_model, |
|
86 | + ?EEM_Message_Template $message_template_model |
|
87 | + ) { |
|
88 | + $this->_messenger = $messenger; |
|
89 | + $this->_message_type = $message_type; |
|
90 | + $this->_GRP_ID = $GRP_ID ?? 0; |
|
91 | + // set the model object |
|
92 | + $this->_message_template_group_model = $message_template_group_model ?? EEM_Message_Template_Group::instance(); |
|
93 | + $this->_message_template_model = $message_template_model ?? EEM_Message_Template::instance(); |
|
94 | + $this->_fields = $this->_messenger->get_template_fields(); |
|
95 | + $this->_contexts = $this->_message_type->get_contexts(); |
|
96 | + } |
|
97 | + |
|
98 | + |
|
99 | + /** |
|
100 | + * Setup the _template_data property. |
|
101 | + * This method sets the _templates property array before templates are created. |
|
102 | + * |
|
103 | + * @param string $template_pack This corresponds to a template pack class reference which will contain information |
|
104 | + * about where to obtain the templates. |
|
105 | + * |
|
106 | + */ |
|
107 | + private function _set_templates(string $template_pack) |
|
108 | + { |
|
109 | + // get the corresponding template pack object (if present. If not then we just load the default and add a |
|
110 | + // notice). The class name should be something like 'EE_Messages_Template_Pack_Default' where "default' would be |
|
111 | + // the incoming template pack reference. |
|
112 | + $class_name = |
|
113 | + 'EE_Messages_Template_Pack_' . str_replace(' ', '_', ucwords(str_replace('_', ' ', $template_pack))); |
|
114 | + |
|
115 | + if (! class_exists($class_name)) { |
|
116 | + EE_Error::add_error( |
|
117 | + sprintf( |
|
118 | + esc_html__( |
|
119 | + 'The template pack represented by a class corresponding to "%1$s" does not exist. Likely the autoloader for this class has the wrong path or the incoming reference is misspelled. The default template pack has been used to generate the templates instead.', |
|
120 | + 'event_espresso' |
|
121 | + ), |
|
122 | + $class_name |
|
123 | + ), |
|
124 | + __FILE__, |
|
125 | + __FUNCTION__, |
|
126 | + __LINE__ |
|
127 | + ); |
|
128 | + $class_name = 'EE_Messages_Template_Pack_Default'; |
|
129 | + } |
|
130 | + /** @type EE_Messages_Template_Pack $template_pack */ |
|
131 | + $template_pack = new $class_name(); |
|
132 | + |
|
133 | + // get all the templates from the template pack. |
|
134 | + $this->_templates = $template_pack->get_templates($this->_messenger, $this->_message_type); |
|
135 | + } |
|
136 | + |
|
137 | + |
|
138 | + /** |
|
139 | + * Return the contexts for the message type as cached on this instance. |
|
140 | + * |
|
141 | + * @return array |
|
142 | + */ |
|
143 | + public function get_contexts(): array |
|
144 | + { |
|
145 | + return $this->_contexts; |
|
146 | + } |
|
147 | + |
|
148 | + |
|
149 | + /** |
|
150 | + * public facing create new templates method |
|
151 | + * |
|
152 | + * @return array|false|int|string success array or false. |
|
153 | + * @throws EE_Error |
|
154 | + * @throws ReflectionException |
|
155 | + */ |
|
156 | + public function create_new_templates() |
|
157 | + { |
|
158 | + $template_pack = 'default'; |
|
159 | + // if we have the GRP_ID then let's use that to see if there is a set template pack and use that for the new templates. |
|
160 | + if (! empty($this->_GRP_ID)) { |
|
161 | + $message_template_group = $this->_message_template_group_model->get_one_by_ID($this->_GRP_ID); |
|
162 | + $template_pack = $message_template_group instanceof EE_Message_Template_Group |
|
163 | + ? $message_template_group->get_template_pack_name() |
|
164 | + : 'default'; |
|
165 | + // we also need to reset the template variation to default |
|
166 | + $message_template_group->set_template_pack_variation('default'); |
|
167 | + } |
|
168 | + return $this->_create_new_templates($template_pack); |
|
169 | + } |
|
170 | + |
|
171 | + |
|
172 | + /** |
|
173 | + * Handles creating new default templates. |
|
174 | + * |
|
175 | + * @param string $template_pack This corresponds to a template pack class reference |
|
176 | + * which will contain information about where to obtain the templates. |
|
177 | + * @return array|bool success array or false. |
|
178 | + * @throws EE_Error |
|
179 | + * @throws ReflectionException |
|
180 | + */ |
|
181 | + protected function _create_new_templates(string $template_pack) |
|
182 | + { |
|
183 | + $this->_set_templates($template_pack); |
|
184 | + |
|
185 | + // necessary properties are set, let's save the default templates |
|
186 | + if (empty($this->_GRP_ID)) { |
|
187 | + $main_template_data = [ |
|
188 | + 'MTP_messenger' => $this->_messenger->name, |
|
189 | + 'MTP_message_type' => $this->_message_type->name, |
|
190 | + 'MTP_is_override' => 0, |
|
191 | + 'MTP_deleted' => 0, |
|
192 | + 'MTP_is_global' => 1, |
|
193 | + 'MTP_user_id' => EEH_Activation::get_default_creator_id(), |
|
194 | + 'MTP_is_active' => 1, |
|
195 | + ]; |
|
196 | + // let's insert the above and get our GRP_ID, then reset the template data array to just include the GRP_ID |
|
197 | + $grp_id = $this->_message_template_group_model->insert($main_template_data); |
|
198 | + if (empty($grp_id)) { |
|
199 | + return $grp_id; |
|
200 | + } |
|
201 | + $this->_GRP_ID = $grp_id; |
|
202 | + } |
|
203 | + |
|
204 | + $template_data = ['GRP_ID' => $this->_GRP_ID]; |
|
205 | + |
|
206 | + foreach ($this->_contexts as $context => $details) { |
|
207 | + foreach ($this->_fields as $field => $field_type) { |
|
208 | + if ($field != 'extra') { |
|
209 | + $template_data['MTP_context'] = $context; |
|
210 | + $template_data['MTP_template_field'] = $field; |
|
211 | + $template_data['MTP_content'] = $this->_templates[ $context ][ $field ]; |
|
212 | + |
|
213 | + $MTP = $this->_message_template_model->insert($template_data); |
|
214 | + if (! $MTP) { |
|
215 | + EE_Error::add_error( |
|
216 | + sprintf( |
|
217 | + esc_html__( |
|
218 | + 'There was an error in saving new template data for %1$s messenger, %2$s message type, %3$s context and %4$s template field.', |
|
219 | + 'event_espresso' |
|
220 | + ), |
|
221 | + $this->_messenger->name, |
|
222 | + $this->_message_type->name, |
|
223 | + $context, |
|
224 | + $field |
|
225 | + ), |
|
226 | + __FILE__, |
|
227 | + __FUNCTION__, |
|
228 | + __LINE__ |
|
229 | + ); |
|
230 | + return false; |
|
231 | + } |
|
232 | + } |
|
233 | + } |
|
234 | + } |
|
235 | + |
|
236 | + return [ |
|
237 | + 'GRP_ID' => $this->_GRP_ID, |
|
238 | + 'MTP_context' => key($this->_contexts), |
|
239 | + ]; |
|
240 | + } |
|
241 | 241 | } |
@@ -11,1141 +11,1141 @@ |
||
11 | 11 | */ |
12 | 12 | class EE_Message_Resource_Manager |
13 | 13 | { |
14 | - /** |
|
15 | - * This option in the database is used to keep a record of message types that have been activated for a messenger |
|
16 | - * at some point in the history of the site. It is utilized by the implementation of the 'force' flag in |
|
17 | - * EE_Register_Message_Type. The force flag is an indication of whether a message type should be activated by |
|
18 | - * default when the message type is registered. However, if a user has explicitly deactivated a message type, then |
|
19 | - * the force flag is ignored. The method by which the code knows whether to ignore this flag is via this option. |
|
20 | - * Note, that this is NOT a historical record. Its entirely possible for a message type to have been activated for |
|
21 | - * a messenger and yet not have a record in this option. This occurs when a message type is inactivated through an |
|
22 | - * automated process (when an add-on registering the message type deactivates, or when some other code calls the |
|
23 | - * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to |
|
24 | - * ensure the "force" flag is respected if that message type is later re-registered. This option should NOT be used |
|
25 | - * to determine the current "active" state of a message type for a given messenger. The name of this option (and |
|
26 | - * related methods/properties) is due to matching the original intended purpose for the option that got superseded |
|
27 | - * by later behaviour requirements. |
|
28 | - */ |
|
29 | - const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger'; |
|
30 | - |
|
31 | - /** |
|
32 | - * @type boolean $_initialized |
|
33 | - */ |
|
34 | - protected $_initialized = false; |
|
35 | - |
|
36 | - /** |
|
37 | - * @type EE_Messenger_Collection $_messenger_collection_loader |
|
38 | - */ |
|
39 | - protected $_messenger_collection_loader; |
|
40 | - |
|
41 | - /** |
|
42 | - * @type EE_Message_Type_Collection $_message_type_collection_loader |
|
43 | - */ |
|
44 | - protected $_message_type_collection_loader; |
|
45 | - |
|
46 | - /** |
|
47 | - * @type EEM_Message_Template_Group $_message_template_group_model |
|
48 | - */ |
|
49 | - protected $_message_template_group_model; |
|
50 | - |
|
51 | - /** |
|
52 | - * @type EE_messenger[] |
|
53 | - */ |
|
54 | - protected $_installed_messengers = []; |
|
55 | - |
|
56 | - /** |
|
57 | - * @type EE_message_type[] |
|
58 | - */ |
|
59 | - protected $_installed_message_types = []; |
|
60 | - |
|
61 | - /** |
|
62 | - * Array of active messengers. |
|
63 | - * Format is this: |
|
64 | - * array( |
|
65 | - * 'messenger_name' => EE_messenger |
|
66 | - * ) |
|
67 | - * |
|
68 | - * @type EE_messenger[] |
|
69 | - */ |
|
70 | - protected $_active_messengers = []; |
|
71 | - |
|
72 | - /** |
|
73 | - * Formatted array of active message types grouped per messenger. |
|
74 | - * Format is this: |
|
75 | - * array( |
|
76 | - * 'messenger_name' => array( |
|
77 | - * 'settings' => array( |
|
78 | - * '{messenger_name}-message_types' => array( |
|
79 | - * 'message_type_name' => array() //variable array of settings corresponding to message type. |
|
80 | - * ) |
|
81 | - * ) |
|
82 | - * ) |
|
83 | - * ) |
|
84 | - * |
|
85 | - * @type array |
|
86 | - */ |
|
87 | - protected $_active_message_types = []; |
|
88 | - |
|
89 | - |
|
90 | - /** |
|
91 | - * This holds the array of messengers and their corresponding message types that have |
|
92 | - * been activated on a site at some point. This is an important record that helps the messages system |
|
93 | - * not accidentally reactivate something that was intentionally deactivated by a user. |
|
94 | - * |
|
95 | - * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
96 | - * details. |
|
97 | - * @type array |
|
98 | - */ |
|
99 | - protected $_has_activated_messengers_and_message_types = []; |
|
100 | - |
|
101 | - /** |
|
102 | - * An array of unique message type contexts across all active message types. |
|
103 | - * The array will be indexed by either 'slugs' or 'all'. |
|
104 | - * The slugs index contains an array indexed by unique context slugs with the latest label representation for that |
|
105 | - * slug. array( |
|
106 | - * 'context_slug' => 'localized label for context obtained from latest message type in the loop'. |
|
107 | - * ); |
|
108 | - * The all index returns an array in this format: |
|
109 | - * array( |
|
110 | - * 'message_type_name' => array( |
|
111 | - * 'context_slug' => array( |
|
112 | - * 'label' => 'localized label for context', |
|
113 | - * 'description' => 'localized description for context' |
|
114 | - * ) |
|
115 | - * ) |
|
116 | - * ); |
|
117 | - * |
|
118 | - * @type array |
|
119 | - */ |
|
120 | - protected $_contexts = []; |
|
121 | - |
|
122 | - |
|
123 | - /** |
|
124 | - * EE_Message_Resource_Manager constructor. |
|
125 | - * |
|
126 | - * @param \EE_Messenger_Collection_Loader $Messenger_Collection_Loader |
|
127 | - * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader |
|
128 | - * @param \EEM_Message_Template_Group $Message_Template_Group_Model |
|
129 | - */ |
|
130 | - public function __construct( |
|
131 | - EE_Messenger_Collection_Loader $Messenger_Collection_Loader, |
|
132 | - EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader, |
|
133 | - EEM_Message_Template_Group $Message_Template_Group_Model |
|
134 | - ) { |
|
135 | - $this->_messenger_collection_loader = $Messenger_Collection_Loader; |
|
136 | - $this->_message_type_collection_loader = $Message_Type_Collection_Loader; |
|
137 | - $this->_message_template_group_model = $Message_Template_Group_Model; |
|
138 | - } |
|
139 | - |
|
140 | - |
|
141 | - /** |
|
142 | - * @return void |
|
143 | - */ |
|
144 | - protected function _initialize_collections() |
|
145 | - { |
|
146 | - if ($this->_initialized) { |
|
147 | - return; |
|
148 | - } |
|
149 | - $this->_initialized = true; |
|
150 | - $this->_messenger_collection_loader->load_messengers_from_folder(); |
|
151 | - $this->_message_type_collection_loader->load_message_types_from_folder(); |
|
152 | - $this->get_has_activated_messengers_option(true); |
|
153 | - $this->_set_active_messengers_and_message_types(); |
|
154 | - } |
|
155 | - |
|
156 | - |
|
157 | - /** |
|
158 | - * @return EE_Messenger_Collection |
|
159 | - */ |
|
160 | - public function messenger_collection() |
|
161 | - { |
|
162 | - $this->_initialize_collections(); |
|
163 | - return $this->_messenger_collection_loader->messenger_collection(); |
|
164 | - } |
|
165 | - |
|
166 | - |
|
167 | - /** |
|
168 | - * @return EE_messenger[] |
|
169 | - */ |
|
170 | - public function active_messengers() |
|
171 | - { |
|
172 | - $this->_initialize_collections(); |
|
173 | - return $this->_active_messengers; |
|
174 | - } |
|
175 | - |
|
176 | - |
|
177 | - /** |
|
178 | - * @param string $messenger_name |
|
179 | - * @return \EE_messenger |
|
180 | - */ |
|
181 | - public function get_messenger($messenger_name) |
|
182 | - { |
|
183 | - return $this->messenger_collection()->get_by_info($messenger_name); |
|
184 | - } |
|
185 | - |
|
186 | - |
|
187 | - /** |
|
188 | - * This returns the corresponding EE_messenger object for the given string if it is active. |
|
189 | - * |
|
190 | - * @param string $messenger |
|
191 | - * @return EE_messenger | null |
|
192 | - */ |
|
193 | - public function get_active_messenger($messenger) |
|
194 | - { |
|
195 | - $this->_initialize_collections(); |
|
196 | - return ! empty($this->_active_messengers[ $messenger ]) |
|
197 | - ? $this->_active_messengers[ $messenger ] |
|
198 | - : null; |
|
199 | - } |
|
200 | - |
|
201 | - |
|
202 | - /** |
|
203 | - * @return \EE_messenger[] |
|
204 | - */ |
|
205 | - public function installed_messengers() |
|
206 | - { |
|
207 | - if (empty($this->_installed_messengers)) { |
|
208 | - $this->_installed_messengers = []; |
|
209 | - $this->messenger_collection()->rewind(); |
|
210 | - while ($this->messenger_collection()->valid()) { |
|
211 | - $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = |
|
212 | - $this->messenger_collection()->current(); |
|
213 | - $this->messenger_collection()->next(); |
|
214 | - } |
|
215 | - } |
|
216 | - return $this->_installed_messengers; |
|
217 | - } |
|
218 | - |
|
219 | - |
|
220 | - /** |
|
221 | - * @param string $messenger_name |
|
222 | - * @return \EE_messenger |
|
223 | - * @throws EE_Error |
|
224 | - */ |
|
225 | - public function valid_messenger($messenger_name) |
|
226 | - { |
|
227 | - $messenger = $this->get_messenger($messenger_name); |
|
228 | - if ($messenger instanceof EE_messenger) { |
|
229 | - return $messenger; |
|
230 | - } |
|
231 | - throw new EE_Error( |
|
232 | - sprintf( |
|
233 | - esc_html__('The "%1$s" messenger is either invalid or not installed', 'event_espresso'), |
|
234 | - $messenger_name |
|
235 | - ) |
|
236 | - ); |
|
237 | - } |
|
238 | - |
|
239 | - |
|
240 | - /** |
|
241 | - * @return EE_Message_Type_Collection |
|
242 | - */ |
|
243 | - public function message_type_collection() |
|
244 | - { |
|
245 | - $this->_initialize_collections(); |
|
246 | - return $this->_message_type_collection_loader->message_type_collection(); |
|
247 | - } |
|
248 | - |
|
249 | - |
|
250 | - /** |
|
251 | - * @return array |
|
252 | - */ |
|
253 | - public function active_message_types() |
|
254 | - { |
|
255 | - $this->_initialize_collections(); |
|
256 | - return $this->_active_message_types; |
|
257 | - } |
|
258 | - |
|
259 | - |
|
260 | - /** |
|
261 | - * @param string $message_type_name |
|
262 | - * @return \EE_message_type |
|
263 | - */ |
|
264 | - public function get_message_type($message_type_name) |
|
265 | - { |
|
266 | - return $this->message_type_collection()->get_by_info($message_type_name); |
|
267 | - } |
|
268 | - |
|
269 | - |
|
270 | - /** |
|
271 | - * This returns the EE_message_type from the active message types array ( if present ); |
|
272 | - * |
|
273 | - * @param string $messenger_name |
|
274 | - * @param string $message_type_name |
|
275 | - * @return \EE_message_type|null |
|
276 | - */ |
|
277 | - public function get_active_message_type_for_messenger($messenger_name, $message_type_name) |
|
278 | - { |
|
279 | - return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name) |
|
280 | - ? $this->get_message_type($message_type_name) |
|
281 | - : null; |
|
282 | - } |
|
283 | - |
|
284 | - |
|
285 | - /** |
|
286 | - * Returns whether the given message type is active for the given messenger. |
|
287 | - * |
|
288 | - * @param string $messenger_name |
|
289 | - * @param string $message_type_name |
|
290 | - * @return bool |
|
291 | - */ |
|
292 | - public function is_message_type_active_for_messenger($messenger_name, $message_type_name) |
|
293 | - { |
|
294 | - $this->_initialize_collections(); |
|
295 | - return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]); |
|
296 | - } |
|
297 | - |
|
298 | - |
|
299 | - /** |
|
300 | - * Returns whether the given messenger is active. |
|
301 | - * |
|
302 | - * @param string $messenger_name the name of the messenger to check if active. |
|
303 | - * @return bool |
|
304 | - */ |
|
305 | - public function is_messenger_active($messenger_name) |
|
306 | - { |
|
307 | - $this->_initialize_collections(); |
|
308 | - return ! empty($this->_active_message_types[ $messenger_name ]); |
|
309 | - } |
|
310 | - |
|
311 | - |
|
312 | - /** |
|
313 | - * This returns any settings that might be on a message type for a messenger |
|
314 | - * |
|
315 | - * @param string $messenger_name The slug of the messenger |
|
316 | - * @param string $message_type_name The slug of the message type getting the settings for. |
|
317 | - * @return array |
|
318 | - */ |
|
319 | - public function get_message_type_settings_for_messenger($messenger_name, $message_type_name) |
|
320 | - { |
|
321 | - $settings = []; |
|
322 | - if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
323 | - $settings = |
|
324 | - isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']) |
|
325 | - ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] |
|
326 | - : []; |
|
327 | - } |
|
328 | - return $settings; |
|
329 | - } |
|
330 | - |
|
331 | - |
|
332 | - /** |
|
333 | - * Returns whether the given messenger name has active message types on it. |
|
334 | - * Infers whether the messenger is active or not as well. |
|
335 | - * |
|
336 | - * @param string $messenger_name |
|
337 | - * @return bool |
|
338 | - */ |
|
339 | - public function messenger_has_active_message_types($messenger_name) |
|
340 | - { |
|
341 | - $this->_initialize_collections(); |
|
342 | - return |
|
343 | - ! empty($this->_active_message_types[ $messenger_name ]) |
|
344 | - && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]); |
|
345 | - } |
|
346 | - |
|
347 | - |
|
348 | - /** |
|
349 | - * This checks the _active_message_types property for any active message types |
|
350 | - * that are present for the given messenger and returns them. |
|
351 | - * |
|
352 | - * @param string $messenger_name The messenger being checked |
|
353 | - * @return EE_message_type[]|array (empty array if no active_message_types) |
|
354 | - * @since 4.9.0 |
|
355 | - */ |
|
356 | - public function get_active_message_types_for_messenger($messenger_name) |
|
357 | - { |
|
358 | - $message_types = []; |
|
359 | - if (! $this->messenger_has_active_message_types($messenger_name)) { |
|
360 | - return $message_types; |
|
361 | - } |
|
362 | - $installed_message_types = $this->installed_message_types(); |
|
363 | - foreach ($installed_message_types as $message_type_name => $message_type) { |
|
364 | - if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
365 | - $message_types[ $message_type_name ] = $message_type; |
|
366 | - } |
|
367 | - } |
|
368 | - return $message_types; |
|
369 | - } |
|
370 | - |
|
371 | - |
|
372 | - /** |
|
373 | - * This does NOT return the _active_message_types property but |
|
374 | - * simply returns an array of active message type names from that property. |
|
375 | - * (The _active_message_types property is indexed by messenger and active message_types per messenger). |
|
376 | - * |
|
377 | - * @return array message_type references (string) |
|
378 | - */ |
|
379 | - public function list_of_active_message_types() |
|
380 | - { |
|
381 | - $active_message_type_names = []; |
|
382 | - $this->_initialize_collections(); |
|
383 | - foreach ($this->_active_message_types as $messenger => $messenger_settings) { |
|
384 | - if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) { |
|
385 | - continue; |
|
386 | - } |
|
387 | - foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) { |
|
388 | - if (! in_array($message_type_name, $active_message_type_names)) { |
|
389 | - $active_message_type_names[] = $message_type_name; |
|
390 | - } |
|
391 | - } |
|
392 | - } |
|
393 | - return $active_message_type_names; |
|
394 | - } |
|
395 | - |
|
396 | - |
|
397 | - /** |
|
398 | - * Same as list_of_active_message_types() except this returns actual EE_message_type objects |
|
399 | - * |
|
400 | - * @return \EE_message_type[] |
|
401 | - * @since 4.9.0 |
|
402 | - */ |
|
403 | - public function get_active_message_type_objects() |
|
404 | - { |
|
405 | - $active_message_types = []; |
|
406 | - $installed_message_types = $this->installed_message_types(); |
|
407 | - $active_message_type_names = $this->list_of_active_message_types(); |
|
408 | - foreach ($active_message_type_names as $active_message_type_name) { |
|
409 | - if (isset($installed_message_types[ $active_message_type_name ])) { |
|
410 | - $active_message_types[ $active_message_type_name ] = |
|
411 | - $installed_message_types[ $active_message_type_name ]; |
|
412 | - } |
|
413 | - } |
|
414 | - return $active_message_types; |
|
415 | - } |
|
416 | - |
|
417 | - |
|
418 | - /** |
|
419 | - * @return \EE_message_type[] |
|
420 | - */ |
|
421 | - public function installed_message_types() |
|
422 | - { |
|
423 | - if (empty($this->_installed_message_types)) { |
|
424 | - $this->message_type_collection()->rewind(); |
|
425 | - while ($this->message_type_collection()->valid()) { |
|
426 | - $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = |
|
427 | - $this->message_type_collection()->current(); |
|
428 | - $this->message_type_collection()->next(); |
|
429 | - } |
|
430 | - } |
|
431 | - return $this->_installed_message_types; |
|
432 | - } |
|
433 | - |
|
434 | - |
|
435 | - /** |
|
436 | - * @param string $message_type_name |
|
437 | - * @return \EE_message_type |
|
438 | - * @throws EE_Error |
|
439 | - */ |
|
440 | - public function valid_message_type($message_type_name) |
|
441 | - { |
|
442 | - $message_type = $this->get_message_type($message_type_name); |
|
443 | - if ($message_type instanceof EE_message_type) { |
|
444 | - return $message_type; |
|
445 | - } |
|
446 | - throw new EE_Error( |
|
447 | - sprintf( |
|
448 | - esc_html__('The "%1$s" message type is either invalid or not installed', 'event_espresso'), |
|
449 | - $message_type_name |
|
450 | - ) |
|
451 | - ); |
|
452 | - } |
|
453 | - |
|
454 | - |
|
455 | - /** |
|
456 | - * valid_message_type_for_messenger |
|
457 | - * |
|
458 | - * @param EE_messenger $messenger |
|
459 | - * @param string $message_type_name |
|
460 | - * @return boolean |
|
461 | - * @throws EE_Error |
|
462 | - */ |
|
463 | - public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name) |
|
464 | - { |
|
465 | - $valid_message_types = $messenger->get_valid_message_types(); |
|
466 | - if (! in_array($message_type_name, $valid_message_types)) { |
|
467 | - throw new EE_Error( |
|
468 | - sprintf( |
|
469 | - esc_html__( |
|
470 | - 'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger. Double-check the spelling and verify that message type has been registered as a valid type with the messenger.', |
|
471 | - 'event_espresso' |
|
472 | - ), |
|
473 | - $message_type_name, |
|
474 | - __METHOD__, |
|
475 | - $messenger->name |
|
476 | - ) |
|
477 | - ); |
|
478 | - } |
|
479 | - return true; |
|
480 | - } |
|
481 | - |
|
482 | - |
|
483 | - /** |
|
484 | - * Used to return active messengers array stored in the wp options table. |
|
485 | - * If no value is present in the option then an empty array is returned. |
|
486 | - * |
|
487 | - * @param bool $reset If true then we ignore whether the option is cached on the _active_message_types |
|
488 | - * property and pull directly from the db. Otherwise whatever is currently on the |
|
489 | - * $_active_message_types property is pulled. |
|
490 | - * @return array |
|
491 | - */ |
|
492 | - public function get_active_messengers_option($reset = false) |
|
493 | - { |
|
494 | - if ($reset) { |
|
495 | - $this->_active_message_types = get_option('ee_active_messengers', []); |
|
496 | - } |
|
497 | - return $this->_active_message_types; |
|
498 | - } |
|
499 | - |
|
500 | - |
|
501 | - /** |
|
502 | - * Used to update the active messengers array stored in the wp options table. |
|
503 | - * |
|
504 | - * @param array $active_messenger_settings Incoming data to save. If empty, then the internal cached property |
|
505 | - * representing this data is used. |
|
506 | - * @return bool FALSE if not updated, TRUE if updated. |
|
507 | - */ |
|
508 | - public function update_active_messengers_option($active_messenger_settings = []) |
|
509 | - { |
|
510 | - $active_messenger_settings = empty($active_messenger_settings) |
|
511 | - ? $this->_active_message_types |
|
512 | - : $active_messenger_settings; |
|
513 | - // make sure _active_message_types is updated (this is the internal cache for the settings). |
|
514 | - $this->_active_message_types = $active_messenger_settings; |
|
515 | - return update_option('ee_active_messengers', $active_messenger_settings); |
|
516 | - } |
|
517 | - |
|
518 | - |
|
519 | - /** |
|
520 | - * Used to return has activated message types for messengers array stored in the wp options table. |
|
521 | - * If no value is present in the option then an empty array is returned. |
|
522 | - * The value is cached on the $_has_activated_messengers_and_message_types property for future calls. |
|
523 | - * |
|
524 | - * @param bool $reset Used to indicate that any cached value should be ignored. |
|
525 | - * @return array |
|
526 | - * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
527 | - * details. |
|
528 | - */ |
|
529 | - public function get_has_activated_messengers_option($reset = false) |
|
530 | - { |
|
531 | - if ($reset || empty($this->_has_activated_messengers_and_message_types)) { |
|
532 | - $this->_has_activated_messengers_and_message_types = |
|
533 | - get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, []); |
|
534 | - } |
|
535 | - return $this->_has_activated_messengers_and_message_types; |
|
536 | - } |
|
537 | - |
|
538 | - |
|
539 | - /** |
|
540 | - * Used to update the has activated option in the db. |
|
541 | - * |
|
542 | - * @param array $has_activated_messengers Incoming data to save. If empty, then the internal cached property |
|
543 | - * representing this data is used. |
|
544 | - * @return bool FALSE if not updated, TRUE if updated. |
|
545 | - * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
546 | - * details. |
|
547 | - */ |
|
548 | - public function update_has_activated_messengers_option($has_activated_messengers = []) |
|
549 | - { |
|
550 | - // make sure the option has been retrieved from first so we don't overwrite it accidentally. |
|
551 | - if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) { |
|
552 | - $this->get_has_activated_messengers_option(); |
|
553 | - } |
|
554 | - $has_activated_messengers = empty($has_activated_messengers) |
|
555 | - ? $this->_has_activated_messengers_and_message_types |
|
556 | - : $has_activated_messengers; |
|
557 | - return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers); |
|
558 | - } |
|
559 | - |
|
560 | - |
|
561 | - /** |
|
562 | - * wrapper for _set_active_messengers_and_message_types() |
|
563 | - */ |
|
564 | - public function reset_active_messengers_and_message_types() |
|
565 | - { |
|
566 | - $this->_set_active_messengers_and_message_types(); |
|
567 | - } |
|
568 | - |
|
569 | - |
|
570 | - /** |
|
571 | - * Generate list of active messengers and message types from collection. |
|
572 | - * This sets up the active messengers from what is present in the database. |
|
573 | - */ |
|
574 | - protected function _set_active_messengers_and_message_types() |
|
575 | - { |
|
576 | - // echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n"; |
|
577 | - // list of activated messengers as set via the admin |
|
578 | - // note calling `get_active_messengers_options` also initializes the _active_message_types property. |
|
579 | - $this->get_active_messengers_option(true); |
|
580 | - $this->ensure_messengers_are_active([], false, true); |
|
581 | - $this->update_active_messengers_option(); |
|
582 | - $this->update_has_activated_messengers_option(); |
|
583 | - } |
|
584 | - |
|
585 | - |
|
586 | - /** |
|
587 | - * Ensures that the specified messenger is currently active. |
|
588 | - * If not, activates it and its default message types. |
|
589 | - * |
|
590 | - * @param string $messenger_name |
|
591 | - * @param bool $update_option Whether to update the option in the db or not. |
|
592 | - * @return boolean true if either already active or successfully activated. |
|
593 | - */ |
|
594 | - public function ensure_messenger_is_active($messenger_name, $update_option = true) |
|
595 | - { |
|
596 | - if (! isset($this->_active_messengers[ $messenger_name ])) { |
|
597 | - try { |
|
598 | - $this->activate_messenger($messenger_name, [], $update_option); |
|
599 | - } catch (EE_Error $e) { |
|
600 | - EE_Error::add_error( |
|
601 | - $e->getMessage(), |
|
602 | - __FILE__, |
|
603 | - __FUNCTION__, |
|
604 | - __LINE__ |
|
605 | - ); |
|
606 | - return false; |
|
607 | - } |
|
608 | - } |
|
609 | - return true; |
|
610 | - } |
|
611 | - |
|
612 | - |
|
613 | - /** |
|
614 | - * This ensures the given array of messenger names is active in the system. |
|
615 | - * Note, this method will not activate any NEW message types for the messenger when it is called. Instead, |
|
616 | - * it will automatically activate the default message types for the messenger if its not active. |
|
617 | - * |
|
618 | - * @param array $messenger_names Array of messenger names for messengers to be activated. If an empty array |
|
619 | - * (default) then will attempt to set the active messengers from the |
|
620 | - * activated_messengers option |
|
621 | - * (stored in $_active_message_types property). |
|
622 | - * @param bool $update_option Whether to update the related active messengers option. |
|
623 | - * @param bool $verify Whether to verify the messengers are installed before activating. Note if this is |
|
624 | - * set to true and a messenger is indicated as active, but is NOT installed, then it |
|
625 | - * will automatically be deactivated. |
|
626 | - */ |
|
627 | - public function ensure_messengers_are_active($messenger_names = [], $update_option = true, $verify = false) |
|
628 | - { |
|
629 | - $messenger_names = empty($messenger_names) |
|
630 | - ? array_keys($this->_active_message_types) |
|
631 | - : $messenger_names; |
|
632 | - |
|
633 | - $not_installed = []; |
|
634 | - foreach ($messenger_names as $messenger_name) { |
|
635 | - if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) { |
|
636 | - $not_installed[] = $messenger_name; |
|
637 | - $this->deactivate_messenger($messenger_name); |
|
638 | - continue; |
|
639 | - } |
|
640 | - $this->ensure_messenger_is_active($messenger_name, $update_option); |
|
641 | - } |
|
642 | - |
|
643 | - if (! empty($not_installed)) { |
|
644 | - EE_Error::add_error( |
|
645 | - sprintf( |
|
646 | - esc_html__( |
|
647 | - 'The following messengers are either not installed or are invalid:%1$s %2$s', |
|
648 | - 'event_espresso' |
|
649 | - ), |
|
650 | - '<br />', |
|
651 | - implode(', ', $not_installed) |
|
652 | - ), |
|
653 | - __FILE__, |
|
654 | - __FUNCTION__, |
|
655 | - __LINE__ |
|
656 | - ); |
|
657 | - } |
|
658 | - } |
|
659 | - |
|
660 | - |
|
661 | - /** |
|
662 | - * Ensures that the specified message type for the given messenger is currently active, if not activates it. |
|
663 | - * This ALSO ensures that the given messenger is active as well! |
|
664 | - * |
|
665 | - * @param string $message_type_name message type name. |
|
666 | - * @param $messenger_name |
|
667 | - * @param bool $update_option Whether to update the option in the db or not. |
|
668 | - * @return bool Returns true if already is active or if was activated successfully. |
|
669 | - * @throws EE_Error |
|
670 | - */ |
|
671 | - public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true) |
|
672 | - { |
|
673 | - // grab the messenger to work with. |
|
674 | - $messenger = $this->valid_messenger($messenger_name); |
|
675 | - if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) { |
|
676 | - // ensure messenger is active (that's an inherent coupling between active message types and the |
|
677 | - // messenger they are being activated for. |
|
678 | - try { |
|
679 | - if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
680 | - // all is good so let's just get it active |
|
681 | - $this->activate_messenger($messenger, [$message_type_name], $update_option); |
|
682 | - } |
|
683 | - } catch (EE_Error $e) { |
|
684 | - EE_Error::add_error( |
|
685 | - $e->getMessage(), |
|
686 | - __FILE__, |
|
687 | - __FUNCTION__, |
|
688 | - __LINE__ |
|
689 | - ); |
|
690 | - return false; |
|
691 | - } |
|
692 | - } |
|
693 | - return true; |
|
694 | - } |
|
695 | - |
|
696 | - |
|
697 | - /** |
|
698 | - * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a |
|
699 | - * messenger are active in one go. |
|
700 | - * |
|
701 | - * @param array $message_type_names Array of message type names to ensure are active. |
|
702 | - * @param string $messenger_name The name of the messenger that the message types are to be activated on. |
|
703 | - * @param bool $update_option Whether to persist the activation to the database or not (default true). |
|
704 | - */ |
|
705 | - public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true) |
|
706 | - { |
|
707 | - $message_type_names = (array) $message_type_names; |
|
708 | - foreach ($message_type_names as $message_type_name) { |
|
709 | - // note, intentionally not updating option here because we're in a loop. |
|
710 | - // We'll follow the instructions of the incoming $update_option argument after the loop. |
|
711 | - $this->ensure_message_type_is_active($message_type_name, $messenger_name, false); |
|
712 | - } |
|
713 | - if ($update_option) { |
|
714 | - $this->update_active_messengers_option(); |
|
715 | - $this->update_has_activated_messengers_option(); |
|
716 | - } |
|
717 | - } |
|
718 | - |
|
719 | - |
|
720 | - /** |
|
721 | - * Activates the specified messenger. |
|
722 | - * |
|
723 | - * @param EE_messenger|string $messenger Instantiated EE_messenger OR messenger name if not already loaded! |
|
724 | - * @param array $message_type_names An array of message type names to activate with this messenger. |
|
725 | - * If included we do NOT setup the default message types |
|
726 | - * (assuming they are already setup.) |
|
727 | - * @param bool $update_active_messengers_option |
|
728 | - * @return array of generated templates |
|
729 | - * @throws EE_Error |
|
730 | - */ |
|
731 | - public function activate_messenger( |
|
732 | - $messenger, |
|
733 | - $message_type_names = [], |
|
734 | - $update_active_messengers_option = true |
|
735 | - ) { |
|
736 | - $templates = []; |
|
737 | - // grab the messenger to work with. |
|
738 | - $messenger = $messenger instanceof EE_messenger |
|
739 | - ? $messenger |
|
740 | - : $this->messenger_collection()->get_by_info($messenger); |
|
741 | - // it's inactive. Activate it. |
|
742 | - if ($messenger instanceof EE_messenger) { |
|
743 | - $this->_active_messengers[ $messenger->name ] = $messenger; |
|
744 | - // activate incoming message types set to be activated with messenger. |
|
745 | - $message_type_names = $this->_activate_message_types($messenger, $message_type_names); |
|
746 | - // setup any initial settings for the messenger if necessary. |
|
747 | - $this->add_settings_for_messenger($messenger->name); |
|
748 | - if ($update_active_messengers_option) { |
|
749 | - $this->update_active_messengers_option(); |
|
750 | - $this->update_has_activated_messengers_option(); |
|
751 | - } |
|
752 | - // generate new templates if necessary and ensure all related templates that are already in the database are |
|
753 | - // marked active. Note, this will also deactivate a message type for a messenger if the template |
|
754 | - // cannot be successfully created during its attempt (only happens for global template attempts). |
|
755 | - if (! empty($message_type_names)) { |
|
756 | - $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true); |
|
757 | - EEH_MSG_Template::update_to_active([$messenger->name], $message_type_names); |
|
758 | - } |
|
759 | - } |
|
760 | - return $templates; |
|
761 | - } |
|
762 | - |
|
763 | - |
|
764 | - /** |
|
765 | - * Activates given message types for the given EE_messenger object. |
|
766 | - * Note: (very important) This method does not persist the activation to the database. |
|
767 | - * See code implementing this method in this class for examples of how to persist. |
|
768 | - * |
|
769 | - * @param \EE_messenger $messenger |
|
770 | - * @param array $message_type_names |
|
771 | - * @return array |
|
772 | - */ |
|
773 | - protected function _activate_message_types(EE_messenger $messenger, $message_type_names = []) |
|
774 | - { |
|
775 | - // If $message_type_names is empty, AND $this->_active_message_types is empty, then that means |
|
776 | - // things have never been initialized (which should happen on EEH_Activation::generate_message_templates). |
|
777 | - // So ONLY then do we need to actually grab defaults and cycle through them. Otherwise we |
|
778 | - // only override _active_message_types when an explicit array of $message_type_names has been provided. |
|
779 | - $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ]) |
|
780 | - ? $messenger->get_default_message_types() |
|
781 | - : (array) $message_type_names; |
|
782 | - |
|
783 | - // now we ALWAYS need to make sure that the messenger is active for the message types we're activating! |
|
784 | - if (! isset($this->_active_message_types[ $messenger->name ])) { |
|
785 | - $this->_active_message_types[ $messenger->name ]['settings'] = []; |
|
786 | - } |
|
787 | - |
|
788 | - if ($message_type_names) { |
|
789 | - // cycle thru message types |
|
790 | - foreach ($message_type_names as $message_type_name) { |
|
791 | - // only register the message type as active IF it isn't already active |
|
792 | - // and if its actually installed. |
|
793 | - if ( |
|
794 | - ! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name) |
|
795 | - ) { |
|
796 | - $this->add_settings_for_message_type($messenger->name, $message_type_name); |
|
797 | - $this->_set_messenger_has_activated_message_type( |
|
798 | - $messenger, |
|
799 | - $message_type_name |
|
800 | - ); |
|
801 | - } |
|
802 | - } |
|
803 | - } |
|
804 | - return $message_type_names; |
|
805 | - } |
|
806 | - |
|
807 | - |
|
808 | - /** |
|
809 | - * add_settings_for_message_type |
|
810 | - * NOTE This does NOT automatically persist any settings to the db. Client code should call |
|
811 | - * $this->update_active_messengers_option to persist. |
|
812 | - * |
|
813 | - * @param string $messenger_name The name of the messenger adding the settings for |
|
814 | - * @param string $message_type_name The name of the message type adding the settings for |
|
815 | - * @param array $new_settings Any new settings being set for the message type and messenger |
|
816 | - */ |
|
817 | - public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = []) |
|
818 | - { |
|
819 | - // get installed message type from collection |
|
820 | - $message_type = $this->message_type_collection()->get_by_info($message_type_name); |
|
821 | - $existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name); |
|
822 | - // we need to setup any initial settings for message types |
|
823 | - if ($message_type instanceof EE_message_type) { |
|
824 | - $default_settings = $message_type->get_admin_settings_fields(); |
|
825 | - foreach ($default_settings as $field => $values) { |
|
826 | - if (isset($new_settings[ $field ])) { |
|
827 | - $existing_settings[ $field ] = $new_settings[ $field ]; |
|
828 | - continue; |
|
829 | - } |
|
830 | - if (! isset($existing_settings[ $field ])) { |
|
831 | - $existing_settings[ $field ] = $values['default']; |
|
832 | - } |
|
833 | - } |
|
834 | - } |
|
835 | - $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = |
|
836 | - $existing_settings; |
|
837 | - } |
|
838 | - |
|
839 | - |
|
840 | - /** |
|
841 | - * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger |
|
842 | - * and message type. |
|
843 | - * |
|
844 | - * @param \EE_messenger $messenger |
|
845 | - * @param string $message_type_name |
|
846 | - * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
847 | - * details. |
|
848 | - * @access protected |
|
849 | - */ |
|
850 | - protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name) |
|
851 | - { |
|
852 | - // if _has_activated_messengers_and_message_types is empty then lets ensure its initialized |
|
853 | - if (empty($this->_has_activated_messengers_and_message_types)) { |
|
854 | - $this->get_has_activated_messengers_option(); |
|
855 | - } |
|
856 | - |
|
857 | - // make sure this messenger has a record in the has_activated array |
|
858 | - if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) { |
|
859 | - $this->_has_activated_messengers_and_message_types[ $messenger->name ] = []; |
|
860 | - } |
|
861 | - // check if message type has already been added |
|
862 | - if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) { |
|
863 | - $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name; |
|
864 | - } |
|
865 | - } |
|
866 | - |
|
867 | - |
|
868 | - /** |
|
869 | - * add_settings_for_messenger |
|
870 | - * NOTE This does NOT automatically persist any settings to the db. Client code should call |
|
871 | - * $this->update_active_messengers_option to persist. |
|
872 | - * |
|
873 | - * @param string $messenger_name The name of the messenger the settings is being added for. |
|
874 | - * @param array $new_settings An array of settings to update the existing settings. |
|
875 | - */ |
|
876 | - public function add_settings_for_messenger($messenger_name, $new_settings = []) |
|
877 | - { |
|
878 | - $messenger = $this->get_messenger($messenger_name); |
|
879 | - if ($messenger instanceof EE_messenger) { |
|
880 | - $msgr_settings = $messenger->get_admin_settings_fields(); |
|
881 | - if (! empty($msgr_settings)) { |
|
882 | - foreach ($msgr_settings as $field => $value) { |
|
883 | - // is there a new setting for this? |
|
884 | - if (isset($new_settings[ $field ])) { |
|
885 | - $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = |
|
886 | - $new_settings[ $field ]; |
|
887 | - continue; |
|
888 | - } |
|
889 | - // only set the default if it isn't already set. |
|
890 | - if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) { |
|
891 | - $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value; |
|
892 | - } |
|
893 | - } |
|
894 | - } |
|
895 | - } |
|
896 | - } |
|
897 | - |
|
898 | - |
|
899 | - /** |
|
900 | - * deactivate_messenger |
|
901 | - * |
|
902 | - * @param string|EE_messenger $messenger_name name of messenger |
|
903 | - * @return void |
|
904 | - */ |
|
905 | - public function deactivate_messenger($messenger_name) |
|
906 | - { |
|
907 | - $this->_initialize_collections(); |
|
908 | - if ($messenger_name instanceof EE_messenger) { |
|
909 | - $messenger_name = $messenger_name->name; |
|
910 | - } |
|
911 | - unset($this->_active_messengers[ $messenger_name ]); |
|
912 | - unset($this->_active_message_types[ $messenger_name ]); |
|
913 | - $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name); |
|
914 | - $this->update_active_messengers_option(); |
|
915 | - } |
|
916 | - |
|
917 | - |
|
918 | - /** |
|
919 | - * Deactivates a message type (note this will deactivate across all messenger's it is active on. |
|
920 | - * |
|
921 | - * @param string $message_type_name name of message type being deactivated |
|
922 | - * @param bool $set_has_active_record By default we always record the has_active record when deactivating a |
|
923 | - * message type. However, this can be overridden if we don't want this set |
|
924 | - * (usually when this is called as a part of deregistration of a custom |
|
925 | - * message type) |
|
926 | - */ |
|
927 | - public function deactivate_message_type($message_type_name, $set_has_active_record = true) |
|
928 | - { |
|
929 | - $this->_initialize_collections(); |
|
930 | - if ($message_type_name instanceof EE_message_type) { |
|
931 | - $message_type_name = $message_type_name->name; |
|
932 | - } |
|
933 | - foreach ($this->_active_message_types as $messenger_name => $settings) { |
|
934 | - unset( |
|
935 | - $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ] |
|
936 | - ); |
|
937 | - |
|
938 | - // we always record (even on deactivation) that a message type has been activated because there should at |
|
939 | - // least be a record in the "has_activated" option that it WAS active at one point. |
|
940 | - if ($set_has_active_record) { |
|
941 | - $messenger = $this->get_messenger($messenger_name); |
|
942 | - $this->_set_messenger_has_activated_message_type($messenger, $message_type_name); |
|
943 | - } |
|
944 | - } |
|
945 | - $this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name); |
|
946 | - $this->update_active_messengers_option(); |
|
947 | - $this->update_has_activated_messengers_option(); |
|
948 | - } |
|
949 | - |
|
950 | - |
|
951 | - /** |
|
952 | - * Deactivates a message type for a specific messenger as opposed to all messengers. |
|
953 | - * |
|
954 | - * @param string $message_type_name Name of message type being deactivated. |
|
955 | - * @param string $messenger_name Name of messenger the message type is being deactivated for. |
|
956 | - */ |
|
957 | - public function deactivate_message_type_for_messenger($message_type_name, $messenger_name) |
|
958 | - { |
|
959 | - $this->_initialize_collections(); |
|
960 | - if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
961 | - unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]); |
|
962 | - } |
|
963 | - $this->_message_template_group_model->deactivate_message_template_groups_for( |
|
964 | - [$messenger_name], |
|
965 | - [$message_type_name] |
|
966 | - ); |
|
967 | - $this->update_active_messengers_option(); |
|
968 | - } |
|
969 | - |
|
970 | - |
|
971 | - /** |
|
972 | - * Used to verify if a message can be sent for the given messenger and message type |
|
973 | - * and that it is a generating messenger (used for generating message templates). |
|
974 | - * |
|
975 | - * @param EE_messenger $messenger messenger used in trigger |
|
976 | - * @param EE_message_type $message_type message type used in trigger |
|
977 | - * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send. |
|
978 | - */ |
|
979 | - public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type) |
|
980 | - { |
|
981 | - // get the $messengers the message type says it can be used with. |
|
982 | - foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) { |
|
983 | - if ( |
|
984 | - $messenger->name === $generating_messenger |
|
985 | - && $this->is_message_type_active_for_messenger($messenger->name, $message_type->name) |
|
986 | - ) { |
|
987 | - return true; |
|
988 | - } |
|
989 | - } |
|
990 | - return false; |
|
991 | - } |
|
992 | - |
|
993 | - |
|
994 | - /** |
|
995 | - * This returns all the contexts that are registered by all message types. |
|
996 | - * If $slugs_only is true, |
|
997 | - * then just an array indexed by unique context slugs with the latest label representation for that slug. |
|
998 | - * array( |
|
999 | - * 'context_slug' => 'localized label for context obtained from latest message type in the loop'. |
|
1000 | - * ); |
|
1001 | - * If $slugs_only is false, then the format is: |
|
1002 | - * array( |
|
1003 | - * 'message_type_name' => array( |
|
1004 | - * 'context_slug' => array( |
|
1005 | - * 'label' => 'localized label for context', |
|
1006 | - * 'description' => 'localized description for context' |
|
1007 | - * ) |
|
1008 | - * ) |
|
1009 | - * ); |
|
1010 | - * Keep in mind that although different message types may share the same context slugs, |
|
1011 | - * it is possible that the context is described differently by the message type. |
|
1012 | - * |
|
1013 | - * @param bool $slugs_only Whether to return an array of just slugs and labels (true) |
|
1014 | - * or all contexts indexed by message type. |
|
1015 | - * @return array |
|
1016 | - * @since 4.9.0 |
|
1017 | - */ |
|
1018 | - public function get_all_contexts($slugs_only = true) |
|
1019 | - { |
|
1020 | - $key = $slugs_only |
|
1021 | - ? 'slugs' |
|
1022 | - : 'all'; |
|
1023 | - // check if contexts has been setup yet. |
|
1024 | - if (empty($this->_contexts[ $key ])) { |
|
1025 | - // So let's get all active message type objects and loop through to get all unique contexts |
|
1026 | - foreach ($this->get_active_message_type_objects() as $message_type) { |
|
1027 | - if ($message_type instanceof EE_message_type) { |
|
1028 | - $message_type_contexts = $message_type->get_contexts(); |
|
1029 | - if ($slugs_only) { |
|
1030 | - foreach ($message_type_contexts as $context => $context_details) { |
|
1031 | - $this->_contexts[ $key ][ $context ] = $context_details['label']; |
|
1032 | - } |
|
1033 | - } else { |
|
1034 | - $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts; |
|
1035 | - } |
|
1036 | - } |
|
1037 | - } |
|
1038 | - } |
|
1039 | - return ! empty($this->_contexts[ $key ]) |
|
1040 | - ? $this->_contexts[ $key ] |
|
1041 | - : []; |
|
1042 | - } |
|
1043 | - |
|
1044 | - |
|
1045 | - /** |
|
1046 | - * This checks the internal record of what message types are considered "active" and verifies that |
|
1047 | - * there is an installed class definition for that message type. If the active message type does not have a |
|
1048 | - * corresponding accessible message type class then it will be deactivated from all messengers it is active on and |
|
1049 | - * any related message templates will be inactivated as well. |
|
1050 | - * |
|
1051 | - * @return bool true means all active message types are valid, false means at least one message type was |
|
1052 | - * deactivated. |
|
1053 | - */ |
|
1054 | - public function validate_active_message_types_are_installed() |
|
1055 | - { |
|
1056 | - $list_of_active_message_type_names = $this->list_of_active_message_types(); |
|
1057 | - $installed_message_types = $this->installed_message_types(); |
|
1058 | - $all_message_types_valid = true; |
|
1059 | - // loop through list of active message types and verify they are installed. |
|
1060 | - foreach ($list_of_active_message_type_names as $message_type_name) { |
|
1061 | - if (! isset($installed_message_types[ $message_type_name ])) { |
|
1062 | - $this->remove_message_type_has_been_activated_from_all_messengers( |
|
1063 | - $message_type_name, |
|
1064 | - true |
|
1065 | - ); |
|
1066 | - $this->deactivate_message_type($message_type_name, false); |
|
1067 | - $all_message_types_valid = false; |
|
1068 | - } |
|
1069 | - } |
|
1070 | - return $all_message_types_valid; |
|
1071 | - } |
|
1072 | - |
|
1073 | - |
|
1074 | - /** |
|
1075 | - * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been |
|
1076 | - * activated for the given messenger. This can be called by client code on plugin updates etc to determine whether |
|
1077 | - * to attempt automatically reactivating message types that should be activated by default or not. |
|
1078 | - * |
|
1079 | - * @param $message_type_name |
|
1080 | - * @param $messenger_name |
|
1081 | - * @return bool |
|
1082 | - * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
1083 | - * details. |
|
1084 | - */ |
|
1085 | - public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name) |
|
1086 | - { |
|
1087 | - $has_activated = $this->get_has_activated_messengers_option(); |
|
1088 | - return isset($has_activated[ $messenger_name ]) |
|
1089 | - && in_array($message_type_name, $has_activated[ $messenger_name ]); |
|
1090 | - } |
|
1091 | - |
|
1092 | - |
|
1093 | - /** |
|
1094 | - * This method unsets a message type from the given messenger has activated option. |
|
1095 | - * |
|
1096 | - * @param string $message_type_name |
|
1097 | - * @param string $messenger_name |
|
1098 | - * @param bool $consider_current_state Whether to consider whether the message type is currently active or not. |
|
1099 | - * If it is currently active, then remove. Otherwise leave it alone. |
|
1100 | - * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
1101 | - * details. |
|
1102 | - */ |
|
1103 | - public function remove_message_type_has_been_activated_for_messenger( |
|
1104 | - $message_type_name, |
|
1105 | - $messenger_name, |
|
1106 | - $consider_current_state = false |
|
1107 | - ) { |
|
1108 | - if ( |
|
1109 | - $consider_current_state |
|
1110 | - && ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name) |
|
1111 | - ) { |
|
1112 | - // when consider current state is true, this means we don't want to change anything on the "has_activated" |
|
1113 | - // record if the message type is currently active for this messenger. This is used when we want to retain |
|
1114 | - // the record for user initiated inactivations of the message type. |
|
1115 | - return; |
|
1116 | - } |
|
1117 | - $has_activated = $this->get_has_activated_messengers_option(); |
|
1118 | - $key_for_message_type = isset($has_activated[ $messenger_name ]) |
|
1119 | - ? array_search($message_type_name, $has_activated[ $messenger_name ], true) |
|
1120 | - : false; |
|
1121 | - if ($key_for_message_type !== false) { |
|
1122 | - unset($has_activated[ $messenger_name ][ $key_for_message_type ]); |
|
1123 | - $this->update_has_activated_messengers_option($has_activated); |
|
1124 | - // reset the internal cached property |
|
1125 | - $this->get_has_activated_messengers_option(true); |
|
1126 | - } |
|
1127 | - } |
|
1128 | - |
|
1129 | - |
|
1130 | - /** |
|
1131 | - * Removes a message type active record from all messengers it is attached to. |
|
1132 | - * |
|
1133 | - * @param $message_type_name |
|
1134 | - * @param bool $consider_current_state Whether to consider whether the message type is currently active or not. |
|
1135 | - * If it is currently active, then remove. Otherwise leave it alone. |
|
1136 | - * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
1137 | - * details. |
|
1138 | - */ |
|
1139 | - public function remove_message_type_has_been_activated_from_all_messengers( |
|
1140 | - $message_type_name, |
|
1141 | - $consider_current_state = false |
|
1142 | - ) { |
|
1143 | - foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) { |
|
1144 | - $this->remove_message_type_has_been_activated_for_messenger( |
|
1145 | - $message_type_name, |
|
1146 | - $messenger_name, |
|
1147 | - $consider_current_state |
|
1148 | - ); |
|
1149 | - } |
|
1150 | - } |
|
14 | + /** |
|
15 | + * This option in the database is used to keep a record of message types that have been activated for a messenger |
|
16 | + * at some point in the history of the site. It is utilized by the implementation of the 'force' flag in |
|
17 | + * EE_Register_Message_Type. The force flag is an indication of whether a message type should be activated by |
|
18 | + * default when the message type is registered. However, if a user has explicitly deactivated a message type, then |
|
19 | + * the force flag is ignored. The method by which the code knows whether to ignore this flag is via this option. |
|
20 | + * Note, that this is NOT a historical record. Its entirely possible for a message type to have been activated for |
|
21 | + * a messenger and yet not have a record in this option. This occurs when a message type is inactivated through an |
|
22 | + * automated process (when an add-on registering the message type deactivates, or when some other code calls the |
|
23 | + * EE_Registery_Message_Type::deregister method) and the related record(s) is(are) removed from this option to |
|
24 | + * ensure the "force" flag is respected if that message type is later re-registered. This option should NOT be used |
|
25 | + * to determine the current "active" state of a message type for a given messenger. The name of this option (and |
|
26 | + * related methods/properties) is due to matching the original intended purpose for the option that got superseded |
|
27 | + * by later behaviour requirements. |
|
28 | + */ |
|
29 | + const HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME = 'ee_has_activated_messenger'; |
|
30 | + |
|
31 | + /** |
|
32 | + * @type boolean $_initialized |
|
33 | + */ |
|
34 | + protected $_initialized = false; |
|
35 | + |
|
36 | + /** |
|
37 | + * @type EE_Messenger_Collection $_messenger_collection_loader |
|
38 | + */ |
|
39 | + protected $_messenger_collection_loader; |
|
40 | + |
|
41 | + /** |
|
42 | + * @type EE_Message_Type_Collection $_message_type_collection_loader |
|
43 | + */ |
|
44 | + protected $_message_type_collection_loader; |
|
45 | + |
|
46 | + /** |
|
47 | + * @type EEM_Message_Template_Group $_message_template_group_model |
|
48 | + */ |
|
49 | + protected $_message_template_group_model; |
|
50 | + |
|
51 | + /** |
|
52 | + * @type EE_messenger[] |
|
53 | + */ |
|
54 | + protected $_installed_messengers = []; |
|
55 | + |
|
56 | + /** |
|
57 | + * @type EE_message_type[] |
|
58 | + */ |
|
59 | + protected $_installed_message_types = []; |
|
60 | + |
|
61 | + /** |
|
62 | + * Array of active messengers. |
|
63 | + * Format is this: |
|
64 | + * array( |
|
65 | + * 'messenger_name' => EE_messenger |
|
66 | + * ) |
|
67 | + * |
|
68 | + * @type EE_messenger[] |
|
69 | + */ |
|
70 | + protected $_active_messengers = []; |
|
71 | + |
|
72 | + /** |
|
73 | + * Formatted array of active message types grouped per messenger. |
|
74 | + * Format is this: |
|
75 | + * array( |
|
76 | + * 'messenger_name' => array( |
|
77 | + * 'settings' => array( |
|
78 | + * '{messenger_name}-message_types' => array( |
|
79 | + * 'message_type_name' => array() //variable array of settings corresponding to message type. |
|
80 | + * ) |
|
81 | + * ) |
|
82 | + * ) |
|
83 | + * ) |
|
84 | + * |
|
85 | + * @type array |
|
86 | + */ |
|
87 | + protected $_active_message_types = []; |
|
88 | + |
|
89 | + |
|
90 | + /** |
|
91 | + * This holds the array of messengers and their corresponding message types that have |
|
92 | + * been activated on a site at some point. This is an important record that helps the messages system |
|
93 | + * not accidentally reactivate something that was intentionally deactivated by a user. |
|
94 | + * |
|
95 | + * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
96 | + * details. |
|
97 | + * @type array |
|
98 | + */ |
|
99 | + protected $_has_activated_messengers_and_message_types = []; |
|
100 | + |
|
101 | + /** |
|
102 | + * An array of unique message type contexts across all active message types. |
|
103 | + * The array will be indexed by either 'slugs' or 'all'. |
|
104 | + * The slugs index contains an array indexed by unique context slugs with the latest label representation for that |
|
105 | + * slug. array( |
|
106 | + * 'context_slug' => 'localized label for context obtained from latest message type in the loop'. |
|
107 | + * ); |
|
108 | + * The all index returns an array in this format: |
|
109 | + * array( |
|
110 | + * 'message_type_name' => array( |
|
111 | + * 'context_slug' => array( |
|
112 | + * 'label' => 'localized label for context', |
|
113 | + * 'description' => 'localized description for context' |
|
114 | + * ) |
|
115 | + * ) |
|
116 | + * ); |
|
117 | + * |
|
118 | + * @type array |
|
119 | + */ |
|
120 | + protected $_contexts = []; |
|
121 | + |
|
122 | + |
|
123 | + /** |
|
124 | + * EE_Message_Resource_Manager constructor. |
|
125 | + * |
|
126 | + * @param \EE_Messenger_Collection_Loader $Messenger_Collection_Loader |
|
127 | + * @param \EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader |
|
128 | + * @param \EEM_Message_Template_Group $Message_Template_Group_Model |
|
129 | + */ |
|
130 | + public function __construct( |
|
131 | + EE_Messenger_Collection_Loader $Messenger_Collection_Loader, |
|
132 | + EE_Message_Type_Collection_Loader $Message_Type_Collection_Loader, |
|
133 | + EEM_Message_Template_Group $Message_Template_Group_Model |
|
134 | + ) { |
|
135 | + $this->_messenger_collection_loader = $Messenger_Collection_Loader; |
|
136 | + $this->_message_type_collection_loader = $Message_Type_Collection_Loader; |
|
137 | + $this->_message_template_group_model = $Message_Template_Group_Model; |
|
138 | + } |
|
139 | + |
|
140 | + |
|
141 | + /** |
|
142 | + * @return void |
|
143 | + */ |
|
144 | + protected function _initialize_collections() |
|
145 | + { |
|
146 | + if ($this->_initialized) { |
|
147 | + return; |
|
148 | + } |
|
149 | + $this->_initialized = true; |
|
150 | + $this->_messenger_collection_loader->load_messengers_from_folder(); |
|
151 | + $this->_message_type_collection_loader->load_message_types_from_folder(); |
|
152 | + $this->get_has_activated_messengers_option(true); |
|
153 | + $this->_set_active_messengers_and_message_types(); |
|
154 | + } |
|
155 | + |
|
156 | + |
|
157 | + /** |
|
158 | + * @return EE_Messenger_Collection |
|
159 | + */ |
|
160 | + public function messenger_collection() |
|
161 | + { |
|
162 | + $this->_initialize_collections(); |
|
163 | + return $this->_messenger_collection_loader->messenger_collection(); |
|
164 | + } |
|
165 | + |
|
166 | + |
|
167 | + /** |
|
168 | + * @return EE_messenger[] |
|
169 | + */ |
|
170 | + public function active_messengers() |
|
171 | + { |
|
172 | + $this->_initialize_collections(); |
|
173 | + return $this->_active_messengers; |
|
174 | + } |
|
175 | + |
|
176 | + |
|
177 | + /** |
|
178 | + * @param string $messenger_name |
|
179 | + * @return \EE_messenger |
|
180 | + */ |
|
181 | + public function get_messenger($messenger_name) |
|
182 | + { |
|
183 | + return $this->messenger_collection()->get_by_info($messenger_name); |
|
184 | + } |
|
185 | + |
|
186 | + |
|
187 | + /** |
|
188 | + * This returns the corresponding EE_messenger object for the given string if it is active. |
|
189 | + * |
|
190 | + * @param string $messenger |
|
191 | + * @return EE_messenger | null |
|
192 | + */ |
|
193 | + public function get_active_messenger($messenger) |
|
194 | + { |
|
195 | + $this->_initialize_collections(); |
|
196 | + return ! empty($this->_active_messengers[ $messenger ]) |
|
197 | + ? $this->_active_messengers[ $messenger ] |
|
198 | + : null; |
|
199 | + } |
|
200 | + |
|
201 | + |
|
202 | + /** |
|
203 | + * @return \EE_messenger[] |
|
204 | + */ |
|
205 | + public function installed_messengers() |
|
206 | + { |
|
207 | + if (empty($this->_installed_messengers)) { |
|
208 | + $this->_installed_messengers = []; |
|
209 | + $this->messenger_collection()->rewind(); |
|
210 | + while ($this->messenger_collection()->valid()) { |
|
211 | + $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = |
|
212 | + $this->messenger_collection()->current(); |
|
213 | + $this->messenger_collection()->next(); |
|
214 | + } |
|
215 | + } |
|
216 | + return $this->_installed_messengers; |
|
217 | + } |
|
218 | + |
|
219 | + |
|
220 | + /** |
|
221 | + * @param string $messenger_name |
|
222 | + * @return \EE_messenger |
|
223 | + * @throws EE_Error |
|
224 | + */ |
|
225 | + public function valid_messenger($messenger_name) |
|
226 | + { |
|
227 | + $messenger = $this->get_messenger($messenger_name); |
|
228 | + if ($messenger instanceof EE_messenger) { |
|
229 | + return $messenger; |
|
230 | + } |
|
231 | + throw new EE_Error( |
|
232 | + sprintf( |
|
233 | + esc_html__('The "%1$s" messenger is either invalid or not installed', 'event_espresso'), |
|
234 | + $messenger_name |
|
235 | + ) |
|
236 | + ); |
|
237 | + } |
|
238 | + |
|
239 | + |
|
240 | + /** |
|
241 | + * @return EE_Message_Type_Collection |
|
242 | + */ |
|
243 | + public function message_type_collection() |
|
244 | + { |
|
245 | + $this->_initialize_collections(); |
|
246 | + return $this->_message_type_collection_loader->message_type_collection(); |
|
247 | + } |
|
248 | + |
|
249 | + |
|
250 | + /** |
|
251 | + * @return array |
|
252 | + */ |
|
253 | + public function active_message_types() |
|
254 | + { |
|
255 | + $this->_initialize_collections(); |
|
256 | + return $this->_active_message_types; |
|
257 | + } |
|
258 | + |
|
259 | + |
|
260 | + /** |
|
261 | + * @param string $message_type_name |
|
262 | + * @return \EE_message_type |
|
263 | + */ |
|
264 | + public function get_message_type($message_type_name) |
|
265 | + { |
|
266 | + return $this->message_type_collection()->get_by_info($message_type_name); |
|
267 | + } |
|
268 | + |
|
269 | + |
|
270 | + /** |
|
271 | + * This returns the EE_message_type from the active message types array ( if present ); |
|
272 | + * |
|
273 | + * @param string $messenger_name |
|
274 | + * @param string $message_type_name |
|
275 | + * @return \EE_message_type|null |
|
276 | + */ |
|
277 | + public function get_active_message_type_for_messenger($messenger_name, $message_type_name) |
|
278 | + { |
|
279 | + return $this->is_message_type_active_for_messenger($messenger_name, $message_type_name) |
|
280 | + ? $this->get_message_type($message_type_name) |
|
281 | + : null; |
|
282 | + } |
|
283 | + |
|
284 | + |
|
285 | + /** |
|
286 | + * Returns whether the given message type is active for the given messenger. |
|
287 | + * |
|
288 | + * @param string $messenger_name |
|
289 | + * @param string $message_type_name |
|
290 | + * @return bool |
|
291 | + */ |
|
292 | + public function is_message_type_active_for_messenger($messenger_name, $message_type_name) |
|
293 | + { |
|
294 | + $this->_initialize_collections(); |
|
295 | + return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]); |
|
296 | + } |
|
297 | + |
|
298 | + |
|
299 | + /** |
|
300 | + * Returns whether the given messenger is active. |
|
301 | + * |
|
302 | + * @param string $messenger_name the name of the messenger to check if active. |
|
303 | + * @return bool |
|
304 | + */ |
|
305 | + public function is_messenger_active($messenger_name) |
|
306 | + { |
|
307 | + $this->_initialize_collections(); |
|
308 | + return ! empty($this->_active_message_types[ $messenger_name ]); |
|
309 | + } |
|
310 | + |
|
311 | + |
|
312 | + /** |
|
313 | + * This returns any settings that might be on a message type for a messenger |
|
314 | + * |
|
315 | + * @param string $messenger_name The slug of the messenger |
|
316 | + * @param string $message_type_name The slug of the message type getting the settings for. |
|
317 | + * @return array |
|
318 | + */ |
|
319 | + public function get_message_type_settings_for_messenger($messenger_name, $message_type_name) |
|
320 | + { |
|
321 | + $settings = []; |
|
322 | + if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
323 | + $settings = |
|
324 | + isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']) |
|
325 | + ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] |
|
326 | + : []; |
|
327 | + } |
|
328 | + return $settings; |
|
329 | + } |
|
330 | + |
|
331 | + |
|
332 | + /** |
|
333 | + * Returns whether the given messenger name has active message types on it. |
|
334 | + * Infers whether the messenger is active or not as well. |
|
335 | + * |
|
336 | + * @param string $messenger_name |
|
337 | + * @return bool |
|
338 | + */ |
|
339 | + public function messenger_has_active_message_types($messenger_name) |
|
340 | + { |
|
341 | + $this->_initialize_collections(); |
|
342 | + return |
|
343 | + ! empty($this->_active_message_types[ $messenger_name ]) |
|
344 | + && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]); |
|
345 | + } |
|
346 | + |
|
347 | + |
|
348 | + /** |
|
349 | + * This checks the _active_message_types property for any active message types |
|
350 | + * that are present for the given messenger and returns them. |
|
351 | + * |
|
352 | + * @param string $messenger_name The messenger being checked |
|
353 | + * @return EE_message_type[]|array (empty array if no active_message_types) |
|
354 | + * @since 4.9.0 |
|
355 | + */ |
|
356 | + public function get_active_message_types_for_messenger($messenger_name) |
|
357 | + { |
|
358 | + $message_types = []; |
|
359 | + if (! $this->messenger_has_active_message_types($messenger_name)) { |
|
360 | + return $message_types; |
|
361 | + } |
|
362 | + $installed_message_types = $this->installed_message_types(); |
|
363 | + foreach ($installed_message_types as $message_type_name => $message_type) { |
|
364 | + if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
365 | + $message_types[ $message_type_name ] = $message_type; |
|
366 | + } |
|
367 | + } |
|
368 | + return $message_types; |
|
369 | + } |
|
370 | + |
|
371 | + |
|
372 | + /** |
|
373 | + * This does NOT return the _active_message_types property but |
|
374 | + * simply returns an array of active message type names from that property. |
|
375 | + * (The _active_message_types property is indexed by messenger and active message_types per messenger). |
|
376 | + * |
|
377 | + * @return array message_type references (string) |
|
378 | + */ |
|
379 | + public function list_of_active_message_types() |
|
380 | + { |
|
381 | + $active_message_type_names = []; |
|
382 | + $this->_initialize_collections(); |
|
383 | + foreach ($this->_active_message_types as $messenger => $messenger_settings) { |
|
384 | + if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) { |
|
385 | + continue; |
|
386 | + } |
|
387 | + foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) { |
|
388 | + if (! in_array($message_type_name, $active_message_type_names)) { |
|
389 | + $active_message_type_names[] = $message_type_name; |
|
390 | + } |
|
391 | + } |
|
392 | + } |
|
393 | + return $active_message_type_names; |
|
394 | + } |
|
395 | + |
|
396 | + |
|
397 | + /** |
|
398 | + * Same as list_of_active_message_types() except this returns actual EE_message_type objects |
|
399 | + * |
|
400 | + * @return \EE_message_type[] |
|
401 | + * @since 4.9.0 |
|
402 | + */ |
|
403 | + public function get_active_message_type_objects() |
|
404 | + { |
|
405 | + $active_message_types = []; |
|
406 | + $installed_message_types = $this->installed_message_types(); |
|
407 | + $active_message_type_names = $this->list_of_active_message_types(); |
|
408 | + foreach ($active_message_type_names as $active_message_type_name) { |
|
409 | + if (isset($installed_message_types[ $active_message_type_name ])) { |
|
410 | + $active_message_types[ $active_message_type_name ] = |
|
411 | + $installed_message_types[ $active_message_type_name ]; |
|
412 | + } |
|
413 | + } |
|
414 | + return $active_message_types; |
|
415 | + } |
|
416 | + |
|
417 | + |
|
418 | + /** |
|
419 | + * @return \EE_message_type[] |
|
420 | + */ |
|
421 | + public function installed_message_types() |
|
422 | + { |
|
423 | + if (empty($this->_installed_message_types)) { |
|
424 | + $this->message_type_collection()->rewind(); |
|
425 | + while ($this->message_type_collection()->valid()) { |
|
426 | + $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = |
|
427 | + $this->message_type_collection()->current(); |
|
428 | + $this->message_type_collection()->next(); |
|
429 | + } |
|
430 | + } |
|
431 | + return $this->_installed_message_types; |
|
432 | + } |
|
433 | + |
|
434 | + |
|
435 | + /** |
|
436 | + * @param string $message_type_name |
|
437 | + * @return \EE_message_type |
|
438 | + * @throws EE_Error |
|
439 | + */ |
|
440 | + public function valid_message_type($message_type_name) |
|
441 | + { |
|
442 | + $message_type = $this->get_message_type($message_type_name); |
|
443 | + if ($message_type instanceof EE_message_type) { |
|
444 | + return $message_type; |
|
445 | + } |
|
446 | + throw new EE_Error( |
|
447 | + sprintf( |
|
448 | + esc_html__('The "%1$s" message type is either invalid or not installed', 'event_espresso'), |
|
449 | + $message_type_name |
|
450 | + ) |
|
451 | + ); |
|
452 | + } |
|
453 | + |
|
454 | + |
|
455 | + /** |
|
456 | + * valid_message_type_for_messenger |
|
457 | + * |
|
458 | + * @param EE_messenger $messenger |
|
459 | + * @param string $message_type_name |
|
460 | + * @return boolean |
|
461 | + * @throws EE_Error |
|
462 | + */ |
|
463 | + public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name) |
|
464 | + { |
|
465 | + $valid_message_types = $messenger->get_valid_message_types(); |
|
466 | + if (! in_array($message_type_name, $valid_message_types)) { |
|
467 | + throw new EE_Error( |
|
468 | + sprintf( |
|
469 | + esc_html__( |
|
470 | + 'The message type (%1$s) sent to "%2$s" is not valid for the "%3$s" messenger. Double-check the spelling and verify that message type has been registered as a valid type with the messenger.', |
|
471 | + 'event_espresso' |
|
472 | + ), |
|
473 | + $message_type_name, |
|
474 | + __METHOD__, |
|
475 | + $messenger->name |
|
476 | + ) |
|
477 | + ); |
|
478 | + } |
|
479 | + return true; |
|
480 | + } |
|
481 | + |
|
482 | + |
|
483 | + /** |
|
484 | + * Used to return active messengers array stored in the wp options table. |
|
485 | + * If no value is present in the option then an empty array is returned. |
|
486 | + * |
|
487 | + * @param bool $reset If true then we ignore whether the option is cached on the _active_message_types |
|
488 | + * property and pull directly from the db. Otherwise whatever is currently on the |
|
489 | + * $_active_message_types property is pulled. |
|
490 | + * @return array |
|
491 | + */ |
|
492 | + public function get_active_messengers_option($reset = false) |
|
493 | + { |
|
494 | + if ($reset) { |
|
495 | + $this->_active_message_types = get_option('ee_active_messengers', []); |
|
496 | + } |
|
497 | + return $this->_active_message_types; |
|
498 | + } |
|
499 | + |
|
500 | + |
|
501 | + /** |
|
502 | + * Used to update the active messengers array stored in the wp options table. |
|
503 | + * |
|
504 | + * @param array $active_messenger_settings Incoming data to save. If empty, then the internal cached property |
|
505 | + * representing this data is used. |
|
506 | + * @return bool FALSE if not updated, TRUE if updated. |
|
507 | + */ |
|
508 | + public function update_active_messengers_option($active_messenger_settings = []) |
|
509 | + { |
|
510 | + $active_messenger_settings = empty($active_messenger_settings) |
|
511 | + ? $this->_active_message_types |
|
512 | + : $active_messenger_settings; |
|
513 | + // make sure _active_message_types is updated (this is the internal cache for the settings). |
|
514 | + $this->_active_message_types = $active_messenger_settings; |
|
515 | + return update_option('ee_active_messengers', $active_messenger_settings); |
|
516 | + } |
|
517 | + |
|
518 | + |
|
519 | + /** |
|
520 | + * Used to return has activated message types for messengers array stored in the wp options table. |
|
521 | + * If no value is present in the option then an empty array is returned. |
|
522 | + * The value is cached on the $_has_activated_messengers_and_message_types property for future calls. |
|
523 | + * |
|
524 | + * @param bool $reset Used to indicate that any cached value should be ignored. |
|
525 | + * @return array |
|
526 | + * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
527 | + * details. |
|
528 | + */ |
|
529 | + public function get_has_activated_messengers_option($reset = false) |
|
530 | + { |
|
531 | + if ($reset || empty($this->_has_activated_messengers_and_message_types)) { |
|
532 | + $this->_has_activated_messengers_and_message_types = |
|
533 | + get_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, []); |
|
534 | + } |
|
535 | + return $this->_has_activated_messengers_and_message_types; |
|
536 | + } |
|
537 | + |
|
538 | + |
|
539 | + /** |
|
540 | + * Used to update the has activated option in the db. |
|
541 | + * |
|
542 | + * @param array $has_activated_messengers Incoming data to save. If empty, then the internal cached property |
|
543 | + * representing this data is used. |
|
544 | + * @return bool FALSE if not updated, TRUE if updated. |
|
545 | + * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
546 | + * details. |
|
547 | + */ |
|
548 | + public function update_has_activated_messengers_option($has_activated_messengers = []) |
|
549 | + { |
|
550 | + // make sure the option has been retrieved from first so we don't overwrite it accidentally. |
|
551 | + if (empty($has_activated_messengers) && empty($this->_has_activated_messengers_and_message_types)) { |
|
552 | + $this->get_has_activated_messengers_option(); |
|
553 | + } |
|
554 | + $has_activated_messengers = empty($has_activated_messengers) |
|
555 | + ? $this->_has_activated_messengers_and_message_types |
|
556 | + : $has_activated_messengers; |
|
557 | + return update_option(self::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME, $has_activated_messengers); |
|
558 | + } |
|
559 | + |
|
560 | + |
|
561 | + /** |
|
562 | + * wrapper for _set_active_messengers_and_message_types() |
|
563 | + */ |
|
564 | + public function reset_active_messengers_and_message_types() |
|
565 | + { |
|
566 | + $this->_set_active_messengers_and_message_types(); |
|
567 | + } |
|
568 | + |
|
569 | + |
|
570 | + /** |
|
571 | + * Generate list of active messengers and message types from collection. |
|
572 | + * This sets up the active messengers from what is present in the database. |
|
573 | + */ |
|
574 | + protected function _set_active_messengers_and_message_types() |
|
575 | + { |
|
576 | + // echo "\n\n " . __LINE__ . ") " . __METHOD__ . "() \n"; |
|
577 | + // list of activated messengers as set via the admin |
|
578 | + // note calling `get_active_messengers_options` also initializes the _active_message_types property. |
|
579 | + $this->get_active_messengers_option(true); |
|
580 | + $this->ensure_messengers_are_active([], false, true); |
|
581 | + $this->update_active_messengers_option(); |
|
582 | + $this->update_has_activated_messengers_option(); |
|
583 | + } |
|
584 | + |
|
585 | + |
|
586 | + /** |
|
587 | + * Ensures that the specified messenger is currently active. |
|
588 | + * If not, activates it and its default message types. |
|
589 | + * |
|
590 | + * @param string $messenger_name |
|
591 | + * @param bool $update_option Whether to update the option in the db or not. |
|
592 | + * @return boolean true if either already active or successfully activated. |
|
593 | + */ |
|
594 | + public function ensure_messenger_is_active($messenger_name, $update_option = true) |
|
595 | + { |
|
596 | + if (! isset($this->_active_messengers[ $messenger_name ])) { |
|
597 | + try { |
|
598 | + $this->activate_messenger($messenger_name, [], $update_option); |
|
599 | + } catch (EE_Error $e) { |
|
600 | + EE_Error::add_error( |
|
601 | + $e->getMessage(), |
|
602 | + __FILE__, |
|
603 | + __FUNCTION__, |
|
604 | + __LINE__ |
|
605 | + ); |
|
606 | + return false; |
|
607 | + } |
|
608 | + } |
|
609 | + return true; |
|
610 | + } |
|
611 | + |
|
612 | + |
|
613 | + /** |
|
614 | + * This ensures the given array of messenger names is active in the system. |
|
615 | + * Note, this method will not activate any NEW message types for the messenger when it is called. Instead, |
|
616 | + * it will automatically activate the default message types for the messenger if its not active. |
|
617 | + * |
|
618 | + * @param array $messenger_names Array of messenger names for messengers to be activated. If an empty array |
|
619 | + * (default) then will attempt to set the active messengers from the |
|
620 | + * activated_messengers option |
|
621 | + * (stored in $_active_message_types property). |
|
622 | + * @param bool $update_option Whether to update the related active messengers option. |
|
623 | + * @param bool $verify Whether to verify the messengers are installed before activating. Note if this is |
|
624 | + * set to true and a messenger is indicated as active, but is NOT installed, then it |
|
625 | + * will automatically be deactivated. |
|
626 | + */ |
|
627 | + public function ensure_messengers_are_active($messenger_names = [], $update_option = true, $verify = false) |
|
628 | + { |
|
629 | + $messenger_names = empty($messenger_names) |
|
630 | + ? array_keys($this->_active_message_types) |
|
631 | + : $messenger_names; |
|
632 | + |
|
633 | + $not_installed = []; |
|
634 | + foreach ($messenger_names as $messenger_name) { |
|
635 | + if ($verify && ! $this->messenger_collection()->has_by_name($messenger_name)) { |
|
636 | + $not_installed[] = $messenger_name; |
|
637 | + $this->deactivate_messenger($messenger_name); |
|
638 | + continue; |
|
639 | + } |
|
640 | + $this->ensure_messenger_is_active($messenger_name, $update_option); |
|
641 | + } |
|
642 | + |
|
643 | + if (! empty($not_installed)) { |
|
644 | + EE_Error::add_error( |
|
645 | + sprintf( |
|
646 | + esc_html__( |
|
647 | + 'The following messengers are either not installed or are invalid:%1$s %2$s', |
|
648 | + 'event_espresso' |
|
649 | + ), |
|
650 | + '<br />', |
|
651 | + implode(', ', $not_installed) |
|
652 | + ), |
|
653 | + __FILE__, |
|
654 | + __FUNCTION__, |
|
655 | + __LINE__ |
|
656 | + ); |
|
657 | + } |
|
658 | + } |
|
659 | + |
|
660 | + |
|
661 | + /** |
|
662 | + * Ensures that the specified message type for the given messenger is currently active, if not activates it. |
|
663 | + * This ALSO ensures that the given messenger is active as well! |
|
664 | + * |
|
665 | + * @param string $message_type_name message type name. |
|
666 | + * @param $messenger_name |
|
667 | + * @param bool $update_option Whether to update the option in the db or not. |
|
668 | + * @return bool Returns true if already is active or if was activated successfully. |
|
669 | + * @throws EE_Error |
|
670 | + */ |
|
671 | + public function ensure_message_type_is_active($message_type_name, $messenger_name, $update_option = true) |
|
672 | + { |
|
673 | + // grab the messenger to work with. |
|
674 | + $messenger = $this->valid_messenger($messenger_name); |
|
675 | + if ($this->valid_message_type_for_messenger($messenger, $message_type_name)) { |
|
676 | + // ensure messenger is active (that's an inherent coupling between active message types and the |
|
677 | + // messenger they are being activated for. |
|
678 | + try { |
|
679 | + if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
680 | + // all is good so let's just get it active |
|
681 | + $this->activate_messenger($messenger, [$message_type_name], $update_option); |
|
682 | + } |
|
683 | + } catch (EE_Error $e) { |
|
684 | + EE_Error::add_error( |
|
685 | + $e->getMessage(), |
|
686 | + __FILE__, |
|
687 | + __FUNCTION__, |
|
688 | + __LINE__ |
|
689 | + ); |
|
690 | + return false; |
|
691 | + } |
|
692 | + } |
|
693 | + return true; |
|
694 | + } |
|
695 | + |
|
696 | + |
|
697 | + /** |
|
698 | + * This is a wrapper for `ensure_message_type_is_active` that will handle ensuring multiple message types for a |
|
699 | + * messenger are active in one go. |
|
700 | + * |
|
701 | + * @param array $message_type_names Array of message type names to ensure are active. |
|
702 | + * @param string $messenger_name The name of the messenger that the message types are to be activated on. |
|
703 | + * @param bool $update_option Whether to persist the activation to the database or not (default true). |
|
704 | + */ |
|
705 | + public function ensure_message_types_are_active($message_type_names, $messenger_name, $update_option = true) |
|
706 | + { |
|
707 | + $message_type_names = (array) $message_type_names; |
|
708 | + foreach ($message_type_names as $message_type_name) { |
|
709 | + // note, intentionally not updating option here because we're in a loop. |
|
710 | + // We'll follow the instructions of the incoming $update_option argument after the loop. |
|
711 | + $this->ensure_message_type_is_active($message_type_name, $messenger_name, false); |
|
712 | + } |
|
713 | + if ($update_option) { |
|
714 | + $this->update_active_messengers_option(); |
|
715 | + $this->update_has_activated_messengers_option(); |
|
716 | + } |
|
717 | + } |
|
718 | + |
|
719 | + |
|
720 | + /** |
|
721 | + * Activates the specified messenger. |
|
722 | + * |
|
723 | + * @param EE_messenger|string $messenger Instantiated EE_messenger OR messenger name if not already loaded! |
|
724 | + * @param array $message_type_names An array of message type names to activate with this messenger. |
|
725 | + * If included we do NOT setup the default message types |
|
726 | + * (assuming they are already setup.) |
|
727 | + * @param bool $update_active_messengers_option |
|
728 | + * @return array of generated templates |
|
729 | + * @throws EE_Error |
|
730 | + */ |
|
731 | + public function activate_messenger( |
|
732 | + $messenger, |
|
733 | + $message_type_names = [], |
|
734 | + $update_active_messengers_option = true |
|
735 | + ) { |
|
736 | + $templates = []; |
|
737 | + // grab the messenger to work with. |
|
738 | + $messenger = $messenger instanceof EE_messenger |
|
739 | + ? $messenger |
|
740 | + : $this->messenger_collection()->get_by_info($messenger); |
|
741 | + // it's inactive. Activate it. |
|
742 | + if ($messenger instanceof EE_messenger) { |
|
743 | + $this->_active_messengers[ $messenger->name ] = $messenger; |
|
744 | + // activate incoming message types set to be activated with messenger. |
|
745 | + $message_type_names = $this->_activate_message_types($messenger, $message_type_names); |
|
746 | + // setup any initial settings for the messenger if necessary. |
|
747 | + $this->add_settings_for_messenger($messenger->name); |
|
748 | + if ($update_active_messengers_option) { |
|
749 | + $this->update_active_messengers_option(); |
|
750 | + $this->update_has_activated_messengers_option(); |
|
751 | + } |
|
752 | + // generate new templates if necessary and ensure all related templates that are already in the database are |
|
753 | + // marked active. Note, this will also deactivate a message type for a messenger if the template |
|
754 | + // cannot be successfully created during its attempt (only happens for global template attempts). |
|
755 | + if (! empty($message_type_names)) { |
|
756 | + $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true); |
|
757 | + EEH_MSG_Template::update_to_active([$messenger->name], $message_type_names); |
|
758 | + } |
|
759 | + } |
|
760 | + return $templates; |
|
761 | + } |
|
762 | + |
|
763 | + |
|
764 | + /** |
|
765 | + * Activates given message types for the given EE_messenger object. |
|
766 | + * Note: (very important) This method does not persist the activation to the database. |
|
767 | + * See code implementing this method in this class for examples of how to persist. |
|
768 | + * |
|
769 | + * @param \EE_messenger $messenger |
|
770 | + * @param array $message_type_names |
|
771 | + * @return array |
|
772 | + */ |
|
773 | + protected function _activate_message_types(EE_messenger $messenger, $message_type_names = []) |
|
774 | + { |
|
775 | + // If $message_type_names is empty, AND $this->_active_message_types is empty, then that means |
|
776 | + // things have never been initialized (which should happen on EEH_Activation::generate_message_templates). |
|
777 | + // So ONLY then do we need to actually grab defaults and cycle through them. Otherwise we |
|
778 | + // only override _active_message_types when an explicit array of $message_type_names has been provided. |
|
779 | + $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ]) |
|
780 | + ? $messenger->get_default_message_types() |
|
781 | + : (array) $message_type_names; |
|
782 | + |
|
783 | + // now we ALWAYS need to make sure that the messenger is active for the message types we're activating! |
|
784 | + if (! isset($this->_active_message_types[ $messenger->name ])) { |
|
785 | + $this->_active_message_types[ $messenger->name ]['settings'] = []; |
|
786 | + } |
|
787 | + |
|
788 | + if ($message_type_names) { |
|
789 | + // cycle thru message types |
|
790 | + foreach ($message_type_names as $message_type_name) { |
|
791 | + // only register the message type as active IF it isn't already active |
|
792 | + // and if its actually installed. |
|
793 | + if ( |
|
794 | + ! $this->is_message_type_active_for_messenger($messenger->name, $message_type_name) |
|
795 | + ) { |
|
796 | + $this->add_settings_for_message_type($messenger->name, $message_type_name); |
|
797 | + $this->_set_messenger_has_activated_message_type( |
|
798 | + $messenger, |
|
799 | + $message_type_name |
|
800 | + ); |
|
801 | + } |
|
802 | + } |
|
803 | + } |
|
804 | + return $message_type_names; |
|
805 | + } |
|
806 | + |
|
807 | + |
|
808 | + /** |
|
809 | + * add_settings_for_message_type |
|
810 | + * NOTE This does NOT automatically persist any settings to the db. Client code should call |
|
811 | + * $this->update_active_messengers_option to persist. |
|
812 | + * |
|
813 | + * @param string $messenger_name The name of the messenger adding the settings for |
|
814 | + * @param string $message_type_name The name of the message type adding the settings for |
|
815 | + * @param array $new_settings Any new settings being set for the message type and messenger |
|
816 | + */ |
|
817 | + public function add_settings_for_message_type($messenger_name, $message_type_name, $new_settings = []) |
|
818 | + { |
|
819 | + // get installed message type from collection |
|
820 | + $message_type = $this->message_type_collection()->get_by_info($message_type_name); |
|
821 | + $existing_settings = $this->get_message_type_settings_for_messenger($messenger_name, $message_type_name); |
|
822 | + // we need to setup any initial settings for message types |
|
823 | + if ($message_type instanceof EE_message_type) { |
|
824 | + $default_settings = $message_type->get_admin_settings_fields(); |
|
825 | + foreach ($default_settings as $field => $values) { |
|
826 | + if (isset($new_settings[ $field ])) { |
|
827 | + $existing_settings[ $field ] = $new_settings[ $field ]; |
|
828 | + continue; |
|
829 | + } |
|
830 | + if (! isset($existing_settings[ $field ])) { |
|
831 | + $existing_settings[ $field ] = $values['default']; |
|
832 | + } |
|
833 | + } |
|
834 | + } |
|
835 | + $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = |
|
836 | + $existing_settings; |
|
837 | + } |
|
838 | + |
|
839 | + |
|
840 | + /** |
|
841 | + * Updates the internal cached _has_activated_messengers_and_message_types property with the given messenger |
|
842 | + * and message type. |
|
843 | + * |
|
844 | + * @param \EE_messenger $messenger |
|
845 | + * @param string $message_type_name |
|
846 | + * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
847 | + * details. |
|
848 | + * @access protected |
|
849 | + */ |
|
850 | + protected function _set_messenger_has_activated_message_type(EE_messenger $messenger, $message_type_name) |
|
851 | + { |
|
852 | + // if _has_activated_messengers_and_message_types is empty then lets ensure its initialized |
|
853 | + if (empty($this->_has_activated_messengers_and_message_types)) { |
|
854 | + $this->get_has_activated_messengers_option(); |
|
855 | + } |
|
856 | + |
|
857 | + // make sure this messenger has a record in the has_activated array |
|
858 | + if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) { |
|
859 | + $this->_has_activated_messengers_and_message_types[ $messenger->name ] = []; |
|
860 | + } |
|
861 | + // check if message type has already been added |
|
862 | + if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) { |
|
863 | + $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name; |
|
864 | + } |
|
865 | + } |
|
866 | + |
|
867 | + |
|
868 | + /** |
|
869 | + * add_settings_for_messenger |
|
870 | + * NOTE This does NOT automatically persist any settings to the db. Client code should call |
|
871 | + * $this->update_active_messengers_option to persist. |
|
872 | + * |
|
873 | + * @param string $messenger_name The name of the messenger the settings is being added for. |
|
874 | + * @param array $new_settings An array of settings to update the existing settings. |
|
875 | + */ |
|
876 | + public function add_settings_for_messenger($messenger_name, $new_settings = []) |
|
877 | + { |
|
878 | + $messenger = $this->get_messenger($messenger_name); |
|
879 | + if ($messenger instanceof EE_messenger) { |
|
880 | + $msgr_settings = $messenger->get_admin_settings_fields(); |
|
881 | + if (! empty($msgr_settings)) { |
|
882 | + foreach ($msgr_settings as $field => $value) { |
|
883 | + // is there a new setting for this? |
|
884 | + if (isset($new_settings[ $field ])) { |
|
885 | + $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = |
|
886 | + $new_settings[ $field ]; |
|
887 | + continue; |
|
888 | + } |
|
889 | + // only set the default if it isn't already set. |
|
890 | + if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) { |
|
891 | + $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value; |
|
892 | + } |
|
893 | + } |
|
894 | + } |
|
895 | + } |
|
896 | + } |
|
897 | + |
|
898 | + |
|
899 | + /** |
|
900 | + * deactivate_messenger |
|
901 | + * |
|
902 | + * @param string|EE_messenger $messenger_name name of messenger |
|
903 | + * @return void |
|
904 | + */ |
|
905 | + public function deactivate_messenger($messenger_name) |
|
906 | + { |
|
907 | + $this->_initialize_collections(); |
|
908 | + if ($messenger_name instanceof EE_messenger) { |
|
909 | + $messenger_name = $messenger_name->name; |
|
910 | + } |
|
911 | + unset($this->_active_messengers[ $messenger_name ]); |
|
912 | + unset($this->_active_message_types[ $messenger_name ]); |
|
913 | + $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name); |
|
914 | + $this->update_active_messengers_option(); |
|
915 | + } |
|
916 | + |
|
917 | + |
|
918 | + /** |
|
919 | + * Deactivates a message type (note this will deactivate across all messenger's it is active on. |
|
920 | + * |
|
921 | + * @param string $message_type_name name of message type being deactivated |
|
922 | + * @param bool $set_has_active_record By default we always record the has_active record when deactivating a |
|
923 | + * message type. However, this can be overridden if we don't want this set |
|
924 | + * (usually when this is called as a part of deregistration of a custom |
|
925 | + * message type) |
|
926 | + */ |
|
927 | + public function deactivate_message_type($message_type_name, $set_has_active_record = true) |
|
928 | + { |
|
929 | + $this->_initialize_collections(); |
|
930 | + if ($message_type_name instanceof EE_message_type) { |
|
931 | + $message_type_name = $message_type_name->name; |
|
932 | + } |
|
933 | + foreach ($this->_active_message_types as $messenger_name => $settings) { |
|
934 | + unset( |
|
935 | + $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ] |
|
936 | + ); |
|
937 | + |
|
938 | + // we always record (even on deactivation) that a message type has been activated because there should at |
|
939 | + // least be a record in the "has_activated" option that it WAS active at one point. |
|
940 | + if ($set_has_active_record) { |
|
941 | + $messenger = $this->get_messenger($messenger_name); |
|
942 | + $this->_set_messenger_has_activated_message_type($messenger, $message_type_name); |
|
943 | + } |
|
944 | + } |
|
945 | + $this->_message_template_group_model->deactivate_message_template_groups_for('', $message_type_name); |
|
946 | + $this->update_active_messengers_option(); |
|
947 | + $this->update_has_activated_messengers_option(); |
|
948 | + } |
|
949 | + |
|
950 | + |
|
951 | + /** |
|
952 | + * Deactivates a message type for a specific messenger as opposed to all messengers. |
|
953 | + * |
|
954 | + * @param string $message_type_name Name of message type being deactivated. |
|
955 | + * @param string $messenger_name Name of messenger the message type is being deactivated for. |
|
956 | + */ |
|
957 | + public function deactivate_message_type_for_messenger($message_type_name, $messenger_name) |
|
958 | + { |
|
959 | + $this->_initialize_collections(); |
|
960 | + if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
961 | + unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]); |
|
962 | + } |
|
963 | + $this->_message_template_group_model->deactivate_message_template_groups_for( |
|
964 | + [$messenger_name], |
|
965 | + [$message_type_name] |
|
966 | + ); |
|
967 | + $this->update_active_messengers_option(); |
|
968 | + } |
|
969 | + |
|
970 | + |
|
971 | + /** |
|
972 | + * Used to verify if a message can be sent for the given messenger and message type |
|
973 | + * and that it is a generating messenger (used for generating message templates). |
|
974 | + * |
|
975 | + * @param EE_messenger $messenger messenger used in trigger |
|
976 | + * @param EE_message_type $message_type message type used in trigger |
|
977 | + * @return bool true is a generating messenger and can be sent OR FALSE meaning cannot send. |
|
978 | + */ |
|
979 | + public function is_generating_messenger_and_active(EE_messenger $messenger, EE_message_type $message_type) |
|
980 | + { |
|
981 | + // get the $messengers the message type says it can be used with. |
|
982 | + foreach ($message_type->with_messengers() as $generating_messenger => $secondary_messengers) { |
|
983 | + if ( |
|
984 | + $messenger->name === $generating_messenger |
|
985 | + && $this->is_message_type_active_for_messenger($messenger->name, $message_type->name) |
|
986 | + ) { |
|
987 | + return true; |
|
988 | + } |
|
989 | + } |
|
990 | + return false; |
|
991 | + } |
|
992 | + |
|
993 | + |
|
994 | + /** |
|
995 | + * This returns all the contexts that are registered by all message types. |
|
996 | + * If $slugs_only is true, |
|
997 | + * then just an array indexed by unique context slugs with the latest label representation for that slug. |
|
998 | + * array( |
|
999 | + * 'context_slug' => 'localized label for context obtained from latest message type in the loop'. |
|
1000 | + * ); |
|
1001 | + * If $slugs_only is false, then the format is: |
|
1002 | + * array( |
|
1003 | + * 'message_type_name' => array( |
|
1004 | + * 'context_slug' => array( |
|
1005 | + * 'label' => 'localized label for context', |
|
1006 | + * 'description' => 'localized description for context' |
|
1007 | + * ) |
|
1008 | + * ) |
|
1009 | + * ); |
|
1010 | + * Keep in mind that although different message types may share the same context slugs, |
|
1011 | + * it is possible that the context is described differently by the message type. |
|
1012 | + * |
|
1013 | + * @param bool $slugs_only Whether to return an array of just slugs and labels (true) |
|
1014 | + * or all contexts indexed by message type. |
|
1015 | + * @return array |
|
1016 | + * @since 4.9.0 |
|
1017 | + */ |
|
1018 | + public function get_all_contexts($slugs_only = true) |
|
1019 | + { |
|
1020 | + $key = $slugs_only |
|
1021 | + ? 'slugs' |
|
1022 | + : 'all'; |
|
1023 | + // check if contexts has been setup yet. |
|
1024 | + if (empty($this->_contexts[ $key ])) { |
|
1025 | + // So let's get all active message type objects and loop through to get all unique contexts |
|
1026 | + foreach ($this->get_active_message_type_objects() as $message_type) { |
|
1027 | + if ($message_type instanceof EE_message_type) { |
|
1028 | + $message_type_contexts = $message_type->get_contexts(); |
|
1029 | + if ($slugs_only) { |
|
1030 | + foreach ($message_type_contexts as $context => $context_details) { |
|
1031 | + $this->_contexts[ $key ][ $context ] = $context_details['label']; |
|
1032 | + } |
|
1033 | + } else { |
|
1034 | + $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts; |
|
1035 | + } |
|
1036 | + } |
|
1037 | + } |
|
1038 | + } |
|
1039 | + return ! empty($this->_contexts[ $key ]) |
|
1040 | + ? $this->_contexts[ $key ] |
|
1041 | + : []; |
|
1042 | + } |
|
1043 | + |
|
1044 | + |
|
1045 | + /** |
|
1046 | + * This checks the internal record of what message types are considered "active" and verifies that |
|
1047 | + * there is an installed class definition for that message type. If the active message type does not have a |
|
1048 | + * corresponding accessible message type class then it will be deactivated from all messengers it is active on and |
|
1049 | + * any related message templates will be inactivated as well. |
|
1050 | + * |
|
1051 | + * @return bool true means all active message types are valid, false means at least one message type was |
|
1052 | + * deactivated. |
|
1053 | + */ |
|
1054 | + public function validate_active_message_types_are_installed() |
|
1055 | + { |
|
1056 | + $list_of_active_message_type_names = $this->list_of_active_message_types(); |
|
1057 | + $installed_message_types = $this->installed_message_types(); |
|
1058 | + $all_message_types_valid = true; |
|
1059 | + // loop through list of active message types and verify they are installed. |
|
1060 | + foreach ($list_of_active_message_type_names as $message_type_name) { |
|
1061 | + if (! isset($installed_message_types[ $message_type_name ])) { |
|
1062 | + $this->remove_message_type_has_been_activated_from_all_messengers( |
|
1063 | + $message_type_name, |
|
1064 | + true |
|
1065 | + ); |
|
1066 | + $this->deactivate_message_type($message_type_name, false); |
|
1067 | + $all_message_types_valid = false; |
|
1068 | + } |
|
1069 | + } |
|
1070 | + return $all_message_types_valid; |
|
1071 | + } |
|
1072 | + |
|
1073 | + |
|
1074 | + /** |
|
1075 | + * This method checks the `ee_has_activated_messenger` option to see if the message type has ever been |
|
1076 | + * activated for the given messenger. This can be called by client code on plugin updates etc to determine whether |
|
1077 | + * to attempt automatically reactivating message types that should be activated by default or not. |
|
1078 | + * |
|
1079 | + * @param $message_type_name |
|
1080 | + * @param $messenger_name |
|
1081 | + * @return bool |
|
1082 | + * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
1083 | + * details. |
|
1084 | + */ |
|
1085 | + public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name) |
|
1086 | + { |
|
1087 | + $has_activated = $this->get_has_activated_messengers_option(); |
|
1088 | + return isset($has_activated[ $messenger_name ]) |
|
1089 | + && in_array($message_type_name, $has_activated[ $messenger_name ]); |
|
1090 | + } |
|
1091 | + |
|
1092 | + |
|
1093 | + /** |
|
1094 | + * This method unsets a message type from the given messenger has activated option. |
|
1095 | + * |
|
1096 | + * @param string $message_type_name |
|
1097 | + * @param string $messenger_name |
|
1098 | + * @param bool $consider_current_state Whether to consider whether the message type is currently active or not. |
|
1099 | + * If it is currently active, then remove. Otherwise leave it alone. |
|
1100 | + * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
1101 | + * details. |
|
1102 | + */ |
|
1103 | + public function remove_message_type_has_been_activated_for_messenger( |
|
1104 | + $message_type_name, |
|
1105 | + $messenger_name, |
|
1106 | + $consider_current_state = false |
|
1107 | + ) { |
|
1108 | + if ( |
|
1109 | + $consider_current_state |
|
1110 | + && ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name) |
|
1111 | + ) { |
|
1112 | + // when consider current state is true, this means we don't want to change anything on the "has_activated" |
|
1113 | + // record if the message type is currently active for this messenger. This is used when we want to retain |
|
1114 | + // the record for user initiated inactivations of the message type. |
|
1115 | + return; |
|
1116 | + } |
|
1117 | + $has_activated = $this->get_has_activated_messengers_option(); |
|
1118 | + $key_for_message_type = isset($has_activated[ $messenger_name ]) |
|
1119 | + ? array_search($message_type_name, $has_activated[ $messenger_name ], true) |
|
1120 | + : false; |
|
1121 | + if ($key_for_message_type !== false) { |
|
1122 | + unset($has_activated[ $messenger_name ][ $key_for_message_type ]); |
|
1123 | + $this->update_has_activated_messengers_option($has_activated); |
|
1124 | + // reset the internal cached property |
|
1125 | + $this->get_has_activated_messengers_option(true); |
|
1126 | + } |
|
1127 | + } |
|
1128 | + |
|
1129 | + |
|
1130 | + /** |
|
1131 | + * Removes a message type active record from all messengers it is attached to. |
|
1132 | + * |
|
1133 | + * @param $message_type_name |
|
1134 | + * @param bool $consider_current_state Whether to consider whether the message type is currently active or not. |
|
1135 | + * If it is currently active, then remove. Otherwise leave it alone. |
|
1136 | + * @see phpdocs on EE_Message_Resource_Manager::HAS_ACTIVATED_MESSAGE_TYPE_FOR_MESSENGER_OPTION_NAME for more |
|
1137 | + * details. |
|
1138 | + */ |
|
1139 | + public function remove_message_type_has_been_activated_from_all_messengers( |
|
1140 | + $message_type_name, |
|
1141 | + $consider_current_state = false |
|
1142 | + ) { |
|
1143 | + foreach (array_keys($this->get_has_activated_messengers_option()) as $messenger_name) { |
|
1144 | + $this->remove_message_type_has_been_activated_for_messenger( |
|
1145 | + $message_type_name, |
|
1146 | + $messenger_name, |
|
1147 | + $consider_current_state |
|
1148 | + ); |
|
1149 | + } |
|
1150 | + } |
|
1151 | 1151 | } |
@@ -193,8 +193,8 @@ discard block |
||
193 | 193 | public function get_active_messenger($messenger) |
194 | 194 | { |
195 | 195 | $this->_initialize_collections(); |
196 | - return ! empty($this->_active_messengers[ $messenger ]) |
|
197 | - ? $this->_active_messengers[ $messenger ] |
|
196 | + return ! empty($this->_active_messengers[$messenger]) |
|
197 | + ? $this->_active_messengers[$messenger] |
|
198 | 198 | : null; |
199 | 199 | } |
200 | 200 | |
@@ -208,7 +208,7 @@ discard block |
||
208 | 208 | $this->_installed_messengers = []; |
209 | 209 | $this->messenger_collection()->rewind(); |
210 | 210 | while ($this->messenger_collection()->valid()) { |
211 | - $this->_installed_messengers[ $this->messenger_collection()->current()->name ] = |
|
211 | + $this->_installed_messengers[$this->messenger_collection()->current()->name] = |
|
212 | 212 | $this->messenger_collection()->current(); |
213 | 213 | $this->messenger_collection()->next(); |
214 | 214 | } |
@@ -292,7 +292,7 @@ discard block |
||
292 | 292 | public function is_message_type_active_for_messenger($messenger_name, $message_type_name) |
293 | 293 | { |
294 | 294 | $this->_initialize_collections(); |
295 | - return ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]); |
|
295 | + return ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]); |
|
296 | 296 | } |
297 | 297 | |
298 | 298 | |
@@ -305,7 +305,7 @@ discard block |
||
305 | 305 | public function is_messenger_active($messenger_name) |
306 | 306 | { |
307 | 307 | $this->_initialize_collections(); |
308 | - return ! empty($this->_active_message_types[ $messenger_name ]); |
|
308 | + return ! empty($this->_active_message_types[$messenger_name]); |
|
309 | 309 | } |
310 | 310 | |
311 | 311 | |
@@ -321,8 +321,8 @@ discard block |
||
321 | 321 | $settings = []; |
322 | 322 | if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
323 | 323 | $settings = |
324 | - isset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings']) |
|
325 | - ? $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] |
|
324 | + isset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings']) |
|
325 | + ? $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'] |
|
326 | 326 | : []; |
327 | 327 | } |
328 | 328 | return $settings; |
@@ -340,8 +340,8 @@ discard block |
||
340 | 340 | { |
341 | 341 | $this->_initialize_collections(); |
342 | 342 | return |
343 | - ! empty($this->_active_message_types[ $messenger_name ]) |
|
344 | - && ! empty($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ]); |
|
343 | + ! empty($this->_active_message_types[$messenger_name]) |
|
344 | + && ! empty($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types']); |
|
345 | 345 | } |
346 | 346 | |
347 | 347 | |
@@ -356,13 +356,13 @@ discard block |
||
356 | 356 | public function get_active_message_types_for_messenger($messenger_name) |
357 | 357 | { |
358 | 358 | $message_types = []; |
359 | - if (! $this->messenger_has_active_message_types($messenger_name)) { |
|
359 | + if ( ! $this->messenger_has_active_message_types($messenger_name)) { |
|
360 | 360 | return $message_types; |
361 | 361 | } |
362 | 362 | $installed_message_types = $this->installed_message_types(); |
363 | 363 | foreach ($installed_message_types as $message_type_name => $message_type) { |
364 | 364 | if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
365 | - $message_types[ $message_type_name ] = $message_type; |
|
365 | + $message_types[$message_type_name] = $message_type; |
|
366 | 366 | } |
367 | 367 | } |
368 | 368 | return $message_types; |
@@ -381,11 +381,11 @@ discard block |
||
381 | 381 | $active_message_type_names = []; |
382 | 382 | $this->_initialize_collections(); |
383 | 383 | foreach ($this->_active_message_types as $messenger => $messenger_settings) { |
384 | - if (! isset($messenger_settings['settings'][ $messenger . '-message_types' ])) { |
|
384 | + if ( ! isset($messenger_settings['settings'][$messenger.'-message_types'])) { |
|
385 | 385 | continue; |
386 | 386 | } |
387 | - foreach ($messenger_settings['settings'][ $messenger . '-message_types' ] as $message_type_name => $message_type_config) { |
|
388 | - if (! in_array($message_type_name, $active_message_type_names)) { |
|
387 | + foreach ($messenger_settings['settings'][$messenger.'-message_types'] as $message_type_name => $message_type_config) { |
|
388 | + if ( ! in_array($message_type_name, $active_message_type_names)) { |
|
389 | 389 | $active_message_type_names[] = $message_type_name; |
390 | 390 | } |
391 | 391 | } |
@@ -406,9 +406,9 @@ discard block |
||
406 | 406 | $installed_message_types = $this->installed_message_types(); |
407 | 407 | $active_message_type_names = $this->list_of_active_message_types(); |
408 | 408 | foreach ($active_message_type_names as $active_message_type_name) { |
409 | - if (isset($installed_message_types[ $active_message_type_name ])) { |
|
410 | - $active_message_types[ $active_message_type_name ] = |
|
411 | - $installed_message_types[ $active_message_type_name ]; |
|
409 | + if (isset($installed_message_types[$active_message_type_name])) { |
|
410 | + $active_message_types[$active_message_type_name] = |
|
411 | + $installed_message_types[$active_message_type_name]; |
|
412 | 412 | } |
413 | 413 | } |
414 | 414 | return $active_message_types; |
@@ -423,7 +423,7 @@ discard block |
||
423 | 423 | if (empty($this->_installed_message_types)) { |
424 | 424 | $this->message_type_collection()->rewind(); |
425 | 425 | while ($this->message_type_collection()->valid()) { |
426 | - $this->_installed_message_types[ $this->message_type_collection()->current()->name ] = |
|
426 | + $this->_installed_message_types[$this->message_type_collection()->current()->name] = |
|
427 | 427 | $this->message_type_collection()->current(); |
428 | 428 | $this->message_type_collection()->next(); |
429 | 429 | } |
@@ -463,7 +463,7 @@ discard block |
||
463 | 463 | public function valid_message_type_for_messenger(EE_messenger $messenger, $message_type_name) |
464 | 464 | { |
465 | 465 | $valid_message_types = $messenger->get_valid_message_types(); |
466 | - if (! in_array($message_type_name, $valid_message_types)) { |
|
466 | + if ( ! in_array($message_type_name, $valid_message_types)) { |
|
467 | 467 | throw new EE_Error( |
468 | 468 | sprintf( |
469 | 469 | esc_html__( |
@@ -593,7 +593,7 @@ discard block |
||
593 | 593 | */ |
594 | 594 | public function ensure_messenger_is_active($messenger_name, $update_option = true) |
595 | 595 | { |
596 | - if (! isset($this->_active_messengers[ $messenger_name ])) { |
|
596 | + if ( ! isset($this->_active_messengers[$messenger_name])) { |
|
597 | 597 | try { |
598 | 598 | $this->activate_messenger($messenger_name, [], $update_option); |
599 | 599 | } catch (EE_Error $e) { |
@@ -640,7 +640,7 @@ discard block |
||
640 | 640 | $this->ensure_messenger_is_active($messenger_name, $update_option); |
641 | 641 | } |
642 | 642 | |
643 | - if (! empty($not_installed)) { |
|
643 | + if ( ! empty($not_installed)) { |
|
644 | 644 | EE_Error::add_error( |
645 | 645 | sprintf( |
646 | 646 | esc_html__( |
@@ -676,7 +676,7 @@ discard block |
||
676 | 676 | // ensure messenger is active (that's an inherent coupling between active message types and the |
677 | 677 | // messenger they are being activated for. |
678 | 678 | try { |
679 | - if (! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
679 | + if ( ! $this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
|
680 | 680 | // all is good so let's just get it active |
681 | 681 | $this->activate_messenger($messenger, [$message_type_name], $update_option); |
682 | 682 | } |
@@ -740,7 +740,7 @@ discard block |
||
740 | 740 | : $this->messenger_collection()->get_by_info($messenger); |
741 | 741 | // it's inactive. Activate it. |
742 | 742 | if ($messenger instanceof EE_messenger) { |
743 | - $this->_active_messengers[ $messenger->name ] = $messenger; |
|
743 | + $this->_active_messengers[$messenger->name] = $messenger; |
|
744 | 744 | // activate incoming message types set to be activated with messenger. |
745 | 745 | $message_type_names = $this->_activate_message_types($messenger, $message_type_names); |
746 | 746 | // setup any initial settings for the messenger if necessary. |
@@ -752,7 +752,7 @@ discard block |
||
752 | 752 | // generate new templates if necessary and ensure all related templates that are already in the database are |
753 | 753 | // marked active. Note, this will also deactivate a message type for a messenger if the template |
754 | 754 | // cannot be successfully created during its attempt (only happens for global template attempts). |
755 | - if (! empty($message_type_names)) { |
|
755 | + if ( ! empty($message_type_names)) { |
|
756 | 756 | $templates = EEH_MSG_Template::generate_new_templates($messenger->name, $message_type_names, 0, true); |
757 | 757 | EEH_MSG_Template::update_to_active([$messenger->name], $message_type_names); |
758 | 758 | } |
@@ -776,13 +776,13 @@ discard block |
||
776 | 776 | // things have never been initialized (which should happen on EEH_Activation::generate_message_templates). |
777 | 777 | // So ONLY then do we need to actually grab defaults and cycle through them. Otherwise we |
778 | 778 | // only override _active_message_types when an explicit array of $message_type_names has been provided. |
779 | - $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[ $messenger->name ]) |
|
779 | + $message_type_names = empty($message_type_names) && ! isset($this->_active_message_types[$messenger->name]) |
|
780 | 780 | ? $messenger->get_default_message_types() |
781 | 781 | : (array) $message_type_names; |
782 | 782 | |
783 | 783 | // now we ALWAYS need to make sure that the messenger is active for the message types we're activating! |
784 | - if (! isset($this->_active_message_types[ $messenger->name ])) { |
|
785 | - $this->_active_message_types[ $messenger->name ]['settings'] = []; |
|
784 | + if ( ! isset($this->_active_message_types[$messenger->name])) { |
|
785 | + $this->_active_message_types[$messenger->name]['settings'] = []; |
|
786 | 786 | } |
787 | 787 | |
788 | 788 | if ($message_type_names) { |
@@ -823,16 +823,16 @@ discard block |
||
823 | 823 | if ($message_type instanceof EE_message_type) { |
824 | 824 | $default_settings = $message_type->get_admin_settings_fields(); |
825 | 825 | foreach ($default_settings as $field => $values) { |
826 | - if (isset($new_settings[ $field ])) { |
|
827 | - $existing_settings[ $field ] = $new_settings[ $field ]; |
|
826 | + if (isset($new_settings[$field])) { |
|
827 | + $existing_settings[$field] = $new_settings[$field]; |
|
828 | 828 | continue; |
829 | 829 | } |
830 | - if (! isset($existing_settings[ $field ])) { |
|
831 | - $existing_settings[ $field ] = $values['default']; |
|
830 | + if ( ! isset($existing_settings[$field])) { |
|
831 | + $existing_settings[$field] = $values['default']; |
|
832 | 832 | } |
833 | 833 | } |
834 | 834 | } |
835 | - $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]['settings'] = |
|
835 | + $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]['settings'] = |
|
836 | 836 | $existing_settings; |
837 | 837 | } |
838 | 838 | |
@@ -855,12 +855,12 @@ discard block |
||
855 | 855 | } |
856 | 856 | |
857 | 857 | // make sure this messenger has a record in the has_activated array |
858 | - if (! isset($this->_has_activated_messengers_and_message_types[ $messenger->name ])) { |
|
859 | - $this->_has_activated_messengers_and_message_types[ $messenger->name ] = []; |
|
858 | + if ( ! isset($this->_has_activated_messengers_and_message_types[$messenger->name])) { |
|
859 | + $this->_has_activated_messengers_and_message_types[$messenger->name] = []; |
|
860 | 860 | } |
861 | 861 | // check if message type has already been added |
862 | - if (! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[ $messenger->name ])) { |
|
863 | - $this->_has_activated_messengers_and_message_types[ $messenger->name ][] = $message_type_name; |
|
862 | + if ( ! in_array($message_type_name, $this->_has_activated_messengers_and_message_types[$messenger->name])) { |
|
863 | + $this->_has_activated_messengers_and_message_types[$messenger->name][] = $message_type_name; |
|
864 | 864 | } |
865 | 865 | } |
866 | 866 | |
@@ -878,17 +878,17 @@ discard block |
||
878 | 878 | $messenger = $this->get_messenger($messenger_name); |
879 | 879 | if ($messenger instanceof EE_messenger) { |
880 | 880 | $msgr_settings = $messenger->get_admin_settings_fields(); |
881 | - if (! empty($msgr_settings)) { |
|
881 | + if ( ! empty($msgr_settings)) { |
|
882 | 882 | foreach ($msgr_settings as $field => $value) { |
883 | 883 | // is there a new setting for this? |
884 | - if (isset($new_settings[ $field ])) { |
|
885 | - $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = |
|
886 | - $new_settings[ $field ]; |
|
884 | + if (isset($new_settings[$field])) { |
|
885 | + $this->_active_message_types[$messenger->name]['settings'][$field] = |
|
886 | + $new_settings[$field]; |
|
887 | 887 | continue; |
888 | 888 | } |
889 | 889 | // only set the default if it isn't already set. |
890 | - if (! isset($this->_active_message_types[ $messenger->name ]['settings'][ $field ])) { |
|
891 | - $this->_active_message_types[ $messenger->name ]['settings'][ $field ] = $value; |
|
890 | + if ( ! isset($this->_active_message_types[$messenger->name]['settings'][$field])) { |
|
891 | + $this->_active_message_types[$messenger->name]['settings'][$field] = $value; |
|
892 | 892 | } |
893 | 893 | } |
894 | 894 | } |
@@ -908,8 +908,8 @@ discard block |
||
908 | 908 | if ($messenger_name instanceof EE_messenger) { |
909 | 909 | $messenger_name = $messenger_name->name; |
910 | 910 | } |
911 | - unset($this->_active_messengers[ $messenger_name ]); |
|
912 | - unset($this->_active_message_types[ $messenger_name ]); |
|
911 | + unset($this->_active_messengers[$messenger_name]); |
|
912 | + unset($this->_active_message_types[$messenger_name]); |
|
913 | 913 | $this->_message_template_group_model->deactivate_message_template_groups_for($messenger_name); |
914 | 914 | $this->update_active_messengers_option(); |
915 | 915 | } |
@@ -932,7 +932,7 @@ discard block |
||
932 | 932 | } |
933 | 933 | foreach ($this->_active_message_types as $messenger_name => $settings) { |
934 | 934 | unset( |
935 | - $this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ] |
|
935 | + $this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name] |
|
936 | 936 | ); |
937 | 937 | |
938 | 938 | // we always record (even on deactivation) that a message type has been activated because there should at |
@@ -958,7 +958,7 @@ discard block |
||
958 | 958 | { |
959 | 959 | $this->_initialize_collections(); |
960 | 960 | if ($this->is_message_type_active_for_messenger($messenger_name, $message_type_name)) { |
961 | - unset($this->_active_message_types[ $messenger_name ]['settings'][ $messenger_name . '-message_types' ][ $message_type_name ]); |
|
961 | + unset($this->_active_message_types[$messenger_name]['settings'][$messenger_name.'-message_types'][$message_type_name]); |
|
962 | 962 | } |
963 | 963 | $this->_message_template_group_model->deactivate_message_template_groups_for( |
964 | 964 | [$messenger_name], |
@@ -1021,23 +1021,23 @@ discard block |
||
1021 | 1021 | ? 'slugs' |
1022 | 1022 | : 'all'; |
1023 | 1023 | // check if contexts has been setup yet. |
1024 | - if (empty($this->_contexts[ $key ])) { |
|
1024 | + if (empty($this->_contexts[$key])) { |
|
1025 | 1025 | // So let's get all active message type objects and loop through to get all unique contexts |
1026 | 1026 | foreach ($this->get_active_message_type_objects() as $message_type) { |
1027 | 1027 | if ($message_type instanceof EE_message_type) { |
1028 | 1028 | $message_type_contexts = $message_type->get_contexts(); |
1029 | 1029 | if ($slugs_only) { |
1030 | 1030 | foreach ($message_type_contexts as $context => $context_details) { |
1031 | - $this->_contexts[ $key ][ $context ] = $context_details['label']; |
|
1031 | + $this->_contexts[$key][$context] = $context_details['label']; |
|
1032 | 1032 | } |
1033 | 1033 | } else { |
1034 | - $this->_contexts[ $key ][ $message_type->name ] = $message_type_contexts; |
|
1034 | + $this->_contexts[$key][$message_type->name] = $message_type_contexts; |
|
1035 | 1035 | } |
1036 | 1036 | } |
1037 | 1037 | } |
1038 | 1038 | } |
1039 | - return ! empty($this->_contexts[ $key ]) |
|
1040 | - ? $this->_contexts[ $key ] |
|
1039 | + return ! empty($this->_contexts[$key]) |
|
1040 | + ? $this->_contexts[$key] |
|
1041 | 1041 | : []; |
1042 | 1042 | } |
1043 | 1043 | |
@@ -1058,7 +1058,7 @@ discard block |
||
1058 | 1058 | $all_message_types_valid = true; |
1059 | 1059 | // loop through list of active message types and verify they are installed. |
1060 | 1060 | foreach ($list_of_active_message_type_names as $message_type_name) { |
1061 | - if (! isset($installed_message_types[ $message_type_name ])) { |
|
1061 | + if ( ! isset($installed_message_types[$message_type_name])) { |
|
1062 | 1062 | $this->remove_message_type_has_been_activated_from_all_messengers( |
1063 | 1063 | $message_type_name, |
1064 | 1064 | true |
@@ -1085,8 +1085,8 @@ discard block |
||
1085 | 1085 | public function has_message_type_been_activated_for_messenger($message_type_name, $messenger_name) |
1086 | 1086 | { |
1087 | 1087 | $has_activated = $this->get_has_activated_messengers_option(); |
1088 | - return isset($has_activated[ $messenger_name ]) |
|
1089 | - && in_array($message_type_name, $has_activated[ $messenger_name ]); |
|
1088 | + return isset($has_activated[$messenger_name]) |
|
1089 | + && in_array($message_type_name, $has_activated[$messenger_name]); |
|
1090 | 1090 | } |
1091 | 1091 | |
1092 | 1092 | |
@@ -1115,11 +1115,11 @@ discard block |
||
1115 | 1115 | return; |
1116 | 1116 | } |
1117 | 1117 | $has_activated = $this->get_has_activated_messengers_option(); |
1118 | - $key_for_message_type = isset($has_activated[ $messenger_name ]) |
|
1119 | - ? array_search($message_type_name, $has_activated[ $messenger_name ], true) |
|
1118 | + $key_for_message_type = isset($has_activated[$messenger_name]) |
|
1119 | + ? array_search($message_type_name, $has_activated[$messenger_name], true) |
|
1120 | 1120 | : false; |
1121 | 1121 | if ($key_for_message_type !== false) { |
1122 | - unset($has_activated[ $messenger_name ][ $key_for_message_type ]); |
|
1122 | + unset($has_activated[$messenger_name][$key_for_message_type]); |
|
1123 | 1123 | $this->update_has_activated_messengers_option($has_activated); |
1124 | 1124 | // reset the internal cached property |
1125 | 1125 | $this->get_has_activated_messengers_option(true); |
@@ -12,140 +12,140 @@ |
||
12 | 12 | */ |
13 | 13 | class EE_Message_Factory |
14 | 14 | { |
15 | - protected static ?EE_Message_Factory $_instance = null; |
|
16 | - |
|
17 | - protected EE_Message_Resource_Manager $_message_resource_manager; |
|
18 | - |
|
19 | - |
|
20 | - /** |
|
21 | - * EE_Message_Factory constructor. |
|
22 | - * |
|
23 | - * @param EE_Message_Resource_Manager $Message_Resource_Manager |
|
24 | - */ |
|
25 | - protected function __construct(EE_Message_Resource_Manager $Message_Resource_Manager) |
|
26 | - { |
|
27 | - $this->_message_resource_manager = $Message_Resource_Manager; |
|
28 | - } |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * @singleton method used to instantiate class object |
|
33 | - * @access public |
|
34 | - * @param EE_Message_Resource_Manager $Message_Resource_Manager |
|
35 | - * @return EE_Message_Factory instance |
|
36 | - */ |
|
37 | - public static function instance(EE_Message_Resource_Manager $Message_Resource_Manager): ?EE_Message_Factory |
|
38 | - { |
|
39 | - // check if class object is instantiated, and instantiated properly |
|
40 | - if (! self::$_instance instanceof EE_Message_Factory) { |
|
41 | - self::$_instance = new EE_Message_Factory($Message_Resource_Manager); |
|
42 | - } |
|
43 | - return self::$_instance; |
|
44 | - } |
|
45 | - |
|
46 | - |
|
47 | - /** |
|
48 | - * @param array $props_n_values |
|
49 | - * @return EE_Message |
|
50 | - */ |
|
51 | - public static function create(array $props_n_values = []): EE_Message |
|
52 | - { |
|
53 | - /** @type EE_Message_Factory $Message_Factory */ |
|
54 | - $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
55 | - return $Message_Factory->_create($props_n_values); |
|
56 | - } |
|
57 | - |
|
58 | - |
|
59 | - /** |
|
60 | - * @param EE_Message $message |
|
61 | - * @return EE_Message |
|
62 | - */ |
|
63 | - public static function set_messenger_and_message_type(EE_Message $message): EE_Message |
|
64 | - { |
|
65 | - /** @type EE_Message_Factory $Message_Factory */ |
|
66 | - $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
67 | - return $Message_Factory->_set_messenger_and_message_type($message); |
|
68 | - } |
|
69 | - |
|
70 | - |
|
71 | - /** |
|
72 | - * @param EE_Message $message |
|
73 | - * @return EE_Message |
|
74 | - */ |
|
75 | - public static function set_messenger(EE_Message $message): EE_Message |
|
76 | - { |
|
77 | - /** @type EE_Message_Factory $Message_Factory */ |
|
78 | - $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
79 | - return $Message_Factory->_set_messenger($message); |
|
80 | - } |
|
81 | - |
|
82 | - |
|
83 | - /** |
|
84 | - * @param EE_Message $message |
|
85 | - * @return EE_Message |
|
86 | - */ |
|
87 | - public static function set_message_type(EE_Message $message): EE_Message |
|
88 | - { |
|
89 | - /** @type EE_Message_Factory $Message_Factory */ |
|
90 | - $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
91 | - return $Message_Factory->_set_message_type($message); |
|
92 | - } |
|
93 | - |
|
94 | - |
|
95 | - /** |
|
96 | - * @param array $props_n_values |
|
97 | - * @return EE_Message |
|
98 | - */ |
|
99 | - protected function _create(array $props_n_values = []): EE_Message |
|
100 | - { |
|
101 | - $new_instance = false; |
|
102 | - if (! empty($props_n_values['MSG_ID'])) { |
|
103 | - $message = EE_Message::new_instance_from_db($props_n_values); |
|
104 | - } else { |
|
105 | - $message = EE_Message::new_instance($props_n_values); |
|
106 | - $new_instance = true; |
|
107 | - } |
|
108 | - return $this->_set_messenger_and_message_type($message, $new_instance); |
|
109 | - } |
|
110 | - |
|
111 | - |
|
112 | - /** |
|
113 | - * @param EE_Message $message |
|
114 | - * @param bool $new_instance Whether the message type was setup from the database (false) or not (true) |
|
115 | - * @return EE_Message |
|
116 | - */ |
|
117 | - protected function _set_messenger_and_message_type(EE_Message $message, bool $new_instance = false): EE_Message |
|
118 | - { |
|
119 | - $message = $this->_set_messenger($message); |
|
120 | - return $this->_set_message_type($message, $new_instance); |
|
121 | - } |
|
122 | - |
|
123 | - |
|
124 | - /** |
|
125 | - * @param EE_Message $message |
|
126 | - * @return EE_Message |
|
127 | - */ |
|
128 | - protected function _set_messenger(EE_Message $message): EE_Message |
|
129 | - { |
|
130 | - $messenger = $this->_message_resource_manager->get_messenger($message->messenger()); |
|
131 | - if ($messenger instanceof EE_messenger) { |
|
132 | - $message->set_messenger_object($messenger); |
|
133 | - } |
|
134 | - return $message; |
|
135 | - } |
|
136 | - |
|
137 | - |
|
138 | - /** |
|
139 | - * @param EE_Message $message |
|
140 | - * @param bool $new_instance Whether the message type was setup from the database (false) or not (true) |
|
141 | - * @return EE_Message |
|
142 | - */ |
|
143 | - protected function _set_message_type(EE_Message $message, bool $new_instance = false): EE_Message |
|
144 | - { |
|
145 | - $message_type = $this->_message_resource_manager->get_message_type($message->message_type()); |
|
146 | - if ($message_type instanceof EE_message_type) { |
|
147 | - $message->set_message_type_object($message_type, $new_instance); |
|
148 | - } |
|
149 | - return $message; |
|
150 | - } |
|
15 | + protected static ?EE_Message_Factory $_instance = null; |
|
16 | + |
|
17 | + protected EE_Message_Resource_Manager $_message_resource_manager; |
|
18 | + |
|
19 | + |
|
20 | + /** |
|
21 | + * EE_Message_Factory constructor. |
|
22 | + * |
|
23 | + * @param EE_Message_Resource_Manager $Message_Resource_Manager |
|
24 | + */ |
|
25 | + protected function __construct(EE_Message_Resource_Manager $Message_Resource_Manager) |
|
26 | + { |
|
27 | + $this->_message_resource_manager = $Message_Resource_Manager; |
|
28 | + } |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * @singleton method used to instantiate class object |
|
33 | + * @access public |
|
34 | + * @param EE_Message_Resource_Manager $Message_Resource_Manager |
|
35 | + * @return EE_Message_Factory instance |
|
36 | + */ |
|
37 | + public static function instance(EE_Message_Resource_Manager $Message_Resource_Manager): ?EE_Message_Factory |
|
38 | + { |
|
39 | + // check if class object is instantiated, and instantiated properly |
|
40 | + if (! self::$_instance instanceof EE_Message_Factory) { |
|
41 | + self::$_instance = new EE_Message_Factory($Message_Resource_Manager); |
|
42 | + } |
|
43 | + return self::$_instance; |
|
44 | + } |
|
45 | + |
|
46 | + |
|
47 | + /** |
|
48 | + * @param array $props_n_values |
|
49 | + * @return EE_Message |
|
50 | + */ |
|
51 | + public static function create(array $props_n_values = []): EE_Message |
|
52 | + { |
|
53 | + /** @type EE_Message_Factory $Message_Factory */ |
|
54 | + $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
55 | + return $Message_Factory->_create($props_n_values); |
|
56 | + } |
|
57 | + |
|
58 | + |
|
59 | + /** |
|
60 | + * @param EE_Message $message |
|
61 | + * @return EE_Message |
|
62 | + */ |
|
63 | + public static function set_messenger_and_message_type(EE_Message $message): EE_Message |
|
64 | + { |
|
65 | + /** @type EE_Message_Factory $Message_Factory */ |
|
66 | + $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
67 | + return $Message_Factory->_set_messenger_and_message_type($message); |
|
68 | + } |
|
69 | + |
|
70 | + |
|
71 | + /** |
|
72 | + * @param EE_Message $message |
|
73 | + * @return EE_Message |
|
74 | + */ |
|
75 | + public static function set_messenger(EE_Message $message): EE_Message |
|
76 | + { |
|
77 | + /** @type EE_Message_Factory $Message_Factory */ |
|
78 | + $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
79 | + return $Message_Factory->_set_messenger($message); |
|
80 | + } |
|
81 | + |
|
82 | + |
|
83 | + /** |
|
84 | + * @param EE_Message $message |
|
85 | + * @return EE_Message |
|
86 | + */ |
|
87 | + public static function set_message_type(EE_Message $message): EE_Message |
|
88 | + { |
|
89 | + /** @type EE_Message_Factory $Message_Factory */ |
|
90 | + $Message_Factory = LoaderFactory::getShared('EE_Message_Factory'); |
|
91 | + return $Message_Factory->_set_message_type($message); |
|
92 | + } |
|
93 | + |
|
94 | + |
|
95 | + /** |
|
96 | + * @param array $props_n_values |
|
97 | + * @return EE_Message |
|
98 | + */ |
|
99 | + protected function _create(array $props_n_values = []): EE_Message |
|
100 | + { |
|
101 | + $new_instance = false; |
|
102 | + if (! empty($props_n_values['MSG_ID'])) { |
|
103 | + $message = EE_Message::new_instance_from_db($props_n_values); |
|
104 | + } else { |
|
105 | + $message = EE_Message::new_instance($props_n_values); |
|
106 | + $new_instance = true; |
|
107 | + } |
|
108 | + return $this->_set_messenger_and_message_type($message, $new_instance); |
|
109 | + } |
|
110 | + |
|
111 | + |
|
112 | + /** |
|
113 | + * @param EE_Message $message |
|
114 | + * @param bool $new_instance Whether the message type was setup from the database (false) or not (true) |
|
115 | + * @return EE_Message |
|
116 | + */ |
|
117 | + protected function _set_messenger_and_message_type(EE_Message $message, bool $new_instance = false): EE_Message |
|
118 | + { |
|
119 | + $message = $this->_set_messenger($message); |
|
120 | + return $this->_set_message_type($message, $new_instance); |
|
121 | + } |
|
122 | + |
|
123 | + |
|
124 | + /** |
|
125 | + * @param EE_Message $message |
|
126 | + * @return EE_Message |
|
127 | + */ |
|
128 | + protected function _set_messenger(EE_Message $message): EE_Message |
|
129 | + { |
|
130 | + $messenger = $this->_message_resource_manager->get_messenger($message->messenger()); |
|
131 | + if ($messenger instanceof EE_messenger) { |
|
132 | + $message->set_messenger_object($messenger); |
|
133 | + } |
|
134 | + return $message; |
|
135 | + } |
|
136 | + |
|
137 | + |
|
138 | + /** |
|
139 | + * @param EE_Message $message |
|
140 | + * @param bool $new_instance Whether the message type was setup from the database (false) or not (true) |
|
141 | + * @return EE_Message |
|
142 | + */ |
|
143 | + protected function _set_message_type(EE_Message $message, bool $new_instance = false): EE_Message |
|
144 | + { |
|
145 | + $message_type = $this->_message_resource_manager->get_message_type($message->message_type()); |
|
146 | + if ($message_type instanceof EE_message_type) { |
|
147 | + $message->set_message_type_object($message_type, $new_instance); |
|
148 | + } |
|
149 | + return $message; |
|
150 | + } |
|
151 | 151 | } |
@@ -47,644 +47,644 @@ |
||
47 | 47 | */ |
48 | 48 | class RegistrationsReport extends JobHandlerFile |
49 | 49 | { |
50 | - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
51 | - // phpcs:disable PSR2.Methods.MethodDeclaration.Underscore |
|
52 | - /** |
|
53 | - * Performs any necessary setup for starting the job. This is also a good |
|
54 | - * place to set up the $job_arguments which will be used for subsequent HTTP requests |
|
55 | - * when continue_job will be called |
|
56 | - * |
|
57 | - * @param JobParameters $job_parameters |
|
58 | - * @return JobStepResponse |
|
59 | - * @throws BatchRequestException |
|
60 | - * @throws EE_Error |
|
61 | - * @throws ReflectionException |
|
62 | - * @throws Exception |
|
63 | - */ |
|
64 | - public function create_job(JobParameters $job_parameters): JobStepResponse |
|
65 | - { |
|
66 | - $event_id = absint($job_parameters->request_datum('EVT_ID', '0')); |
|
67 | - $DTT_ID = absint($job_parameters->request_datum('DTT_ID', '0')); |
|
68 | - if (! EE_Capabilities::instance()->current_user_can('ee_read_registrations', 'generating_report')) { |
|
69 | - throw new BatchRequestException( |
|
70 | - esc_html__('You do not have permission to view registrations', 'event_espresso') |
|
71 | - ); |
|
72 | - } |
|
73 | - $filepath = $this->create_file_from_job_with_name( |
|
74 | - $job_parameters->job_id(), |
|
75 | - $this->get_filename() |
|
76 | - ); |
|
77 | - $job_parameters->add_extra_data('filepath', $filepath); |
|
78 | - |
|
79 | - if ($job_parameters->request_datum('use_filters', false)) { |
|
80 | - $query_params = maybe_unserialize($job_parameters->request_datum('filters', [])); |
|
81 | - } else { |
|
82 | - $query_params = [ |
|
83 | - [ 'Ticket.TKT_deleted' => ['IN', [true, false]] ], |
|
84 | - 'order_by' => ['Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'], |
|
85 | - 'force_join' => ['Transaction', 'Ticket', 'Attendee'], |
|
86 | - 'caps' => EEM_Base::caps_read_admin, |
|
87 | - ]; |
|
88 | - if ($event_id) { |
|
89 | - $query_params[0]['EVT_ID'] = $event_id; |
|
90 | - } else { |
|
91 | - $query_params['force_join'][] = 'Event'; |
|
92 | - } |
|
93 | - } |
|
94 | - // unless the query params already include a status, |
|
95 | - // we want to exclude registrations from failed or abandoned transactions |
|
96 | - if (! isset($query_params[0]['Transaction.STS_ID'])) { |
|
97 | - $query_params[0]['OR'] = [ |
|
98 | - // don't include registrations from failed or abandoned transactions... |
|
99 | - 'Transaction.STS_ID' => [ |
|
100 | - 'NOT IN', |
|
101 | - [ |
|
102 | - EEM_Transaction::failed_status_code, |
|
103 | - EEM_Transaction::abandoned_status_code, |
|
104 | - ], |
|
105 | - ], |
|
106 | - // unless the registration is approved, |
|
107 | - // in which case include it regardless of transaction status |
|
108 | - 'STS_ID' => RegStatus::APPROVED, |
|
109 | - ]; |
|
110 | - } |
|
111 | - |
|
112 | - if (! isset($query_params['force_join'])) { |
|
113 | - $query_params['force_join'] = ['Event', 'Transaction', 'Ticket', 'Attendee']; |
|
114 | - } |
|
115 | - |
|
116 | - $return_url_args = []; |
|
117 | - parse_str( |
|
118 | - parse_url( |
|
119 | - $job_parameters->request_datum('return_url'), |
|
120 | - PHP_URL_QUERY |
|
121 | - ), |
|
122 | - $return_url_args |
|
123 | - ); |
|
124 | - |
|
125 | - if ( |
|
126 | - isset($return_url_args['orderby'], $return_url_args['order']) |
|
127 | - && $return_url_args['orderby'] === 'ATT_lname' |
|
128 | - ) { |
|
129 | - $query_params['order_by'] = [ |
|
130 | - 'Attendee.ATT_lname' => $return_url_args['order'], |
|
131 | - 'Attendee.ATT_fname' => $return_url_args['order'], |
|
132 | - 'REG_ID' => $return_url_args['order'] |
|
133 | - ]; |
|
134 | - } |
|
135 | - |
|
136 | - $query_params = apply_filters( |
|
137 | - 'FHEE__EE_Export__report_registration_for_event', |
|
138 | - $query_params, |
|
139 | - $event_id |
|
140 | - ); |
|
141 | - |
|
142 | - $utc_timezone = new DateTimeZone('UTC'); |
|
143 | - $site_timezone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
144 | - $query_params = $this->convertDateStringsToObjects($query_params, $site_timezone, $utc_timezone); |
|
145 | - |
|
146 | - $job_parameters->add_extra_data('query_params', $query_params); |
|
147 | - $question_labels = $this->_get_question_labels($query_params); |
|
148 | - $job_parameters->add_extra_data('question_labels', $question_labels); |
|
149 | - $job_parameters->set_job_size($this->count_units_to_process($query_params)); |
|
150 | - // we need to set the header columns |
|
151 | - // but to do that we need to process one row so that we can extract ALL the column headers |
|
152 | - $csv_data_for_row = $this->get_csv_data_for( |
|
153 | - $event_id, |
|
154 | - 0, |
|
155 | - 1, |
|
156 | - $question_labels, |
|
157 | - $query_params, |
|
158 | - $DTT_ID |
|
159 | - ); |
|
160 | - // but we don't want to write any actual data yet... |
|
161 | - // so let's blank out all the values for that first row |
|
162 | - array_walk( |
|
163 | - $csv_data_for_row[0], |
|
164 | - function (&$value) { |
|
165 | - $value = null; |
|
166 | - } |
|
167 | - ); |
|
168 | - |
|
169 | - EEH_Export::write_data_array_to_csv($filepath, $csv_data_for_row, true, true); |
|
170 | - $this->updateTextHeader( |
|
171 | - esc_html__('Registrations report started successfully...', 'event_espresso') |
|
172 | - ); |
|
173 | - return new JobStepResponse($job_parameters, $this->feedback); |
|
174 | - } |
|
175 | - |
|
176 | - |
|
177 | - /** |
|
178 | - * Gets the filename |
|
179 | - * |
|
180 | - * @return string |
|
181 | - */ |
|
182 | - protected function get_filename(): string |
|
183 | - { |
|
184 | - return apply_filters( |
|
185 | - 'FHEE__EventEspressoBatchRequest__JobHandlers__RegistrationsReport__get_filename', |
|
186 | - sprintf( |
|
187 | - 'event-espresso-registrations-%s.csv', |
|
188 | - str_replace([':', ' '], '-', current_time('mysql')) |
|
189 | - ) |
|
190 | - ); |
|
191 | - } |
|
192 | - |
|
193 | - |
|
194 | - /** |
|
195 | - * Gets the questions which are to be used for this report, |
|
196 | - * so they can be remembered for later |
|
197 | - * |
|
198 | - * @param array $registration_query_params |
|
199 | - * @return array question admin labels to be used for this report |
|
200 | - * @throws EE_Error |
|
201 | - * @throws ReflectionException |
|
202 | - */ |
|
203 | - protected function _get_question_labels(array $registration_query_params): array |
|
204 | - { |
|
205 | - $where = $registration_query_params[0] ?? null; |
|
206 | - $question_query_params = []; |
|
207 | - if ($where !== null) { |
|
208 | - $question_query_params = [ |
|
209 | - $this->_change_registration_where_params_to_question_where_params($registration_query_params[0]), |
|
210 | - ]; |
|
211 | - } |
|
212 | - // Make sure it's not a system question |
|
213 | - $question_query_params[0]['OR*not-system-questions'] = [ |
|
214 | - 'QST_system' => '', |
|
215 | - 'QST_system*null' => ['IS_NULL'] |
|
216 | - ]; |
|
217 | - if ( |
|
218 | - apply_filters( |
|
219 | - 'FHEE__EventEspressoBatchRequest__JobHandlers__RegistrationsReport___get_question_labels__only_include_answered_questions', |
|
220 | - false, |
|
221 | - $registration_query_params |
|
222 | - ) |
|
223 | - ) { |
|
224 | - $question_query_params[0]['Answer.ANS_ID'] = ['IS_NOT_NULL']; |
|
225 | - } |
|
226 | - $question_query_params['order_by'] = [ |
|
227 | - 'Question_Group_Question.QGQ_order' => 'ASC', |
|
228 | - 'QST_order' => 'ASC', |
|
229 | - 'QST_admin_label' => 'ASC' |
|
230 | - ]; |
|
231 | - $question_query_params['group_by'] = ['QST_ID']; |
|
232 | - return array_unique(EEM_Question::instance()->get_col($question_query_params, 'QST_admin_label')); |
|
233 | - } |
|
234 | - |
|
235 | - |
|
236 | - /** |
|
237 | - * Takes where params meant for registrations and changes them to work for questions |
|
238 | - * |
|
239 | - * @param array $reg_where_params |
|
240 | - * @return array |
|
241 | - * @throws EE_Error |
|
242 | - * @throws ReflectionException |
|
243 | - */ |
|
244 | - protected function _change_registration_where_params_to_question_where_params(array $reg_where_params): array |
|
245 | - { |
|
246 | - $question_where_params = []; |
|
247 | - foreach ($reg_where_params as $key => $val) { |
|
248 | - if (EEM_Registration::instance()->is_logic_query_param_key($key)) { |
|
249 | - $question_where_params[ $key ] = |
|
250 | - $this->_change_registration_where_params_to_question_where_params($val); |
|
251 | - } else { |
|
252 | - // it's a normal where condition |
|
253 | - $question_where_params[ 'Question_Group.Event.Registration.' . $key ] = $val; |
|
254 | - } |
|
255 | - } |
|
256 | - return $question_where_params; |
|
257 | - } |
|
258 | - |
|
259 | - |
|
260 | - /** |
|
261 | - * Performs another step of the job |
|
262 | - * |
|
263 | - * @param JobParameters $job_parameters |
|
264 | - * @param int $batch_size |
|
265 | - * @return JobStepResponse |
|
266 | - * @throws EE_Error |
|
267 | - * @throws ReflectionException |
|
268 | - */ |
|
269 | - public function continue_job(JobParameters $job_parameters, int $batch_size = 50): JobStepResponse |
|
270 | - { |
|
271 | - if ($job_parameters->units_processed() < $job_parameters->job_size()) { |
|
272 | - $csv_data = $this->get_csv_data_for( |
|
273 | - (int) $job_parameters->request_datum('EVT_ID', '0'), |
|
274 | - $job_parameters->units_processed(), |
|
275 | - $batch_size, |
|
276 | - $job_parameters->extra_datum('question_labels'), |
|
277 | - $job_parameters->extra_datum('query_params'), |
|
278 | - (int) $job_parameters->request_datum('DTT_ID', '0') |
|
279 | - ); |
|
280 | - EEH_Export::write_data_array_to_csv( |
|
281 | - $job_parameters->extra_datum('filepath'), |
|
282 | - $csv_data, |
|
283 | - false |
|
284 | - ); |
|
285 | - $units_processed = count($csv_data); |
|
286 | - if ($units_processed) { |
|
287 | - $job_parameters->mark_processed($units_processed); |
|
288 | - $this->updateText( |
|
289 | - sprintf( |
|
290 | - esc_html__('Wrote %1$s rows to report CSV file...', 'event_espresso'), |
|
291 | - $units_processed |
|
292 | - ) |
|
293 | - ); |
|
294 | - } |
|
295 | - } |
|
296 | - $extra_response_data = ['file_url' => '']; |
|
297 | - if ($job_parameters->units_processed() >= $job_parameters->job_size()) { |
|
298 | - $job_parameters->set_status(JobParameters::status_complete); |
|
299 | - $extra_response_data['file_url'] = $this->get_url_to_file($job_parameters->extra_datum('filepath')); |
|
300 | - $this->displayJobFinalResults($job_parameters); |
|
301 | - } else { |
|
302 | - $job_parameters->set_status(JobParameters::status_continue); |
|
303 | - } |
|
304 | - return new JobStepResponse($job_parameters, $this->feedback, $extra_response_data); |
|
305 | - } |
|
306 | - |
|
307 | - |
|
308 | - /** |
|
309 | - * Gets the csv data for a batch of registrations |
|
310 | - * |
|
311 | - * @param int|null $event_id |
|
312 | - * @param int $offset |
|
313 | - * @param int $limit |
|
314 | - * @param array $question_labels the IDs for all the questions which were answered by someone in this selection |
|
315 | - * @param array $query_params for using where querying the model |
|
316 | - * @param int $DTT_ID |
|
317 | - * @return array top-level keys are numeric, next-level keys are column headers |
|
318 | - * @throws EE_Error |
|
319 | - * @throws ReflectionException |
|
320 | - */ |
|
321 | - public function get_csv_data_for( |
|
322 | - ?int $event_id, |
|
323 | - int $offset, |
|
324 | - int $limit, |
|
325 | - array $question_labels, |
|
326 | - array $query_params, |
|
327 | - int $DTT_ID = 0 |
|
328 | - ): array { |
|
329 | - $reg_fields_to_include = [ |
|
330 | - 'TXN_ID', |
|
331 | - 'ATT_ID', |
|
332 | - 'REG_ID', |
|
333 | - 'REG_date', |
|
334 | - 'REG_code', |
|
335 | - 'REG_count', |
|
336 | - 'REG_final_price', |
|
337 | - ]; |
|
338 | - $att_fields_to_include = [ |
|
339 | - 'ATT_fname', |
|
340 | - 'ATT_lname', |
|
341 | - 'ATT_email', |
|
342 | - 'ATT_address', |
|
343 | - 'ATT_address2', |
|
344 | - 'ATT_city', |
|
345 | - 'STA_ID', |
|
346 | - 'CNT_ISO', |
|
347 | - 'ATT_zip', |
|
348 | - 'ATT_phone', |
|
349 | - ]; |
|
350 | - |
|
351 | - // get models |
|
352 | - $event_model = EEM_Event::instance(); |
|
353 | - $date_model = EEM_Datetime::instance(); |
|
354 | - $ticket_model = EEM_Ticket::instance(); |
|
355 | - $txn_model = EEM_Transaction::instance(); |
|
356 | - $reg_model = EEM_Registration::instance(); |
|
357 | - $pay_model = EEM_Payment::instance(); |
|
358 | - $status_model = EEM_Status::instance(); |
|
359 | - |
|
360 | - $registrations_csv_ready_array = []; |
|
361 | - $query_params['limit'] = [$offset, $limit]; |
|
362 | - $registration_rows = $reg_model->get_all_wpdb_results($query_params); |
|
363 | - |
|
364 | - foreach ($registration_rows as $reg_row) { |
|
365 | - if (! is_array($reg_row)) { |
|
366 | - continue; |
|
367 | - } |
|
368 | - $reg_csv_array = []; |
|
369 | - // registration ID |
|
370 | - $reg_id_field = $reg_model->field_settings_for('REG_ID'); |
|
371 | - $reg_csv_array[ EEH_Export::get_column_name_for_field($reg_id_field) ] = |
|
372 | - EEH_Export::prepare_value_from_db_for_display( |
|
373 | - $reg_model, |
|
374 | - 'REG_ID', |
|
375 | - $reg_row[ $reg_id_field->get_qualified_column() ] |
|
376 | - ); |
|
377 | - // ALL registrations, or is list filtered to just one? |
|
378 | - if (! $event_id) { |
|
379 | - // ALL registrations, so get each event's name and ID |
|
380 | - $reg_csv_array[ esc_html__('Event', 'event_espresso') ] = sprintf( |
|
381 | - /* translators: 1: event name, 2: event ID */ |
|
382 | - esc_html__('%1$s (%2$s)', 'event_espresso'), |
|
383 | - EEH_Export::prepare_value_from_db_for_display( |
|
384 | - $event_model, |
|
385 | - 'EVT_name', |
|
386 | - $reg_row['Event_CPT.post_title'] |
|
387 | - ), |
|
388 | - $reg_row['Event_CPT.ID'] |
|
389 | - ); |
|
390 | - } |
|
391 | - // add attendee columns |
|
392 | - $reg_csv_array = AttendeeCSV::addAttendeeColumns($att_fields_to_include, $reg_row, $reg_csv_array); |
|
393 | - // add registration columns |
|
394 | - $reg_csv_array = RegistrationCSV::addRegistrationColumns($reg_fields_to_include, $reg_row, $reg_csv_array); |
|
395 | - // get pretty status |
|
396 | - $stati = $status_model->localized_status( |
|
397 | - [ |
|
398 | - $reg_row['Registration.STS_ID'] => esc_html__('unknown', 'event_espresso'), |
|
399 | - $reg_row['TransactionTable.STS_ID'] => esc_html__('unknown', 'event_espresso'), |
|
400 | - ], |
|
401 | - false, |
|
402 | - 'sentence' |
|
403 | - ); |
|
404 | - $is_primary_reg = $reg_row['Registration.REG_count'] == '1'; |
|
405 | - |
|
406 | - $reg_csv_array[ esc_html__('Registration Status', 'event_espresso') ] = |
|
407 | - $stati[ $reg_row['Registration.STS_ID'] ]; |
|
408 | - // get pretty transaction status |
|
409 | - $reg_csv_array[ esc_html__('Transaction Status', 'event_espresso') ] = |
|
410 | - $stati[ $reg_row['TransactionTable.STS_ID'] ]; |
|
411 | - $reg_csv_array[ esc_html__('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg |
|
412 | - ? EEH_Export::prepare_value_from_db_for_display( |
|
413 | - $txn_model, |
|
414 | - 'TXN_total', |
|
415 | - $reg_row['TransactionTable.TXN_total'], |
|
416 | - 'localized_float' |
|
417 | - ) |
|
418 | - : '0.00'; |
|
419 | - |
|
420 | - $reg_csv_array[ esc_html__('Amount Paid', 'event_espresso') ] = $is_primary_reg |
|
421 | - ? EEH_Export::prepare_value_from_db_for_display( |
|
422 | - $txn_model, |
|
423 | - 'TXN_paid', |
|
424 | - $reg_row['TransactionTable.TXN_paid'], |
|
425 | - 'localized_float' |
|
426 | - ) |
|
427 | - : '0.00'; |
|
428 | - |
|
429 | - $payment_methods = []; |
|
430 | - $gateway_txn_ids_etc = []; |
|
431 | - $payment_times = []; |
|
432 | - if ($is_primary_reg && $reg_row['TransactionTable.TXN_ID']) { |
|
433 | - $payments_info = $pay_model->get_all_wpdb_results( |
|
434 | - [ |
|
435 | - [ |
|
436 | - 'TXN_ID' => $reg_row['TransactionTable.TXN_ID'], |
|
437 | - 'STS_ID' => EEM_Payment::status_id_approved, |
|
438 | - ], |
|
439 | - 'force_join' => ['Payment_Method'], |
|
440 | - ], |
|
441 | - ARRAY_A, |
|
442 | - 'Payment_Method.PMD_admin_name as name, Payment.PAY_txn_id_chq_nmbr as gateway_txn_id, Payment.PAY_timestamp as payment_time' |
|
443 | - ); |
|
444 | - [$payment_methods, $gateway_txn_ids_etc, $payment_times] = PaymentsInfoCSV::extractPaymentInfo( |
|
445 | - $payments_info |
|
446 | - ); |
|
447 | - } |
|
448 | - |
|
449 | - $reg_csv_array[ esc_html__('Payment Date(s)', 'event_espresso') ] = implode( |
|
450 | - ',', |
|
451 | - $payment_times |
|
452 | - ); |
|
453 | - |
|
454 | - $reg_csv_array[ esc_html__('Payment Method(s)', 'event_espresso') ] = implode( |
|
455 | - ',', |
|
456 | - $payment_methods |
|
457 | - ); |
|
458 | - |
|
459 | - $reg_csv_array[ esc_html__('Gateway Transaction ID(s)', 'event_espresso') ] = implode( |
|
460 | - ',', |
|
461 | - $gateway_txn_ids_etc |
|
462 | - ); |
|
463 | - |
|
464 | - $ticket_name = esc_html__('Unknown', 'event_espresso'); |
|
465 | - $datetime_strings = [esc_html__('Unknown', 'event_espresso')]; |
|
466 | - if ($reg_row['Ticket.TKT_ID']) { |
|
467 | - $ticket_name = EEH_Export::prepare_value_from_db_for_display( |
|
468 | - $ticket_model, |
|
469 | - 'TKT_name', |
|
470 | - $reg_row['Ticket.TKT_name'] |
|
471 | - ); |
|
472 | - $datetime_strings = []; |
|
473 | - $datetimes = $date_model->get_all_wpdb_results( |
|
474 | - [ |
|
475 | - ['Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID']], |
|
476 | - 'order_by' => ['DTT_EVT_start' => 'ASC'], |
|
477 | - 'default_where_conditions' => 'none', |
|
478 | - ] |
|
479 | - ); |
|
480 | - foreach ($datetimes as $datetime) { |
|
481 | - $datetime_strings[] = EEH_Export::prepare_value_from_db_for_display( |
|
482 | - $date_model, |
|
483 | - 'DTT_EVT_start', |
|
484 | - $datetime['Datetime.DTT_EVT_start'] |
|
485 | - ); |
|
486 | - } |
|
487 | - } |
|
488 | - |
|
489 | - $reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name; |
|
490 | - |
|
491 | - |
|
492 | - $reg_csv_array[ esc_html__('Ticket Datetimes', 'event_espresso') ] = implode( |
|
493 | - ', ', |
|
494 | - $datetime_strings |
|
495 | - ); |
|
496 | - |
|
497 | - // add answer columns |
|
498 | - $reg_csv_array = AnswersCSV::addAnswerColumns($reg_row, $reg_csv_array, $question_labels); |
|
499 | - // Include check-in data |
|
500 | - if ($event_id && $DTT_ID) { |
|
501 | - // get whether the user has checked in |
|
502 | - $reg_csv_array[ esc_html__('Datetime Check-ins #', 'event_espresso') ] = |
|
503 | - $reg_model->count_related( |
|
504 | - $reg_row['Registration.REG_ID'], |
|
505 | - 'Checkin', |
|
506 | - [ |
|
507 | - [ |
|
508 | - 'DTT_ID' => $DTT_ID |
|
509 | - ] |
|
510 | - ] |
|
511 | - ); |
|
512 | - $datetime = $date_model->get_one_by_ID($DTT_ID); |
|
513 | - $checkin_rows = EEM_Checkin::instance()->get_all( |
|
514 | - [ |
|
515 | - [ |
|
516 | - 'REG_ID' => $reg_row['Registration.REG_ID'], |
|
517 | - 'DTT_ID' => $datetime->get('DTT_ID'), |
|
518 | - ], |
|
519 | - ] |
|
520 | - ); |
|
521 | - $checkins = []; |
|
522 | - foreach ($checkin_rows as $checkin_row) { |
|
523 | - /** @var EE_Checkin $checkin_row */ |
|
524 | - $checkin_value = CheckinsCSV::getCheckinValue($checkin_row); |
|
525 | - if ($checkin_value) { |
|
526 | - $checkins[] = $checkin_value; |
|
527 | - } |
|
528 | - } |
|
529 | - $datetime_name = CheckinsCSV::getDatetimeLabel($datetime); |
|
530 | - $reg_csv_array[ $datetime_name ] = implode(' --- ', $checkins); |
|
531 | - } elseif ($event_id) { |
|
532 | - // get whether the user has checked in |
|
533 | - $reg_csv_array[ esc_html__('Event Check-ins #', 'event_espresso') ] = |
|
534 | - $reg_model->count_related( |
|
535 | - $reg_row['Registration.REG_ID'], |
|
536 | - 'Checkin' |
|
537 | - ); |
|
538 | - |
|
539 | - $datetimes = $date_model->get_all( |
|
540 | - [ |
|
541 | - [ |
|
542 | - 'Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID'], |
|
543 | - ], |
|
544 | - 'order_by' => ['DTT_EVT_start' => 'ASC'], |
|
545 | - 'default_where_conditions' => 'none', |
|
546 | - ] |
|
547 | - ); |
|
548 | - foreach ($datetimes as $datetime) { |
|
549 | - if (! $datetime instanceof EE_Datetime) { |
|
550 | - continue; |
|
551 | - } |
|
552 | - |
|
553 | - /** @var EE_Checkin $checkin_row */ |
|
554 | - $checkin_row = EEM_Checkin::instance()->get_one( |
|
555 | - [ |
|
556 | - [ |
|
557 | - 'REG_ID' => $reg_row['Registration.REG_ID'], |
|
558 | - 'DTT_ID' => $datetime->get('DTT_ID'), |
|
559 | - ], |
|
560 | - 'limit' => 1, |
|
561 | - 'order_by' => [ |
|
562 | - 'CHK_ID' => 'DESC' |
|
563 | - ] |
|
564 | - ] |
|
565 | - ); |
|
566 | - |
|
567 | - $checkin_value = CheckinsCSV::getCheckinValue($checkin_row); |
|
568 | - $datetime_name = CheckinsCSV::getDatetimeLabel($datetime); |
|
569 | - |
|
570 | - $reg_csv_array[ $datetime_name ] = $checkin_value; |
|
571 | - } |
|
572 | - } |
|
573 | - /** |
|
574 | - * Filter to change the contents of each row of the registrations report CSV file. |
|
575 | - * This can be used to add or remote columns from the CSV file, or change their values. |
|
576 | - * Note when using: all rows in the CSV should have the same columns. |
|
577 | - * |
|
578 | - * @param array $reg_csv_array keys are the column names, values are their cell values |
|
579 | - * @param array $reg_row one entry from EEM_Registration::get_all_wpdb_results() |
|
580 | - */ |
|
581 | - $registrations_csv_ready_array[] = apply_filters( |
|
582 | - 'FHEE__EventEspressoBatchRequest__JobHandlers__RegistrationsReport__reg_csv_array', |
|
583 | - $reg_csv_array, |
|
584 | - $reg_row |
|
585 | - ); |
|
586 | - } |
|
587 | - // if we couldn't export anything, we want to at least show the column headers |
|
588 | - if (empty($registrations_csv_ready_array)) { |
|
589 | - $reg_csv_array = []; |
|
590 | - $model_and_fields_to_include = [ |
|
591 | - 'Registration' => $reg_fields_to_include, |
|
592 | - 'Attendee' => $att_fields_to_include, |
|
593 | - ]; |
|
594 | - foreach ($model_and_fields_to_include as $model_name => $field_list) { |
|
595 | - $model = EE_Registry::instance()->load_model($model_name); |
|
596 | - foreach ($field_list as $field_name) { |
|
597 | - $field = |
|
598 | - $model->field_settings_for($field_name); |
|
599 | - $reg_csv_array[ EEH_Export::get_column_name_for_field($field) ] = null; |
|
600 | - } |
|
601 | - } |
|
602 | - $registrations_csv_ready_array[] = $reg_csv_array; |
|
603 | - } |
|
604 | - return $registrations_csv_ready_array; |
|
605 | - } |
|
606 | - |
|
607 | - |
|
608 | - /** |
|
609 | - * recursively convert MySQL format date strings in query params array to Datetime objects |
|
610 | - * |
|
611 | - * @param array $query_params |
|
612 | - * @param DateTimeZone $site_timezone |
|
613 | - * @param DateTimeZone $utc_timezone |
|
614 | - * @return array |
|
615 | - * @throws Exception |
|
616 | - * @since 5.0.19.p |
|
617 | - */ |
|
618 | - private function convertDateStringsToObjects( |
|
619 | - array $query_params, |
|
620 | - DateTimeZone $site_timezone, |
|
621 | - DateTimeZone $utc_timezone |
|
622 | - ): array { |
|
623 | - foreach ($query_params as $key => $value) { |
|
624 | - if (is_array($value)) { |
|
625 | - $query_params[ $key ] = $this->convertDateStringsToObjects($value, $site_timezone, $utc_timezone); |
|
626 | - continue; |
|
627 | - } |
|
628 | - if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value)) { |
|
629 | - $query_params[ $key ] = DbSafeDateTime::createFromFormat('Y-m-d H:i:s', $value, $site_timezone); |
|
630 | - $query_params[ $key ] = $query_params[ $key ]->setTimezone($utc_timezone); |
|
631 | - } |
|
632 | - } |
|
633 | - return $query_params; |
|
634 | - } |
|
635 | - |
|
636 | - |
|
637 | - /** |
|
638 | - * Counts total unit to process |
|
639 | - * |
|
640 | - * @param array $query_params |
|
641 | - * @return int |
|
642 | - * @throws EE_Error |
|
643 | - * @throws ReflectionException |
|
644 | - */ |
|
645 | - public function count_units_to_process(array $query_params): int |
|
646 | - { |
|
647 | - return EEM_Registration::instance()->count( |
|
648 | - array_diff_key( |
|
649 | - $query_params, |
|
650 | - array_flip( |
|
651 | - ['limit'] |
|
652 | - ) |
|
653 | - ) |
|
654 | - ); |
|
655 | - } |
|
656 | - |
|
657 | - |
|
658 | - /** |
|
659 | - * Performs any clean-up logic when we know the job is completed. |
|
660 | - * In this case, we delete the temporary file |
|
661 | - * |
|
662 | - * @param JobParameters $job_parameters |
|
663 | - * @return JobStepResponse |
|
664 | - */ |
|
665 | - public function cleanup_job(JobParameters $job_parameters): JobStepResponse |
|
666 | - { |
|
667 | - $this->updateText(esc_html__('File Generation complete and downloaded', 'event_espresso')); |
|
668 | - |
|
669 | - $this->_file_helper->delete( |
|
670 | - EEH_File::remove_filename_from_filepath($job_parameters->extra_datum('filepath')), |
|
671 | - true, |
|
672 | - 'd' |
|
673 | - ); |
|
674 | - $this->updateText(esc_html__('Cleaned up temporary file', 'event_espresso')); |
|
675 | - $this->updateText( |
|
676 | - $this->infoWrapper( |
|
677 | - sprintf( |
|
678 | - esc_html__( |
|
679 | - 'If not automatically redirected in %1$s seconds, click here to return to the %2$sRegistrations List Table%3$s', |
|
680 | - 'event_espresso' |
|
681 | - ), |
|
682 | - '<span id="ee-redirect-timer">10</span>', |
|
683 | - '<a href="' . $job_parameters->request_datum('return_url') . '">', |
|
684 | - '</a>' |
|
685 | - ) |
|
686 | - ) |
|
687 | - ); |
|
688 | - return new JobStepResponse($job_parameters, $this->feedback); |
|
689 | - } |
|
50 | + // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
51 | + // phpcs:disable PSR2.Methods.MethodDeclaration.Underscore |
|
52 | + /** |
|
53 | + * Performs any necessary setup for starting the job. This is also a good |
|
54 | + * place to set up the $job_arguments which will be used for subsequent HTTP requests |
|
55 | + * when continue_job will be called |
|
56 | + * |
|
57 | + * @param JobParameters $job_parameters |
|
58 | + * @return JobStepResponse |
|
59 | + * @throws BatchRequestException |
|
60 | + * @throws EE_Error |
|
61 | + * @throws ReflectionException |
|
62 | + * @throws Exception |
|
63 | + */ |
|
64 | + public function create_job(JobParameters $job_parameters): JobStepResponse |
|
65 | + { |
|
66 | + $event_id = absint($job_parameters->request_datum('EVT_ID', '0')); |
|
67 | + $DTT_ID = absint($job_parameters->request_datum('DTT_ID', '0')); |
|
68 | + if (! EE_Capabilities::instance()->current_user_can('ee_read_registrations', 'generating_report')) { |
|
69 | + throw new BatchRequestException( |
|
70 | + esc_html__('You do not have permission to view registrations', 'event_espresso') |
|
71 | + ); |
|
72 | + } |
|
73 | + $filepath = $this->create_file_from_job_with_name( |
|
74 | + $job_parameters->job_id(), |
|
75 | + $this->get_filename() |
|
76 | + ); |
|
77 | + $job_parameters->add_extra_data('filepath', $filepath); |
|
78 | + |
|
79 | + if ($job_parameters->request_datum('use_filters', false)) { |
|
80 | + $query_params = maybe_unserialize($job_parameters->request_datum('filters', [])); |
|
81 | + } else { |
|
82 | + $query_params = [ |
|
83 | + [ 'Ticket.TKT_deleted' => ['IN', [true, false]] ], |
|
84 | + 'order_by' => ['Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'], |
|
85 | + 'force_join' => ['Transaction', 'Ticket', 'Attendee'], |
|
86 | + 'caps' => EEM_Base::caps_read_admin, |
|
87 | + ]; |
|
88 | + if ($event_id) { |
|
89 | + $query_params[0]['EVT_ID'] = $event_id; |
|
90 | + } else { |
|
91 | + $query_params['force_join'][] = 'Event'; |
|
92 | + } |
|
93 | + } |
|
94 | + // unless the query params already include a status, |
|
95 | + // we want to exclude registrations from failed or abandoned transactions |
|
96 | + if (! isset($query_params[0]['Transaction.STS_ID'])) { |
|
97 | + $query_params[0]['OR'] = [ |
|
98 | + // don't include registrations from failed or abandoned transactions... |
|
99 | + 'Transaction.STS_ID' => [ |
|
100 | + 'NOT IN', |
|
101 | + [ |
|
102 | + EEM_Transaction::failed_status_code, |
|
103 | + EEM_Transaction::abandoned_status_code, |
|
104 | + ], |
|
105 | + ], |
|
106 | + // unless the registration is approved, |
|
107 | + // in which case include it regardless of transaction status |
|
108 | + 'STS_ID' => RegStatus::APPROVED, |
|
109 | + ]; |
|
110 | + } |
|
111 | + |
|
112 | + if (! isset($query_params['force_join'])) { |
|
113 | + $query_params['force_join'] = ['Event', 'Transaction', 'Ticket', 'Attendee']; |
|
114 | + } |
|
115 | + |
|
116 | + $return_url_args = []; |
|
117 | + parse_str( |
|
118 | + parse_url( |
|
119 | + $job_parameters->request_datum('return_url'), |
|
120 | + PHP_URL_QUERY |
|
121 | + ), |
|
122 | + $return_url_args |
|
123 | + ); |
|
124 | + |
|
125 | + if ( |
|
126 | + isset($return_url_args['orderby'], $return_url_args['order']) |
|
127 | + && $return_url_args['orderby'] === 'ATT_lname' |
|
128 | + ) { |
|
129 | + $query_params['order_by'] = [ |
|
130 | + 'Attendee.ATT_lname' => $return_url_args['order'], |
|
131 | + 'Attendee.ATT_fname' => $return_url_args['order'], |
|
132 | + 'REG_ID' => $return_url_args['order'] |
|
133 | + ]; |
|
134 | + } |
|
135 | + |
|
136 | + $query_params = apply_filters( |
|
137 | + 'FHEE__EE_Export__report_registration_for_event', |
|
138 | + $query_params, |
|
139 | + $event_id |
|
140 | + ); |
|
141 | + |
|
142 | + $utc_timezone = new DateTimeZone('UTC'); |
|
143 | + $site_timezone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); |
|
144 | + $query_params = $this->convertDateStringsToObjects($query_params, $site_timezone, $utc_timezone); |
|
145 | + |
|
146 | + $job_parameters->add_extra_data('query_params', $query_params); |
|
147 | + $question_labels = $this->_get_question_labels($query_params); |
|
148 | + $job_parameters->add_extra_data('question_labels', $question_labels); |
|
149 | + $job_parameters->set_job_size($this->count_units_to_process($query_params)); |
|
150 | + // we need to set the header columns |
|
151 | + // but to do that we need to process one row so that we can extract ALL the column headers |
|
152 | + $csv_data_for_row = $this->get_csv_data_for( |
|
153 | + $event_id, |
|
154 | + 0, |
|
155 | + 1, |
|
156 | + $question_labels, |
|
157 | + $query_params, |
|
158 | + $DTT_ID |
|
159 | + ); |
|
160 | + // but we don't want to write any actual data yet... |
|
161 | + // so let's blank out all the values for that first row |
|
162 | + array_walk( |
|
163 | + $csv_data_for_row[0], |
|
164 | + function (&$value) { |
|
165 | + $value = null; |
|
166 | + } |
|
167 | + ); |
|
168 | + |
|
169 | + EEH_Export::write_data_array_to_csv($filepath, $csv_data_for_row, true, true); |
|
170 | + $this->updateTextHeader( |
|
171 | + esc_html__('Registrations report started successfully...', 'event_espresso') |
|
172 | + ); |
|
173 | + return new JobStepResponse($job_parameters, $this->feedback); |
|
174 | + } |
|
175 | + |
|
176 | + |
|
177 | + /** |
|
178 | + * Gets the filename |
|
179 | + * |
|
180 | + * @return string |
|
181 | + */ |
|
182 | + protected function get_filename(): string |
|
183 | + { |
|
184 | + return apply_filters( |
|
185 | + 'FHEE__EventEspressoBatchRequest__JobHandlers__RegistrationsReport__get_filename', |
|
186 | + sprintf( |
|
187 | + 'event-espresso-registrations-%s.csv', |
|
188 | + str_replace([':', ' '], '-', current_time('mysql')) |
|
189 | + ) |
|
190 | + ); |
|
191 | + } |
|
192 | + |
|
193 | + |
|
194 | + /** |
|
195 | + * Gets the questions which are to be used for this report, |
|
196 | + * so they can be remembered for later |
|
197 | + * |
|
198 | + * @param array $registration_query_params |
|
199 | + * @return array question admin labels to be used for this report |
|
200 | + * @throws EE_Error |
|
201 | + * @throws ReflectionException |
|
202 | + */ |
|
203 | + protected function _get_question_labels(array $registration_query_params): array |
|
204 | + { |
|
205 | + $where = $registration_query_params[0] ?? null; |
|
206 | + $question_query_params = []; |
|
207 | + if ($where !== null) { |
|
208 | + $question_query_params = [ |
|
209 | + $this->_change_registration_where_params_to_question_where_params($registration_query_params[0]), |
|
210 | + ]; |
|
211 | + } |
|
212 | + // Make sure it's not a system question |
|
213 | + $question_query_params[0]['OR*not-system-questions'] = [ |
|
214 | + 'QST_system' => '', |
|
215 | + 'QST_system*null' => ['IS_NULL'] |
|
216 | + ]; |
|
217 | + if ( |
|
218 | + apply_filters( |
|
219 | + 'FHEE__EventEspressoBatchRequest__JobHandlers__RegistrationsReport___get_question_labels__only_include_answered_questions', |
|
220 | + false, |
|
221 | + $registration_query_params |
|
222 | + ) |
|
223 | + ) { |
|
224 | + $question_query_params[0]['Answer.ANS_ID'] = ['IS_NOT_NULL']; |
|
225 | + } |
|
226 | + $question_query_params['order_by'] = [ |
|
227 | + 'Question_Group_Question.QGQ_order' => 'ASC', |
|
228 | + 'QST_order' => 'ASC', |
|
229 | + 'QST_admin_label' => 'ASC' |
|
230 | + ]; |
|
231 | + $question_query_params['group_by'] = ['QST_ID']; |
|
232 | + return array_unique(EEM_Question::instance()->get_col($question_query_params, 'QST_admin_label')); |
|
233 | + } |
|
234 | + |
|
235 | + |
|
236 | + /** |
|
237 | + * Takes where params meant for registrations and changes them to work for questions |
|
238 | + * |
|
239 | + * @param array $reg_where_params |
|
240 | + * @return array |
|
241 | + * @throws EE_Error |
|
242 | + * @throws ReflectionException |
|
243 | + */ |
|
244 | + protected function _change_registration_where_params_to_question_where_params(array $reg_where_params): array |
|
245 | + { |
|
246 | + $question_where_params = []; |
|
247 | + foreach ($reg_where_params as $key => $val) { |
|
248 | + if (EEM_Registration::instance()->is_logic_query_param_key($key)) { |
|
249 | + $question_where_params[ $key ] = |
|
250 | + $this->_change_registration_where_params_to_question_where_params($val); |
|
251 | + } else { |
|
252 | + // it's a normal where condition |
|
253 | + $question_where_params[ 'Question_Group.Event.Registration.' . $key ] = $val; |
|
254 | + } |
|
255 | + } |
|
256 | + return $question_where_params; |
|
257 | + } |
|
258 | + |
|
259 | + |
|
260 | + /** |
|
261 | + * Performs another step of the job |
|
262 | + * |
|
263 | + * @param JobParameters $job_parameters |
|
264 | + * @param int $batch_size |
|
265 | + * @return JobStepResponse |
|
266 | + * @throws EE_Error |
|
267 | + * @throws ReflectionException |
|
268 | + */ |
|
269 | + public function continue_job(JobParameters $job_parameters, int $batch_size = 50): JobStepResponse |
|
270 | + { |
|
271 | + if ($job_parameters->units_processed() < $job_parameters->job_size()) { |
|
272 | + $csv_data = $this->get_csv_data_for( |
|
273 | + (int) $job_parameters->request_datum('EVT_ID', '0'), |
|
274 | + $job_parameters->units_processed(), |
|
275 | + $batch_size, |
|
276 | + $job_parameters->extra_datum('question_labels'), |
|
277 | + $job_parameters->extra_datum('query_params'), |
|
278 | + (int) $job_parameters->request_datum('DTT_ID', '0') |
|
279 | + ); |
|
280 | + EEH_Export::write_data_array_to_csv( |
|
281 | + $job_parameters->extra_datum('filepath'), |
|
282 | + $csv_data, |
|
283 | + false |
|
284 | + ); |
|
285 | + $units_processed = count($csv_data); |
|
286 | + if ($units_processed) { |
|
287 | + $job_parameters->mark_processed($units_processed); |
|
288 | + $this->updateText( |
|
289 | + sprintf( |
|
290 | + esc_html__('Wrote %1$s rows to report CSV file...', 'event_espresso'), |
|
291 | + $units_processed |
|
292 | + ) |
|
293 | + ); |
|
294 | + } |
|
295 | + } |
|
296 | + $extra_response_data = ['file_url' => '']; |
|
297 | + if ($job_parameters->units_processed() >= $job_parameters->job_size()) { |
|
298 | + $job_parameters->set_status(JobParameters::status_complete); |
|
299 | + $extra_response_data['file_url'] = $this->get_url_to_file($job_parameters->extra_datum('filepath')); |
|
300 | + $this->displayJobFinalResults($job_parameters); |
|
301 | + } else { |
|
302 | + $job_parameters->set_status(JobParameters::status_continue); |
|
303 | + } |
|
304 | + return new JobStepResponse($job_parameters, $this->feedback, $extra_response_data); |
|
305 | + } |
|
306 | + |
|
307 | + |
|
308 | + /** |
|
309 | + * Gets the csv data for a batch of registrations |
|
310 | + * |
|
311 | + * @param int|null $event_id |
|
312 | + * @param int $offset |
|
313 | + * @param int $limit |
|
314 | + * @param array $question_labels the IDs for all the questions which were answered by someone in this selection |
|
315 | + * @param array $query_params for using where querying the model |
|
316 | + * @param int $DTT_ID |
|
317 | + * @return array top-level keys are numeric, next-level keys are column headers |
|
318 | + * @throws EE_Error |
|
319 | + * @throws ReflectionException |
|
320 | + */ |
|
321 | + public function get_csv_data_for( |
|
322 | + ?int $event_id, |
|
323 | + int $offset, |
|
324 | + int $limit, |
|
325 | + array $question_labels, |
|
326 | + array $query_params, |
|
327 | + int $DTT_ID = 0 |
|
328 | + ): array { |
|
329 | + $reg_fields_to_include = [ |
|
330 | + 'TXN_ID', |
|
331 | + 'ATT_ID', |
|
332 | + 'REG_ID', |
|
333 | + 'REG_date', |
|
334 | + 'REG_code', |
|
335 | + 'REG_count', |
|
336 | + 'REG_final_price', |
|
337 | + ]; |
|
338 | + $att_fields_to_include = [ |
|
339 | + 'ATT_fname', |
|
340 | + 'ATT_lname', |
|
341 | + 'ATT_email', |
|
342 | + 'ATT_address', |
|
343 | + 'ATT_address2', |
|
344 | + 'ATT_city', |
|
345 | + 'STA_ID', |
|
346 | + 'CNT_ISO', |
|
347 | + 'ATT_zip', |
|
348 | + 'ATT_phone', |
|
349 | + ]; |
|
350 | + |
|
351 | + // get models |
|
352 | + $event_model = EEM_Event::instance(); |
|
353 | + $date_model = EEM_Datetime::instance(); |
|
354 | + $ticket_model = EEM_Ticket::instance(); |
|
355 | + $txn_model = EEM_Transaction::instance(); |
|
356 | + $reg_model = EEM_Registration::instance(); |
|
357 | + $pay_model = EEM_Payment::instance(); |
|
358 | + $status_model = EEM_Status::instance(); |
|
359 | + |
|
360 | + $registrations_csv_ready_array = []; |
|
361 | + $query_params['limit'] = [$offset, $limit]; |
|
362 | + $registration_rows = $reg_model->get_all_wpdb_results($query_params); |
|
363 | + |
|
364 | + foreach ($registration_rows as $reg_row) { |
|
365 | + if (! is_array($reg_row)) { |
|
366 | + continue; |
|
367 | + } |
|
368 | + $reg_csv_array = []; |
|
369 | + // registration ID |
|
370 | + $reg_id_field = $reg_model->field_settings_for('REG_ID'); |
|
371 | + $reg_csv_array[ EEH_Export::get_column_name_for_field($reg_id_field) ] = |
|
372 | + EEH_Export::prepare_value_from_db_for_display( |
|
373 | + $reg_model, |
|
374 | + 'REG_ID', |
|
375 | + $reg_row[ $reg_id_field->get_qualified_column() ] |
|
376 | + ); |
|
377 | + // ALL registrations, or is list filtered to just one? |
|
378 | + if (! $event_id) { |
|
379 | + // ALL registrations, so get each event's name and ID |
|
380 | + $reg_csv_array[ esc_html__('Event', 'event_espresso') ] = sprintf( |
|
381 | + /* translators: 1: event name, 2: event ID */ |
|
382 | + esc_html__('%1$s (%2$s)', 'event_espresso'), |
|
383 | + EEH_Export::prepare_value_from_db_for_display( |
|
384 | + $event_model, |
|
385 | + 'EVT_name', |
|
386 | + $reg_row['Event_CPT.post_title'] |
|
387 | + ), |
|
388 | + $reg_row['Event_CPT.ID'] |
|
389 | + ); |
|
390 | + } |
|
391 | + // add attendee columns |
|
392 | + $reg_csv_array = AttendeeCSV::addAttendeeColumns($att_fields_to_include, $reg_row, $reg_csv_array); |
|
393 | + // add registration columns |
|
394 | + $reg_csv_array = RegistrationCSV::addRegistrationColumns($reg_fields_to_include, $reg_row, $reg_csv_array); |
|
395 | + // get pretty status |
|
396 | + $stati = $status_model->localized_status( |
|
397 | + [ |
|
398 | + $reg_row['Registration.STS_ID'] => esc_html__('unknown', 'event_espresso'), |
|
399 | + $reg_row['TransactionTable.STS_ID'] => esc_html__('unknown', 'event_espresso'), |
|
400 | + ], |
|
401 | + false, |
|
402 | + 'sentence' |
|
403 | + ); |
|
404 | + $is_primary_reg = $reg_row['Registration.REG_count'] == '1'; |
|
405 | + |
|
406 | + $reg_csv_array[ esc_html__('Registration Status', 'event_espresso') ] = |
|
407 | + $stati[ $reg_row['Registration.STS_ID'] ]; |
|
408 | + // get pretty transaction status |
|
409 | + $reg_csv_array[ esc_html__('Transaction Status', 'event_espresso') ] = |
|
410 | + $stati[ $reg_row['TransactionTable.STS_ID'] ]; |
|
411 | + $reg_csv_array[ esc_html__('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg |
|
412 | + ? EEH_Export::prepare_value_from_db_for_display( |
|
413 | + $txn_model, |
|
414 | + 'TXN_total', |
|
415 | + $reg_row['TransactionTable.TXN_total'], |
|
416 | + 'localized_float' |
|
417 | + ) |
|
418 | + : '0.00'; |
|
419 | + |
|
420 | + $reg_csv_array[ esc_html__('Amount Paid', 'event_espresso') ] = $is_primary_reg |
|
421 | + ? EEH_Export::prepare_value_from_db_for_display( |
|
422 | + $txn_model, |
|
423 | + 'TXN_paid', |
|
424 | + $reg_row['TransactionTable.TXN_paid'], |
|
425 | + 'localized_float' |
|
426 | + ) |
|
427 | + : '0.00'; |
|
428 | + |
|
429 | + $payment_methods = []; |
|
430 | + $gateway_txn_ids_etc = []; |
|
431 | + $payment_times = []; |
|
432 | + if ($is_primary_reg && $reg_row['TransactionTable.TXN_ID']) { |
|
433 | + $payments_info = $pay_model->get_all_wpdb_results( |
|
434 | + [ |
|
435 | + [ |
|
436 | + 'TXN_ID' => $reg_row['TransactionTable.TXN_ID'], |
|
437 | + 'STS_ID' => EEM_Payment::status_id_approved, |
|
438 | + ], |
|
439 | + 'force_join' => ['Payment_Method'], |
|
440 | + ], |
|
441 | + ARRAY_A, |
|
442 | + 'Payment_Method.PMD_admin_name as name, Payment.PAY_txn_id_chq_nmbr as gateway_txn_id, Payment.PAY_timestamp as payment_time' |
|
443 | + ); |
|
444 | + [$payment_methods, $gateway_txn_ids_etc, $payment_times] = PaymentsInfoCSV::extractPaymentInfo( |
|
445 | + $payments_info |
|
446 | + ); |
|
447 | + } |
|
448 | + |
|
449 | + $reg_csv_array[ esc_html__('Payment Date(s)', 'event_espresso') ] = implode( |
|
450 | + ',', |
|
451 | + $payment_times |
|
452 | + ); |
|
453 | + |
|
454 | + $reg_csv_array[ esc_html__('Payment Method(s)', 'event_espresso') ] = implode( |
|
455 | + ',', |
|
456 | + $payment_methods |
|
457 | + ); |
|
458 | + |
|
459 | + $reg_csv_array[ esc_html__('Gateway Transaction ID(s)', 'event_espresso') ] = implode( |
|
460 | + ',', |
|
461 | + $gateway_txn_ids_etc |
|
462 | + ); |
|
463 | + |
|
464 | + $ticket_name = esc_html__('Unknown', 'event_espresso'); |
|
465 | + $datetime_strings = [esc_html__('Unknown', 'event_espresso')]; |
|
466 | + if ($reg_row['Ticket.TKT_ID']) { |
|
467 | + $ticket_name = EEH_Export::prepare_value_from_db_for_display( |
|
468 | + $ticket_model, |
|
469 | + 'TKT_name', |
|
470 | + $reg_row['Ticket.TKT_name'] |
|
471 | + ); |
|
472 | + $datetime_strings = []; |
|
473 | + $datetimes = $date_model->get_all_wpdb_results( |
|
474 | + [ |
|
475 | + ['Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID']], |
|
476 | + 'order_by' => ['DTT_EVT_start' => 'ASC'], |
|
477 | + 'default_where_conditions' => 'none', |
|
478 | + ] |
|
479 | + ); |
|
480 | + foreach ($datetimes as $datetime) { |
|
481 | + $datetime_strings[] = EEH_Export::prepare_value_from_db_for_display( |
|
482 | + $date_model, |
|
483 | + 'DTT_EVT_start', |
|
484 | + $datetime['Datetime.DTT_EVT_start'] |
|
485 | + ); |
|
486 | + } |
|
487 | + } |
|
488 | + |
|
489 | + $reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name; |
|
490 | + |
|
491 | + |
|
492 | + $reg_csv_array[ esc_html__('Ticket Datetimes', 'event_espresso') ] = implode( |
|
493 | + ', ', |
|
494 | + $datetime_strings |
|
495 | + ); |
|
496 | + |
|
497 | + // add answer columns |
|
498 | + $reg_csv_array = AnswersCSV::addAnswerColumns($reg_row, $reg_csv_array, $question_labels); |
|
499 | + // Include check-in data |
|
500 | + if ($event_id && $DTT_ID) { |
|
501 | + // get whether the user has checked in |
|
502 | + $reg_csv_array[ esc_html__('Datetime Check-ins #', 'event_espresso') ] = |
|
503 | + $reg_model->count_related( |
|
504 | + $reg_row['Registration.REG_ID'], |
|
505 | + 'Checkin', |
|
506 | + [ |
|
507 | + [ |
|
508 | + 'DTT_ID' => $DTT_ID |
|
509 | + ] |
|
510 | + ] |
|
511 | + ); |
|
512 | + $datetime = $date_model->get_one_by_ID($DTT_ID); |
|
513 | + $checkin_rows = EEM_Checkin::instance()->get_all( |
|
514 | + [ |
|
515 | + [ |
|
516 | + 'REG_ID' => $reg_row['Registration.REG_ID'], |
|
517 | + 'DTT_ID' => $datetime->get('DTT_ID'), |
|
518 | + ], |
|
519 | + ] |
|
520 | + ); |
|
521 | + $checkins = []; |
|
522 | + foreach ($checkin_rows as $checkin_row) { |
|
523 | + /** @var EE_Checkin $checkin_row */ |
|
524 | + $checkin_value = CheckinsCSV::getCheckinValue($checkin_row); |
|
525 | + if ($checkin_value) { |
|
526 | + $checkins[] = $checkin_value; |
|
527 | + } |
|
528 | + } |
|
529 | + $datetime_name = CheckinsCSV::getDatetimeLabel($datetime); |
|
530 | + $reg_csv_array[ $datetime_name ] = implode(' --- ', $checkins); |
|
531 | + } elseif ($event_id) { |
|
532 | + // get whether the user has checked in |
|
533 | + $reg_csv_array[ esc_html__('Event Check-ins #', 'event_espresso') ] = |
|
534 | + $reg_model->count_related( |
|
535 | + $reg_row['Registration.REG_ID'], |
|
536 | + 'Checkin' |
|
537 | + ); |
|
538 | + |
|
539 | + $datetimes = $date_model->get_all( |
|
540 | + [ |
|
541 | + [ |
|
542 | + 'Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID'], |
|
543 | + ], |
|
544 | + 'order_by' => ['DTT_EVT_start' => 'ASC'], |
|
545 | + 'default_where_conditions' => 'none', |
|
546 | + ] |
|
547 | + ); |
|
548 | + foreach ($datetimes as $datetime) { |
|
549 | + if (! $datetime instanceof EE_Datetime) { |
|
550 | + continue; |
|
551 | + } |
|
552 | + |
|
553 | + /** @var EE_Checkin $checkin_row */ |
|
554 | + $checkin_row = EEM_Checkin::instance()->get_one( |
|
555 | + [ |
|
556 | + [ |
|
557 | + 'REG_ID' => $reg_row['Registration.REG_ID'], |
|
558 | + 'DTT_ID' => $datetime->get('DTT_ID'), |
|
559 | + ], |
|
560 | + 'limit' => 1, |
|
561 | + 'order_by' => [ |
|
562 | + 'CHK_ID' => 'DESC' |
|
563 | + ] |
|
564 | + ] |
|
565 | + ); |
|
566 | + |
|
567 | + $checkin_value = CheckinsCSV::getCheckinValue($checkin_row); |
|
568 | + $datetime_name = CheckinsCSV::getDatetimeLabel($datetime); |
|
569 | + |
|
570 | + $reg_csv_array[ $datetime_name ] = $checkin_value; |
|
571 | + } |
|
572 | + } |
|
573 | + /** |
|
574 | + * Filter to change the contents of each row of the registrations report CSV file. |
|
575 | + * This can be used to add or remote columns from the CSV file, or change their values. |
|
576 | + * Note when using: all rows in the CSV should have the same columns. |
|
577 | + * |
|
578 | + * @param array $reg_csv_array keys are the column names, values are their cell values |
|
579 | + * @param array $reg_row one entry from EEM_Registration::get_all_wpdb_results() |
|
580 | + */ |
|
581 | + $registrations_csv_ready_array[] = apply_filters( |
|
582 | + 'FHEE__EventEspressoBatchRequest__JobHandlers__RegistrationsReport__reg_csv_array', |
|
583 | + $reg_csv_array, |
|
584 | + $reg_row |
|
585 | + ); |
|
586 | + } |
|
587 | + // if we couldn't export anything, we want to at least show the column headers |
|
588 | + if (empty($registrations_csv_ready_array)) { |
|
589 | + $reg_csv_array = []; |
|
590 | + $model_and_fields_to_include = [ |
|
591 | + 'Registration' => $reg_fields_to_include, |
|
592 | + 'Attendee' => $att_fields_to_include, |
|
593 | + ]; |
|
594 | + foreach ($model_and_fields_to_include as $model_name => $field_list) { |
|
595 | + $model = EE_Registry::instance()->load_model($model_name); |
|
596 | + foreach ($field_list as $field_name) { |
|
597 | + $field = |
|
598 | + $model->field_settings_for($field_name); |
|
599 | + $reg_csv_array[ EEH_Export::get_column_name_for_field($field) ] = null; |
|
600 | + } |
|
601 | + } |
|
602 | + $registrations_csv_ready_array[] = $reg_csv_array; |
|
603 | + } |
|
604 | + return $registrations_csv_ready_array; |
|
605 | + } |
|
606 | + |
|
607 | + |
|
608 | + /** |
|
609 | + * recursively convert MySQL format date strings in query params array to Datetime objects |
|
610 | + * |
|
611 | + * @param array $query_params |
|
612 | + * @param DateTimeZone $site_timezone |
|
613 | + * @param DateTimeZone $utc_timezone |
|
614 | + * @return array |
|
615 | + * @throws Exception |
|
616 | + * @since 5.0.19.p |
|
617 | + */ |
|
618 | + private function convertDateStringsToObjects( |
|
619 | + array $query_params, |
|
620 | + DateTimeZone $site_timezone, |
|
621 | + DateTimeZone $utc_timezone |
|
622 | + ): array { |
|
623 | + foreach ($query_params as $key => $value) { |
|
624 | + if (is_array($value)) { |
|
625 | + $query_params[ $key ] = $this->convertDateStringsToObjects($value, $site_timezone, $utc_timezone); |
|
626 | + continue; |
|
627 | + } |
|
628 | + if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value)) { |
|
629 | + $query_params[ $key ] = DbSafeDateTime::createFromFormat('Y-m-d H:i:s', $value, $site_timezone); |
|
630 | + $query_params[ $key ] = $query_params[ $key ]->setTimezone($utc_timezone); |
|
631 | + } |
|
632 | + } |
|
633 | + return $query_params; |
|
634 | + } |
|
635 | + |
|
636 | + |
|
637 | + /** |
|
638 | + * Counts total unit to process |
|
639 | + * |
|
640 | + * @param array $query_params |
|
641 | + * @return int |
|
642 | + * @throws EE_Error |
|
643 | + * @throws ReflectionException |
|
644 | + */ |
|
645 | + public function count_units_to_process(array $query_params): int |
|
646 | + { |
|
647 | + return EEM_Registration::instance()->count( |
|
648 | + array_diff_key( |
|
649 | + $query_params, |
|
650 | + array_flip( |
|
651 | + ['limit'] |
|
652 | + ) |
|
653 | + ) |
|
654 | + ); |
|
655 | + } |
|
656 | + |
|
657 | + |
|
658 | + /** |
|
659 | + * Performs any clean-up logic when we know the job is completed. |
|
660 | + * In this case, we delete the temporary file |
|
661 | + * |
|
662 | + * @param JobParameters $job_parameters |
|
663 | + * @return JobStepResponse |
|
664 | + */ |
|
665 | + public function cleanup_job(JobParameters $job_parameters): JobStepResponse |
|
666 | + { |
|
667 | + $this->updateText(esc_html__('File Generation complete and downloaded', 'event_espresso')); |
|
668 | + |
|
669 | + $this->_file_helper->delete( |
|
670 | + EEH_File::remove_filename_from_filepath($job_parameters->extra_datum('filepath')), |
|
671 | + true, |
|
672 | + 'd' |
|
673 | + ); |
|
674 | + $this->updateText(esc_html__('Cleaned up temporary file', 'event_espresso')); |
|
675 | + $this->updateText( |
|
676 | + $this->infoWrapper( |
|
677 | + sprintf( |
|
678 | + esc_html__( |
|
679 | + 'If not automatically redirected in %1$s seconds, click here to return to the %2$sRegistrations List Table%3$s', |
|
680 | + 'event_espresso' |
|
681 | + ), |
|
682 | + '<span id="ee-redirect-timer">10</span>', |
|
683 | + '<a href="' . $job_parameters->request_datum('return_url') . '">', |
|
684 | + '</a>' |
|
685 | + ) |
|
686 | + ) |
|
687 | + ); |
|
688 | + return new JobStepResponse($job_parameters, $this->feedback); |
|
689 | + } |
|
690 | 690 | } |
@@ -65,7 +65,7 @@ discard block |
||
65 | 65 | { |
66 | 66 | $event_id = absint($job_parameters->request_datum('EVT_ID', '0')); |
67 | 67 | $DTT_ID = absint($job_parameters->request_datum('DTT_ID', '0')); |
68 | - if (! EE_Capabilities::instance()->current_user_can('ee_read_registrations', 'generating_report')) { |
|
68 | + if ( ! EE_Capabilities::instance()->current_user_can('ee_read_registrations', 'generating_report')) { |
|
69 | 69 | throw new BatchRequestException( |
70 | 70 | esc_html__('You do not have permission to view registrations', 'event_espresso') |
71 | 71 | ); |
@@ -80,7 +80,7 @@ discard block |
||
80 | 80 | $query_params = maybe_unserialize($job_parameters->request_datum('filters', [])); |
81 | 81 | } else { |
82 | 82 | $query_params = [ |
83 | - [ 'Ticket.TKT_deleted' => ['IN', [true, false]] ], |
|
83 | + ['Ticket.TKT_deleted' => ['IN', [true, false]]], |
|
84 | 84 | 'order_by' => ['Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'], |
85 | 85 | 'force_join' => ['Transaction', 'Ticket', 'Attendee'], |
86 | 86 | 'caps' => EEM_Base::caps_read_admin, |
@@ -93,7 +93,7 @@ discard block |
||
93 | 93 | } |
94 | 94 | // unless the query params already include a status, |
95 | 95 | // we want to exclude registrations from failed or abandoned transactions |
96 | - if (! isset($query_params[0]['Transaction.STS_ID'])) { |
|
96 | + if ( ! isset($query_params[0]['Transaction.STS_ID'])) { |
|
97 | 97 | $query_params[0]['OR'] = [ |
98 | 98 | // don't include registrations from failed or abandoned transactions... |
99 | 99 | 'Transaction.STS_ID' => [ |
@@ -109,7 +109,7 @@ discard block |
||
109 | 109 | ]; |
110 | 110 | } |
111 | 111 | |
112 | - if (! isset($query_params['force_join'])) { |
|
112 | + if ( ! isset($query_params['force_join'])) { |
|
113 | 113 | $query_params['force_join'] = ['Event', 'Transaction', 'Ticket', 'Attendee']; |
114 | 114 | } |
115 | 115 | |
@@ -161,7 +161,7 @@ discard block |
||
161 | 161 | // so let's blank out all the values for that first row |
162 | 162 | array_walk( |
163 | 163 | $csv_data_for_row[0], |
164 | - function (&$value) { |
|
164 | + function(&$value) { |
|
165 | 165 | $value = null; |
166 | 166 | } |
167 | 167 | ); |
@@ -246,11 +246,11 @@ discard block |
||
246 | 246 | $question_where_params = []; |
247 | 247 | foreach ($reg_where_params as $key => $val) { |
248 | 248 | if (EEM_Registration::instance()->is_logic_query_param_key($key)) { |
249 | - $question_where_params[ $key ] = |
|
249 | + $question_where_params[$key] = |
|
250 | 250 | $this->_change_registration_where_params_to_question_where_params($val); |
251 | 251 | } else { |
252 | 252 | // it's a normal where condition |
253 | - $question_where_params[ 'Question_Group.Event.Registration.' . $key ] = $val; |
|
253 | + $question_where_params['Question_Group.Event.Registration.'.$key] = $val; |
|
254 | 254 | } |
255 | 255 | } |
256 | 256 | return $question_where_params; |
@@ -362,22 +362,22 @@ discard block |
||
362 | 362 | $registration_rows = $reg_model->get_all_wpdb_results($query_params); |
363 | 363 | |
364 | 364 | foreach ($registration_rows as $reg_row) { |
365 | - if (! is_array($reg_row)) { |
|
365 | + if ( ! is_array($reg_row)) { |
|
366 | 366 | continue; |
367 | 367 | } |
368 | 368 | $reg_csv_array = []; |
369 | 369 | // registration ID |
370 | 370 | $reg_id_field = $reg_model->field_settings_for('REG_ID'); |
371 | - $reg_csv_array[ EEH_Export::get_column_name_for_field($reg_id_field) ] = |
|
371 | + $reg_csv_array[EEH_Export::get_column_name_for_field($reg_id_field)] = |
|
372 | 372 | EEH_Export::prepare_value_from_db_for_display( |
373 | 373 | $reg_model, |
374 | 374 | 'REG_ID', |
375 | - $reg_row[ $reg_id_field->get_qualified_column() ] |
|
375 | + $reg_row[$reg_id_field->get_qualified_column()] |
|
376 | 376 | ); |
377 | 377 | // ALL registrations, or is list filtered to just one? |
378 | - if (! $event_id) { |
|
378 | + if ( ! $event_id) { |
|
379 | 379 | // ALL registrations, so get each event's name and ID |
380 | - $reg_csv_array[ esc_html__('Event', 'event_espresso') ] = sprintf( |
|
380 | + $reg_csv_array[esc_html__('Event', 'event_espresso')] = sprintf( |
|
381 | 381 | /* translators: 1: event name, 2: event ID */ |
382 | 382 | esc_html__('%1$s (%2$s)', 'event_espresso'), |
383 | 383 | EEH_Export::prepare_value_from_db_for_display( |
@@ -403,12 +403,12 @@ discard block |
||
403 | 403 | ); |
404 | 404 | $is_primary_reg = $reg_row['Registration.REG_count'] == '1'; |
405 | 405 | |
406 | - $reg_csv_array[ esc_html__('Registration Status', 'event_espresso') ] = |
|
407 | - $stati[ $reg_row['Registration.STS_ID'] ]; |
|
406 | + $reg_csv_array[esc_html__('Registration Status', 'event_espresso')] = |
|
407 | + $stati[$reg_row['Registration.STS_ID']]; |
|
408 | 408 | // get pretty transaction status |
409 | - $reg_csv_array[ esc_html__('Transaction Status', 'event_espresso') ] = |
|
410 | - $stati[ $reg_row['TransactionTable.STS_ID'] ]; |
|
411 | - $reg_csv_array[ esc_html__('Transaction Amount Due', 'event_espresso') ] = $is_primary_reg |
|
409 | + $reg_csv_array[esc_html__('Transaction Status', 'event_espresso')] = |
|
410 | + $stati[$reg_row['TransactionTable.STS_ID']]; |
|
411 | + $reg_csv_array[esc_html__('Transaction Amount Due', 'event_espresso')] = $is_primary_reg |
|
412 | 412 | ? EEH_Export::prepare_value_from_db_for_display( |
413 | 413 | $txn_model, |
414 | 414 | 'TXN_total', |
@@ -417,7 +417,7 @@ discard block |
||
417 | 417 | ) |
418 | 418 | : '0.00'; |
419 | 419 | |
420 | - $reg_csv_array[ esc_html__('Amount Paid', 'event_espresso') ] = $is_primary_reg |
|
420 | + $reg_csv_array[esc_html__('Amount Paid', 'event_espresso')] = $is_primary_reg |
|
421 | 421 | ? EEH_Export::prepare_value_from_db_for_display( |
422 | 422 | $txn_model, |
423 | 423 | 'TXN_paid', |
@@ -446,17 +446,17 @@ discard block |
||
446 | 446 | ); |
447 | 447 | } |
448 | 448 | |
449 | - $reg_csv_array[ esc_html__('Payment Date(s)', 'event_espresso') ] = implode( |
|
449 | + $reg_csv_array[esc_html__('Payment Date(s)', 'event_espresso')] = implode( |
|
450 | 450 | ',', |
451 | 451 | $payment_times |
452 | 452 | ); |
453 | 453 | |
454 | - $reg_csv_array[ esc_html__('Payment Method(s)', 'event_espresso') ] = implode( |
|
454 | + $reg_csv_array[esc_html__('Payment Method(s)', 'event_espresso')] = implode( |
|
455 | 455 | ',', |
456 | 456 | $payment_methods |
457 | 457 | ); |
458 | 458 | |
459 | - $reg_csv_array[ esc_html__('Gateway Transaction ID(s)', 'event_espresso') ] = implode( |
|
459 | + $reg_csv_array[esc_html__('Gateway Transaction ID(s)', 'event_espresso')] = implode( |
|
460 | 460 | ',', |
461 | 461 | $gateway_txn_ids_etc |
462 | 462 | ); |
@@ -464,7 +464,7 @@ discard block |
||
464 | 464 | $ticket_name = esc_html__('Unknown', 'event_espresso'); |
465 | 465 | $datetime_strings = [esc_html__('Unknown', 'event_espresso')]; |
466 | 466 | if ($reg_row['Ticket.TKT_ID']) { |
467 | - $ticket_name = EEH_Export::prepare_value_from_db_for_display( |
|
467 | + $ticket_name = EEH_Export::prepare_value_from_db_for_display( |
|
468 | 468 | $ticket_model, |
469 | 469 | 'TKT_name', |
470 | 470 | $reg_row['Ticket.TKT_name'] |
@@ -486,10 +486,10 @@ discard block |
||
486 | 486 | } |
487 | 487 | } |
488 | 488 | |
489 | - $reg_csv_array[ $ticket_model->field_settings_for('TKT_name')->get_nicename() ] = $ticket_name; |
|
489 | + $reg_csv_array[$ticket_model->field_settings_for('TKT_name')->get_nicename()] = $ticket_name; |
|
490 | 490 | |
491 | 491 | |
492 | - $reg_csv_array[ esc_html__('Ticket Datetimes', 'event_espresso') ] = implode( |
|
492 | + $reg_csv_array[esc_html__('Ticket Datetimes', 'event_espresso')] = implode( |
|
493 | 493 | ', ', |
494 | 494 | $datetime_strings |
495 | 495 | ); |
@@ -499,7 +499,7 @@ discard block |
||
499 | 499 | // Include check-in data |
500 | 500 | if ($event_id && $DTT_ID) { |
501 | 501 | // get whether the user has checked in |
502 | - $reg_csv_array[ esc_html__('Datetime Check-ins #', 'event_espresso') ] = |
|
502 | + $reg_csv_array[esc_html__('Datetime Check-ins #', 'event_espresso')] = |
|
503 | 503 | $reg_model->count_related( |
504 | 504 | $reg_row['Registration.REG_ID'], |
505 | 505 | 'Checkin', |
@@ -518,7 +518,7 @@ discard block |
||
518 | 518 | ], |
519 | 519 | ] |
520 | 520 | ); |
521 | - $checkins = []; |
|
521 | + $checkins = []; |
|
522 | 522 | foreach ($checkin_rows as $checkin_row) { |
523 | 523 | /** @var EE_Checkin $checkin_row */ |
524 | 524 | $checkin_value = CheckinsCSV::getCheckinValue($checkin_row); |
@@ -527,10 +527,10 @@ discard block |
||
527 | 527 | } |
528 | 528 | } |
529 | 529 | $datetime_name = CheckinsCSV::getDatetimeLabel($datetime); |
530 | - $reg_csv_array[ $datetime_name ] = implode(' --- ', $checkins); |
|
530 | + $reg_csv_array[$datetime_name] = implode(' --- ', $checkins); |
|
531 | 531 | } elseif ($event_id) { |
532 | 532 | // get whether the user has checked in |
533 | - $reg_csv_array[ esc_html__('Event Check-ins #', 'event_espresso') ] = |
|
533 | + $reg_csv_array[esc_html__('Event Check-ins #', 'event_espresso')] = |
|
534 | 534 | $reg_model->count_related( |
535 | 535 | $reg_row['Registration.REG_ID'], |
536 | 536 | 'Checkin' |
@@ -546,7 +546,7 @@ discard block |
||
546 | 546 | ] |
547 | 547 | ); |
548 | 548 | foreach ($datetimes as $datetime) { |
549 | - if (! $datetime instanceof EE_Datetime) { |
|
549 | + if ( ! $datetime instanceof EE_Datetime) { |
|
550 | 550 | continue; |
551 | 551 | } |
552 | 552 | |
@@ -567,7 +567,7 @@ discard block |
||
567 | 567 | $checkin_value = CheckinsCSV::getCheckinValue($checkin_row); |
568 | 568 | $datetime_name = CheckinsCSV::getDatetimeLabel($datetime); |
569 | 569 | |
570 | - $reg_csv_array[ $datetime_name ] = $checkin_value; |
|
570 | + $reg_csv_array[$datetime_name] = $checkin_value; |
|
571 | 571 | } |
572 | 572 | } |
573 | 573 | /** |
@@ -596,7 +596,7 @@ discard block |
||
596 | 596 | foreach ($field_list as $field_name) { |
597 | 597 | $field = |
598 | 598 | $model->field_settings_for($field_name); |
599 | - $reg_csv_array[ EEH_Export::get_column_name_for_field($field) ] = null; |
|
599 | + $reg_csv_array[EEH_Export::get_column_name_for_field($field)] = null; |
|
600 | 600 | } |
601 | 601 | } |
602 | 602 | $registrations_csv_ready_array[] = $reg_csv_array; |
@@ -622,12 +622,12 @@ discard block |
||
622 | 622 | ): array { |
623 | 623 | foreach ($query_params as $key => $value) { |
624 | 624 | if (is_array($value)) { |
625 | - $query_params[ $key ] = $this->convertDateStringsToObjects($value, $site_timezone, $utc_timezone); |
|
625 | + $query_params[$key] = $this->convertDateStringsToObjects($value, $site_timezone, $utc_timezone); |
|
626 | 626 | continue; |
627 | 627 | } |
628 | 628 | if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value)) { |
629 | - $query_params[ $key ] = DbSafeDateTime::createFromFormat('Y-m-d H:i:s', $value, $site_timezone); |
|
630 | - $query_params[ $key ] = $query_params[ $key ]->setTimezone($utc_timezone); |
|
629 | + $query_params[$key] = DbSafeDateTime::createFromFormat('Y-m-d H:i:s', $value, $site_timezone); |
|
630 | + $query_params[$key] = $query_params[$key]->setTimezone($utc_timezone); |
|
631 | 631 | } |
632 | 632 | } |
633 | 633 | return $query_params; |
@@ -680,7 +680,7 @@ discard block |
||
680 | 680 | 'event_espresso' |
681 | 681 | ), |
682 | 682 | '<span id="ee-redirect-timer">10</span>', |
683 | - '<a href="' . $job_parameters->request_datum('return_url') . '">', |
|
683 | + '<a href="'.$job_parameters->request_datum('return_url').'">', |
|
684 | 684 | '</a>' |
685 | 685 | ) |
686 | 686 | ) |
@@ -16,838 +16,838 @@ |
||
16 | 16 | */ |
17 | 17 | abstract class EE_PMT_Base |
18 | 18 | { |
19 | - const onsite = 'on-site'; |
|
20 | - |
|
21 | - const offsite = 'off-site'; |
|
22 | - |
|
23 | - const offline = 'off-line'; |
|
24 | - |
|
25 | - /** |
|
26 | - * @var EE_Payment_Method |
|
27 | - */ |
|
28 | - protected $_pm_instance = null; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var boolean |
|
32 | - */ |
|
33 | - protected $_requires_https = false; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var boolean |
|
37 | - */ |
|
38 | - protected $_has_billing_form; |
|
39 | - |
|
40 | - /** |
|
41 | - * @var EE_Gateway |
|
42 | - */ |
|
43 | - protected $_gateway = null; |
|
44 | - |
|
45 | - /** |
|
46 | - * @var EE_Payment_Method_Form |
|
47 | - */ |
|
48 | - protected $_settings_form = null; |
|
49 | - |
|
50 | - /** |
|
51 | - * @var EE_Form_Section_Proper |
|
52 | - */ |
|
53 | - protected $_billing_form = null; |
|
54 | - |
|
55 | - /** |
|
56 | - * @var boolean |
|
57 | - */ |
|
58 | - protected $_cache_billing_form = true; |
|
59 | - |
|
60 | - /** |
|
61 | - * String of the absolute path to the folder containing this file, with a trailing slash. |
|
62 | - * eg '/public_html/wp-site/wp-content/plugins/event-espresso/payment_methods/Invoice/' |
|
63 | - * |
|
64 | - * @var string|null |
|
65 | - */ |
|
66 | - protected $_file_folder = null; |
|
67 | - |
|
68 | - /** |
|
69 | - * String to the absolute URL to this file (useful for getting its web-accessible resources |
|
70 | - * like images, js, or css) |
|
71 | - * |
|
72 | - * @var string|null |
|
73 | - */ |
|
74 | - protected $_file_url = null; |
|
75 | - |
|
76 | - /** |
|
77 | - * Pretty name for the payment method |
|
78 | - * |
|
79 | - * @var string|null |
|
80 | - */ |
|
81 | - protected $_pretty_name = null; |
|
82 | - |
|
83 | - /** |
|
84 | - * @var string|null |
|
85 | - */ |
|
86 | - protected $_default_button_url = null; |
|
87 | - |
|
88 | - /** |
|
89 | - * @var string|null |
|
90 | - */ |
|
91 | - protected $_default_description = null; |
|
92 | - |
|
93 | - /** |
|
94 | - * @var string|null |
|
95 | - */ |
|
96 | - protected $_template_path = null; |
|
97 | - |
|
98 | - /** |
|
99 | - * @param EE_Payment_Method|null $pm_instance |
|
100 | - * @throws ReflectionException |
|
101 | - * @throws EE_Error |
|
102 | - */ |
|
103 | - public function __construct($pm_instance = null) |
|
104 | - { |
|
105 | - if ($pm_instance instanceof EE_Payment_Method) { |
|
106 | - $this->set_instance($pm_instance); |
|
107 | - } |
|
108 | - if ($this->_gateway) { |
|
109 | - $this->_gateway->set_payment_model(EEM_Payment::instance()); |
|
110 | - $this->_gateway->set_payment_log(EEM_Change_Log::instance()); |
|
111 | - $this->_gateway->set_template_helper(new EEH_Template()); |
|
112 | - $this->_gateway->set_line_item_helper(new EEH_Line_Item()); |
|
113 | - $this->_gateway->set_money_helper(new EEH_Money()); |
|
114 | - $this->_gateway->set_gateway_data_formatter(new GatewayDataFormatter()); |
|
115 | - $this->_gateway->set_unsupported_character_remover(new AsciiOnly()); |
|
116 | - do_action('AHEE__EE_PMT_Base___construct__done_initializing_gateway_class', $this, $this->_gateway); |
|
117 | - } |
|
118 | - if (! isset($this->_has_billing_form)) { |
|
119 | - // by default, On Site gateways have a billing form |
|
120 | - if ($this->payment_occurs() == EE_PMT_Base::onsite) { |
|
121 | - $this->set_has_billing_form(true); |
|
122 | - } else { |
|
123 | - $this->set_has_billing_form(false); |
|
124 | - } |
|
125 | - } |
|
126 | - |
|
127 | - if (! $this->_pretty_name) { |
|
128 | - throw new EE_Error( |
|
129 | - esc_html__( |
|
130 | - 'You must set the pretty name for the Payment Method Type in the constructor (_pretty_name), and please make it internationalized', |
|
131 | - 'event_espresso' |
|
132 | - ) |
|
133 | - ); |
|
134 | - } |
|
135 | - // if the child didn't specify a default button, use the credit card one |
|
136 | - if ($this->_default_button_url === null) { |
|
137 | - $this->_default_button_url = EE_PLUGIN_DIR_URL . 'payment_methods/pay-by-credit-card.png'; |
|
138 | - } |
|
139 | - } |
|
140 | - |
|
141 | - |
|
142 | - /** |
|
143 | - * @param boolean $has_billing_form |
|
144 | - */ |
|
145 | - public function set_has_billing_form(bool $has_billing_form) |
|
146 | - { |
|
147 | - $this->_has_billing_form = filter_var($has_billing_form, FILTER_VALIDATE_BOOLEAN); |
|
148 | - } |
|
149 | - |
|
150 | - |
|
151 | - /** |
|
152 | - * sets the file_folder property |
|
153 | - */ |
|
154 | - protected function _set_file_folder() |
|
155 | - { |
|
156 | - $reflector = new ReflectionClass(get_class($this)); |
|
157 | - $fn = $reflector->getFileName(); |
|
158 | - $this->_file_folder = dirname($fn) . '/'; |
|
159 | - } |
|
160 | - |
|
161 | - |
|
162 | - /** |
|
163 | - * sets the file URL with a trailing slash for this PMT |
|
164 | - */ |
|
165 | - protected function _set_file_url() |
|
166 | - { |
|
167 | - $plugins_dir_fixed = str_replace('\\', '/', WP_PLUGIN_DIR); |
|
168 | - $file_folder_fixed = str_replace('\\', '/', $this->file_folder()); |
|
169 | - $file_path = str_replace($plugins_dir_fixed, WP_PLUGIN_URL, $file_folder_fixed); |
|
170 | - $this->_file_url = set_url_scheme($file_path); |
|
171 | - } |
|
172 | - |
|
173 | - |
|
174 | - /** |
|
175 | - * Gets the default description on all payment methods of this type |
|
176 | - * |
|
177 | - * @return string |
|
178 | - */ |
|
179 | - public function default_description(): ?string |
|
180 | - { |
|
181 | - return $this->_default_description; |
|
182 | - } |
|
183 | - |
|
184 | - |
|
185 | - /** |
|
186 | - * Returns the folder containing the PMT child class, with a trailing slash |
|
187 | - * |
|
188 | - * @return string |
|
189 | - */ |
|
190 | - public function file_folder(): ?string |
|
191 | - { |
|
192 | - if (! $this->_file_folder) { |
|
193 | - $this->_set_file_folder(); |
|
194 | - } |
|
195 | - return $this->_file_folder; |
|
196 | - } |
|
197 | - |
|
198 | - |
|
199 | - /** |
|
200 | - * @return string |
|
201 | - */ |
|
202 | - public function file_url(): ?string |
|
203 | - { |
|
204 | - if (! $this->_file_url) { |
|
205 | - $this->_set_file_url(); |
|
206 | - } |
|
207 | - return $this->_file_url; |
|
208 | - } |
|
209 | - |
|
210 | - |
|
211 | - /** |
|
212 | - * Sets the payment method instance this payment method type is for. |
|
213 | - * Its important teh payment method instance is set before |
|
214 | - * |
|
215 | - * @param EE_Payment_Method $payment_method_instance |
|
216 | - * @throws EE_Error |
|
217 | - * @throws ReflectionException |
|
218 | - */ |
|
219 | - public function set_instance(EE_Payment_Method $payment_method_instance) |
|
220 | - { |
|
221 | - $this->_pm_instance = $payment_method_instance; |
|
222 | - // if they have already requested the settings form, make sure its |
|
223 | - // data matches this model object |
|
224 | - if ($this->_settings_form) { |
|
225 | - $this->settings_form()->populate_model_obj($payment_method_instance); |
|
226 | - } |
|
227 | - if ($this->_gateway instanceof EE_Gateway) { |
|
228 | - $this->_gateway->set_settings($payment_method_instance->settings_array()); |
|
229 | - } |
|
230 | - } |
|
231 | - |
|
232 | - |
|
233 | - /** |
|
234 | - * Gets teh form for displaying to admins where they set up the payment method |
|
235 | - * |
|
236 | - * @return EE_Payment_Method_Form |
|
237 | - * @throws EE_Error |
|
238 | - * @throws ReflectionException |
|
239 | - */ |
|
240 | - public function settings_form(): EE_Payment_Method_Form |
|
241 | - { |
|
242 | - if (! $this->_settings_form) { |
|
243 | - $this->_settings_form = $this->generate_new_settings_form(); |
|
244 | - $this->_settings_form->set_payment_method_type($this); |
|
245 | - // if we have already assigned a model object to this pmt, make |
|
246 | - // sure it's reflected in the form we just generated |
|
247 | - if ($this->_pm_instance) { |
|
248 | - $this->_settings_form->populate_model_obj($this->_pm_instance); |
|
249 | - } |
|
250 | - } |
|
251 | - return $this->_settings_form; |
|
252 | - } |
|
253 | - |
|
254 | - |
|
255 | - /** |
|
256 | - * Gets the form for all the settings related to this payment method type |
|
257 | - * |
|
258 | - * @return EE_Payment_Method_Form |
|
259 | - */ |
|
260 | - abstract public function generate_new_settings_form(); |
|
261 | - |
|
262 | - |
|
263 | - /** |
|
264 | - * Sets the form for settings. This may be useful if we have already received |
|
265 | - * a form submission and have form data it in, and want to use it anytime we're showing |
|
266 | - * this payment method type's settings form later in the request |
|
267 | - * |
|
268 | - * @param EE_Payment_Method_Form $form |
|
269 | - */ |
|
270 | - public function set_settings_form(EE_Payment_Method_Form $form) |
|
271 | - { |
|
272 | - $this->_settings_form = $form; |
|
273 | - } |
|
274 | - |
|
275 | - |
|
276 | - /** |
|
277 | - * @return boolean |
|
278 | - */ |
|
279 | - public function has_billing_form(): bool |
|
280 | - { |
|
281 | - return $this->_has_billing_form; |
|
282 | - } |
|
283 | - |
|
284 | - |
|
285 | - /** |
|
286 | - * Gets the form for displaying to attendees where they can enter their billing info |
|
287 | - * which will be sent to teh gateway (can be null) |
|
288 | - * |
|
289 | - * @param EE_Transaction|null $transaction |
|
290 | - * @param array $extra_args |
|
291 | - * @return EE_Billing_Attendee_Info_Form|EE_Billing_Info_Form|null |
|
292 | - * @throws EE_Error |
|
293 | - * @throws ReflectionException |
|
294 | - */ |
|
295 | - public function billing_form(EE_Transaction $transaction = null, array $extra_args = []) |
|
296 | - { |
|
297 | - // has billing form already been regenerated ? or overwrite cache? |
|
298 | - if (! $this->_billing_form instanceof EE_Billing_Info_Form || ! $this->_cache_billing_form) { |
|
299 | - $this->_billing_form = $this->generate_new_billing_form($transaction, $extra_args); |
|
300 | - } |
|
301 | - // if we know who the attendee is, and this is a billing form |
|
302 | - // that uses attendee info, populate it |
|
303 | - if ( |
|
304 | - apply_filters( |
|
305 | - 'FHEE__populate_billing_form_fields_from_attendee', |
|
306 | - ( |
|
307 | - $this->_billing_form instanceof EE_Billing_Attendee_Info_Form |
|
308 | - && $transaction instanceof EE_Transaction |
|
309 | - && $transaction->primary_registration() instanceof EE_Registration |
|
310 | - && $transaction->primary_registration()->attendee() instanceof EE_Attendee |
|
311 | - ), |
|
312 | - $this->_billing_form, |
|
313 | - $transaction |
|
314 | - ) |
|
315 | - ) { |
|
316 | - $this->_billing_form->populate_from_attendee($transaction->primary_registration()->attendee()); |
|
317 | - } |
|
318 | - return $this->_billing_form; |
|
319 | - } |
|
320 | - |
|
321 | - |
|
322 | - /** |
|
323 | - * Creates the billing form for this payment method type |
|
324 | - * |
|
325 | - * @param EE_Transaction|null $transaction |
|
326 | - * @return EE_Billing_Info_Form|null |
|
327 | - */ |
|
328 | - abstract public function generate_new_billing_form(EE_Transaction $transaction = null); |
|
329 | - |
|
330 | - |
|
331 | - /** |
|
332 | - * applies debug data to the form |
|
333 | - * |
|
334 | - * @param EE_Billing_Info_Form $billing_form |
|
335 | - * @return EE_Billing_Info_Form|null |
|
336 | - */ |
|
337 | - public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form) |
|
338 | - { |
|
339 | - return $billing_form; |
|
340 | - } |
|
341 | - |
|
342 | - |
|
343 | - /** |
|
344 | - * Sets the billing form for this payment method type. You may want to use this |
|
345 | - * if you have form |
|
346 | - * |
|
347 | - * @param EE_Payment_Method $form |
|
348 | - */ |
|
349 | - public function set_billing_form(EE_Payment_Method $form) |
|
350 | - { |
|
351 | - $this->_billing_form = $form; |
|
352 | - } |
|
353 | - |
|
354 | - |
|
355 | - /** |
|
356 | - * Returns whether this payment method requires HTTPS to be used |
|
357 | - * |
|
358 | - * @return boolean |
|
359 | - */ |
|
360 | - public function requires_https(): bool |
|
361 | - { |
|
362 | - return $this->_requires_https; |
|
363 | - } |
|
364 | - |
|
365 | - |
|
366 | - /** |
|
367 | - * @param EE_Transaction $transaction |
|
368 | - * @param float|null $amount |
|
369 | - * @param EE_Billing_Info_Form|null $billing_info |
|
370 | - * @param string|null $return_url |
|
371 | - * @param string $fail_url |
|
372 | - * @param string $method |
|
373 | - * @param bool $by_admin |
|
374 | - * @return EE_Payment |
|
375 | - * @throws EE_Error |
|
376 | - * @throws ReflectionException |
|
377 | - */ |
|
378 | - public function process_payment( |
|
379 | - EE_Transaction $transaction, |
|
380 | - $amount = null, |
|
381 | - $billing_info = null, |
|
382 | - $return_url = null, |
|
383 | - $fail_url = '', |
|
384 | - $method = 'CART', |
|
385 | - $by_admin = false |
|
386 | - ) { |
|
387 | - // @todo: add surcharge for the payment method, if any |
|
388 | - if ($this->_gateway) { |
|
389 | - // there is a gateway, so we're going to make a payment object |
|
390 | - // but wait! do they already have a payment in progress that we thought was failed? |
|
391 | - $duplicate_properties = [ |
|
392 | - 'STS_ID' => EEM_Payment::status_id_failed, |
|
393 | - 'TXN_ID' => $transaction->ID(), |
|
394 | - 'PMD_ID' => $this->_pm_instance->ID(), |
|
395 | - 'PAY_source' => $method, |
|
396 | - 'PAY_amount' => $amount !== null |
|
397 | - ? $amount |
|
398 | - : $transaction->remaining(), |
|
399 | - 'PAY_gateway_response' => null, |
|
400 | - ]; |
|
401 | - $payment = EEM_Payment::instance()->get_one([$duplicate_properties]); |
|
402 | - // if we didn't already have a payment in progress for the same thing, |
|
403 | - // then we actually want to make a new payment |
|
404 | - if (! $payment instanceof EE_Payment) { |
|
405 | - $payment = EE_Payment::new_instance( |
|
406 | - array_merge( |
|
407 | - $duplicate_properties, |
|
408 | - [ |
|
409 | - 'PAY_timestamp' => time(), |
|
410 | - 'PAY_txn_id_chq_nmbr' => null, |
|
411 | - 'PAY_po_number' => null, |
|
412 | - 'PAY_extra_accntng' => null, |
|
413 | - 'PAY_details' => null, |
|
414 | - ] |
|
415 | - ) |
|
416 | - ); |
|
417 | - } |
|
418 | - // make sure the payment has been saved to show we started it, and so it has an ID should the gateway try to log it |
|
419 | - $payment->save(); |
|
420 | - $billing_values = $this->_get_billing_values_from_form($billing_info); |
|
421 | - |
|
422 | - // Offsite Gateway |
|
423 | - if ($this->_gateway instanceof EE_Offsite_Gateway) { |
|
424 | - $payment = $this->_gateway->set_redirection_info( |
|
425 | - $payment, |
|
426 | - $billing_values, |
|
427 | - $return_url, |
|
428 | - EE_Config::instance()->core->txn_page_url( |
|
429 | - [ |
|
430 | - 'e_reg_url_link' => $transaction->primary_registration()->reg_url_link(), |
|
431 | - 'ee_payment_method' => $this->_pm_instance->slug(), |
|
432 | - ] |
|
433 | - ), |
|
434 | - $fail_url |
|
435 | - ); |
|
436 | - $payment->save(); |
|
437 | - // Onsite Gateway |
|
438 | - } elseif ($this->_gateway instanceof EE_Onsite_Gateway) { |
|
439 | - $payment = $this->_gateway->do_direct_payment($payment, $billing_values); |
|
440 | - $payment->save(); |
|
441 | - } else { |
|
442 | - throw new EE_Error( |
|
443 | - sprintf( |
|
444 | - esc_html__( |
|
445 | - 'Gateway for payment method type "%s" is "%s", not a subclass of either EE_Offsite_Gateway or EE_Onsite_Gateway, or null (to indicate NO gateway)', |
|
446 | - 'event_espresso' |
|
447 | - ), |
|
448 | - get_class($this), |
|
449 | - gettype($this->_gateway) |
|
450 | - ) |
|
451 | - ); |
|
452 | - } |
|
453 | - } else { |
|
454 | - // no gateway provided |
|
455 | - // there is no payment. Must be an offline gateway |
|
456 | - // create a payment object anyways, but dont save it |
|
457 | - $payment = EE_Payment::new_instance( |
|
458 | - [ |
|
459 | - 'STS_ID' => EEM_Payment::status_id_pending, |
|
460 | - 'TXN_ID' => $transaction->ID(), |
|
461 | - 'PMD_ID' => $transaction->payment_method_ID(), |
|
462 | - 'PAY_amount' => 0.00, |
|
463 | - 'PAY_timestamp' => time(), |
|
464 | - ] |
|
465 | - ); |
|
466 | - } |
|
467 | - |
|
468 | - // if there is billing info, clean it and save it now |
|
469 | - if ($billing_info instanceof EE_Billing_Attendee_Info_Form) { |
|
470 | - $this->_save_billing_info_to_attendee($billing_info, $transaction); |
|
471 | - } |
|
472 | - |
|
473 | - return $payment; |
|
474 | - } |
|
475 | - |
|
476 | - |
|
477 | - /** |
|
478 | - * Gets the values we want to pass onto the gateway. Normally these |
|
479 | - * are just the 'pretty' values, but there may be times the data may need |
|
480 | - * a little massaging. Proper subsections will become arrays of inputs |
|
481 | - * |
|
482 | - * @param EE_Billing_Info_Form|null $billing_form |
|
483 | - * @return array |
|
484 | - * @throws EE_Error |
|
485 | - */ |
|
486 | - protected function _get_billing_values_from_form($billing_form) |
|
487 | - { |
|
488 | - return $billing_form instanceof EE_Form_Section_Proper |
|
489 | - ? $billing_form->input_pretty_values(true) |
|
490 | - : []; |
|
491 | - } |
|
492 | - |
|
493 | - |
|
494 | - /** |
|
495 | - * Handles an instant payment notification when the transaction is known (by default). |
|
496 | - * |
|
497 | - * @param array $req_data |
|
498 | - * @param EE_Transaction $transaction |
|
499 | - * @return EE_Payment |
|
500 | - * @throws EE_Error |
|
501 | - * @throws ReflectionException |
|
502 | - */ |
|
503 | - public function handle_ipn(array $req_data, EE_Transaction $transaction): EE_Payment |
|
504 | - { |
|
505 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
506 | - if (! $this->_gateway instanceof EE_Offsite_Gateway) { |
|
507 | - throw new EE_Error( |
|
508 | - sprintf( |
|
509 | - esc_html__("Could not handle IPN because '%s' is not an offsite gateway", "event_espresso"), |
|
510 | - print_r($this->_gateway, true) |
|
511 | - ) |
|
512 | - ); |
|
513 | - } |
|
514 | - return $this->_gateway->handle_payment_update($req_data, $transaction); |
|
515 | - } |
|
516 | - |
|
517 | - |
|
518 | - /** |
|
519 | - * Saves the billing info onto the attendee of the primary registrant on this transaction, and |
|
520 | - * cleans it first. |
|
521 | - * |
|
522 | - * @param EE_Billing_Attendee_Info_Form $billing_form |
|
523 | - * @param EE_Transaction|null $transaction |
|
524 | - * @return boolean success |
|
525 | - * @throws EE_Error |
|
526 | - * @throws ReflectionException |
|
527 | - */ |
|
528 | - protected function _save_billing_info_to_attendee( |
|
529 | - EE_Billing_Attendee_Info_Form $billing_form, |
|
530 | - ?EE_Transaction $transaction |
|
531 | - ): bool { |
|
532 | - if (! $transaction instanceof EE_Transaction) { |
|
533 | - EE_Error::add_error( |
|
534 | - esc_html__("Cannot save billing info because no transaction was specified", "event_espresso"), |
|
535 | - __FILE__, |
|
536 | - __FUNCTION__, |
|
537 | - __LINE__ |
|
538 | - ); |
|
539 | - return false; |
|
540 | - } |
|
541 | - $primary_reg = $transaction->primary_registration(); |
|
542 | - if (! $primary_reg) { |
|
543 | - EE_Error::add_error( |
|
544 | - esc_html__( |
|
545 | - "Cannot save billing info because the transaction has no primary registration", |
|
546 | - "event_espresso" |
|
547 | - ), |
|
548 | - __FILE__, |
|
549 | - __FUNCTION__, |
|
550 | - __LINE__ |
|
551 | - ); |
|
552 | - return false; |
|
553 | - } |
|
554 | - $attendee = $primary_reg->attendee(); |
|
555 | - if (! $attendee) { |
|
556 | - EE_Error::add_error( |
|
557 | - esc_html__( |
|
558 | - "Cannot save billing info because the transaction's primary registration has no attendee!", |
|
559 | - "event_espresso" |
|
560 | - ), |
|
561 | - __FILE__, |
|
562 | - __FUNCTION__, |
|
563 | - __LINE__ |
|
564 | - ); |
|
565 | - return false; |
|
566 | - } |
|
567 | - return $attendee->save_and_clean_billing_info_for_payment_method($billing_form, $transaction->payment_method()); |
|
568 | - } |
|
569 | - |
|
570 | - |
|
571 | - /** |
|
572 | - * Gets the payment this IPN is for. Children may often want to |
|
573 | - * override this to inspect the request |
|
574 | - * |
|
575 | - * @param EE_Transaction $transaction |
|
576 | - * @param array $req_data |
|
577 | - * @return EE_Payment |
|
578 | - * @throws EE_Error |
|
579 | - * @throws ReflectionException |
|
580 | - */ |
|
581 | - protected function find_payment_for_ipn(EE_Transaction $transaction, array $req_data = []): EE_Payment |
|
582 | - { |
|
583 | - return $transaction->last_payment(); |
|
584 | - } |
|
585 | - |
|
586 | - |
|
587 | - /** |
|
588 | - * In case generic code cannot provide the payment processor with a specific payment method |
|
589 | - * and transaction, it will try calling this method on each activate payment method. |
|
590 | - * If the payment method is able to identify the request as being for it, it should fetch |
|
591 | - * the payment it's for and return it. If not, it should throw an EE_Error to indicate it cannot |
|
592 | - * handle the IPN |
|
593 | - * |
|
594 | - * @param array $req_data |
|
595 | - * @return EE_Payment only if this payment method can find the info its needs from $req_data |
|
596 | - * and identifies the IPN as being for this payment method (not just fo ra payment method of this type) |
|
597 | - * @throws EE_Error |
|
598 | - */ |
|
599 | - public function handle_unclaimed_ipn(array $req_data = []): EE_Payment |
|
600 | - { |
|
601 | - throw new EE_Error( |
|
602 | - sprintf( |
|
603 | - esc_html__("Payment Method '%s' cannot handle unclaimed IPNs", "event_espresso"), |
|
604 | - get_class($this) |
|
605 | - ) |
|
606 | - ); |
|
607 | - } |
|
608 | - |
|
609 | - |
|
610 | - /** |
|
611 | - * Logic to be accomplished when the payment attempt is complete. |
|
612 | - * Most payment methods don't need to do anything at this point; but some, like Mijireh, do. |
|
613 | - * (Mijireh is an offsite gateway which doesn't send an IPN. So when the user returns to EE from |
|
614 | - * mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status |
|
615 | - * of the payment). Fed a transaction because it's always assumed to be the last payment that |
|
616 | - * we're dealing with. Returns that last payment (if there is one) |
|
617 | - * |
|
618 | - * @param EE_Transaction $transaction |
|
619 | - * @return EE_Payment|null |
|
620 | - * @throws EE_Error |
|
621 | - * @throws ReflectionException |
|
622 | - */ |
|
623 | - public function finalize_payment_for(EE_Transaction $transaction): ?EE_Payment |
|
624 | - { |
|
625 | - return $transaction->last_payment(); |
|
626 | - } |
|
627 | - |
|
628 | - |
|
629 | - /** |
|
630 | - * Whether this payment method's gateway supports sending refund requests |
|
631 | - * |
|
632 | - * @return boolean |
|
633 | - */ |
|
634 | - public function supports_sending_refunds(): bool |
|
635 | - { |
|
636 | - return $this->_gateway instanceof EE_Gateway && $this->_gateway->supports_sending_refunds(); |
|
637 | - } |
|
638 | - |
|
639 | - |
|
640 | - /** |
|
641 | - * @param EE_Payment $payment |
|
642 | - * @param array $refund_info |
|
643 | - * @return EE_Payment |
|
644 | - * @throws EE_Error |
|
645 | - */ |
|
646 | - public function process_refund(EE_Payment $payment, array $refund_info = []): EE_Payment |
|
647 | - { |
|
648 | - if ($this->_gateway instanceof EE_Gateway) { |
|
649 | - return $this->_gateway->do_direct_refund($payment, $refund_info); |
|
650 | - } else { |
|
651 | - throw new EE_Error( |
|
652 | - sprintf( |
|
653 | - esc_html__('Payment Method Type "%s" does not support sending refund requests', 'event_espresso'), |
|
654 | - get_class($this) |
|
655 | - ) |
|
656 | - ); |
|
657 | - } |
|
658 | - } |
|
659 | - |
|
660 | - |
|
661 | - /** |
|
662 | - * Returns one the class's constants onsite,offsite, or offline, depending on this |
|
663 | - * payment method's gateway. |
|
664 | - * |
|
665 | - * @return string |
|
666 | - * @throws EE_Error |
|
667 | - */ |
|
668 | - public function payment_occurs(): string |
|
669 | - { |
|
670 | - if (! $this->_gateway) { |
|
671 | - return EE_PMT_Base::offline; |
|
672 | - } |
|
673 | - if ($this->_gateway instanceof EE_Onsite_Gateway) { |
|
674 | - return EE_PMT_Base::onsite; |
|
675 | - } |
|
676 | - if ($this->_gateway instanceof EE_Offsite_Gateway) { |
|
677 | - return EE_PMT_Base::offsite; |
|
678 | - } |
|
679 | - throw new EE_Error( |
|
680 | - sprintf( |
|
681 | - esc_html__( |
|
682 | - "Payment method type '%s's gateway isn't an instance of EE_Onsite_Gateway, EE_Offsite_Gateway, or null. It must be one of those", |
|
683 | - "event_espresso" |
|
684 | - ), |
|
685 | - get_class($this) |
|
686 | - ) |
|
687 | - ); |
|
688 | - } |
|
689 | - |
|
690 | - |
|
691 | - /** |
|
692 | - * For adding any html output ab ove the payment overview. |
|
693 | - * Many gateways won't want ot display anything, so this function just returns an empty string. |
|
694 | - * Other gateways may want to override this, such as offline gateways. |
|
695 | - * |
|
696 | - * @param EE_Payment $payment |
|
697 | - * @return string |
|
698 | - */ |
|
699 | - public function payment_overview_content(EE_Payment $payment) |
|
700 | - { |
|
701 | - return EEH_Template::display_template( |
|
702 | - EE_LIBRARIES . 'payment_methods/templates/payment_details_content.template.php', |
|
703 | - ['payment_method' => $this->_pm_instance, 'payment' => $payment], |
|
704 | - true |
|
705 | - ); |
|
706 | - } |
|
707 | - |
|
708 | - |
|
709 | - /** |
|
710 | - * @return array where keys are the help tab name, |
|
711 | - * values are: array { |
|
712 | - * @type string $title i18n name for the help tab |
|
713 | - * @type string $filename name of the file located in ./help_tabs/ (ie, in a folder next to this file) |
|
714 | - * @type array $template_args any arguments you want passed to the template file while rendering. |
|
715 | - * Keys will be variable names and values with be their values. |
|
716 | - */ |
|
717 | - public function help_tabs_config() |
|
718 | - { |
|
719 | - return []; |
|
720 | - } |
|
721 | - |
|
722 | - |
|
723 | - /** |
|
724 | - * The system name for this PMT (eg AIM, Paypal_Pro, Invoice... what gets put into |
|
725 | - * the payment method's table's PMT_type column) |
|
726 | - * |
|
727 | - * @return string |
|
728 | - */ |
|
729 | - public function system_name() |
|
730 | - { |
|
731 | - $classname = get_class($this); |
|
732 | - return str_replace("EE_PMT_", '', $classname); |
|
733 | - } |
|
734 | - |
|
735 | - |
|
736 | - /** |
|
737 | - * A pretty i18n version of the PMT name. Often the same as the "pretty_name", but you can change it by overriding |
|
738 | - * this method. |
|
739 | - * |
|
740 | - * @return string|null |
|
741 | - */ |
|
742 | - public function defaultFrontendName() |
|
743 | - { |
|
744 | - return $this->pretty_name(); |
|
745 | - } |
|
746 | - |
|
747 | - |
|
748 | - /** |
|
749 | - * A pretty i18n version of the PMT name |
|
750 | - * |
|
751 | - * @return string|null |
|
752 | - */ |
|
753 | - public function pretty_name(): ?string |
|
754 | - { |
|
755 | - return $this->_pretty_name; |
|
756 | - } |
|
757 | - |
|
758 | - |
|
759 | - /** |
|
760 | - * Gets the default absolute URL to the payment method type's button |
|
761 | - * |
|
762 | - * @return string|null |
|
763 | - */ |
|
764 | - public function default_button_url(): ?string |
|
765 | - { |
|
766 | - return $this->_default_button_url; |
|
767 | - } |
|
768 | - |
|
769 | - |
|
770 | - /** |
|
771 | - * Gets the gateway used by this payment method (if any) |
|
772 | - * |
|
773 | - * @return EE_Gateway |
|
774 | - */ |
|
775 | - public function get_gateway(): ?EE_Gateway |
|
776 | - { |
|
777 | - return $this->_gateway; |
|
778 | - } |
|
779 | - |
|
780 | - |
|
781 | - /** |
|
782 | - * @return string html for the link to a help tab |
|
783 | - */ |
|
784 | - public function get_help_tab_link(): string |
|
785 | - { |
|
786 | - return EEH_Template::get_help_tab_link( |
|
787 | - $this->get_help_tab_name(), |
|
788 | - 'espresso_payment_settings', |
|
789 | - 'default' |
|
790 | - ); |
|
791 | - } |
|
792 | - |
|
793 | - |
|
794 | - /** |
|
795 | - * Returns the name of the help tab for this PMT |
|
796 | - * |
|
797 | - * @return string |
|
798 | - */ |
|
799 | - public function get_help_tab_name(): string |
|
800 | - { |
|
801 | - return 'ee_' . strtolower($this->system_name()) . '_help_tab'; |
|
802 | - } |
|
803 | - |
|
804 | - |
|
805 | - /** |
|
806 | - * The name of the wp capability that should be associated with the usage of |
|
807 | - * this PMT by an admin |
|
808 | - * |
|
809 | - * @return string |
|
810 | - */ |
|
811 | - public function cap_name(): string |
|
812 | - { |
|
813 | - return 'ee_payment_method_' . strtolower($this->system_name()); |
|
814 | - } |
|
815 | - |
|
816 | - |
|
817 | - /** |
|
818 | - * Called by client code to tell the gateway that if it wants to change |
|
819 | - * the transaction or line items or registrations related to teh payment it already |
|
820 | - * processed (we think, but possibly not) that now's the time to do it. |
|
821 | - * It is expected that gateways will store any info they need for this on the PAY_details, |
|
822 | - * or maybe an extra meta value |
|
823 | - * |
|
824 | - * @param EE_Payment $payment |
|
825 | - * @return void |
|
826 | - */ |
|
827 | - public function update_txn_based_on_payment($payment) |
|
828 | - { |
|
829 | - if ($this->_gateway instanceof EE_Gateway) { |
|
830 | - $this->_gateway->update_txn_based_on_payment($payment); |
|
831 | - } |
|
832 | - } |
|
833 | - |
|
834 | - |
|
835 | - /** |
|
836 | - * Returns a string of HTML describing this payment method type for an admin, |
|
837 | - * primarily intended for them to read before activating it. |
|
838 | - * The easiest way to set this is to create a folder 'templates' alongside |
|
839 | - * your EE_PMT_{System_Name} file, and in it create a file named "{system_name}_intro.template.php". |
|
840 | - * Eg, if your payment method file is named "EE_PMT_Foo_Bar.pm.php", |
|
841 | - * then you'd create a file named "templates" in the same folder as it, and name the file |
|
842 | - * "foo_bar_intro.template.php", and its content will be returned by this method |
|
843 | - * |
|
844 | - * @return string |
|
845 | - */ |
|
846 | - public function introductory_html(): string |
|
847 | - { |
|
848 | - return EEH_Template::locate_template( |
|
849 | - $this->file_folder() . 'templates/' . strtolower($this->system_name()) . '_intro.template.php', |
|
850 | - ['pmt_obj' => $this, 'pm_instance' => $this->_pm_instance] |
|
851 | - ); |
|
852 | - } |
|
19 | + const onsite = 'on-site'; |
|
20 | + |
|
21 | + const offsite = 'off-site'; |
|
22 | + |
|
23 | + const offline = 'off-line'; |
|
24 | + |
|
25 | + /** |
|
26 | + * @var EE_Payment_Method |
|
27 | + */ |
|
28 | + protected $_pm_instance = null; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var boolean |
|
32 | + */ |
|
33 | + protected $_requires_https = false; |
|
34 | + |
|
35 | + /** |
|
36 | + * @var boolean |
|
37 | + */ |
|
38 | + protected $_has_billing_form; |
|
39 | + |
|
40 | + /** |
|
41 | + * @var EE_Gateway |
|
42 | + */ |
|
43 | + protected $_gateway = null; |
|
44 | + |
|
45 | + /** |
|
46 | + * @var EE_Payment_Method_Form |
|
47 | + */ |
|
48 | + protected $_settings_form = null; |
|
49 | + |
|
50 | + /** |
|
51 | + * @var EE_Form_Section_Proper |
|
52 | + */ |
|
53 | + protected $_billing_form = null; |
|
54 | + |
|
55 | + /** |
|
56 | + * @var boolean |
|
57 | + */ |
|
58 | + protected $_cache_billing_form = true; |
|
59 | + |
|
60 | + /** |
|
61 | + * String of the absolute path to the folder containing this file, with a trailing slash. |
|
62 | + * eg '/public_html/wp-site/wp-content/plugins/event-espresso/payment_methods/Invoice/' |
|
63 | + * |
|
64 | + * @var string|null |
|
65 | + */ |
|
66 | + protected $_file_folder = null; |
|
67 | + |
|
68 | + /** |
|
69 | + * String to the absolute URL to this file (useful for getting its web-accessible resources |
|
70 | + * like images, js, or css) |
|
71 | + * |
|
72 | + * @var string|null |
|
73 | + */ |
|
74 | + protected $_file_url = null; |
|
75 | + |
|
76 | + /** |
|
77 | + * Pretty name for the payment method |
|
78 | + * |
|
79 | + * @var string|null |
|
80 | + */ |
|
81 | + protected $_pretty_name = null; |
|
82 | + |
|
83 | + /** |
|
84 | + * @var string|null |
|
85 | + */ |
|
86 | + protected $_default_button_url = null; |
|
87 | + |
|
88 | + /** |
|
89 | + * @var string|null |
|
90 | + */ |
|
91 | + protected $_default_description = null; |
|
92 | + |
|
93 | + /** |
|
94 | + * @var string|null |
|
95 | + */ |
|
96 | + protected $_template_path = null; |
|
97 | + |
|
98 | + /** |
|
99 | + * @param EE_Payment_Method|null $pm_instance |
|
100 | + * @throws ReflectionException |
|
101 | + * @throws EE_Error |
|
102 | + */ |
|
103 | + public function __construct($pm_instance = null) |
|
104 | + { |
|
105 | + if ($pm_instance instanceof EE_Payment_Method) { |
|
106 | + $this->set_instance($pm_instance); |
|
107 | + } |
|
108 | + if ($this->_gateway) { |
|
109 | + $this->_gateway->set_payment_model(EEM_Payment::instance()); |
|
110 | + $this->_gateway->set_payment_log(EEM_Change_Log::instance()); |
|
111 | + $this->_gateway->set_template_helper(new EEH_Template()); |
|
112 | + $this->_gateway->set_line_item_helper(new EEH_Line_Item()); |
|
113 | + $this->_gateway->set_money_helper(new EEH_Money()); |
|
114 | + $this->_gateway->set_gateway_data_formatter(new GatewayDataFormatter()); |
|
115 | + $this->_gateway->set_unsupported_character_remover(new AsciiOnly()); |
|
116 | + do_action('AHEE__EE_PMT_Base___construct__done_initializing_gateway_class', $this, $this->_gateway); |
|
117 | + } |
|
118 | + if (! isset($this->_has_billing_form)) { |
|
119 | + // by default, On Site gateways have a billing form |
|
120 | + if ($this->payment_occurs() == EE_PMT_Base::onsite) { |
|
121 | + $this->set_has_billing_form(true); |
|
122 | + } else { |
|
123 | + $this->set_has_billing_form(false); |
|
124 | + } |
|
125 | + } |
|
126 | + |
|
127 | + if (! $this->_pretty_name) { |
|
128 | + throw new EE_Error( |
|
129 | + esc_html__( |
|
130 | + 'You must set the pretty name for the Payment Method Type in the constructor (_pretty_name), and please make it internationalized', |
|
131 | + 'event_espresso' |
|
132 | + ) |
|
133 | + ); |
|
134 | + } |
|
135 | + // if the child didn't specify a default button, use the credit card one |
|
136 | + if ($this->_default_button_url === null) { |
|
137 | + $this->_default_button_url = EE_PLUGIN_DIR_URL . 'payment_methods/pay-by-credit-card.png'; |
|
138 | + } |
|
139 | + } |
|
140 | + |
|
141 | + |
|
142 | + /** |
|
143 | + * @param boolean $has_billing_form |
|
144 | + */ |
|
145 | + public function set_has_billing_form(bool $has_billing_form) |
|
146 | + { |
|
147 | + $this->_has_billing_form = filter_var($has_billing_form, FILTER_VALIDATE_BOOLEAN); |
|
148 | + } |
|
149 | + |
|
150 | + |
|
151 | + /** |
|
152 | + * sets the file_folder property |
|
153 | + */ |
|
154 | + protected function _set_file_folder() |
|
155 | + { |
|
156 | + $reflector = new ReflectionClass(get_class($this)); |
|
157 | + $fn = $reflector->getFileName(); |
|
158 | + $this->_file_folder = dirname($fn) . '/'; |
|
159 | + } |
|
160 | + |
|
161 | + |
|
162 | + /** |
|
163 | + * sets the file URL with a trailing slash for this PMT |
|
164 | + */ |
|
165 | + protected function _set_file_url() |
|
166 | + { |
|
167 | + $plugins_dir_fixed = str_replace('\\', '/', WP_PLUGIN_DIR); |
|
168 | + $file_folder_fixed = str_replace('\\', '/', $this->file_folder()); |
|
169 | + $file_path = str_replace($plugins_dir_fixed, WP_PLUGIN_URL, $file_folder_fixed); |
|
170 | + $this->_file_url = set_url_scheme($file_path); |
|
171 | + } |
|
172 | + |
|
173 | + |
|
174 | + /** |
|
175 | + * Gets the default description on all payment methods of this type |
|
176 | + * |
|
177 | + * @return string |
|
178 | + */ |
|
179 | + public function default_description(): ?string |
|
180 | + { |
|
181 | + return $this->_default_description; |
|
182 | + } |
|
183 | + |
|
184 | + |
|
185 | + /** |
|
186 | + * Returns the folder containing the PMT child class, with a trailing slash |
|
187 | + * |
|
188 | + * @return string |
|
189 | + */ |
|
190 | + public function file_folder(): ?string |
|
191 | + { |
|
192 | + if (! $this->_file_folder) { |
|
193 | + $this->_set_file_folder(); |
|
194 | + } |
|
195 | + return $this->_file_folder; |
|
196 | + } |
|
197 | + |
|
198 | + |
|
199 | + /** |
|
200 | + * @return string |
|
201 | + */ |
|
202 | + public function file_url(): ?string |
|
203 | + { |
|
204 | + if (! $this->_file_url) { |
|
205 | + $this->_set_file_url(); |
|
206 | + } |
|
207 | + return $this->_file_url; |
|
208 | + } |
|
209 | + |
|
210 | + |
|
211 | + /** |
|
212 | + * Sets the payment method instance this payment method type is for. |
|
213 | + * Its important teh payment method instance is set before |
|
214 | + * |
|
215 | + * @param EE_Payment_Method $payment_method_instance |
|
216 | + * @throws EE_Error |
|
217 | + * @throws ReflectionException |
|
218 | + */ |
|
219 | + public function set_instance(EE_Payment_Method $payment_method_instance) |
|
220 | + { |
|
221 | + $this->_pm_instance = $payment_method_instance; |
|
222 | + // if they have already requested the settings form, make sure its |
|
223 | + // data matches this model object |
|
224 | + if ($this->_settings_form) { |
|
225 | + $this->settings_form()->populate_model_obj($payment_method_instance); |
|
226 | + } |
|
227 | + if ($this->_gateway instanceof EE_Gateway) { |
|
228 | + $this->_gateway->set_settings($payment_method_instance->settings_array()); |
|
229 | + } |
|
230 | + } |
|
231 | + |
|
232 | + |
|
233 | + /** |
|
234 | + * Gets teh form for displaying to admins where they set up the payment method |
|
235 | + * |
|
236 | + * @return EE_Payment_Method_Form |
|
237 | + * @throws EE_Error |
|
238 | + * @throws ReflectionException |
|
239 | + */ |
|
240 | + public function settings_form(): EE_Payment_Method_Form |
|
241 | + { |
|
242 | + if (! $this->_settings_form) { |
|
243 | + $this->_settings_form = $this->generate_new_settings_form(); |
|
244 | + $this->_settings_form->set_payment_method_type($this); |
|
245 | + // if we have already assigned a model object to this pmt, make |
|
246 | + // sure it's reflected in the form we just generated |
|
247 | + if ($this->_pm_instance) { |
|
248 | + $this->_settings_form->populate_model_obj($this->_pm_instance); |
|
249 | + } |
|
250 | + } |
|
251 | + return $this->_settings_form; |
|
252 | + } |
|
253 | + |
|
254 | + |
|
255 | + /** |
|
256 | + * Gets the form for all the settings related to this payment method type |
|
257 | + * |
|
258 | + * @return EE_Payment_Method_Form |
|
259 | + */ |
|
260 | + abstract public function generate_new_settings_form(); |
|
261 | + |
|
262 | + |
|
263 | + /** |
|
264 | + * Sets the form for settings. This may be useful if we have already received |
|
265 | + * a form submission and have form data it in, and want to use it anytime we're showing |
|
266 | + * this payment method type's settings form later in the request |
|
267 | + * |
|
268 | + * @param EE_Payment_Method_Form $form |
|
269 | + */ |
|
270 | + public function set_settings_form(EE_Payment_Method_Form $form) |
|
271 | + { |
|
272 | + $this->_settings_form = $form; |
|
273 | + } |
|
274 | + |
|
275 | + |
|
276 | + /** |
|
277 | + * @return boolean |
|
278 | + */ |
|
279 | + public function has_billing_form(): bool |
|
280 | + { |
|
281 | + return $this->_has_billing_form; |
|
282 | + } |
|
283 | + |
|
284 | + |
|
285 | + /** |
|
286 | + * Gets the form for displaying to attendees where they can enter their billing info |
|
287 | + * which will be sent to teh gateway (can be null) |
|
288 | + * |
|
289 | + * @param EE_Transaction|null $transaction |
|
290 | + * @param array $extra_args |
|
291 | + * @return EE_Billing_Attendee_Info_Form|EE_Billing_Info_Form|null |
|
292 | + * @throws EE_Error |
|
293 | + * @throws ReflectionException |
|
294 | + */ |
|
295 | + public function billing_form(EE_Transaction $transaction = null, array $extra_args = []) |
|
296 | + { |
|
297 | + // has billing form already been regenerated ? or overwrite cache? |
|
298 | + if (! $this->_billing_form instanceof EE_Billing_Info_Form || ! $this->_cache_billing_form) { |
|
299 | + $this->_billing_form = $this->generate_new_billing_form($transaction, $extra_args); |
|
300 | + } |
|
301 | + // if we know who the attendee is, and this is a billing form |
|
302 | + // that uses attendee info, populate it |
|
303 | + if ( |
|
304 | + apply_filters( |
|
305 | + 'FHEE__populate_billing_form_fields_from_attendee', |
|
306 | + ( |
|
307 | + $this->_billing_form instanceof EE_Billing_Attendee_Info_Form |
|
308 | + && $transaction instanceof EE_Transaction |
|
309 | + && $transaction->primary_registration() instanceof EE_Registration |
|
310 | + && $transaction->primary_registration()->attendee() instanceof EE_Attendee |
|
311 | + ), |
|
312 | + $this->_billing_form, |
|
313 | + $transaction |
|
314 | + ) |
|
315 | + ) { |
|
316 | + $this->_billing_form->populate_from_attendee($transaction->primary_registration()->attendee()); |
|
317 | + } |
|
318 | + return $this->_billing_form; |
|
319 | + } |
|
320 | + |
|
321 | + |
|
322 | + /** |
|
323 | + * Creates the billing form for this payment method type |
|
324 | + * |
|
325 | + * @param EE_Transaction|null $transaction |
|
326 | + * @return EE_Billing_Info_Form|null |
|
327 | + */ |
|
328 | + abstract public function generate_new_billing_form(EE_Transaction $transaction = null); |
|
329 | + |
|
330 | + |
|
331 | + /** |
|
332 | + * applies debug data to the form |
|
333 | + * |
|
334 | + * @param EE_Billing_Info_Form $billing_form |
|
335 | + * @return EE_Billing_Info_Form|null |
|
336 | + */ |
|
337 | + public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form) |
|
338 | + { |
|
339 | + return $billing_form; |
|
340 | + } |
|
341 | + |
|
342 | + |
|
343 | + /** |
|
344 | + * Sets the billing form for this payment method type. You may want to use this |
|
345 | + * if you have form |
|
346 | + * |
|
347 | + * @param EE_Payment_Method $form |
|
348 | + */ |
|
349 | + public function set_billing_form(EE_Payment_Method $form) |
|
350 | + { |
|
351 | + $this->_billing_form = $form; |
|
352 | + } |
|
353 | + |
|
354 | + |
|
355 | + /** |
|
356 | + * Returns whether this payment method requires HTTPS to be used |
|
357 | + * |
|
358 | + * @return boolean |
|
359 | + */ |
|
360 | + public function requires_https(): bool |
|
361 | + { |
|
362 | + return $this->_requires_https; |
|
363 | + } |
|
364 | + |
|
365 | + |
|
366 | + /** |
|
367 | + * @param EE_Transaction $transaction |
|
368 | + * @param float|null $amount |
|
369 | + * @param EE_Billing_Info_Form|null $billing_info |
|
370 | + * @param string|null $return_url |
|
371 | + * @param string $fail_url |
|
372 | + * @param string $method |
|
373 | + * @param bool $by_admin |
|
374 | + * @return EE_Payment |
|
375 | + * @throws EE_Error |
|
376 | + * @throws ReflectionException |
|
377 | + */ |
|
378 | + public function process_payment( |
|
379 | + EE_Transaction $transaction, |
|
380 | + $amount = null, |
|
381 | + $billing_info = null, |
|
382 | + $return_url = null, |
|
383 | + $fail_url = '', |
|
384 | + $method = 'CART', |
|
385 | + $by_admin = false |
|
386 | + ) { |
|
387 | + // @todo: add surcharge for the payment method, if any |
|
388 | + if ($this->_gateway) { |
|
389 | + // there is a gateway, so we're going to make a payment object |
|
390 | + // but wait! do they already have a payment in progress that we thought was failed? |
|
391 | + $duplicate_properties = [ |
|
392 | + 'STS_ID' => EEM_Payment::status_id_failed, |
|
393 | + 'TXN_ID' => $transaction->ID(), |
|
394 | + 'PMD_ID' => $this->_pm_instance->ID(), |
|
395 | + 'PAY_source' => $method, |
|
396 | + 'PAY_amount' => $amount !== null |
|
397 | + ? $amount |
|
398 | + : $transaction->remaining(), |
|
399 | + 'PAY_gateway_response' => null, |
|
400 | + ]; |
|
401 | + $payment = EEM_Payment::instance()->get_one([$duplicate_properties]); |
|
402 | + // if we didn't already have a payment in progress for the same thing, |
|
403 | + // then we actually want to make a new payment |
|
404 | + if (! $payment instanceof EE_Payment) { |
|
405 | + $payment = EE_Payment::new_instance( |
|
406 | + array_merge( |
|
407 | + $duplicate_properties, |
|
408 | + [ |
|
409 | + 'PAY_timestamp' => time(), |
|
410 | + 'PAY_txn_id_chq_nmbr' => null, |
|
411 | + 'PAY_po_number' => null, |
|
412 | + 'PAY_extra_accntng' => null, |
|
413 | + 'PAY_details' => null, |
|
414 | + ] |
|
415 | + ) |
|
416 | + ); |
|
417 | + } |
|
418 | + // make sure the payment has been saved to show we started it, and so it has an ID should the gateway try to log it |
|
419 | + $payment->save(); |
|
420 | + $billing_values = $this->_get_billing_values_from_form($billing_info); |
|
421 | + |
|
422 | + // Offsite Gateway |
|
423 | + if ($this->_gateway instanceof EE_Offsite_Gateway) { |
|
424 | + $payment = $this->_gateway->set_redirection_info( |
|
425 | + $payment, |
|
426 | + $billing_values, |
|
427 | + $return_url, |
|
428 | + EE_Config::instance()->core->txn_page_url( |
|
429 | + [ |
|
430 | + 'e_reg_url_link' => $transaction->primary_registration()->reg_url_link(), |
|
431 | + 'ee_payment_method' => $this->_pm_instance->slug(), |
|
432 | + ] |
|
433 | + ), |
|
434 | + $fail_url |
|
435 | + ); |
|
436 | + $payment->save(); |
|
437 | + // Onsite Gateway |
|
438 | + } elseif ($this->_gateway instanceof EE_Onsite_Gateway) { |
|
439 | + $payment = $this->_gateway->do_direct_payment($payment, $billing_values); |
|
440 | + $payment->save(); |
|
441 | + } else { |
|
442 | + throw new EE_Error( |
|
443 | + sprintf( |
|
444 | + esc_html__( |
|
445 | + 'Gateway for payment method type "%s" is "%s", not a subclass of either EE_Offsite_Gateway or EE_Onsite_Gateway, or null (to indicate NO gateway)', |
|
446 | + 'event_espresso' |
|
447 | + ), |
|
448 | + get_class($this), |
|
449 | + gettype($this->_gateway) |
|
450 | + ) |
|
451 | + ); |
|
452 | + } |
|
453 | + } else { |
|
454 | + // no gateway provided |
|
455 | + // there is no payment. Must be an offline gateway |
|
456 | + // create a payment object anyways, but dont save it |
|
457 | + $payment = EE_Payment::new_instance( |
|
458 | + [ |
|
459 | + 'STS_ID' => EEM_Payment::status_id_pending, |
|
460 | + 'TXN_ID' => $transaction->ID(), |
|
461 | + 'PMD_ID' => $transaction->payment_method_ID(), |
|
462 | + 'PAY_amount' => 0.00, |
|
463 | + 'PAY_timestamp' => time(), |
|
464 | + ] |
|
465 | + ); |
|
466 | + } |
|
467 | + |
|
468 | + // if there is billing info, clean it and save it now |
|
469 | + if ($billing_info instanceof EE_Billing_Attendee_Info_Form) { |
|
470 | + $this->_save_billing_info_to_attendee($billing_info, $transaction); |
|
471 | + } |
|
472 | + |
|
473 | + return $payment; |
|
474 | + } |
|
475 | + |
|
476 | + |
|
477 | + /** |
|
478 | + * Gets the values we want to pass onto the gateway. Normally these |
|
479 | + * are just the 'pretty' values, but there may be times the data may need |
|
480 | + * a little massaging. Proper subsections will become arrays of inputs |
|
481 | + * |
|
482 | + * @param EE_Billing_Info_Form|null $billing_form |
|
483 | + * @return array |
|
484 | + * @throws EE_Error |
|
485 | + */ |
|
486 | + protected function _get_billing_values_from_form($billing_form) |
|
487 | + { |
|
488 | + return $billing_form instanceof EE_Form_Section_Proper |
|
489 | + ? $billing_form->input_pretty_values(true) |
|
490 | + : []; |
|
491 | + } |
|
492 | + |
|
493 | + |
|
494 | + /** |
|
495 | + * Handles an instant payment notification when the transaction is known (by default). |
|
496 | + * |
|
497 | + * @param array $req_data |
|
498 | + * @param EE_Transaction $transaction |
|
499 | + * @return EE_Payment |
|
500 | + * @throws EE_Error |
|
501 | + * @throws ReflectionException |
|
502 | + */ |
|
503 | + public function handle_ipn(array $req_data, EE_Transaction $transaction): EE_Payment |
|
504 | + { |
|
505 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
506 | + if (! $this->_gateway instanceof EE_Offsite_Gateway) { |
|
507 | + throw new EE_Error( |
|
508 | + sprintf( |
|
509 | + esc_html__("Could not handle IPN because '%s' is not an offsite gateway", "event_espresso"), |
|
510 | + print_r($this->_gateway, true) |
|
511 | + ) |
|
512 | + ); |
|
513 | + } |
|
514 | + return $this->_gateway->handle_payment_update($req_data, $transaction); |
|
515 | + } |
|
516 | + |
|
517 | + |
|
518 | + /** |
|
519 | + * Saves the billing info onto the attendee of the primary registrant on this transaction, and |
|
520 | + * cleans it first. |
|
521 | + * |
|
522 | + * @param EE_Billing_Attendee_Info_Form $billing_form |
|
523 | + * @param EE_Transaction|null $transaction |
|
524 | + * @return boolean success |
|
525 | + * @throws EE_Error |
|
526 | + * @throws ReflectionException |
|
527 | + */ |
|
528 | + protected function _save_billing_info_to_attendee( |
|
529 | + EE_Billing_Attendee_Info_Form $billing_form, |
|
530 | + ?EE_Transaction $transaction |
|
531 | + ): bool { |
|
532 | + if (! $transaction instanceof EE_Transaction) { |
|
533 | + EE_Error::add_error( |
|
534 | + esc_html__("Cannot save billing info because no transaction was specified", "event_espresso"), |
|
535 | + __FILE__, |
|
536 | + __FUNCTION__, |
|
537 | + __LINE__ |
|
538 | + ); |
|
539 | + return false; |
|
540 | + } |
|
541 | + $primary_reg = $transaction->primary_registration(); |
|
542 | + if (! $primary_reg) { |
|
543 | + EE_Error::add_error( |
|
544 | + esc_html__( |
|
545 | + "Cannot save billing info because the transaction has no primary registration", |
|
546 | + "event_espresso" |
|
547 | + ), |
|
548 | + __FILE__, |
|
549 | + __FUNCTION__, |
|
550 | + __LINE__ |
|
551 | + ); |
|
552 | + return false; |
|
553 | + } |
|
554 | + $attendee = $primary_reg->attendee(); |
|
555 | + if (! $attendee) { |
|
556 | + EE_Error::add_error( |
|
557 | + esc_html__( |
|
558 | + "Cannot save billing info because the transaction's primary registration has no attendee!", |
|
559 | + "event_espresso" |
|
560 | + ), |
|
561 | + __FILE__, |
|
562 | + __FUNCTION__, |
|
563 | + __LINE__ |
|
564 | + ); |
|
565 | + return false; |
|
566 | + } |
|
567 | + return $attendee->save_and_clean_billing_info_for_payment_method($billing_form, $transaction->payment_method()); |
|
568 | + } |
|
569 | + |
|
570 | + |
|
571 | + /** |
|
572 | + * Gets the payment this IPN is for. Children may often want to |
|
573 | + * override this to inspect the request |
|
574 | + * |
|
575 | + * @param EE_Transaction $transaction |
|
576 | + * @param array $req_data |
|
577 | + * @return EE_Payment |
|
578 | + * @throws EE_Error |
|
579 | + * @throws ReflectionException |
|
580 | + */ |
|
581 | + protected function find_payment_for_ipn(EE_Transaction $transaction, array $req_data = []): EE_Payment |
|
582 | + { |
|
583 | + return $transaction->last_payment(); |
|
584 | + } |
|
585 | + |
|
586 | + |
|
587 | + /** |
|
588 | + * In case generic code cannot provide the payment processor with a specific payment method |
|
589 | + * and transaction, it will try calling this method on each activate payment method. |
|
590 | + * If the payment method is able to identify the request as being for it, it should fetch |
|
591 | + * the payment it's for and return it. If not, it should throw an EE_Error to indicate it cannot |
|
592 | + * handle the IPN |
|
593 | + * |
|
594 | + * @param array $req_data |
|
595 | + * @return EE_Payment only if this payment method can find the info its needs from $req_data |
|
596 | + * and identifies the IPN as being for this payment method (not just fo ra payment method of this type) |
|
597 | + * @throws EE_Error |
|
598 | + */ |
|
599 | + public function handle_unclaimed_ipn(array $req_data = []): EE_Payment |
|
600 | + { |
|
601 | + throw new EE_Error( |
|
602 | + sprintf( |
|
603 | + esc_html__("Payment Method '%s' cannot handle unclaimed IPNs", "event_espresso"), |
|
604 | + get_class($this) |
|
605 | + ) |
|
606 | + ); |
|
607 | + } |
|
608 | + |
|
609 | + |
|
610 | + /** |
|
611 | + * Logic to be accomplished when the payment attempt is complete. |
|
612 | + * Most payment methods don't need to do anything at this point; but some, like Mijireh, do. |
|
613 | + * (Mijireh is an offsite gateway which doesn't send an IPN. So when the user returns to EE from |
|
614 | + * mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status |
|
615 | + * of the payment). Fed a transaction because it's always assumed to be the last payment that |
|
616 | + * we're dealing with. Returns that last payment (if there is one) |
|
617 | + * |
|
618 | + * @param EE_Transaction $transaction |
|
619 | + * @return EE_Payment|null |
|
620 | + * @throws EE_Error |
|
621 | + * @throws ReflectionException |
|
622 | + */ |
|
623 | + public function finalize_payment_for(EE_Transaction $transaction): ?EE_Payment |
|
624 | + { |
|
625 | + return $transaction->last_payment(); |
|
626 | + } |
|
627 | + |
|
628 | + |
|
629 | + /** |
|
630 | + * Whether this payment method's gateway supports sending refund requests |
|
631 | + * |
|
632 | + * @return boolean |
|
633 | + */ |
|
634 | + public function supports_sending_refunds(): bool |
|
635 | + { |
|
636 | + return $this->_gateway instanceof EE_Gateway && $this->_gateway->supports_sending_refunds(); |
|
637 | + } |
|
638 | + |
|
639 | + |
|
640 | + /** |
|
641 | + * @param EE_Payment $payment |
|
642 | + * @param array $refund_info |
|
643 | + * @return EE_Payment |
|
644 | + * @throws EE_Error |
|
645 | + */ |
|
646 | + public function process_refund(EE_Payment $payment, array $refund_info = []): EE_Payment |
|
647 | + { |
|
648 | + if ($this->_gateway instanceof EE_Gateway) { |
|
649 | + return $this->_gateway->do_direct_refund($payment, $refund_info); |
|
650 | + } else { |
|
651 | + throw new EE_Error( |
|
652 | + sprintf( |
|
653 | + esc_html__('Payment Method Type "%s" does not support sending refund requests', 'event_espresso'), |
|
654 | + get_class($this) |
|
655 | + ) |
|
656 | + ); |
|
657 | + } |
|
658 | + } |
|
659 | + |
|
660 | + |
|
661 | + /** |
|
662 | + * Returns one the class's constants onsite,offsite, or offline, depending on this |
|
663 | + * payment method's gateway. |
|
664 | + * |
|
665 | + * @return string |
|
666 | + * @throws EE_Error |
|
667 | + */ |
|
668 | + public function payment_occurs(): string |
|
669 | + { |
|
670 | + if (! $this->_gateway) { |
|
671 | + return EE_PMT_Base::offline; |
|
672 | + } |
|
673 | + if ($this->_gateway instanceof EE_Onsite_Gateway) { |
|
674 | + return EE_PMT_Base::onsite; |
|
675 | + } |
|
676 | + if ($this->_gateway instanceof EE_Offsite_Gateway) { |
|
677 | + return EE_PMT_Base::offsite; |
|
678 | + } |
|
679 | + throw new EE_Error( |
|
680 | + sprintf( |
|
681 | + esc_html__( |
|
682 | + "Payment method type '%s's gateway isn't an instance of EE_Onsite_Gateway, EE_Offsite_Gateway, or null. It must be one of those", |
|
683 | + "event_espresso" |
|
684 | + ), |
|
685 | + get_class($this) |
|
686 | + ) |
|
687 | + ); |
|
688 | + } |
|
689 | + |
|
690 | + |
|
691 | + /** |
|
692 | + * For adding any html output ab ove the payment overview. |
|
693 | + * Many gateways won't want ot display anything, so this function just returns an empty string. |
|
694 | + * Other gateways may want to override this, such as offline gateways. |
|
695 | + * |
|
696 | + * @param EE_Payment $payment |
|
697 | + * @return string |
|
698 | + */ |
|
699 | + public function payment_overview_content(EE_Payment $payment) |
|
700 | + { |
|
701 | + return EEH_Template::display_template( |
|
702 | + EE_LIBRARIES . 'payment_methods/templates/payment_details_content.template.php', |
|
703 | + ['payment_method' => $this->_pm_instance, 'payment' => $payment], |
|
704 | + true |
|
705 | + ); |
|
706 | + } |
|
707 | + |
|
708 | + |
|
709 | + /** |
|
710 | + * @return array where keys are the help tab name, |
|
711 | + * values are: array { |
|
712 | + * @type string $title i18n name for the help tab |
|
713 | + * @type string $filename name of the file located in ./help_tabs/ (ie, in a folder next to this file) |
|
714 | + * @type array $template_args any arguments you want passed to the template file while rendering. |
|
715 | + * Keys will be variable names and values with be their values. |
|
716 | + */ |
|
717 | + public function help_tabs_config() |
|
718 | + { |
|
719 | + return []; |
|
720 | + } |
|
721 | + |
|
722 | + |
|
723 | + /** |
|
724 | + * The system name for this PMT (eg AIM, Paypal_Pro, Invoice... what gets put into |
|
725 | + * the payment method's table's PMT_type column) |
|
726 | + * |
|
727 | + * @return string |
|
728 | + */ |
|
729 | + public function system_name() |
|
730 | + { |
|
731 | + $classname = get_class($this); |
|
732 | + return str_replace("EE_PMT_", '', $classname); |
|
733 | + } |
|
734 | + |
|
735 | + |
|
736 | + /** |
|
737 | + * A pretty i18n version of the PMT name. Often the same as the "pretty_name", but you can change it by overriding |
|
738 | + * this method. |
|
739 | + * |
|
740 | + * @return string|null |
|
741 | + */ |
|
742 | + public function defaultFrontendName() |
|
743 | + { |
|
744 | + return $this->pretty_name(); |
|
745 | + } |
|
746 | + |
|
747 | + |
|
748 | + /** |
|
749 | + * A pretty i18n version of the PMT name |
|
750 | + * |
|
751 | + * @return string|null |
|
752 | + */ |
|
753 | + public function pretty_name(): ?string |
|
754 | + { |
|
755 | + return $this->_pretty_name; |
|
756 | + } |
|
757 | + |
|
758 | + |
|
759 | + /** |
|
760 | + * Gets the default absolute URL to the payment method type's button |
|
761 | + * |
|
762 | + * @return string|null |
|
763 | + */ |
|
764 | + public function default_button_url(): ?string |
|
765 | + { |
|
766 | + return $this->_default_button_url; |
|
767 | + } |
|
768 | + |
|
769 | + |
|
770 | + /** |
|
771 | + * Gets the gateway used by this payment method (if any) |
|
772 | + * |
|
773 | + * @return EE_Gateway |
|
774 | + */ |
|
775 | + public function get_gateway(): ?EE_Gateway |
|
776 | + { |
|
777 | + return $this->_gateway; |
|
778 | + } |
|
779 | + |
|
780 | + |
|
781 | + /** |
|
782 | + * @return string html for the link to a help tab |
|
783 | + */ |
|
784 | + public function get_help_tab_link(): string |
|
785 | + { |
|
786 | + return EEH_Template::get_help_tab_link( |
|
787 | + $this->get_help_tab_name(), |
|
788 | + 'espresso_payment_settings', |
|
789 | + 'default' |
|
790 | + ); |
|
791 | + } |
|
792 | + |
|
793 | + |
|
794 | + /** |
|
795 | + * Returns the name of the help tab for this PMT |
|
796 | + * |
|
797 | + * @return string |
|
798 | + */ |
|
799 | + public function get_help_tab_name(): string |
|
800 | + { |
|
801 | + return 'ee_' . strtolower($this->system_name()) . '_help_tab'; |
|
802 | + } |
|
803 | + |
|
804 | + |
|
805 | + /** |
|
806 | + * The name of the wp capability that should be associated with the usage of |
|
807 | + * this PMT by an admin |
|
808 | + * |
|
809 | + * @return string |
|
810 | + */ |
|
811 | + public function cap_name(): string |
|
812 | + { |
|
813 | + return 'ee_payment_method_' . strtolower($this->system_name()); |
|
814 | + } |
|
815 | + |
|
816 | + |
|
817 | + /** |
|
818 | + * Called by client code to tell the gateway that if it wants to change |
|
819 | + * the transaction or line items or registrations related to teh payment it already |
|
820 | + * processed (we think, but possibly not) that now's the time to do it. |
|
821 | + * It is expected that gateways will store any info they need for this on the PAY_details, |
|
822 | + * or maybe an extra meta value |
|
823 | + * |
|
824 | + * @param EE_Payment $payment |
|
825 | + * @return void |
|
826 | + */ |
|
827 | + public function update_txn_based_on_payment($payment) |
|
828 | + { |
|
829 | + if ($this->_gateway instanceof EE_Gateway) { |
|
830 | + $this->_gateway->update_txn_based_on_payment($payment); |
|
831 | + } |
|
832 | + } |
|
833 | + |
|
834 | + |
|
835 | + /** |
|
836 | + * Returns a string of HTML describing this payment method type for an admin, |
|
837 | + * primarily intended for them to read before activating it. |
|
838 | + * The easiest way to set this is to create a folder 'templates' alongside |
|
839 | + * your EE_PMT_{System_Name} file, and in it create a file named "{system_name}_intro.template.php". |
|
840 | + * Eg, if your payment method file is named "EE_PMT_Foo_Bar.pm.php", |
|
841 | + * then you'd create a file named "templates" in the same folder as it, and name the file |
|
842 | + * "foo_bar_intro.template.php", and its content will be returned by this method |
|
843 | + * |
|
844 | + * @return string |
|
845 | + */ |
|
846 | + public function introductory_html(): string |
|
847 | + { |
|
848 | + return EEH_Template::locate_template( |
|
849 | + $this->file_folder() . 'templates/' . strtolower($this->system_name()) . '_intro.template.php', |
|
850 | + ['pmt_obj' => $this, 'pm_instance' => $this->_pm_instance] |
|
851 | + ); |
|
852 | + } |
|
853 | 853 | } |
@@ -29,243 +29,243 @@ |
||
29 | 29 | */ |
30 | 30 | class Router |
31 | 31 | { |
32 | - protected EE_Dependency_Map $dependency_map; |
|
32 | + protected EE_Dependency_Map $dependency_map; |
|
33 | 33 | |
34 | - protected LoaderInterface $loader; |
|
34 | + protected LoaderInterface $loader; |
|
35 | 35 | |
36 | - protected RouteHandler $route_handler; |
|
36 | + protected RouteHandler $route_handler; |
|
37 | 37 | |
38 | - protected string $route_request_type; |
|
38 | + protected string $route_request_type; |
|
39 | 39 | |
40 | - protected array $routes_loaded; |
|
40 | + protected array $routes_loaded; |
|
41 | 41 | |
42 | 42 | |
43 | - /** |
|
44 | - * RoutingSwitch constructor. |
|
45 | - * |
|
46 | - * @param EE_Dependency_Map $dependency_map |
|
47 | - * @param LoaderInterface $loader |
|
48 | - * @param RouteHandler $router |
|
49 | - */ |
|
50 | - public function __construct(EE_Dependency_Map $dependency_map, LoaderInterface $loader, RouteHandler $router) |
|
51 | - { |
|
52 | - $this->dependency_map = $dependency_map; |
|
53 | - $this->loader = $loader; |
|
54 | - $this->route_handler = $router; |
|
55 | - } |
|
43 | + /** |
|
44 | + * RoutingSwitch constructor. |
|
45 | + * |
|
46 | + * @param EE_Dependency_Map $dependency_map |
|
47 | + * @param LoaderInterface $loader |
|
48 | + * @param RouteHandler $router |
|
49 | + */ |
|
50 | + public function __construct(EE_Dependency_Map $dependency_map, LoaderInterface $loader, RouteHandler $router) |
|
51 | + { |
|
52 | + $this->dependency_map = $dependency_map; |
|
53 | + $this->loader = $loader; |
|
54 | + $this->route_handler = $router; |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | - /** |
|
59 | - * @throws Exception |
|
60 | - */ |
|
61 | - public function loadPrimaryRoutes() |
|
62 | - { |
|
63 | - if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
64 | - return; |
|
65 | - } |
|
66 | - $this->dependency_map->registerDependencies( |
|
67 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\ActivationRequests', |
|
68 | - Route::getFullDependencies() |
|
69 | - ); |
|
70 | - $this->dependency_map->registerDependencies( |
|
71 | - 'EventEspresso\core\domain\entities\routing\handlers\shared\RegularRequests', |
|
72 | - Route::getFullDependencies() |
|
73 | - ); |
|
74 | - // now load and prep all primary Routes |
|
75 | - $this->route_handler->addRoute('EventEspresso\core\domain\entities\routing\handlers\admin\ActivationRequests'); |
|
76 | - $this->route_handler->addRoute('EventEspresso\core\domain\entities\routing\handlers\shared\RegularRequests'); |
|
77 | - $this->route_request_type = $this->route_handler->getRouteRequestType(); |
|
78 | - do_action( |
|
79 | - 'AHEE__EventEspresso_core_services_routing_Router__loadPrimaryRoutes', |
|
80 | - $this->route_handler, |
|
81 | - $this->route_request_type, |
|
82 | - $this->dependency_map |
|
83 | - ); |
|
84 | - $this->routes_loaded[ __FUNCTION__ ] = true; |
|
85 | - } |
|
58 | + /** |
|
59 | + * @throws Exception |
|
60 | + */ |
|
61 | + public function loadPrimaryRoutes() |
|
62 | + { |
|
63 | + if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
64 | + return; |
|
65 | + } |
|
66 | + $this->dependency_map->registerDependencies( |
|
67 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\ActivationRequests', |
|
68 | + Route::getFullDependencies() |
|
69 | + ); |
|
70 | + $this->dependency_map->registerDependencies( |
|
71 | + 'EventEspresso\core\domain\entities\routing\handlers\shared\RegularRequests', |
|
72 | + Route::getFullDependencies() |
|
73 | + ); |
|
74 | + // now load and prep all primary Routes |
|
75 | + $this->route_handler->addRoute('EventEspresso\core\domain\entities\routing\handlers\admin\ActivationRequests'); |
|
76 | + $this->route_handler->addRoute('EventEspresso\core\domain\entities\routing\handlers\shared\RegularRequests'); |
|
77 | + $this->route_request_type = $this->route_handler->getRouteRequestType(); |
|
78 | + do_action( |
|
79 | + 'AHEE__EventEspresso_core_services_routing_Router__loadPrimaryRoutes', |
|
80 | + $this->route_handler, |
|
81 | + $this->route_request_type, |
|
82 | + $this->dependency_map |
|
83 | + ); |
|
84 | + $this->routes_loaded[ __FUNCTION__ ] = true; |
|
85 | + } |
|
86 | 86 | |
87 | 87 | |
88 | - /** |
|
89 | - * @throws Exception |
|
90 | - */ |
|
91 | - public function registerShortcodesModulesAndWidgets() |
|
92 | - { |
|
93 | - if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
94 | - return; |
|
95 | - } |
|
96 | - do_action( |
|
97 | - 'AHEE__EventEspresso_core_services_routing_Router__registerShortcodesModulesAndWidgets', |
|
98 | - $this->route_handler, |
|
99 | - $this->route_request_type, |
|
100 | - $this->dependency_map |
|
101 | - ); |
|
88 | + /** |
|
89 | + * @throws Exception |
|
90 | + */ |
|
91 | + public function registerShortcodesModulesAndWidgets() |
|
92 | + { |
|
93 | + if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
94 | + return; |
|
95 | + } |
|
96 | + do_action( |
|
97 | + 'AHEE__EventEspresso_core_services_routing_Router__registerShortcodesModulesAndWidgets', |
|
98 | + $this->route_handler, |
|
99 | + $this->route_request_type, |
|
100 | + $this->dependency_map |
|
101 | + ); |
|
102 | 102 | |
103 | - /** @var LegacyModulesManager $legacy_modules_manager */ |
|
104 | - $legacy_modules_manager = $this->loader->getShared(LegacyModulesManager::class); |
|
105 | - $legacy_modules_manager->setHooks(); |
|
103 | + /** @var LegacyModulesManager $legacy_modules_manager */ |
|
104 | + $legacy_modules_manager = $this->loader->getShared(LegacyModulesManager::class); |
|
105 | + $legacy_modules_manager->setHooks(); |
|
106 | 106 | |
107 | - switch ($this->route_request_type) { |
|
108 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
109 | - break; |
|
110 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
111 | - $this->route_handler->addRoute( |
|
112 | - 'EventEspresso\core\domain\entities\routing\handlers\frontend\ShortcodeRequests' |
|
113 | - ); |
|
114 | - /** @var LegacyWidgetsManager $legacy_widgets_manager */ |
|
115 | - $legacy_widgets_manager = $this->loader->getShared(LegacyWidgetsManager::class); |
|
116 | - $legacy_widgets_manager->setHooks(); |
|
117 | - break; |
|
118 | - } |
|
119 | - $this->routes_loaded[ __FUNCTION__ ] = true; |
|
120 | - } |
|
107 | + switch ($this->route_request_type) { |
|
108 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
109 | + break; |
|
110 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
111 | + $this->route_handler->addRoute( |
|
112 | + 'EventEspresso\core\domain\entities\routing\handlers\frontend\ShortcodeRequests' |
|
113 | + ); |
|
114 | + /** @var LegacyWidgetsManager $legacy_widgets_manager */ |
|
115 | + $legacy_widgets_manager = $this->loader->getShared(LegacyWidgetsManager::class); |
|
116 | + $legacy_widgets_manager->setHooks(); |
|
117 | + break; |
|
118 | + } |
|
119 | + $this->routes_loaded[ __FUNCTION__ ] = true; |
|
120 | + } |
|
121 | 121 | |
122 | 122 | |
123 | - /** |
|
124 | - * @throws Exception |
|
125 | - */ |
|
126 | - public function brewEspresso() |
|
127 | - { |
|
128 | - if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
129 | - return; |
|
130 | - } |
|
131 | - do_action( |
|
132 | - 'AHEE__EventEspresso_core_services_routing_Router__brewEspresso', |
|
133 | - $this->route_handler, |
|
134 | - $this->route_request_type, |
|
135 | - $this->dependency_map |
|
136 | - ); |
|
137 | - switch ($this->route_request_type) { |
|
138 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
139 | - break; |
|
140 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
141 | - $this->route_handler->addRoute( |
|
142 | - 'EventEspresso\core\domain\entities\routing\handlers\shared\GQLRequests' |
|
143 | - ); |
|
144 | - $this->route_handler->addRoute( |
|
145 | - 'EventEspresso\core\domain\entities\routing\handlers\shared\RestApiRequests' |
|
146 | - ); |
|
147 | - break; |
|
148 | - } |
|
149 | - $this->routes_loaded[ __FUNCTION__ ] = true; |
|
150 | - } |
|
123 | + /** |
|
124 | + * @throws Exception |
|
125 | + */ |
|
126 | + public function brewEspresso() |
|
127 | + { |
|
128 | + if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
129 | + return; |
|
130 | + } |
|
131 | + do_action( |
|
132 | + 'AHEE__EventEspresso_core_services_routing_Router__brewEspresso', |
|
133 | + $this->route_handler, |
|
134 | + $this->route_request_type, |
|
135 | + $this->dependency_map |
|
136 | + ); |
|
137 | + switch ($this->route_request_type) { |
|
138 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
139 | + break; |
|
140 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
141 | + $this->route_handler->addRoute( |
|
142 | + 'EventEspresso\core\domain\entities\routing\handlers\shared\GQLRequests' |
|
143 | + ); |
|
144 | + $this->route_handler->addRoute( |
|
145 | + 'EventEspresso\core\domain\entities\routing\handlers\shared\RestApiRequests' |
|
146 | + ); |
|
147 | + break; |
|
148 | + } |
|
149 | + $this->routes_loaded[ __FUNCTION__ ] = true; |
|
150 | + } |
|
151 | 151 | |
152 | 152 | |
153 | - /** |
|
154 | - * @throws Exception |
|
155 | - */ |
|
156 | - public function loadControllers() |
|
157 | - { |
|
158 | - if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
159 | - return; |
|
160 | - } |
|
161 | - do_action( |
|
162 | - 'AHEE__EventEspresso_core_services_routing_Router__loadControllers', |
|
163 | - $this->route_handler, |
|
164 | - $this->route_request_type, |
|
165 | - $this->dependency_map |
|
166 | - ); |
|
167 | - $this->route_handler->addRoute( |
|
168 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\AdminRoute' |
|
169 | - ); |
|
170 | - switch ($this->route_request_type) { |
|
171 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
172 | - $this->route_handler->addRoute( |
|
173 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressPluginsPage' |
|
174 | - ); |
|
175 | - break; |
|
176 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
177 | - $this->route_handler->addRoute( |
|
178 | - 'EventEspresso\core\domain\entities\routing\handlers\frontend\FrontendRequests' |
|
179 | - ); |
|
180 | - $this->route_handler->addRoute( |
|
181 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoLegacyAdmin' |
|
182 | - ); |
|
183 | - $this->route_handler->addRoute( |
|
184 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoEventsAdmin' |
|
185 | - ); |
|
186 | - $this->route_handler->addRoute( |
|
187 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoEventEditor' |
|
188 | - ); |
|
189 | - $this->route_handler->addRoute( |
|
190 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\GutenbergEditor' |
|
191 | - ); |
|
192 | - $this->route_handler->addRoute( |
|
193 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\NonEspressoAdminAjax' |
|
194 | - ); |
|
195 | - $this->route_handler->addRoute( |
|
196 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressPluginsPage' |
|
197 | - ); |
|
198 | - $this->route_handler->addRoute( |
|
199 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressProfilePage' |
|
200 | - ); |
|
201 | - $this->route_handler->addRoute( |
|
202 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressPostsPage' |
|
203 | - ); |
|
204 | - $this->route_handler->addRoute( |
|
205 | - 'EventEspresso\core\domain\entities\routing\handlers\shared\WordPressHeartbeat' |
|
206 | - ); |
|
207 | - $this->route_handler->addRoute( |
|
208 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoBatchJob' |
|
209 | - ); |
|
210 | - break; |
|
211 | - } |
|
212 | - $this->routes_loaded[ __FUNCTION__ ] = true; |
|
213 | - } |
|
153 | + /** |
|
154 | + * @throws Exception |
|
155 | + */ |
|
156 | + public function loadControllers() |
|
157 | + { |
|
158 | + if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
159 | + return; |
|
160 | + } |
|
161 | + do_action( |
|
162 | + 'AHEE__EventEspresso_core_services_routing_Router__loadControllers', |
|
163 | + $this->route_handler, |
|
164 | + $this->route_request_type, |
|
165 | + $this->dependency_map |
|
166 | + ); |
|
167 | + $this->route_handler->addRoute( |
|
168 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\AdminRoute' |
|
169 | + ); |
|
170 | + switch ($this->route_request_type) { |
|
171 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
172 | + $this->route_handler->addRoute( |
|
173 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressPluginsPage' |
|
174 | + ); |
|
175 | + break; |
|
176 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
177 | + $this->route_handler->addRoute( |
|
178 | + 'EventEspresso\core\domain\entities\routing\handlers\frontend\FrontendRequests' |
|
179 | + ); |
|
180 | + $this->route_handler->addRoute( |
|
181 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoLegacyAdmin' |
|
182 | + ); |
|
183 | + $this->route_handler->addRoute( |
|
184 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoEventsAdmin' |
|
185 | + ); |
|
186 | + $this->route_handler->addRoute( |
|
187 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoEventEditor' |
|
188 | + ); |
|
189 | + $this->route_handler->addRoute( |
|
190 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\GutenbergEditor' |
|
191 | + ); |
|
192 | + $this->route_handler->addRoute( |
|
193 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\NonEspressoAdminAjax' |
|
194 | + ); |
|
195 | + $this->route_handler->addRoute( |
|
196 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressPluginsPage' |
|
197 | + ); |
|
198 | + $this->route_handler->addRoute( |
|
199 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressProfilePage' |
|
200 | + ); |
|
201 | + $this->route_handler->addRoute( |
|
202 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\WordPressPostsPage' |
|
203 | + ); |
|
204 | + $this->route_handler->addRoute( |
|
205 | + 'EventEspresso\core\domain\entities\routing\handlers\shared\WordPressHeartbeat' |
|
206 | + ); |
|
207 | + $this->route_handler->addRoute( |
|
208 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\EspressoBatchJob' |
|
209 | + ); |
|
210 | + break; |
|
211 | + } |
|
212 | + $this->routes_loaded[ __FUNCTION__ ] = true; |
|
213 | + } |
|
214 | 214 | |
215 | 215 | |
216 | - /** |
|
217 | - * @throws Exception |
|
218 | - */ |
|
219 | - public function coreLoadedAndReady() |
|
220 | - { |
|
221 | - if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
222 | - return; |
|
223 | - } |
|
224 | - do_action( |
|
225 | - 'AHEE__EventEspresso_core_services_routing_Router__coreLoadedAndReady', |
|
226 | - $this->route_handler, |
|
227 | - $this->route_request_type, |
|
228 | - $this->dependency_map |
|
229 | - ); |
|
230 | - switch ($this->route_request_type) { |
|
231 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
232 | - break; |
|
233 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
234 | - $this->route_handler->addRoute( |
|
235 | - 'EventEspresso\core\domain\entities\routing\handlers\shared\AssetRequests' |
|
236 | - ); |
|
237 | - $this->route_handler->addRoute( |
|
238 | - 'EventEspresso\core\domain\entities\routing\handlers\shared\SessionRequests' |
|
239 | - ); |
|
240 | - break; |
|
241 | - } |
|
242 | - $this->routes_loaded[ __FUNCTION__ ] = true; |
|
243 | - } |
|
216 | + /** |
|
217 | + * @throws Exception |
|
218 | + */ |
|
219 | + public function coreLoadedAndReady() |
|
220 | + { |
|
221 | + if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
222 | + return; |
|
223 | + } |
|
224 | + do_action( |
|
225 | + 'AHEE__EventEspresso_core_services_routing_Router__coreLoadedAndReady', |
|
226 | + $this->route_handler, |
|
227 | + $this->route_request_type, |
|
228 | + $this->dependency_map |
|
229 | + ); |
|
230 | + switch ($this->route_request_type) { |
|
231 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
232 | + break; |
|
233 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
234 | + $this->route_handler->addRoute( |
|
235 | + 'EventEspresso\core\domain\entities\routing\handlers\shared\AssetRequests' |
|
236 | + ); |
|
237 | + $this->route_handler->addRoute( |
|
238 | + 'EventEspresso\core\domain\entities\routing\handlers\shared\SessionRequests' |
|
239 | + ); |
|
240 | + break; |
|
241 | + } |
|
242 | + $this->routes_loaded[ __FUNCTION__ ] = true; |
|
243 | + } |
|
244 | 244 | |
245 | 245 | |
246 | - /** |
|
247 | - * @throws Exception |
|
248 | - */ |
|
249 | - public function initializeLast() |
|
250 | - { |
|
251 | - if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
252 | - return; |
|
253 | - } |
|
254 | - do_action( |
|
255 | - 'AHEE__EventEspresso_core_services_routing_Router__initializeLast', |
|
256 | - $this->route_handler, |
|
257 | - $this->route_request_type, |
|
258 | - $this->dependency_map |
|
259 | - ); |
|
260 | - switch ($this->route_request_type) { |
|
261 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
262 | - break; |
|
263 | - case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
264 | - $this->route_handler->addRoute( |
|
265 | - 'EventEspresso\core\domain\entities\routing\handlers\admin\PersonalDataRequests' |
|
266 | - ); |
|
267 | - break; |
|
268 | - } |
|
269 | - $this->routes_loaded[ __FUNCTION__ ] = true; |
|
270 | - } |
|
246 | + /** |
|
247 | + * @throws Exception |
|
248 | + */ |
|
249 | + public function initializeLast() |
|
250 | + { |
|
251 | + if (isset($this->routes_loaded[ __FUNCTION__ ])) { |
|
252 | + return; |
|
253 | + } |
|
254 | + do_action( |
|
255 | + 'AHEE__EventEspresso_core_services_routing_Router__initializeLast', |
|
256 | + $this->route_handler, |
|
257 | + $this->route_request_type, |
|
258 | + $this->dependency_map |
|
259 | + ); |
|
260 | + switch ($this->route_request_type) { |
|
261 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_ACTIVATION: |
|
262 | + break; |
|
263 | + case PrimaryRoute::ROUTE_REQUEST_TYPE_REGULAR: |
|
264 | + $this->route_handler->addRoute( |
|
265 | + 'EventEspresso\core\domain\entities\routing\handlers\admin\PersonalDataRequests' |
|
266 | + ); |
|
267 | + break; |
|
268 | + } |
|
269 | + $this->routes_loaded[ __FUNCTION__ ] = true; |
|
270 | + } |
|
271 | 271 | } |
@@ -14,194 +14,194 @@ |
||
14 | 14 | */ |
15 | 15 | class CipherMethod |
16 | 16 | { |
17 | - protected string $cipher_method_option_name = ''; |
|
18 | - |
|
19 | - /** |
|
20 | - * list of cipher methods that we consider usable, |
|
21 | - * essentially all of the installed_cipher_methods minus weak_algorithms |
|
22 | - */ |
|
23 | - protected array $cipher_methods = []; |
|
24 | - |
|
25 | - protected string $default_cipher_method = ''; |
|
26 | - |
|
27 | - /** |
|
28 | - * list of ALL cipher methods available on the server |
|
29 | - */ |
|
30 | - protected array $installed_cipher_methods = []; |
|
31 | - |
|
32 | - /** |
|
33 | - * the OpenSSL cipher method to use. default: AES-128-CBC |
|
34 | - */ |
|
35 | - protected ?string $validated_cipher_method = null; |
|
36 | - |
|
37 | - /** |
|
38 | - * as early as Aug 2016, Openssl declared the following weak: RC2, RC4, DES, 3DES, MD5 based |
|
39 | - * and ECB mode should be avoided |
|
40 | - */ |
|
41 | - protected array $weak_algorithms = ['des', 'ecb', 'md5', 'rc2', 'rc4']; |
|
42 | - |
|
43 | - |
|
44 | - /** |
|
45 | - * @param string $default_cipher_method |
|
46 | - * @param string $cipher_method_option_name |
|
47 | - */ |
|
48 | - public function __construct(string $default_cipher_method, string $cipher_method_option_name) |
|
49 | - { |
|
50 | - $this->default_cipher_method = $default_cipher_method; |
|
51 | - $this->cipher_method_option_name = $cipher_method_option_name; |
|
52 | - $this->installed_cipher_methods = openssl_get_cipher_methods(); |
|
53 | - } |
|
54 | - |
|
55 | - |
|
56 | - /** |
|
57 | - * Returns a cipher method that has been verified to work. |
|
58 | - * First checks if the cached cipher has been set already and if so, returns that. |
|
59 | - * Then tests the incoming default and returns that if it's good. |
|
60 | - * If not, then it retrieves the previously tested and saved cipher method. |
|
61 | - * But if that doesn't exist, then calls getAvailableCipherMethod() |
|
62 | - * to see what is available on the server, and returns the results. |
|
63 | - * |
|
64 | - * @param string $cipher_method |
|
65 | - * @param bool $load_alternate [optional] if TRUE, will load the default cipher method (or any strong algorithm) |
|
66 | - * if the requested cipher method is not installed or invalid. |
|
67 | - * if FALSE, will throw an exception if the requested cipher method is not valid. |
|
68 | - * @return string |
|
69 | - * @throws RuntimeException |
|
70 | - */ |
|
71 | - public function getCipherMethod(string $cipher_method = '', bool $load_alternate = true): ?string |
|
72 | - { |
|
73 | - if (empty($cipher_method) && $this->validated_cipher_method !== null) { |
|
74 | - return $this->validated_cipher_method; |
|
75 | - } |
|
76 | - // if nothing specific was requested and it's ok to load an alternate, then grab the system default |
|
77 | - if (empty($cipher_method) && $load_alternate) { |
|
78 | - $cipher_method = $this->default_cipher_method; |
|
79 | - } |
|
80 | - // verify that the cipher method can produce an initialization vector. |
|
81 | - // but if the requested is invalid and we don't want to load an alternate, then throw an exception |
|
82 | - $throw_exception = ! $load_alternate; |
|
83 | - if ($this->validateCipherMethod($cipher_method, $throw_exception) === false) { |
|
84 | - // nope? ... ok let's see what we can find |
|
85 | - $cipher_method = $this->getAvailableCipherMethod(); |
|
86 | - } |
|
87 | - // if nothing has been previously validated, then save the currently requested cipher which appears to be good |
|
88 | - if ($this->validated_cipher_method === null) { |
|
89 | - $this->validated_cipher_method = $cipher_method; |
|
90 | - } |
|
91 | - return $cipher_method; |
|
92 | - } |
|
93 | - |
|
94 | - |
|
95 | - /** |
|
96 | - * returns true if the selected cipher method either uses Galois/Counter Mode (GCM) |
|
97 | - * or Counter with CBC-MAC (CCM) authenticated encryption modes |
|
98 | - * (also need to be using PHP 7.1 or greater to actually use authenticated encryption modes) |
|
99 | - * |
|
100 | - * @return bool |
|
101 | - */ |
|
102 | - public function usesAuthenticatedEncryptionMode(): bool |
|
103 | - { |
|
104 | - return PHP_VERSION_ID >= 70100 |
|
105 | - && ( |
|
106 | - stripos($this->validated_cipher_method, 'gcm') !== false |
|
107 | - || stripos($this->validated_cipher_method, 'ccm') !== false |
|
108 | - ); |
|
109 | - } |
|
110 | - |
|
111 | - |
|
112 | - /** |
|
113 | - * @param string $cipher_method |
|
114 | - * @return string |
|
115 | - * @throws RuntimeException |
|
116 | - */ |
|
117 | - protected function getAvailableCipherMethod(string $cipher_method = ''): ?string |
|
118 | - { |
|
119 | - // if nothing was supplied, the get what we found in the past to work |
|
120 | - $cipher_method_to_test = $cipher_method |
|
121 | - ?: get_option($this->cipher_method_option_name, ''); |
|
122 | - // verify that the incoming cipher method exists and can produce an initialization vector |
|
123 | - if ($this->validateCipherMethod($cipher_method_to_test) === false) { |
|
124 | - // what? there's no list? |
|
125 | - if (empty($this->cipher_methods)) { |
|
126 | - // generate that list and cache it |
|
127 | - $this->cipher_methods = $this->getAvailableStrongCipherMethods(); |
|
128 | - } |
|
129 | - // then grab the first item from the list (we'll add it back later if it is good) |
|
130 | - $cipher_method_to_test = array_shift($this->cipher_methods); |
|
131 | - if ($cipher_method_to_test === null) { |
|
132 | - throw new RuntimeException( |
|
133 | - esc_html__( |
|
134 | - 'OpenSSL support appears to be enabled on the server, but no cipher methods are available. Please contact the server administrator.', |
|
135 | - 'event_espresso' |
|
136 | - ) |
|
137 | - ); |
|
138 | - } |
|
139 | - // verify that the next cipher method works |
|
140 | - return $this->getAvailableCipherMethod($cipher_method_to_test); |
|
141 | - } |
|
142 | - // if we've gotten this far, then we found an available cipher method that works |
|
143 | - // so save that for next time, if it's not the same as what's there already |
|
144 | - if ($cipher_method_to_test !== $cipher_method) { |
|
145 | - update_option($this->cipher_method_option_name, $cipher_method_to_test); |
|
146 | - } |
|
147 | - // if we previously removed this cipher method from the list of valid ones, then let's put it back |
|
148 | - if (! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
149 | - array_unshift($this->cipher_methods, $cipher_method_to_test); |
|
150 | - } |
|
151 | - return $cipher_method_to_test; |
|
152 | - } |
|
153 | - |
|
154 | - |
|
155 | - /** |
|
156 | - * @return array |
|
157 | - */ |
|
158 | - protected function getAvailableStrongCipherMethods(): array |
|
159 | - { |
|
160 | - return array_filter($this->installed_cipher_methods, [$this, 'weakAlgorithmFilter']); |
|
161 | - } |
|
162 | - |
|
163 | - |
|
164 | - /** |
|
165 | - * @param string $cipher_method |
|
166 | - * @param bool $throw_exception |
|
167 | - * @return bool |
|
168 | - */ |
|
169 | - protected function validateCipherMethod(string $cipher_method, bool $throw_exception = false): bool |
|
170 | - { |
|
171 | - // verify that the requested cipher method is actually installed and can produce an initialization vector |
|
172 | - if ( |
|
173 | - in_array($cipher_method, $this->installed_cipher_methods, true) |
|
174 | - && openssl_cipher_iv_length($cipher_method) !== false |
|
175 | - ) { |
|
176 | - return true; |
|
177 | - } |
|
178 | - if (! $throw_exception) { |
|
179 | - return false; |
|
180 | - } |
|
181 | - throw new RuntimeException( |
|
182 | - sprintf( |
|
183 | - esc_html__( |
|
184 | - 'The requested OpenSSL cipher method "%1$s" is invalid or not installed on the server. Please contact the server administrator.', |
|
185 | - 'event_espresso' |
|
186 | - ), |
|
187 | - $cipher_method |
|
188 | - ) |
|
189 | - ); |
|
190 | - } |
|
191 | - |
|
192 | - |
|
193 | - /** |
|
194 | - * @see https://www.php.net/manual/en/function.openssl-get-cipher-methods.php#example-890 |
|
195 | - * @param string $cipher_method |
|
196 | - * @return bool |
|
197 | - */ |
|
198 | - protected function weakAlgorithmFilter(string $cipher_method): bool |
|
199 | - { |
|
200 | - foreach ($this->weak_algorithms as $weak_algorithm) { |
|
201 | - if (stripos($cipher_method, $weak_algorithm) !== false) { |
|
202 | - return false; |
|
203 | - } |
|
204 | - } |
|
205 | - return true; |
|
206 | - } |
|
17 | + protected string $cipher_method_option_name = ''; |
|
18 | + |
|
19 | + /** |
|
20 | + * list of cipher methods that we consider usable, |
|
21 | + * essentially all of the installed_cipher_methods minus weak_algorithms |
|
22 | + */ |
|
23 | + protected array $cipher_methods = []; |
|
24 | + |
|
25 | + protected string $default_cipher_method = ''; |
|
26 | + |
|
27 | + /** |
|
28 | + * list of ALL cipher methods available on the server |
|
29 | + */ |
|
30 | + protected array $installed_cipher_methods = []; |
|
31 | + |
|
32 | + /** |
|
33 | + * the OpenSSL cipher method to use. default: AES-128-CBC |
|
34 | + */ |
|
35 | + protected ?string $validated_cipher_method = null; |
|
36 | + |
|
37 | + /** |
|
38 | + * as early as Aug 2016, Openssl declared the following weak: RC2, RC4, DES, 3DES, MD5 based |
|
39 | + * and ECB mode should be avoided |
|
40 | + */ |
|
41 | + protected array $weak_algorithms = ['des', 'ecb', 'md5', 'rc2', 'rc4']; |
|
42 | + |
|
43 | + |
|
44 | + /** |
|
45 | + * @param string $default_cipher_method |
|
46 | + * @param string $cipher_method_option_name |
|
47 | + */ |
|
48 | + public function __construct(string $default_cipher_method, string $cipher_method_option_name) |
|
49 | + { |
|
50 | + $this->default_cipher_method = $default_cipher_method; |
|
51 | + $this->cipher_method_option_name = $cipher_method_option_name; |
|
52 | + $this->installed_cipher_methods = openssl_get_cipher_methods(); |
|
53 | + } |
|
54 | + |
|
55 | + |
|
56 | + /** |
|
57 | + * Returns a cipher method that has been verified to work. |
|
58 | + * First checks if the cached cipher has been set already and if so, returns that. |
|
59 | + * Then tests the incoming default and returns that if it's good. |
|
60 | + * If not, then it retrieves the previously tested and saved cipher method. |
|
61 | + * But if that doesn't exist, then calls getAvailableCipherMethod() |
|
62 | + * to see what is available on the server, and returns the results. |
|
63 | + * |
|
64 | + * @param string $cipher_method |
|
65 | + * @param bool $load_alternate [optional] if TRUE, will load the default cipher method (or any strong algorithm) |
|
66 | + * if the requested cipher method is not installed or invalid. |
|
67 | + * if FALSE, will throw an exception if the requested cipher method is not valid. |
|
68 | + * @return string |
|
69 | + * @throws RuntimeException |
|
70 | + */ |
|
71 | + public function getCipherMethod(string $cipher_method = '', bool $load_alternate = true): ?string |
|
72 | + { |
|
73 | + if (empty($cipher_method) && $this->validated_cipher_method !== null) { |
|
74 | + return $this->validated_cipher_method; |
|
75 | + } |
|
76 | + // if nothing specific was requested and it's ok to load an alternate, then grab the system default |
|
77 | + if (empty($cipher_method) && $load_alternate) { |
|
78 | + $cipher_method = $this->default_cipher_method; |
|
79 | + } |
|
80 | + // verify that the cipher method can produce an initialization vector. |
|
81 | + // but if the requested is invalid and we don't want to load an alternate, then throw an exception |
|
82 | + $throw_exception = ! $load_alternate; |
|
83 | + if ($this->validateCipherMethod($cipher_method, $throw_exception) === false) { |
|
84 | + // nope? ... ok let's see what we can find |
|
85 | + $cipher_method = $this->getAvailableCipherMethod(); |
|
86 | + } |
|
87 | + // if nothing has been previously validated, then save the currently requested cipher which appears to be good |
|
88 | + if ($this->validated_cipher_method === null) { |
|
89 | + $this->validated_cipher_method = $cipher_method; |
|
90 | + } |
|
91 | + return $cipher_method; |
|
92 | + } |
|
93 | + |
|
94 | + |
|
95 | + /** |
|
96 | + * returns true if the selected cipher method either uses Galois/Counter Mode (GCM) |
|
97 | + * or Counter with CBC-MAC (CCM) authenticated encryption modes |
|
98 | + * (also need to be using PHP 7.1 or greater to actually use authenticated encryption modes) |
|
99 | + * |
|
100 | + * @return bool |
|
101 | + */ |
|
102 | + public function usesAuthenticatedEncryptionMode(): bool |
|
103 | + { |
|
104 | + return PHP_VERSION_ID >= 70100 |
|
105 | + && ( |
|
106 | + stripos($this->validated_cipher_method, 'gcm') !== false |
|
107 | + || stripos($this->validated_cipher_method, 'ccm') !== false |
|
108 | + ); |
|
109 | + } |
|
110 | + |
|
111 | + |
|
112 | + /** |
|
113 | + * @param string $cipher_method |
|
114 | + * @return string |
|
115 | + * @throws RuntimeException |
|
116 | + */ |
|
117 | + protected function getAvailableCipherMethod(string $cipher_method = ''): ?string |
|
118 | + { |
|
119 | + // if nothing was supplied, the get what we found in the past to work |
|
120 | + $cipher_method_to_test = $cipher_method |
|
121 | + ?: get_option($this->cipher_method_option_name, ''); |
|
122 | + // verify that the incoming cipher method exists and can produce an initialization vector |
|
123 | + if ($this->validateCipherMethod($cipher_method_to_test) === false) { |
|
124 | + // what? there's no list? |
|
125 | + if (empty($this->cipher_methods)) { |
|
126 | + // generate that list and cache it |
|
127 | + $this->cipher_methods = $this->getAvailableStrongCipherMethods(); |
|
128 | + } |
|
129 | + // then grab the first item from the list (we'll add it back later if it is good) |
|
130 | + $cipher_method_to_test = array_shift($this->cipher_methods); |
|
131 | + if ($cipher_method_to_test === null) { |
|
132 | + throw new RuntimeException( |
|
133 | + esc_html__( |
|
134 | + 'OpenSSL support appears to be enabled on the server, but no cipher methods are available. Please contact the server administrator.', |
|
135 | + 'event_espresso' |
|
136 | + ) |
|
137 | + ); |
|
138 | + } |
|
139 | + // verify that the next cipher method works |
|
140 | + return $this->getAvailableCipherMethod($cipher_method_to_test); |
|
141 | + } |
|
142 | + // if we've gotten this far, then we found an available cipher method that works |
|
143 | + // so save that for next time, if it's not the same as what's there already |
|
144 | + if ($cipher_method_to_test !== $cipher_method) { |
|
145 | + update_option($this->cipher_method_option_name, $cipher_method_to_test); |
|
146 | + } |
|
147 | + // if we previously removed this cipher method from the list of valid ones, then let's put it back |
|
148 | + if (! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
149 | + array_unshift($this->cipher_methods, $cipher_method_to_test); |
|
150 | + } |
|
151 | + return $cipher_method_to_test; |
|
152 | + } |
|
153 | + |
|
154 | + |
|
155 | + /** |
|
156 | + * @return array |
|
157 | + */ |
|
158 | + protected function getAvailableStrongCipherMethods(): array |
|
159 | + { |
|
160 | + return array_filter($this->installed_cipher_methods, [$this, 'weakAlgorithmFilter']); |
|
161 | + } |
|
162 | + |
|
163 | + |
|
164 | + /** |
|
165 | + * @param string $cipher_method |
|
166 | + * @param bool $throw_exception |
|
167 | + * @return bool |
|
168 | + */ |
|
169 | + protected function validateCipherMethod(string $cipher_method, bool $throw_exception = false): bool |
|
170 | + { |
|
171 | + // verify that the requested cipher method is actually installed and can produce an initialization vector |
|
172 | + if ( |
|
173 | + in_array($cipher_method, $this->installed_cipher_methods, true) |
|
174 | + && openssl_cipher_iv_length($cipher_method) !== false |
|
175 | + ) { |
|
176 | + return true; |
|
177 | + } |
|
178 | + if (! $throw_exception) { |
|
179 | + return false; |
|
180 | + } |
|
181 | + throw new RuntimeException( |
|
182 | + sprintf( |
|
183 | + esc_html__( |
|
184 | + 'The requested OpenSSL cipher method "%1$s" is invalid or not installed on the server. Please contact the server administrator.', |
|
185 | + 'event_espresso' |
|
186 | + ), |
|
187 | + $cipher_method |
|
188 | + ) |
|
189 | + ); |
|
190 | + } |
|
191 | + |
|
192 | + |
|
193 | + /** |
|
194 | + * @see https://www.php.net/manual/en/function.openssl-get-cipher-methods.php#example-890 |
|
195 | + * @param string $cipher_method |
|
196 | + * @return bool |
|
197 | + */ |
|
198 | + protected function weakAlgorithmFilter(string $cipher_method): bool |
|
199 | + { |
|
200 | + foreach ($this->weak_algorithms as $weak_algorithm) { |
|
201 | + if (stripos($cipher_method, $weak_algorithm) !== false) { |
|
202 | + return false; |
|
203 | + } |
|
204 | + } |
|
205 | + return true; |
|
206 | + } |
|
207 | 207 | } |
@@ -20,7 +20,7 @@ discard block |
||
20 | 20 | * list of cipher methods that we consider usable, |
21 | 21 | * essentially all of the installed_cipher_methods minus weak_algorithms |
22 | 22 | */ |
23 | - protected array $cipher_methods = []; |
|
23 | + protected array $cipher_methods = []; |
|
24 | 24 | |
25 | 25 | protected string $default_cipher_method = ''; |
26 | 26 | |
@@ -145,7 +145,7 @@ discard block |
||
145 | 145 | update_option($this->cipher_method_option_name, $cipher_method_to_test); |
146 | 146 | } |
147 | 147 | // if we previously removed this cipher method from the list of valid ones, then let's put it back |
148 | - if (! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
148 | + if ( ! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
149 | 149 | array_unshift($this->cipher_methods, $cipher_method_to_test); |
150 | 150 | } |
151 | 151 | return $cipher_method_to_test; |
@@ -175,7 +175,7 @@ discard block |
||
175 | 175 | ) { |
176 | 176 | return true; |
177 | 177 | } |
178 | - if (! $throw_exception) { |
|
178 | + if ( ! $throw_exception) { |
|
179 | 179 | return false; |
180 | 180 | } |
181 | 181 | throw new RuntimeException( |
@@ -18,88 +18,88 @@ |
||
18 | 18 | */ |
19 | 19 | class GraphQLEndpoint extends WordPressOption |
20 | 20 | { |
21 | - const DEFAULT_ENDPOINT = 'graphql'; |
|
21 | + const DEFAULT_ENDPOINT = 'graphql'; |
|
22 | 22 | |
23 | - const OPTION_NAME = 'ee-graphql-endpoint'; |
|
23 | + const OPTION_NAME = 'ee-graphql-endpoint'; |
|
24 | 24 | |
25 | - private bool $is_gql_request; |
|
25 | + private bool $is_gql_request; |
|
26 | 26 | |
27 | 27 | |
28 | - /** |
|
29 | - * GraphQLEndpoint constructor. |
|
30 | - */ |
|
31 | - public function __construct() |
|
32 | - { |
|
33 | - parent::__construct(GraphQLEndpoint::OPTION_NAME, GraphQLEndpoint::DEFAULT_ENDPOINT, true); |
|
34 | - add_action('graphql_register_settings', [$this, 'verifyAndSetEndpoint'], 20); |
|
35 | - if (! $this->graphqlDebug()) { |
|
36 | - // disable WPGraphQL admin by default. |
|
37 | - add_filter('graphql_show_admin', '__return_false'); |
|
38 | - add_filter('graphql_enable_graphiql', '__return_false'); |
|
39 | - } |
|
40 | - } |
|
28 | + /** |
|
29 | + * GraphQLEndpoint constructor. |
|
30 | + */ |
|
31 | + public function __construct() |
|
32 | + { |
|
33 | + parent::__construct(GraphQLEndpoint::OPTION_NAME, GraphQLEndpoint::DEFAULT_ENDPOINT, true); |
|
34 | + add_action('graphql_register_settings', [$this, 'verifyAndSetEndpoint'], 20); |
|
35 | + if (! $this->graphqlDebug()) { |
|
36 | + // disable WPGraphQL admin by default. |
|
37 | + add_filter('graphql_show_admin', '__return_false'); |
|
38 | + add_filter('graphql_enable_graphiql', '__return_false'); |
|
39 | + } |
|
40 | + } |
|
41 | 41 | |
42 | - /** |
|
43 | - * Determine the value of global constant GRAPHQL_DEBUG |
|
44 | - * @return bool |
|
45 | - */ |
|
46 | - private function graphqlDebug(): bool |
|
47 | - { |
|
48 | - return defined('GRAPHQL_DEBUG') && GRAPHQL_DEBUG; |
|
49 | - } |
|
42 | + /** |
|
43 | + * Determine the value of global constant GRAPHQL_DEBUG |
|
44 | + * @return bool |
|
45 | + */ |
|
46 | + private function graphqlDebug(): bool |
|
47 | + { |
|
48 | + return defined('GRAPHQL_DEBUG') && GRAPHQL_DEBUG; |
|
49 | + } |
|
50 | 50 | |
51 | 51 | |
52 | - /** |
|
53 | - * @return false|mixed|void |
|
54 | - */ |
|
55 | - public function getEndpoint() |
|
56 | - { |
|
57 | - return $this->loadOption(); |
|
58 | - } |
|
52 | + /** |
|
53 | + * @return false|mixed|void |
|
54 | + */ |
|
55 | + public function getEndpoint() |
|
56 | + { |
|
57 | + return $this->loadOption(); |
|
58 | + } |
|
59 | 59 | |
60 | 60 | |
61 | - /** |
|
62 | - * @return mixed|void|bool |
|
63 | - */ |
|
64 | - public function isGraphqlRequest() |
|
65 | - { |
|
66 | - if (! isset($this->is_gql_request)) { |
|
67 | - // grab the GQL endpoint that we saved in the future... wait... wut? |
|
68 | - $endpoint = $this->getEndpoint(); |
|
69 | - // set our saved endpoint on the WP GQL Pouter class |
|
70 | - // don't worry, this is a static property that they overwrite when they initialize things, |
|
71 | - // and we are essentially getting the value from them anyways, so it should be ok (fingers crossed) |
|
72 | - Router::$route = $endpoint; |
|
73 | - // now call their function for checking if this is a GQL request |
|
74 | - // because they use a bunch of filters and stuff we don't want to duplicate here |
|
75 | - $this->is_gql_request = Router::is_graphql_http_request(); |
|
76 | - } |
|
77 | - return $this->is_gql_request; |
|
78 | - } |
|
61 | + /** |
|
62 | + * @return mixed|void|bool |
|
63 | + */ |
|
64 | + public function isGraphqlRequest() |
|
65 | + { |
|
66 | + if (! isset($this->is_gql_request)) { |
|
67 | + // grab the GQL endpoint that we saved in the future... wait... wut? |
|
68 | + $endpoint = $this->getEndpoint(); |
|
69 | + // set our saved endpoint on the WP GQL Pouter class |
|
70 | + // don't worry, this is a static property that they overwrite when they initialize things, |
|
71 | + // and we are essentially getting the value from them anyways, so it should be ok (fingers crossed) |
|
72 | + Router::$route = $endpoint; |
|
73 | + // now call their function for checking if this is a GQL request |
|
74 | + // because they use a bunch of filters and stuff we don't want to duplicate here |
|
75 | + $this->is_gql_request = Router::is_graphql_http_request(); |
|
76 | + } |
|
77 | + return $this->is_gql_request; |
|
78 | + } |
|
79 | 79 | |
80 | 80 | |
81 | - /** |
|
82 | - * callback hooked into the graphql_register_settings action |
|
83 | - * basically grabs the value for the 'graphql_endpoint' setting and saves it to our own WP option. |
|
84 | - * i know, i know, i know... |
|
85 | - * WHY are we saving the graphql_endpoint to a WP option if WP GraphQL is already doing the same ?!?! |
|
86 | - * Because we perform our request type detection during `plugins_loaded`, |
|
87 | - * but they don't settle on their endpoint until `after_setup_theme` has run, |
|
88 | - * which is too late for us, so we are just going to save this separately so that we have it. |
|
89 | - * Oh, and this will essentially recheck this value on EVERY request |
|
90 | - * but will only update our saved value if it has actually changed |
|
91 | - */ |
|
92 | - public function verifyAndSetEndpoint() |
|
93 | - { |
|
94 | - try { |
|
95 | - $this->updateOption( |
|
96 | - get_graphql_setting( |
|
97 | - 'graphql_endpoint', |
|
98 | - apply_filters('graphql_endpoint', GraphQLEndpoint::DEFAULT_ENDPOINT) |
|
99 | - ) |
|
100 | - ); |
|
101 | - } catch (Throwable $t) { |
|
102 | - // eat it |
|
103 | - } |
|
104 | - } |
|
81 | + /** |
|
82 | + * callback hooked into the graphql_register_settings action |
|
83 | + * basically grabs the value for the 'graphql_endpoint' setting and saves it to our own WP option. |
|
84 | + * i know, i know, i know... |
|
85 | + * WHY are we saving the graphql_endpoint to a WP option if WP GraphQL is already doing the same ?!?! |
|
86 | + * Because we perform our request type detection during `plugins_loaded`, |
|
87 | + * but they don't settle on their endpoint until `after_setup_theme` has run, |
|
88 | + * which is too late for us, so we are just going to save this separately so that we have it. |
|
89 | + * Oh, and this will essentially recheck this value on EVERY request |
|
90 | + * but will only update our saved value if it has actually changed |
|
91 | + */ |
|
92 | + public function verifyAndSetEndpoint() |
|
93 | + { |
|
94 | + try { |
|
95 | + $this->updateOption( |
|
96 | + get_graphql_setting( |
|
97 | + 'graphql_endpoint', |
|
98 | + apply_filters('graphql_endpoint', GraphQLEndpoint::DEFAULT_ENDPOINT) |
|
99 | + ) |
|
100 | + ); |
|
101 | + } catch (Throwable $t) { |
|
102 | + // eat it |
|
103 | + } |
|
104 | + } |
|
105 | 105 | } |
@@ -32,7 +32,7 @@ discard block |
||
32 | 32 | { |
33 | 33 | parent::__construct(GraphQLEndpoint::OPTION_NAME, GraphQLEndpoint::DEFAULT_ENDPOINT, true); |
34 | 34 | add_action('graphql_register_settings', [$this, 'verifyAndSetEndpoint'], 20); |
35 | - if (! $this->graphqlDebug()) { |
|
35 | + if ( ! $this->graphqlDebug()) { |
|
36 | 36 | // disable WPGraphQL admin by default. |
37 | 37 | add_filter('graphql_show_admin', '__return_false'); |
38 | 38 | add_filter('graphql_enable_graphiql', '__return_false'); |
@@ -63,7 +63,7 @@ discard block |
||
63 | 63 | */ |
64 | 64 | public function isGraphqlRequest() |
65 | 65 | { |
66 | - if (! isset($this->is_gql_request)) { |
|
66 | + if ( ! isset($this->is_gql_request)) { |
|
67 | 67 | // grab the GQL endpoint that we saved in the future... wait... wut? |
68 | 68 | $endpoint = $this->getEndpoint(); |
69 | 69 | // set our saved endpoint on the WP GQL Pouter class |