@@ -14,84 +14,84 @@ |
||
14 | 14 | trait EventsAdmin |
15 | 15 | { |
16 | 16 | |
17 | - /** |
|
18 | - * @param string $additional_params |
|
19 | - */ |
|
20 | - public function amOnDefaultEventsListTablePage($additional_params = '') |
|
21 | - { |
|
22 | - $this->actor()->amOnAdminPage(EventsPage::defaultEventsListTableUrl($additional_params)); |
|
23 | - } |
|
17 | + /** |
|
18 | + * @param string $additional_params |
|
19 | + */ |
|
20 | + public function amOnDefaultEventsListTablePage($additional_params = '') |
|
21 | + { |
|
22 | + $this->actor()->amOnAdminPage(EventsPage::defaultEventsListTableUrl($additional_params)); |
|
23 | + } |
|
24 | 24 | |
25 | 25 | |
26 | - /** |
|
27 | - * Triggers the publishing of the Event. |
|
28 | - */ |
|
29 | - public function publishEvent() |
|
30 | - { |
|
31 | - $this->actor()->click(EventsPage::EVENT_EDITOR_PUBLISH_BUTTON_SELECTOR); |
|
32 | - } |
|
26 | + /** |
|
27 | + * Triggers the publishing of the Event. |
|
28 | + */ |
|
29 | + public function publishEvent() |
|
30 | + { |
|
31 | + $this->actor()->click(EventsPage::EVENT_EDITOR_PUBLISH_BUTTON_SELECTOR); |
|
32 | + } |
|
33 | 33 | |
34 | 34 | |
35 | - /** |
|
36 | - * Navigates the actor to the event list table page and will attempt to edit the event for the given title. |
|
37 | - * First this will search using the given title and then attempt to edit from the results of the search. |
|
38 | - * |
|
39 | - * Assumes actor is already logged in. |
|
40 | - * @param $event_title |
|
41 | - */ |
|
42 | - public function amEditingTheEventWithTitle($event_title) |
|
43 | - { |
|
44 | - $this->amOnDefaultEventsListTablePage(); |
|
45 | - $this->actor()->fillField(EventsPage::EVENT_LIST_TABLE_SEARCH_INPUT_SELECTOR, $event_title); |
|
46 | - $this->actor()->click(CoreAdmin::LIST_TABLE_SEARCH_SUBMIT_SELECTOR); |
|
47 | - $this->actor()->waitForText('Displaying search results for'); |
|
48 | - $this->actor()->click(EventsPage::eventListTableEventTitleEditLink($event_title)); |
|
49 | - } |
|
35 | + /** |
|
36 | + * Navigates the actor to the event list table page and will attempt to edit the event for the given title. |
|
37 | + * First this will search using the given title and then attempt to edit from the results of the search. |
|
38 | + * |
|
39 | + * Assumes actor is already logged in. |
|
40 | + * @param $event_title |
|
41 | + */ |
|
42 | + public function amEditingTheEventWithTitle($event_title) |
|
43 | + { |
|
44 | + $this->amOnDefaultEventsListTablePage(); |
|
45 | + $this->actor()->fillField(EventsPage::EVENT_LIST_TABLE_SEARCH_INPUT_SELECTOR, $event_title); |
|
46 | + $this->actor()->click(CoreAdmin::LIST_TABLE_SEARCH_SUBMIT_SELECTOR); |
|
47 | + $this->actor()->waitForText('Displaying search results for'); |
|
48 | + $this->actor()->click(EventsPage::eventListTableEventTitleEditLink($event_title)); |
|
49 | + } |
|
50 | 50 | |
51 | 51 | |
52 | - /** |
|
53 | - * Navigates the user to the single event page (frontend view) for the given event title via clicking the "View" |
|
54 | - * link for the event in the event list table. |
|
55 | - * Assumes the actor is already logged in and on the Event list table page. |
|
56 | - * |
|
57 | - * @param string $event_title |
|
58 | - */ |
|
59 | - public function amOnEventPageAfterClickingViewLinkInListTableForEvent($event_title) |
|
60 | - { |
|
61 | - $this->actor()->moveMouseOver(EventsPage::eventListTableEventTitleEditLinkSelectorForTitle($event_title)); |
|
62 | - $this->actor()->click(EventsPage::eventListTableEventTitleViewLinkSelectorForTitle($event_title)); |
|
63 | - } |
|
52 | + /** |
|
53 | + * Navigates the user to the single event page (frontend view) for the given event title via clicking the "View" |
|
54 | + * link for the event in the event list table. |
|
55 | + * Assumes the actor is already logged in and on the Event list table page. |
|
56 | + * |
|
57 | + * @param string $event_title |
|
58 | + */ |
|
59 | + public function amOnEventPageAfterClickingViewLinkInListTableForEvent($event_title) |
|
60 | + { |
|
61 | + $this->actor()->moveMouseOver(EventsPage::eventListTableEventTitleEditLinkSelectorForTitle($event_title)); |
|
62 | + $this->actor()->click(EventsPage::eventListTableEventTitleViewLinkSelectorForTitle($event_title)); |
|
63 | + } |
|
64 | 64 | |
65 | 65 | |
66 | - /** |
|
67 | - * Use to change the default registration status for the event. |
|
68 | - * Assumes the view is already on the event editor. |
|
69 | - * @param $registration_status |
|
70 | - */ |
|
71 | - public function changeDefaultRegistrationStatusTo($registration_status) |
|
72 | - { |
|
73 | - $this->actor()->selectOption( |
|
74 | - EventsPage::EVENT_EDITOR_DEFAULT_REGISTRATION_STATUS_FIELD_SELECTOR, |
|
75 | - $registration_status |
|
76 | - ); |
|
77 | - } |
|
66 | + /** |
|
67 | + * Use to change the default registration status for the event. |
|
68 | + * Assumes the view is already on the event editor. |
|
69 | + * @param $registration_status |
|
70 | + */ |
|
71 | + public function changeDefaultRegistrationStatusTo($registration_status) |
|
72 | + { |
|
73 | + $this->actor()->selectOption( |
|
74 | + EventsPage::EVENT_EDITOR_DEFAULT_REGISTRATION_STATUS_FIELD_SELECTOR, |
|
75 | + $registration_status |
|
76 | + ); |
|
77 | + } |
|
78 | 78 | |
79 | 79 | |
80 | - /** |
|
81 | - * Use this from the context of the event editor to select the given custom template for a given message type and |
|
82 | - * messenger. |
|
83 | - * |
|
84 | - * @param string $message_type_label The visible label for the message type (eg Registration Approved) |
|
85 | - * @param string $messenger_slug The slug for the messenger (eg 'email') |
|
86 | - * @param string $custom_template_label The visible label in the select input for the custom template you want |
|
87 | - * selected. |
|
88 | - */ |
|
89 | - public function selectCustomTemplateFor($message_type_label, $messenger_slug, $custom_template_label) |
|
90 | - { |
|
91 | - $this->actor()->click(EventsPage::eventEditorNotificationsMetaBoxMessengerTabSelector($messenger_slug)); |
|
92 | - $this->actor()->selectOption( |
|
93 | - EventsPage::eventEditorNotificationsMetaBoxSelectSelectorForMessageType($message_type_label), |
|
94 | - $custom_template_label |
|
95 | - ); |
|
96 | - } |
|
80 | + /** |
|
81 | + * Use this from the context of the event editor to select the given custom template for a given message type and |
|
82 | + * messenger. |
|
83 | + * |
|
84 | + * @param string $message_type_label The visible label for the message type (eg Registration Approved) |
|
85 | + * @param string $messenger_slug The slug for the messenger (eg 'email') |
|
86 | + * @param string $custom_template_label The visible label in the select input for the custom template you want |
|
87 | + * selected. |
|
88 | + */ |
|
89 | + public function selectCustomTemplateFor($message_type_label, $messenger_slug, $custom_template_label) |
|
90 | + { |
|
91 | + $this->actor()->click(EventsPage::eventEditorNotificationsMetaBoxMessengerTabSelector($messenger_slug)); |
|
92 | + $this->actor()->selectOption( |
|
93 | + EventsPage::eventEditorNotificationsMetaBoxSelectSelectorForMessageType($message_type_label), |
|
94 | + $custom_template_label |
|
95 | + ); |
|
96 | + } |
|
97 | 97 | } |
98 | 98 | \ No newline at end of file |
@@ -13,84 +13,84 @@ |
||
13 | 13 | class CoreAdmin |
14 | 14 | { |
15 | 15 | |
16 | - /** |
|
17 | - * @var string |
|
18 | - */ |
|
19 | - const URL_PREFIX = 'admin.php?page='; |
|
20 | - |
|
21 | - |
|
22 | - /** |
|
23 | - * This is the selector for the next page button on list tables. |
|
24 | - * @var string |
|
25 | - */ |
|
26 | - const ADMIN_LIST_TABLE_NEXT_PAGE_CLASS = '.next-page'; |
|
27 | - |
|
28 | - |
|
29 | - /** |
|
30 | - * The selector for the search input submit button on list table pages |
|
31 | - * @var string |
|
32 | - */ |
|
33 | - const LIST_TABLE_SEARCH_SUBMIT_SELECTOR = '#search-submit'; |
|
34 | - |
|
35 | - |
|
36 | - /** |
|
37 | - * Selector for the screen options dropdown. |
|
38 | - * @var string |
|
39 | - */ |
|
40 | - const WP_SCREEN_SETTINGS_LINK_SELECTOR = '#show-settings-link'; |
|
41 | - |
|
42 | - |
|
43 | - /** |
|
44 | - * Selector for the per page field setting selector (found within screen options dropdown) |
|
45 | - * @var string |
|
46 | - */ |
|
47 | - const WP_SCREEN_SETTINGS_PER_PAGE_FIELD_SELECTOR = '.screen-per-page'; |
|
48 | - |
|
49 | - |
|
50 | - /** |
|
51 | - * Selector for apply screen options settings. |
|
52 | - * @var string |
|
53 | - */ |
|
54 | - const WP_SCREEN_OPTIONS_APPLY_SETTINGS_BUTTON_SELECTOR = '#screen-options-apply'; |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * Get the EE admin url for the given properties. |
|
59 | - * Note, this is JUST the endpoint for the admin route. It is expected that the actor/test would be calling this |
|
60 | - * with `amOnAdminPage` action. |
|
61 | - * |
|
62 | - * @param string $page |
|
63 | - * @param string $action |
|
64 | - * @param string $additional_params |
|
65 | - * @return string |
|
66 | - */ |
|
67 | - public static function adminUrl($page = 'espresso_events', $action = 'default', $additional_params = '') |
|
68 | - { |
|
69 | - $url = self::URL_PREFIX . $page; |
|
70 | - $url .= $action ? '&action=' . $action : ''; |
|
71 | - $url .= $additional_params ? '&' . ltrim('&', ltrim('?', $additional_params)) : ''; |
|
72 | - return $url; |
|
73 | - } |
|
74 | - |
|
75 | - |
|
76 | - /** |
|
77 | - * Returns the selector for the text tab switcher for a wp-editor instance. |
|
78 | - * @param $field_reference |
|
79 | - * @return string |
|
80 | - */ |
|
81 | - public static function wpEditorTextTabSelector($field_reference) |
|
82 | - { |
|
83 | - return '#content-' . $field_reference . '-content-html'; |
|
84 | - } |
|
85 | - |
|
86 | - |
|
87 | - /** |
|
88 | - * Returns the selector for the textarea exposed when clicing the text tab switcher for a wp-editor instance. |
|
89 | - * @param $field_reference |
|
90 | - * @return string |
|
91 | - */ |
|
92 | - public static function wpEditorTextAreaSelector($field_reference) |
|
93 | - { |
|
94 | - return '#content-' . $field_reference . '-content'; |
|
95 | - } |
|
16 | + /** |
|
17 | + * @var string |
|
18 | + */ |
|
19 | + const URL_PREFIX = 'admin.php?page='; |
|
20 | + |
|
21 | + |
|
22 | + /** |
|
23 | + * This is the selector for the next page button on list tables. |
|
24 | + * @var string |
|
25 | + */ |
|
26 | + const ADMIN_LIST_TABLE_NEXT_PAGE_CLASS = '.next-page'; |
|
27 | + |
|
28 | + |
|
29 | + /** |
|
30 | + * The selector for the search input submit button on list table pages |
|
31 | + * @var string |
|
32 | + */ |
|
33 | + const LIST_TABLE_SEARCH_SUBMIT_SELECTOR = '#search-submit'; |
|
34 | + |
|
35 | + |
|
36 | + /** |
|
37 | + * Selector for the screen options dropdown. |
|
38 | + * @var string |
|
39 | + */ |
|
40 | + const WP_SCREEN_SETTINGS_LINK_SELECTOR = '#show-settings-link'; |
|
41 | + |
|
42 | + |
|
43 | + /** |
|
44 | + * Selector for the per page field setting selector (found within screen options dropdown) |
|
45 | + * @var string |
|
46 | + */ |
|
47 | + const WP_SCREEN_SETTINGS_PER_PAGE_FIELD_SELECTOR = '.screen-per-page'; |
|
48 | + |
|
49 | + |
|
50 | + /** |
|
51 | + * Selector for apply screen options settings. |
|
52 | + * @var string |
|
53 | + */ |
|
54 | + const WP_SCREEN_OPTIONS_APPLY_SETTINGS_BUTTON_SELECTOR = '#screen-options-apply'; |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * Get the EE admin url for the given properties. |
|
59 | + * Note, this is JUST the endpoint for the admin route. It is expected that the actor/test would be calling this |
|
60 | + * with `amOnAdminPage` action. |
|
61 | + * |
|
62 | + * @param string $page |
|
63 | + * @param string $action |
|
64 | + * @param string $additional_params |
|
65 | + * @return string |
|
66 | + */ |
|
67 | + public static function adminUrl($page = 'espresso_events', $action = 'default', $additional_params = '') |
|
68 | + { |
|
69 | + $url = self::URL_PREFIX . $page; |
|
70 | + $url .= $action ? '&action=' . $action : ''; |
|
71 | + $url .= $additional_params ? '&' . ltrim('&', ltrim('?', $additional_params)) : ''; |
|
72 | + return $url; |
|
73 | + } |
|
74 | + |
|
75 | + |
|
76 | + /** |
|
77 | + * Returns the selector for the text tab switcher for a wp-editor instance. |
|
78 | + * @param $field_reference |
|
79 | + * @return string |
|
80 | + */ |
|
81 | + public static function wpEditorTextTabSelector($field_reference) |
|
82 | + { |
|
83 | + return '#content-' . $field_reference . '-content-html'; |
|
84 | + } |
|
85 | + |
|
86 | + |
|
87 | + /** |
|
88 | + * Returns the selector for the textarea exposed when clicing the text tab switcher for a wp-editor instance. |
|
89 | + * @param $field_reference |
|
90 | + * @return string |
|
91 | + */ |
|
92 | + public static function wpEditorTextAreaSelector($field_reference) |
|
93 | + { |
|
94 | + return '#content-' . $field_reference . '-content'; |
|
95 | + } |
|
96 | 96 | } |
@@ -66,9 +66,9 @@ discard block |
||
66 | 66 | */ |
67 | 67 | public static function adminUrl($page = 'espresso_events', $action = 'default', $additional_params = '') |
68 | 68 | { |
69 | - $url = self::URL_PREFIX . $page; |
|
70 | - $url .= $action ? '&action=' . $action : ''; |
|
71 | - $url .= $additional_params ? '&' . ltrim('&', ltrim('?', $additional_params)) : ''; |
|
69 | + $url = self::URL_PREFIX.$page; |
|
70 | + $url .= $action ? '&action='.$action : ''; |
|
71 | + $url .= $additional_params ? '&'.ltrim('&', ltrim('?', $additional_params)) : ''; |
|
72 | 72 | return $url; |
73 | 73 | } |
74 | 74 | |
@@ -80,7 +80,7 @@ discard block |
||
80 | 80 | */ |
81 | 81 | public static function wpEditorTextTabSelector($field_reference) |
82 | 82 | { |
83 | - return '#content-' . $field_reference . '-content-html'; |
|
83 | + return '#content-'.$field_reference.'-content-html'; |
|
84 | 84 | } |
85 | 85 | |
86 | 86 | |
@@ -91,6 +91,6 @@ discard block |
||
91 | 91 | */ |
92 | 92 | public static function wpEditorTextAreaSelector($field_reference) |
93 | 93 | { |
94 | - return '#content-' . $field_reference . '-content'; |
|
94 | + return '#content-'.$field_reference.'-content'; |
|
95 | 95 | } |
96 | 96 | } |
@@ -12,255 +12,255 @@ |
||
12 | 12 | class MessagesAdmin extends CoreAdmin |
13 | 13 | { |
14 | 14 | |
15 | - /** |
|
16 | - * Context slug for the admin messages context. |
|
17 | - * @var string |
|
18 | - */ |
|
19 | - const ADMIN_CONTEXT_SLUG = 'admin'; |
|
15 | + /** |
|
16 | + * Context slug for the admin messages context. |
|
17 | + * @var string |
|
18 | + */ |
|
19 | + const ADMIN_CONTEXT_SLUG = 'admin'; |
|
20 | 20 | |
21 | - /** |
|
22 | - * Context slug for the primary attendee messages context |
|
23 | - * @var string |
|
24 | - */ |
|
25 | - const PRIMARY_ATTENDEE_CONTEXT_SLUG = 'primary_attendee'; |
|
21 | + /** |
|
22 | + * Context slug for the primary attendee messages context |
|
23 | + * @var string |
|
24 | + */ |
|
25 | + const PRIMARY_ATTENDEE_CONTEXT_SLUG = 'primary_attendee'; |
|
26 | 26 | |
27 | 27 | |
28 | - /** |
|
29 | - * Status reference for the EEM_Message::status_sent status. |
|
30 | - * @var string |
|
31 | - */ |
|
32 | - const MESSAGE_STATUS_SENT = 'MSN'; |
|
28 | + /** |
|
29 | + * Status reference for the EEM_Message::status_sent status. |
|
30 | + * @var string |
|
31 | + */ |
|
32 | + const MESSAGE_STATUS_SENT = 'MSN'; |
|
33 | 33 | |
34 | 34 | |
35 | - /** |
|
36 | - * Message type slug for the Payment Failed message type |
|
37 | - */ |
|
38 | - const PAYMENT_FAILED_MESSAGE_TYPE_SLUG = 'payment_failed'; |
|
35 | + /** |
|
36 | + * Message type slug for the Payment Failed message type |
|
37 | + */ |
|
38 | + const PAYMENT_FAILED_MESSAGE_TYPE_SLUG = 'payment_failed'; |
|
39 | 39 | |
40 | 40 | |
41 | - /** |
|
42 | - * Selector for the Global Messages "Send on same request" field in the Messages Settings tab. |
|
43 | - * @var string |
|
44 | - */ |
|
45 | - const GLOBAL_MESSAGES_SETTINGS_ON_REQUEST_SELECTION_SELECTOR = |
|
46 | - '#global_messages_settings-do-messages-on-same-request'; |
|
47 | - |
|
41 | + /** |
|
42 | + * Selector for the Global Messages "Send on same request" field in the Messages Settings tab. |
|
43 | + * @var string |
|
44 | + */ |
|
45 | + const GLOBAL_MESSAGES_SETTINGS_ON_REQUEST_SELECTION_SELECTOR = |
|
46 | + '#global_messages_settings-do-messages-on-same-request'; |
|
47 | + |
|
48 | 48 | |
49 | - /** |
|
50 | - * Selector for the Global Messages Settings submit button in the Messages Settings tab. |
|
51 | - * @var string |
|
52 | - */ |
|
53 | - const GLOBAL_MESSAGES_SETTINGS_SUBMIT_SELECTOR = '#global_messages_settings-update-settings-submit'; |
|
54 | - |
|
55 | - |
|
56 | - /** |
|
57 | - * This is the container where active message types for a messenger are found/dragged to. |
|
58 | - * @var string |
|
59 | - */ |
|
60 | - const MESSAGES_SETTINGS_ACTIVE_MESSAGE_TYPES_CONTAINER_SELECTOR = '#active-message-types'; |
|
61 | - |
|
62 | - |
|
63 | - /** |
|
64 | - * Locator for the context switcher selector on the Message Template Editor page. |
|
65 | - * @var string |
|
66 | - */ |
|
67 | - const MESSAGES_CONTEXT_SWITCHER_SELECTOR = "//form[@id='ee-msg-context-switcher-frm']/select"; |
|
68 | - |
|
69 | - |
|
70 | - /** |
|
71 | - * Locator for the context switcher submit button in the Message Template Editor page. |
|
72 | - * @var string |
|
73 | - */ |
|
74 | - const MESSAGES_CONTEXT_SWITCHER_BUTTON_SELECTOR = "#submit-msg-context-switcher-sbmt"; |
|
75 | - |
|
76 | - |
|
77 | - /** |
|
78 | - * Locator for the dialog container used for housing viewed messages in the message activity list table. |
|
79 | - * @var string |
|
80 | - */ |
|
81 | - const MESSAGES_LIST_TABLE_VIEW_MESSAGE_DIALOG_CONTAINER_SELECTOR = '.ee-admin-dialog-container-inner-content'; |
|
82 | - |
|
83 | - |
|
84 | - |
|
85 | - /** |
|
86 | - * @param string $additional_params Any additional request parameters for the generated url should be included as |
|
87 | - * a string. |
|
88 | - * @return string |
|
89 | - */ |
|
90 | - public static function messageActivityListTableUrl($additional_params = '') |
|
91 | - { |
|
92 | - return self::adminUrl('espresso_messages', 'default', $additional_params); |
|
93 | - } |
|
94 | - |
|
95 | - |
|
96 | - /** |
|
97 | - * @param string $additional_params Any additional request parameters for the generated url should be included as |
|
98 | - * a string. |
|
99 | - * @return string |
|
100 | - */ |
|
101 | - public static function defaultMessageTemplateListTableUrl($additional_params = '') |
|
102 | - { |
|
103 | - return self::adminUrl('espresso_messages', 'global_mtps', $additional_params); |
|
104 | - } |
|
105 | - |
|
106 | - |
|
107 | - /** |
|
108 | - * @param string $additional_params Any additional request parameters for the generated url should be included as |
|
109 | - * a string. |
|
110 | - * @return string |
|
111 | - */ |
|
112 | - public static function customMessageTemplateListTableUrl($additional_params = '') |
|
113 | - { |
|
114 | - return self::adminUrl('espresso_messages', 'custom_mtps', $additional_params); |
|
115 | - } |
|
116 | - |
|
117 | - |
|
118 | - /** |
|
119 | - * @return string |
|
120 | - */ |
|
121 | - public static function messageSettingsUrl() |
|
122 | - { |
|
123 | - return self::adminUrl('espresso_messages', 'settings'); |
|
124 | - } |
|
125 | - |
|
126 | - |
|
127 | - |
|
128 | - public static function draggableSettingsBoxSelectorForMessageTypeAndMessenger( |
|
129 | - $message_type_slug, |
|
130 | - $messenger_slug = 'email' |
|
131 | - ) { |
|
132 | - return "#$message_type_slug-messagetype-$messenger_slug"; |
|
133 | - } |
|
134 | - |
|
135 | - |
|
136 | - /** |
|
137 | - * @param string $message_type_slug |
|
138 | - * @param string $context |
|
139 | - * @return string |
|
140 | - */ |
|
141 | - public static function editMessageTemplateClassByMessageType($message_type_slug, $context = '') |
|
142 | - { |
|
143 | - return $context |
|
144 | - ? '.' . $message_type_slug . '-' . $context . '-edit-link' |
|
145 | - : '.' . $message_type_slug . '-edit-link'; |
|
146 | - } |
|
147 | - |
|
148 | - |
|
149 | - /** |
|
150 | - * Selector for (a) specific table cell(s) in the Messages Activity list table for the given parameters. |
|
151 | - * |
|
152 | - * @param $field |
|
153 | - * @param $message_type_label |
|
154 | - * @param string $message_status |
|
155 | - * @param string $messenger |
|
156 | - * @param string $context |
|
157 | - * @param string $table_cell_content_for_field |
|
158 | - * @param int $number_in_set It's possible that the given parameters could match multiple items in the view. |
|
159 | - * This allows you to indicate which item from the set to match. If this is set to 0 |
|
160 | - * then all matches for the locator will be returned. |
|
161 | - * @return string |
|
162 | - */ |
|
163 | - public static function messagesActivityListTableCellSelectorFor( |
|
164 | - $field, |
|
165 | - $message_type_label, |
|
166 | - $message_status = self::MESSAGE_STATUS_SENT, |
|
167 | - $messenger = 'Email', |
|
168 | - $context = 'Event Admin', |
|
169 | - $table_cell_content_for_field = '', |
|
170 | - $number_in_set = 1 |
|
171 | - ) { |
|
172 | - $selector = $number_in_set > 0 ? '(' : ''; |
|
173 | - $selector .= "//tr[contains(@class, 'msg-status-$message_status')]" |
|
174 | - . "//td[contains(@class, 'message_type') and text()='$message_type_label']"; |
|
175 | - if ($messenger) { |
|
176 | - $selector .= "/ancestor::tr/td[contains(@class, 'messenger') and text()='$messenger']"; |
|
177 | - } |
|
178 | - $selector .= "/ancestor::tr/td[contains(@class, 'column-context') and text()='$context']"; |
|
179 | - $selector .= $table_cell_content_for_field |
|
180 | - ? "/ancestor::tr/td[contains(@class, 'column-$field') and text()='$table_cell_content_for_field']" |
|
181 | - : "/ancestor::tr/td[contains(@class, 'column-$field')]"; |
|
182 | - $selector .= $number_in_set > 0 ? ")[$number_in_set]" : ''; |
|
183 | - return $selector; |
|
184 | - } |
|
185 | - |
|
186 | - |
|
187 | - /** |
|
188 | - * Selector for the Create Custom button found in the message template list table. |
|
189 | - * @param string $message_type_label |
|
190 | - * @param string $messenger_label |
|
191 | - * @return string |
|
192 | - */ |
|
193 | - public static function createCustomButtonForMessageTypeAndMessenger($message_type_label, $messenger_label) |
|
194 | - { |
|
195 | - $selector = "//tr/td[contains(@class, 'message_type') and text()='$message_type_label']" |
|
196 | - . "//ancestor::tr/td[contains(@class, 'messenger') and contains(., '$messenger_label')]" |
|
197 | - . "//ancestor::tr/td/a[@class='button button-small']"; |
|
198 | - return $selector; |
|
199 | - } |
|
200 | - |
|
201 | - |
|
202 | - /** |
|
203 | - * Note, this could potentially match multiple buttons in the view so the selector is intentionally restricted to |
|
204 | - * the FIRST match (which will be the latest message sent if the table is default sorted). |
|
205 | - * |
|
206 | - * @param string $message_type_label The visible message type label for the row you want to match |
|
207 | - * @param string $message_status The status of the message for the row you want to match. |
|
208 | - * @param string $messenger The visible messenger label for the row you want to match. |
|
209 | - * @param string $context The visible context label for the row you want to match. |
|
210 | - * @param int $number_in_set It's possible that the given parameters could match multiple items in the |
|
211 | - * view. This allows you to indicate which item from the set to match. |
|
212 | - * @return string |
|
213 | - */ |
|
214 | - public static function messagesActivityListTableViewButtonSelectorFor( |
|
215 | - $message_type_label, |
|
216 | - $message_status = self::MESSAGE_STATUS_SENT, |
|
217 | - $messenger = 'Email', |
|
218 | - $context = 'Event Admin', |
|
219 | - $number_in_set = 1 |
|
220 | - ) { |
|
221 | - $selector = self::messagesActivityListTableCellSelectorFor( |
|
222 | - 'action', |
|
223 | - $message_type_label, |
|
224 | - $message_status, |
|
225 | - $messenger, |
|
226 | - $context, |
|
227 | - '', |
|
228 | - $number_in_set |
|
229 | - ); |
|
230 | - $selector .= "/a/span[contains(@class, 'ee-message-action-link-view')" |
|
231 | - . " and not(contains(@class, 'ee-message-action-link-view_transaction'))]"; |
|
232 | - return $selector; |
|
233 | - } |
|
234 | - |
|
235 | - |
|
236 | - |
|
237 | - /** |
|
238 | - * Locator for the delete action link for a message item in the message activity list table. |
|
239 | - * Note: The link is not visible by default, so the column would need hovered over for the link to appear. |
|
240 | - * @param $message_type_label |
|
241 | - * @param string $message_status |
|
242 | - * @param string $messenger |
|
243 | - * @param string $context |
|
244 | - * @param int $number_in_set |
|
245 | - * @return string |
|
246 | - */ |
|
247 | - public static function messagesActivityListTableDeleteActionSelectorFor( |
|
248 | - $message_type_label, |
|
249 | - $message_status = self::MESSAGE_STATUS_SENT, |
|
250 | - $messenger = 'Email', |
|
251 | - $context = 'Event Admin', |
|
252 | - $number_in_set = 1 |
|
253 | - ) { |
|
254 | - $selector = self::messagesActivityListTableCellSelectorFor( |
|
255 | - 'to', |
|
256 | - $message_type_label, |
|
257 | - $message_status, |
|
258 | - $messenger, |
|
259 | - $context, |
|
260 | - '', |
|
261 | - $number_in_set |
|
262 | - ); |
|
263 | - $selector .= "/div/span[@class='delete']/a"; |
|
264 | - return $selector; |
|
265 | - } |
|
49 | + /** |
|
50 | + * Selector for the Global Messages Settings submit button in the Messages Settings tab. |
|
51 | + * @var string |
|
52 | + */ |
|
53 | + const GLOBAL_MESSAGES_SETTINGS_SUBMIT_SELECTOR = '#global_messages_settings-update-settings-submit'; |
|
54 | + |
|
55 | + |
|
56 | + /** |
|
57 | + * This is the container where active message types for a messenger are found/dragged to. |
|
58 | + * @var string |
|
59 | + */ |
|
60 | + const MESSAGES_SETTINGS_ACTIVE_MESSAGE_TYPES_CONTAINER_SELECTOR = '#active-message-types'; |
|
61 | + |
|
62 | + |
|
63 | + /** |
|
64 | + * Locator for the context switcher selector on the Message Template Editor page. |
|
65 | + * @var string |
|
66 | + */ |
|
67 | + const MESSAGES_CONTEXT_SWITCHER_SELECTOR = "//form[@id='ee-msg-context-switcher-frm']/select"; |
|
68 | + |
|
69 | + |
|
70 | + /** |
|
71 | + * Locator for the context switcher submit button in the Message Template Editor page. |
|
72 | + * @var string |
|
73 | + */ |
|
74 | + const MESSAGES_CONTEXT_SWITCHER_BUTTON_SELECTOR = "#submit-msg-context-switcher-sbmt"; |
|
75 | + |
|
76 | + |
|
77 | + /** |
|
78 | + * Locator for the dialog container used for housing viewed messages in the message activity list table. |
|
79 | + * @var string |
|
80 | + */ |
|
81 | + const MESSAGES_LIST_TABLE_VIEW_MESSAGE_DIALOG_CONTAINER_SELECTOR = '.ee-admin-dialog-container-inner-content'; |
|
82 | + |
|
83 | + |
|
84 | + |
|
85 | + /** |
|
86 | + * @param string $additional_params Any additional request parameters for the generated url should be included as |
|
87 | + * a string. |
|
88 | + * @return string |
|
89 | + */ |
|
90 | + public static function messageActivityListTableUrl($additional_params = '') |
|
91 | + { |
|
92 | + return self::adminUrl('espresso_messages', 'default', $additional_params); |
|
93 | + } |
|
94 | + |
|
95 | + |
|
96 | + /** |
|
97 | + * @param string $additional_params Any additional request parameters for the generated url should be included as |
|
98 | + * a string. |
|
99 | + * @return string |
|
100 | + */ |
|
101 | + public static function defaultMessageTemplateListTableUrl($additional_params = '') |
|
102 | + { |
|
103 | + return self::adminUrl('espresso_messages', 'global_mtps', $additional_params); |
|
104 | + } |
|
105 | + |
|
106 | + |
|
107 | + /** |
|
108 | + * @param string $additional_params Any additional request parameters for the generated url should be included as |
|
109 | + * a string. |
|
110 | + * @return string |
|
111 | + */ |
|
112 | + public static function customMessageTemplateListTableUrl($additional_params = '') |
|
113 | + { |
|
114 | + return self::adminUrl('espresso_messages', 'custom_mtps', $additional_params); |
|
115 | + } |
|
116 | + |
|
117 | + |
|
118 | + /** |
|
119 | + * @return string |
|
120 | + */ |
|
121 | + public static function messageSettingsUrl() |
|
122 | + { |
|
123 | + return self::adminUrl('espresso_messages', 'settings'); |
|
124 | + } |
|
125 | + |
|
126 | + |
|
127 | + |
|
128 | + public static function draggableSettingsBoxSelectorForMessageTypeAndMessenger( |
|
129 | + $message_type_slug, |
|
130 | + $messenger_slug = 'email' |
|
131 | + ) { |
|
132 | + return "#$message_type_slug-messagetype-$messenger_slug"; |
|
133 | + } |
|
134 | + |
|
135 | + |
|
136 | + /** |
|
137 | + * @param string $message_type_slug |
|
138 | + * @param string $context |
|
139 | + * @return string |
|
140 | + */ |
|
141 | + public static function editMessageTemplateClassByMessageType($message_type_slug, $context = '') |
|
142 | + { |
|
143 | + return $context |
|
144 | + ? '.' . $message_type_slug . '-' . $context . '-edit-link' |
|
145 | + : '.' . $message_type_slug . '-edit-link'; |
|
146 | + } |
|
147 | + |
|
148 | + |
|
149 | + /** |
|
150 | + * Selector for (a) specific table cell(s) in the Messages Activity list table for the given parameters. |
|
151 | + * |
|
152 | + * @param $field |
|
153 | + * @param $message_type_label |
|
154 | + * @param string $message_status |
|
155 | + * @param string $messenger |
|
156 | + * @param string $context |
|
157 | + * @param string $table_cell_content_for_field |
|
158 | + * @param int $number_in_set It's possible that the given parameters could match multiple items in the view. |
|
159 | + * This allows you to indicate which item from the set to match. If this is set to 0 |
|
160 | + * then all matches for the locator will be returned. |
|
161 | + * @return string |
|
162 | + */ |
|
163 | + public static function messagesActivityListTableCellSelectorFor( |
|
164 | + $field, |
|
165 | + $message_type_label, |
|
166 | + $message_status = self::MESSAGE_STATUS_SENT, |
|
167 | + $messenger = 'Email', |
|
168 | + $context = 'Event Admin', |
|
169 | + $table_cell_content_for_field = '', |
|
170 | + $number_in_set = 1 |
|
171 | + ) { |
|
172 | + $selector = $number_in_set > 0 ? '(' : ''; |
|
173 | + $selector .= "//tr[contains(@class, 'msg-status-$message_status')]" |
|
174 | + . "//td[contains(@class, 'message_type') and text()='$message_type_label']"; |
|
175 | + if ($messenger) { |
|
176 | + $selector .= "/ancestor::tr/td[contains(@class, 'messenger') and text()='$messenger']"; |
|
177 | + } |
|
178 | + $selector .= "/ancestor::tr/td[contains(@class, 'column-context') and text()='$context']"; |
|
179 | + $selector .= $table_cell_content_for_field |
|
180 | + ? "/ancestor::tr/td[contains(@class, 'column-$field') and text()='$table_cell_content_for_field']" |
|
181 | + : "/ancestor::tr/td[contains(@class, 'column-$field')]"; |
|
182 | + $selector .= $number_in_set > 0 ? ")[$number_in_set]" : ''; |
|
183 | + return $selector; |
|
184 | + } |
|
185 | + |
|
186 | + |
|
187 | + /** |
|
188 | + * Selector for the Create Custom button found in the message template list table. |
|
189 | + * @param string $message_type_label |
|
190 | + * @param string $messenger_label |
|
191 | + * @return string |
|
192 | + */ |
|
193 | + public static function createCustomButtonForMessageTypeAndMessenger($message_type_label, $messenger_label) |
|
194 | + { |
|
195 | + $selector = "//tr/td[contains(@class, 'message_type') and text()='$message_type_label']" |
|
196 | + . "//ancestor::tr/td[contains(@class, 'messenger') and contains(., '$messenger_label')]" |
|
197 | + . "//ancestor::tr/td/a[@class='button button-small']"; |
|
198 | + return $selector; |
|
199 | + } |
|
200 | + |
|
201 | + |
|
202 | + /** |
|
203 | + * Note, this could potentially match multiple buttons in the view so the selector is intentionally restricted to |
|
204 | + * the FIRST match (which will be the latest message sent if the table is default sorted). |
|
205 | + * |
|
206 | + * @param string $message_type_label The visible message type label for the row you want to match |
|
207 | + * @param string $message_status The status of the message for the row you want to match. |
|
208 | + * @param string $messenger The visible messenger label for the row you want to match. |
|
209 | + * @param string $context The visible context label for the row you want to match. |
|
210 | + * @param int $number_in_set It's possible that the given parameters could match multiple items in the |
|
211 | + * view. This allows you to indicate which item from the set to match. |
|
212 | + * @return string |
|
213 | + */ |
|
214 | + public static function messagesActivityListTableViewButtonSelectorFor( |
|
215 | + $message_type_label, |
|
216 | + $message_status = self::MESSAGE_STATUS_SENT, |
|
217 | + $messenger = 'Email', |
|
218 | + $context = 'Event Admin', |
|
219 | + $number_in_set = 1 |
|
220 | + ) { |
|
221 | + $selector = self::messagesActivityListTableCellSelectorFor( |
|
222 | + 'action', |
|
223 | + $message_type_label, |
|
224 | + $message_status, |
|
225 | + $messenger, |
|
226 | + $context, |
|
227 | + '', |
|
228 | + $number_in_set |
|
229 | + ); |
|
230 | + $selector .= "/a/span[contains(@class, 'ee-message-action-link-view')" |
|
231 | + . " and not(contains(@class, 'ee-message-action-link-view_transaction'))]"; |
|
232 | + return $selector; |
|
233 | + } |
|
234 | + |
|
235 | + |
|
236 | + |
|
237 | + /** |
|
238 | + * Locator for the delete action link for a message item in the message activity list table. |
|
239 | + * Note: The link is not visible by default, so the column would need hovered over for the link to appear. |
|
240 | + * @param $message_type_label |
|
241 | + * @param string $message_status |
|
242 | + * @param string $messenger |
|
243 | + * @param string $context |
|
244 | + * @param int $number_in_set |
|
245 | + * @return string |
|
246 | + */ |
|
247 | + public static function messagesActivityListTableDeleteActionSelectorFor( |
|
248 | + $message_type_label, |
|
249 | + $message_status = self::MESSAGE_STATUS_SENT, |
|
250 | + $messenger = 'Email', |
|
251 | + $context = 'Event Admin', |
|
252 | + $number_in_set = 1 |
|
253 | + ) { |
|
254 | + $selector = self::messagesActivityListTableCellSelectorFor( |
|
255 | + 'to', |
|
256 | + $message_type_label, |
|
257 | + $message_status, |
|
258 | + $messenger, |
|
259 | + $context, |
|
260 | + '', |
|
261 | + $number_in_set |
|
262 | + ); |
|
263 | + $selector .= "/div/span[@class='delete']/a"; |
|
264 | + return $selector; |
|
265 | + } |
|
266 | 266 | } |
267 | 267 | \ No newline at end of file |
@@ -443,7 +443,7 @@ discard block |
||
443 | 443 | * there's a single shared message template group among all the events. Otherwise it returns null. |
444 | 444 | * |
445 | 445 | * @param array $event_ids |
446 | - * @return EE_Message_Template_Group|null |
|
446 | + * @return null|EE_Base_Class |
|
447 | 447 | * @throws EE_Error |
448 | 448 | */ |
449 | 449 | protected function _get_shared_message_template_for_events(array $event_ids) |
@@ -476,7 +476,7 @@ discard block |
||
476 | 476 | /** |
477 | 477 | * Retrieves the global message template group for the current messenger and message type. |
478 | 478 | * |
479 | - * @return EE_Message_Template_Group|null |
|
479 | + * @return null|EE_Base_Class |
|
480 | 480 | * @throws EE_Error |
481 | 481 | */ |
482 | 482 | protected function _get_global_message_template_group_for_current_messenger_and_message_type() |
@@ -617,7 +617,7 @@ discard block |
||
617 | 617 | * @param EE_Messages_Addressee $recipient |
618 | 618 | * @param array $templates formatted array of templates used for parsing data. |
619 | 619 | * @param EE_Message_Template_Group $message_template_group |
620 | - * @return bool|EE_Message |
|
620 | + * @return EE_Message |
|
621 | 621 | * @throws EE_Error |
622 | 622 | */ |
623 | 623 | protected function _setup_message_object( |
@@ -13,935 +13,935 @@ |
||
13 | 13 | { |
14 | 14 | |
15 | 15 | |
16 | - /** |
|
17 | - * @type EE_Messages_Data_Handler_Collection |
|
18 | - */ |
|
19 | - protected $_data_handler_collection; |
|
20 | - |
|
21 | - /** |
|
22 | - * @type EE_Message_Template_Group_Collection |
|
23 | - */ |
|
24 | - protected $_template_collection; |
|
25 | - |
|
26 | - /** |
|
27 | - * This will hold the data handler for the current EE_Message being generated. |
|
28 | - * |
|
29 | - * @type EE_Messages_incoming_data |
|
30 | - */ |
|
31 | - protected $_current_data_handler; |
|
32 | - |
|
33 | - /** |
|
34 | - * This holds the EE_Messages_Queue that contains the messages to generate. |
|
35 | - * |
|
36 | - * @type EE_Messages_Queue |
|
37 | - */ |
|
38 | - protected $_generation_queue; |
|
39 | - |
|
40 | - /** |
|
41 | - * This holds the EE_Messages_Queue that will store the generated EE_Message objects. |
|
42 | - * |
|
43 | - * @type EE_Messages_Queue |
|
44 | - */ |
|
45 | - protected $_ready_queue; |
|
46 | - |
|
47 | - /** |
|
48 | - * This is a container for any error messages that get created through the generation |
|
49 | - * process. |
|
50 | - * |
|
51 | - * @type array |
|
52 | - */ |
|
53 | - protected $_error_msg = array(); |
|
54 | - |
|
55 | - /** |
|
56 | - * Flag used to set when the current EE_Message in the generation queue has been verified. |
|
57 | - * |
|
58 | - * @type bool |
|
59 | - */ |
|
60 | - protected $_verified = false; |
|
61 | - |
|
62 | - /** |
|
63 | - * This will hold the current messenger object corresponding with the current EE_Message in the generation queue. |
|
64 | - * |
|
65 | - * @type EE_messenger |
|
66 | - */ |
|
67 | - protected $_current_messenger; |
|
68 | - |
|
69 | - /** |
|
70 | - * This will hold the current message type object corresponding with the current EE_Message in the generation queue. |
|
71 | - * |
|
72 | - * @type EE_message_type |
|
73 | - */ |
|
74 | - protected $_current_message_type; |
|
75 | - |
|
76 | - /** |
|
77 | - * @type EEH_Parse_Shortcodes |
|
78 | - */ |
|
79 | - protected $_shortcode_parser; |
|
80 | - |
|
81 | - |
|
82 | - /** |
|
83 | - * @param EE_Messages_Queue $generation_queue |
|
84 | - * @param \EE_Messages_Queue $ready_queue |
|
85 | - * @param \EE_Messages_Data_Handler_Collection $data_handler_collection |
|
86 | - * @param \EE_Message_Template_Group_Collection $template_collection |
|
87 | - * @param \EEH_Parse_Shortcodes $shortcode_parser |
|
88 | - */ |
|
89 | - public function __construct( |
|
90 | - EE_Messages_Queue $generation_queue, |
|
91 | - EE_Messages_Queue $ready_queue, |
|
92 | - EE_Messages_Data_Handler_Collection $data_handler_collection, |
|
93 | - EE_Message_Template_Group_Collection $template_collection, |
|
94 | - EEH_Parse_Shortcodes $shortcode_parser |
|
95 | - ) { |
|
96 | - $this->_generation_queue = $generation_queue; |
|
97 | - $this->_ready_queue = $ready_queue; |
|
98 | - $this->_data_handler_collection = $data_handler_collection; |
|
99 | - $this->_template_collection = $template_collection; |
|
100 | - $this->_shortcode_parser = $shortcode_parser; |
|
101 | - } |
|
102 | - |
|
103 | - |
|
104 | - /** |
|
105 | - * @return EE_Messages_Queue |
|
106 | - */ |
|
107 | - public function generation_queue() |
|
108 | - { |
|
109 | - return $this->_generation_queue; |
|
110 | - } |
|
111 | - |
|
112 | - |
|
113 | - /** |
|
114 | - * This iterates through the provided queue and generates the EE_Message objects. |
|
115 | - * When iterating through the queue, the queued item that served as the base for generating other EE_Message |
|
116 | - * objects gets removed and the new EE_Message objects get added to a NEW queue. The NEW queue is then returned |
|
117 | - * for the caller to decide what to do with it. |
|
118 | - * |
|
119 | - * @param bool $save Whether to save the EE_Message objects in the new queue or just return. |
|
120 | - * @return EE_Messages_Queue The new queue for holding generated EE_Message objects. |
|
121 | - */ |
|
122 | - public function generate($save = true) |
|
123 | - { |
|
124 | - //iterate through the messages in the queue, generate, and add to new queue. |
|
125 | - $this->_generation_queue->get_message_repository()->rewind(); |
|
126 | - while ($this->_generation_queue->get_message_repository()->valid()) { |
|
127 | - //reset "current" properties |
|
128 | - $this->_reset_current_properties(); |
|
129 | - |
|
130 | - /** @type EE_Message $msg */ |
|
131 | - $msg = $this->_generation_queue->get_message_repository()->current(); |
|
132 | - |
|
133 | - /** |
|
134 | - * need to get the next object and capture it for setting manually after deletes. The reason is that when |
|
135 | - * an object is removed from the repo then valid for the next object will fail. |
|
136 | - */ |
|
137 | - $this->_generation_queue->get_message_repository()->next(); |
|
138 | - $next_msg = $this->_generation_queue->get_message_repository()->current(); |
|
139 | - //restore pointer to current item |
|
140 | - $this->_generation_queue->get_message_repository()->set_current($msg); |
|
141 | - |
|
142 | - //skip and delete if the current $msg is NOT incomplete (queued for generation) |
|
143 | - if ($msg->STS_ID() !== EEM_Message::status_incomplete) { |
|
144 | - //we keep this item in the db just remove from the repo. |
|
145 | - $this->_generation_queue->get_message_repository()->remove($msg); |
|
146 | - //next item |
|
147 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
148 | - continue; |
|
149 | - } |
|
150 | - |
|
151 | - if ($this->_verify()) { |
|
152 | - //let's get generating! |
|
153 | - $this->_generate(); |
|
154 | - } |
|
155 | - |
|
156 | - //don't persist debug_only messages if the messages system is not in debug mode. |
|
157 | - if ($msg->STS_ID() === EEM_Message::status_debug_only |
|
158 | - && ! EEM_Message::debug() |
|
159 | - ) { |
|
160 | - do_action( |
|
161 | - 'AHEE__EE_Messages_Generator__generate__before_debug_delete', |
|
162 | - $msg, |
|
163 | - $this->_error_msg, |
|
164 | - $this->_current_messenger, |
|
165 | - $this->_current_message_type, |
|
166 | - $this->_current_data_handler |
|
167 | - ); |
|
168 | - $this->_generation_queue->get_message_repository()->delete(); |
|
169 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
170 | - continue; |
|
171 | - } |
|
172 | - |
|
173 | - //if there are error messages then let's set the status and the error message. |
|
174 | - if ($this->_error_msg) { |
|
175 | - //if the status is already debug only, then let's leave it at that. |
|
176 | - if ($msg->STS_ID() !== EEM_Message::status_debug_only) { |
|
177 | - $msg->set_STS_ID(EEM_Message::status_failed); |
|
178 | - } |
|
179 | - do_action( |
|
180 | - 'AHEE__EE_Messages_Generator__generate__processing_failed_message', |
|
181 | - $msg, |
|
182 | - $this->_error_msg, |
|
183 | - $this->_current_messenger, |
|
184 | - $this->_current_message_type, |
|
185 | - $this->_current_data_handler |
|
186 | - ); |
|
187 | - $msg->set_error_message( |
|
188 | - esc_html__('Message failed to generate for the following reasons: ', 'event_espresso') |
|
189 | - . "\n" |
|
190 | - . implode("\n", $this->_error_msg) |
|
191 | - ); |
|
192 | - $msg->set_modified(time()); |
|
193 | - } else { |
|
194 | - do_action( |
|
195 | - 'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete', |
|
196 | - $msg, |
|
197 | - $this->_error_msg, |
|
198 | - $this->_current_messenger, |
|
199 | - $this->_current_message_type, |
|
200 | - $this->_current_data_handler |
|
201 | - ); |
|
202 | - //remove from db |
|
203 | - $this->_generation_queue->get_message_repository()->delete(); |
|
204 | - } |
|
205 | - //next item |
|
206 | - $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
207 | - } |
|
208 | - |
|
209 | - //generation queue is ALWAYS saved to record any errors in the generation process. |
|
210 | - $this->_generation_queue->save(); |
|
211 | - |
|
212 | - /** |
|
213 | - * save _ready_queue if flag set. |
|
214 | - * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method. This |
|
215 | - * means if a field was added that is not a valid database column. The EE_Message was already saved to the db |
|
216 | - * so a EE_Extra_Meta entry could be created and attached to the EE_Message. In those cases the save flag is |
|
217 | - * irrelevant. |
|
218 | - */ |
|
219 | - if ($save) { |
|
220 | - $this->_ready_queue->save(); |
|
221 | - } |
|
222 | - |
|
223 | - //final reset of properties |
|
224 | - $this->_reset_current_properties(); |
|
225 | - |
|
226 | - return $this->_ready_queue; |
|
227 | - } |
|
228 | - |
|
229 | - |
|
230 | - /** |
|
231 | - * This resets all the properties used for holding "current" values corresponding to the current EE_Message object |
|
232 | - * in the generation queue. |
|
233 | - */ |
|
234 | - protected function _reset_current_properties() |
|
235 | - { |
|
236 | - $this->_verified = false; |
|
237 | - //make sure any _data value in the current message type is reset |
|
238 | - if ($this->_current_message_type instanceof EE_message_type) { |
|
239 | - $this->_current_message_type->reset_data(); |
|
240 | - } |
|
241 | - $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null; |
|
242 | - } |
|
243 | - |
|
244 | - |
|
245 | - /** |
|
246 | - * This proceeds with the actual generation of a message. By the time this is called, there should already be a |
|
247 | - * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the |
|
248 | - * _generating_queue. |
|
249 | - * |
|
250 | - * @return bool Whether the message was successfully generated or not. |
|
251 | - * @throws EE_Error |
|
252 | - */ |
|
253 | - protected function _generate() |
|
254 | - { |
|
255 | - //double check verification has run and that everything is ready to work with (saves us having to validate |
|
256 | - // everything again). |
|
257 | - if (! $this->_verified) { |
|
258 | - return false; //get out because we don't have a valid setup to work with. |
|
259 | - } |
|
260 | - |
|
261 | - |
|
262 | - try { |
|
263 | - $addressees = $this->_current_message_type->get_addressees( |
|
264 | - $this->_current_data_handler, |
|
265 | - $this->_generation_queue->get_message_repository()->current()->context() |
|
266 | - ); |
|
267 | - } catch (EE_Error $e) { |
|
268 | - $this->_error_msg[] = $e->getMessage(); |
|
269 | - return false; |
|
270 | - } |
|
271 | - |
|
272 | - |
|
273 | - //if no addressees then get out because there is nothing to generation (possible bad data). |
|
274 | - if (! $this->_valid_addressees($addressees)) { |
|
275 | - do_action( |
|
276 | - 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
|
277 | - $this->_generation_queue->get_message_repository()->current(), |
|
278 | - $addressees, |
|
279 | - $this->_current_messenger, |
|
280 | - $this->_current_message_type, |
|
281 | - $this->_current_data_handler |
|
282 | - ); |
|
283 | - $this->_generation_queue->get_message_repository()->current()->set_STS_ID( |
|
284 | - EEM_Message::status_debug_only |
|
285 | - ); |
|
286 | - $this->_error_msg[] = esc_html__( |
|
287 | - '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.', |
|
288 | - 'event_espresso' |
|
289 | - ); |
|
290 | - return false; |
|
291 | - } |
|
292 | - |
|
293 | - $message_template_group = $this->_get_message_template_group(); |
|
294 | - |
|
295 | - //in the unlikely event there is no EE_Message_Template_Group available, get out! |
|
296 | - if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
297 | - $this->_error_msg[] = esc_html__( |
|
298 | - 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
|
299 | - 'event_espresso' |
|
300 | - ); |
|
301 | - return false; |
|
302 | - } |
|
303 | - |
|
304 | - //get formatted templates for using to parse and setup EE_Message objects. |
|
305 | - $templates = $this->_get_templates($message_template_group); |
|
306 | - |
|
307 | - |
|
308 | - //setup new EE_Message objects (and add to _ready_queue) |
|
309 | - return $this->_assemble_messages($addressees, $templates, $message_template_group); |
|
310 | - } |
|
311 | - |
|
312 | - |
|
313 | - /** |
|
314 | - * Retrieves the message template group being used for generating messages. |
|
315 | - * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times. |
|
316 | - * |
|
317 | - * @return EE_Message_Template_Group|null |
|
318 | - * @throws EE_Error |
|
319 | - */ |
|
320 | - protected function _get_message_template_group() |
|
321 | - { |
|
322 | - //first see if there is a specific message template group requested (current message in the queue has a specific |
|
323 | - //GRP_ID |
|
324 | - $message_template_group = $this->_specific_message_template_group_from_queue(); |
|
325 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
326 | - return $message_template_group; |
|
327 | - } |
|
328 | - |
|
329 | - //get event_ids from the datahandler so we can check to see if there's already a message template group for them |
|
330 | - //in the collection. |
|
331 | - $event_ids = $this->_get_event_ids_from_current_data_handler(); |
|
332 | - $message_template_group = $this->_template_collection->get_by_key( |
|
333 | - $this->_template_collection->getKey( |
|
334 | - $this->_current_messenger->name, |
|
335 | - $this->_current_message_type->name, |
|
336 | - $event_ids |
|
337 | - ) |
|
338 | - ); |
|
339 | - |
|
340 | - //if we have a message template group then no need to hit the database, just return it. |
|
341 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
342 | - return $message_template_group; |
|
343 | - } |
|
344 | - |
|
345 | - //okay made it here, so let's get the global group first for this messenger and message type to ensure |
|
346 | - //there is no override set. |
|
347 | - $global_message_template_group = $this->_get_global_message_template_group_for_current_messenger_and_message_type(); |
|
348 | - |
|
349 | - if ($global_message_template_group instanceof EE_Message_Template_Group |
|
350 | - && $global_message_template_group->get('MTP_is_override') |
|
351 | - ) { |
|
352 | - return $global_message_template_group; |
|
353 | - } |
|
354 | - |
|
355 | - //if we're still here, that means there was no message template group for the events in the collection and |
|
356 | - //the global message template group for the messenger and message type is not set for override. So next step is |
|
357 | - //to see if there is a common shared custom message template group for this set of events. |
|
358 | - $message_template_group = $this->_get_shared_message_template_for_events($event_ids); |
|
359 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
360 | - return $message_template_group; |
|
361 | - } |
|
362 | - |
|
363 | - //STILL here? Okay that means the fallback is to just use the global message template group for this event set. |
|
364 | - //So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this request) |
|
365 | - //and return it. |
|
366 | - if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
367 | - $this->_template_collection->add( |
|
368 | - $global_message_template_group, |
|
369 | - $event_ids |
|
370 | - ); |
|
371 | - return $global_message_template_group; |
|
372 | - } |
|
373 | - |
|
374 | - //if we land here that means there's NO active message template group for this set. |
|
375 | - //TODO this will be a good target for some optimization down the road. Whenever there is no active message |
|
376 | - //template group for a given event set then cache that result so we don't repeat the logic. However, for now, |
|
377 | - //this should likely bit hit rarely enough that it's not a significant issue. |
|
378 | - return null; |
|
379 | - } |
|
380 | - |
|
381 | - |
|
382 | - /** |
|
383 | - * This checks the current message in the queue and determines if there is a specific Message Template Group |
|
384 | - * requested for that message. |
|
385 | - * |
|
386 | - * @return EE_Message_Template_Group|null |
|
387 | - */ |
|
388 | - protected function _specific_message_template_group_from_queue() |
|
389 | - { |
|
390 | - //is there a GRP_ID already on the EE_Message object? If there is, then a specific template has been requested |
|
391 | - //so let's use that. |
|
392 | - $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID(); |
|
393 | - |
|
394 | - if ($GRP_ID) { |
|
395 | - //attempt to retrieve from repo first |
|
396 | - $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
|
397 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
398 | - return $message_template_group; //got it! |
|
399 | - } |
|
400 | - |
|
401 | - //nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
|
402 | - //is not valid, so we'll continue on in the code assuming there's NO GRP_ID. |
|
403 | - $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID); |
|
404 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
405 | - $this->_template_collection->add($message_template_group); |
|
406 | - return $message_template_group; |
|
407 | - } |
|
408 | - } |
|
409 | - return null; |
|
410 | - } |
|
411 | - |
|
412 | - |
|
413 | - /** |
|
414 | - * Returns whether the event ids passed in all share the same message template group for the current message type |
|
415 | - * and messenger. |
|
416 | - * |
|
417 | - * @param array $event_ids |
|
418 | - * @return bool true means they DO share the same message template group, false means they don't. |
|
419 | - * @throws EE_Error |
|
420 | - */ |
|
421 | - protected function _queue_shares_same_message_template_group_for_events(array $event_ids) |
|
422 | - { |
|
423 | - foreach ($this->_current_data_handler->events as $event) { |
|
424 | - $event_ids[$event['ID']] = $event['ID']; |
|
425 | - } |
|
426 | - $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count( |
|
427 | - array( |
|
428 | - array( |
|
429 | - 'Event.EVT_ID' => array('IN', $event_ids), |
|
430 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
431 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
432 | - ), |
|
433 | - ), |
|
434 | - 'GRP_ID', |
|
435 | - true |
|
436 | - ); |
|
437 | - return $count_of_message_template_groups === 1; |
|
438 | - } |
|
439 | - |
|
440 | - |
|
441 | - /** |
|
442 | - * This will get the shared message template group for events that are in the current data handler but ONLY if |
|
443 | - * there's a single shared message template group among all the events. Otherwise it returns null. |
|
444 | - * |
|
445 | - * @param array $event_ids |
|
446 | - * @return EE_Message_Template_Group|null |
|
447 | - * @throws EE_Error |
|
448 | - */ |
|
449 | - protected function _get_shared_message_template_for_events(array $event_ids) |
|
450 | - { |
|
451 | - $message_template_group = null; |
|
452 | - if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) { |
|
453 | - $message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
454 | - array( |
|
455 | - array( |
|
456 | - 'Event.EVT_ID' => array('IN', $event_ids), |
|
457 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
458 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
459 | - 'MTP_is_active' => true, |
|
460 | - ), |
|
461 | - 'group_by' => 'GRP_ID', |
|
462 | - ) |
|
463 | - ); |
|
464 | - //store this in the collection if its valid |
|
465 | - if ($message_template_group instanceof EE_Message_Template_Group) { |
|
466 | - $this->_template_collection->add( |
|
467 | - $message_template_group, |
|
468 | - $event_ids |
|
469 | - ); |
|
470 | - } |
|
471 | - } |
|
472 | - return $message_template_group; |
|
473 | - } |
|
474 | - |
|
475 | - |
|
476 | - /** |
|
477 | - * Retrieves the global message template group for the current messenger and message type. |
|
478 | - * |
|
479 | - * @return EE_Message_Template_Group|null |
|
480 | - * @throws EE_Error |
|
481 | - */ |
|
482 | - protected function _get_global_message_template_group_for_current_messenger_and_message_type() |
|
483 | - { |
|
484 | - //first check the collection (we use an array with 0 in it to represent global groups). |
|
485 | - $global_message_template_group = $this->_template_collection->get_by_key( |
|
486 | - $this->_template_collection->getKey( |
|
487 | - $this->_current_messenger->name, |
|
488 | - $this->_current_message_type->name, |
|
489 | - array(0) |
|
490 | - ) |
|
491 | - ); |
|
492 | - |
|
493 | - //if we don't have a group lets hit the db. |
|
494 | - if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
495 | - $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
496 | - array( |
|
497 | - array( |
|
498 | - 'MTP_messenger' => $this->_current_messenger->name, |
|
499 | - 'MTP_message_type' => $this->_current_message_type->name, |
|
500 | - 'MTP_is_active' => true, |
|
501 | - 'MTP_is_global' => true, |
|
502 | - ), |
|
503 | - ) |
|
504 | - ); |
|
505 | - //if we have a group, add it to the collection. |
|
506 | - if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
507 | - $this->_template_collection->add( |
|
508 | - $global_message_template_group, |
|
509 | - array(0) |
|
510 | - ); |
|
511 | - } |
|
512 | - } |
|
513 | - return $global_message_template_group; |
|
514 | - } |
|
515 | - |
|
516 | - |
|
517 | - /** |
|
518 | - * Returns an array of event ids for all the events within the current data handler. |
|
519 | - * |
|
520 | - * @return array |
|
521 | - */ |
|
522 | - protected function _get_event_ids_from_current_data_handler() |
|
523 | - { |
|
524 | - $event_ids = array(); |
|
525 | - foreach ($this->_current_data_handler->events as $event) { |
|
526 | - $event_ids[$event['ID']] = $event['ID']; |
|
527 | - } |
|
528 | - return $event_ids; |
|
529 | - } |
|
530 | - |
|
531 | - |
|
532 | - /** |
|
533 | - * Retrieves formatted array of template information for each context specific to the given |
|
534 | - * EE_Message_Template_Group |
|
535 | - * |
|
536 | - * @param EE_Message_Template_Group $message_template_group |
|
537 | - * @return array The returned array is in this structure: |
|
538 | - * array( |
|
539 | - * 'field_name' => array( |
|
540 | - * 'context' => 'content' |
|
541 | - * ) |
|
542 | - * ) |
|
543 | - * @throws EE_Error |
|
544 | - */ |
|
545 | - protected function _get_templates(EE_Message_Template_Group $message_template_group) |
|
546 | - { |
|
547 | - $templates = array(); |
|
548 | - $context_templates = $message_template_group->context_templates(); |
|
549 | - foreach ($context_templates as $context => $template_fields) { |
|
550 | - foreach ($template_fields as $template_field => $template_obj) { |
|
551 | - if (! $template_obj instanceof EE_Message_Template) { |
|
552 | - continue; |
|
553 | - } |
|
554 | - $templates[$template_field][$context] = $template_obj->get('MTP_content'); |
|
555 | - } |
|
556 | - } |
|
557 | - return $templates; |
|
558 | - } |
|
559 | - |
|
560 | - |
|
561 | - /** |
|
562 | - * Assembles new fully generated EE_Message objects and adds to _ready_queue |
|
563 | - * |
|
564 | - * @param array $addressees Array of EE_Messages_Addressee objects indexed by message type |
|
565 | - * context. |
|
566 | - * @param array $templates formatted array of templates used for parsing data. |
|
567 | - * @param EE_Message_Template_Group $message_template_group |
|
568 | - * @return bool true if message generation went a-ok. false if some sort of exception occurred. Note: The |
|
569 | - * method will attempt to generate ALL EE_Message objects and add to |
|
570 | - * the _ready_queue. Successfully generated messages get added to the |
|
571 | - * queue with EEM_Message::status_idle, unsuccessfully generated |
|
572 | - * messages will get added to the queue as EEM_Message::status_failed. |
|
573 | - * Very rarely should "false" be returned from this method. |
|
574 | - */ |
|
575 | - protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group) |
|
576 | - { |
|
577 | - |
|
578 | - //if templates are empty then get out because we can't generate anything. |
|
579 | - if (! $templates) { |
|
580 | - $this->_error_msg[] = esc_html__( |
|
581 | - 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
|
582 | - 'event_espresso' |
|
583 | - ); |
|
584 | - return false; |
|
585 | - } |
|
586 | - |
|
587 | - //We use this as the counter for generated messages because don't forget we may be executing this inside of a |
|
588 | - //generation_queue. So _ready_queue may have generated EE_Message objects already. |
|
589 | - $generated_count = 0; |
|
590 | - foreach ($addressees as $context => $recipients) { |
|
591 | - foreach ($recipients as $recipient) { |
|
592 | - $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group); |
|
593 | - if ($message instanceof EE_Message) { |
|
594 | - $this->_ready_queue->add( |
|
595 | - $message, |
|
596 | - array(), |
|
597 | - $this->_generation_queue->get_message_repository()->is_preview(), |
|
598 | - $this->_generation_queue->get_message_repository()->is_test_send() |
|
599 | - ); |
|
600 | - $generated_count++; |
|
601 | - } |
|
602 | - |
|
603 | - //if the current MSG being generated is for a test send then we'll only use ONE message in the generation. |
|
604 | - if ($this->_generation_queue->get_message_repository()->is_test_send()) { |
|
605 | - break 2; |
|
606 | - } |
|
607 | - } |
|
608 | - } |
|
609 | - |
|
610 | - //if there are no generated messages then something else fatal went wrong. |
|
611 | - return $generated_count > 0; |
|
612 | - } |
|
613 | - |
|
614 | - |
|
615 | - /** |
|
616 | - * @param string $context The context for the generated message. |
|
617 | - * @param EE_Messages_Addressee $recipient |
|
618 | - * @param array $templates formatted array of templates used for parsing data. |
|
619 | - * @param EE_Message_Template_Group $message_template_group |
|
620 | - * @return bool|EE_Message |
|
621 | - * @throws EE_Error |
|
622 | - */ |
|
623 | - protected function _setup_message_object( |
|
624 | - $context, |
|
625 | - EE_Messages_Addressee $recipient, |
|
626 | - $templates, |
|
627 | - EE_Message_Template_Group $message_template_group |
|
628 | - ) { |
|
629 | - //stuff we already know |
|
630 | - $transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0; |
|
631 | - $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction |
|
632 | - ? $this->_current_data_handler->txn->ID() |
|
633 | - : $transaction_id; |
|
634 | - $message_fields = array( |
|
635 | - 'GRP_ID' => $message_template_group->ID(), |
|
636 | - 'TXN_ID' => $transaction_id, |
|
637 | - 'MSG_messenger' => $this->_current_messenger->name, |
|
638 | - 'MSG_message_type' => $this->_current_message_type->name, |
|
639 | - 'MSG_context' => $context, |
|
640 | - ); |
|
641 | - |
|
642 | - //recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab |
|
643 | - // the info from the att_obj found in the EE_Messages_Addressee object. |
|
644 | - if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) { |
|
645 | - $message_fields['MSG_recipient_ID'] = $recipient->att_obj instanceof EE_Attendee |
|
646 | - ? $recipient->att_obj->ID() |
|
647 | - : 0; |
|
648 | - $message_fields['MSG_recipient_type'] = 'Attendee'; |
|
649 | - } else { |
|
650 | - $message_fields['MSG_recipient_ID'] = $recipient->recipient_id; |
|
651 | - $message_fields['MSG_recipient_type'] = $recipient->recipient_type; |
|
652 | - } |
|
653 | - $message = EE_Message_Factory::create($message_fields); |
|
654 | - |
|
655 | - //grab valid shortcodes for shortcode parser |
|
656 | - $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes(); |
|
657 | - $m_shortcodes = $this->_current_messenger->get_valid_shortcodes(); |
|
658 | - |
|
659 | - //if the 'to' field is empty (messages will ALWAYS have a "to" field, then we get out because that means this |
|
660 | - //context is turned off) EXCEPT if we're previewing |
|
661 | - if (empty($templates['to'][$context]) |
|
662 | - && ! $this->_generation_queue->get_message_repository()->is_preview() |
|
663 | - && ! $this->_current_messenger->allow_empty_to_field() |
|
664 | - ) { |
|
665 | - //we silently exit here and do NOT record a fail because the message is "turned off" by having no "to" |
|
666 | - //field. |
|
667 | - return false; |
|
668 | - } |
|
669 | - $error_msg = array(); |
|
670 | - foreach ($templates as $field => $field_context) { |
|
671 | - $error_msg = array(); |
|
672 | - //let's setup the valid shortcodes for the incoming context. |
|
673 | - $valid_shortcodes = $mt_shortcodes[$context]; |
|
674 | - //merge in valid shortcodes for the field. |
|
675 | - $shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes; |
|
676 | - if (isset($templates[$field][$context])) { |
|
677 | - //prefix field. |
|
678 | - $column_name = 'MSG_' . $field; |
|
679 | - try { |
|
680 | - $content = $this->_shortcode_parser->parse_message_template( |
|
681 | - $templates[$field][$context], |
|
682 | - $recipient, |
|
683 | - $shortcodes, |
|
684 | - $this->_current_message_type, |
|
685 | - $this->_current_messenger, |
|
686 | - $message |
|
687 | - ); |
|
688 | - $message->set_field_or_extra_meta($column_name, $content); |
|
689 | - } catch (EE_Error $e) { |
|
690 | - $error_msg[] = sprintf( |
|
691 | - esc_html__( |
|
692 | - 'There was a problem generating the content for the field %s: %s', |
|
693 | - 'event_espresso' |
|
694 | - ), |
|
695 | - $field, |
|
696 | - $e->getMessage() |
|
697 | - ); |
|
698 | - $message->set_STS_ID(EEM_Message::status_failed); |
|
699 | - } |
|
700 | - } |
|
701 | - } |
|
702 | - |
|
703 | - if ($message->STS_ID() === EEM_Message::status_failed) { |
|
704 | - $error_msg = esc_html__('There were problems generating this message:', 'event_espresso') |
|
705 | - . "\n" |
|
706 | - . implode("\n", $error_msg); |
|
707 | - $message->set_error_message($error_msg); |
|
708 | - } else { |
|
709 | - $message->set_STS_ID(EEM_Message::status_idle); |
|
710 | - } |
|
711 | - return $message; |
|
712 | - } |
|
713 | - |
|
714 | - |
|
715 | - /** |
|
716 | - * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate |
|
717 | - * error message if either is missing. |
|
718 | - * |
|
719 | - * @return bool true means there were no errors, false means there were errors. |
|
720 | - */ |
|
721 | - protected function _verify() |
|
722 | - { |
|
723 | - //reset error message to an empty array. |
|
724 | - $this->_error_msg = array(); |
|
725 | - $valid = true; |
|
726 | - $valid = $valid ? $this->_validate_messenger_and_message_type() : $valid; |
|
727 | - $valid = $valid ? $this->_validate_and_setup_data() : $valid; |
|
728 | - |
|
729 | - //set the verified flag so we know everything has been validated. |
|
730 | - $this->_verified = $valid; |
|
731 | - |
|
732 | - return $valid; |
|
733 | - } |
|
734 | - |
|
735 | - |
|
736 | - /** |
|
737 | - * This accepts an array and validates that it is an array indexed by context with each value being an array of |
|
738 | - * EE_Messages_Addressee objects. |
|
739 | - * |
|
740 | - * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[] |
|
741 | - * @return bool |
|
742 | - */ |
|
743 | - protected function _valid_addressees($addressees) |
|
744 | - { |
|
745 | - if (! $addressees || ! is_array($addressees)) { |
|
746 | - return false; |
|
747 | - } |
|
748 | - |
|
749 | - foreach ($addressees as $addressee_array) { |
|
750 | - foreach ($addressee_array as $addressee) { |
|
751 | - if (! $addressee instanceof EE_Messages_Addressee) { |
|
752 | - return false; |
|
753 | - } |
|
754 | - } |
|
755 | - } |
|
756 | - return true; |
|
757 | - } |
|
758 | - |
|
759 | - |
|
760 | - /** |
|
761 | - * This validates the messenger, message type, and presences of generation data for the current EE_Message in the |
|
762 | - * queue. This process sets error messages if something is wrong. |
|
763 | - * |
|
764 | - * @return bool true is if there are no errors. false is if there is. |
|
765 | - */ |
|
766 | - protected function _validate_messenger_and_message_type() |
|
767 | - { |
|
768 | - |
|
769 | - //first are there any existing error messages? If so then return. |
|
770 | - if ($this->_error_msg) { |
|
771 | - return false; |
|
772 | - } |
|
773 | - /** @type EE_Message $message */ |
|
774 | - $message = $this->_generation_queue->get_message_repository()->current(); |
|
775 | - try { |
|
776 | - $this->_current_messenger = $message->valid_messenger(true) |
|
777 | - ? $message->messenger_object() |
|
778 | - : null; |
|
779 | - } catch (Exception $e) { |
|
780 | - $this->_error_msg[] = $e->getMessage(); |
|
781 | - } |
|
782 | - try { |
|
783 | - $this->_current_message_type = $message->valid_message_type(true) |
|
784 | - ? $message->message_type_object() |
|
785 | - : null; |
|
786 | - } catch (Exception $e) { |
|
787 | - $this->_error_msg[] = $e->getMessage(); |
|
788 | - } |
|
789 | - |
|
790 | - /** |
|
791 | - * Check if there is any generation data, but only if this is not for a preview. |
|
792 | - */ |
|
793 | - if (! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
794 | - && ( |
|
795 | - ! $this->_generation_queue->get_message_repository()->is_preview() |
|
796 | - && $this->_generation_queue->get_message_repository()->get_data_handler() |
|
797 | - !== 'EE_Messages_Preview_incoming_data' |
|
798 | - ) |
|
799 | - ) { |
|
800 | - $this->_error_msg[] = esc_html__( |
|
801 | - 'There is no generation data for this message. Unable to generate.', |
|
802 | - 'event_espresso' |
|
803 | - ); |
|
804 | - } |
|
805 | - |
|
806 | - return empty($this->_error_msg); |
|
807 | - } |
|
808 | - |
|
809 | - |
|
810 | - /** |
|
811 | - * This method retrieves the expected data handler for the message type and validates the generation data for that |
|
812 | - * data handler. |
|
813 | - * |
|
814 | - * @return bool true means there are no errors. false means there were errors (and handler did not get setup). |
|
815 | - */ |
|
816 | - protected function _validate_and_setup_data() |
|
817 | - { |
|
818 | - |
|
819 | - //First, are there any existing error messages? If so, return because if there were errors elsewhere this can't |
|
820 | - //be used anyways. |
|
821 | - if ($this->_error_msg) { |
|
822 | - return false; |
|
823 | - } |
|
824 | - |
|
825 | - $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data(); |
|
826 | - |
|
827 | - /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */ |
|
828 | - $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
|
829 | - ? $this->_generation_queue->get_message_repository()->get_data_handler() |
|
830 | - : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
831 | - |
|
832 | - //If this EE_Message is for a preview, then let's switch out to the preview data handler. |
|
833 | - if ($this->_generation_queue->get_message_repository()->is_preview()) { |
|
834 | - $data_handler_class_name = 'EE_Messages_Preview_incoming_data'; |
|
835 | - } |
|
836 | - |
|
837 | - //First get the class name for the data handler (and also verifies it exists. |
|
838 | - if (! class_exists($data_handler_class_name)) { |
|
839 | - $this->_error_msg[] = sprintf( |
|
840 | - esc_html__( |
|
841 | - 'The included data handler class name does not match any valid, accessible, "%1$s" classes. Looking for %2$s.', |
|
842 | - 'event_espresso' |
|
843 | - ), |
|
844 | - 'EE_Messages_incoming_data', |
|
845 | - $data_handler_class_name |
|
846 | - ); |
|
847 | - return false; |
|
848 | - } |
|
849 | - |
|
850 | - //convert generation_data for data_handler_instantiation. |
|
851 | - $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data); |
|
852 | - |
|
853 | - //note, this may set error messages as well. |
|
854 | - $this->_set_data_handler($generation_data, $data_handler_class_name); |
|
855 | - |
|
856 | - return empty($this->_error_msg); |
|
857 | - } |
|
858 | - |
|
859 | - |
|
860 | - /** |
|
861 | - * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and |
|
862 | - * adds it to the _data repository. |
|
863 | - * |
|
864 | - * @param mixed $generating_data This is data expected by the instantiated data handler. |
|
865 | - * @param string $data_handler_class_name This is the reference string indicating what data handler is being |
|
866 | - * instantiated. |
|
867 | - * @return void . |
|
868 | - * @throws EE_Error |
|
869 | - * @throws ReflectionException |
|
870 | - */ |
|
871 | - protected function _set_data_handler($generating_data, $data_handler_class_name) |
|
872 | - { |
|
873 | - //valid classname for the data handler. Now let's setup the key for the data handler repository to see if there |
|
874 | - //is already a ready data handler in the repository. |
|
875 | - $this->_current_data_handler = $this->_data_handler_collection->get_by_key( |
|
876 | - $this->_data_handler_collection->get_key( |
|
877 | - $data_handler_class_name, |
|
878 | - $generating_data |
|
879 | - ) |
|
880 | - ); |
|
881 | - if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
882 | - //no saved data_handler in the repo so let's set one up and add it to the repo. |
|
883 | - try { |
|
884 | - $this->_current_data_handler = new $data_handler_class_name($generating_data); |
|
885 | - $this->_data_handler_collection->add($this->_current_data_handler, $generating_data); |
|
886 | - } catch (EE_Error $e) { |
|
887 | - $this->_error_msg[] = $e->get_error(); |
|
888 | - } |
|
889 | - } |
|
890 | - } |
|
891 | - |
|
892 | - |
|
893 | - /** |
|
894 | - * The queued EE_Message for generation does not save the data used for generation as objects |
|
895 | - * because serialization of those objects could be problematic if the data is saved to the db. |
|
896 | - * So this method calls the static method on the associated data_handler for the given message_type |
|
897 | - * and that preps the data for later instantiation when generating. |
|
898 | - * |
|
899 | - * @param EE_Message_To_Generate $message_to_generate |
|
900 | - * @param bool $preview Indicate whether this is being used for a preview or not. |
|
901 | - * @return mixed Prepped data for persisting to the queue. false is returned if unable to prep data. |
|
902 | - */ |
|
903 | - protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview) |
|
904 | - { |
|
905 | - /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
|
906 | - $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
|
907 | - if (! $message_to_generate->valid()) { |
|
908 | - return false; //unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
|
909 | - } |
|
910 | - return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
|
911 | - } |
|
912 | - |
|
913 | - |
|
914 | - /** |
|
915 | - * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue. |
|
916 | - * |
|
917 | - * @param EE_Message_To_Generate $message_to_generate |
|
918 | - * @param bool $test_send Whether this is just a test send or not. Typically used for previews. |
|
919 | - */ |
|
920 | - public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false) |
|
921 | - { |
|
922 | - //prep data |
|
923 | - $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview()); |
|
924 | - |
|
925 | - $message = $message_to_generate->get_EE_Message(); |
|
926 | - |
|
927 | - //is there a GRP_ID in the request? |
|
928 | - if ($GRP_ID = EE_Registry::instance()->REQ->get('GRP_ID')) { |
|
929 | - $message->set_GRP_ID($GRP_ID); |
|
930 | - } |
|
931 | - |
|
932 | - if ($data === false) { |
|
933 | - $message->set_STS_ID(EEM_Message::status_failed); |
|
934 | - $message->set_error_message( |
|
935 | - esc_html__( |
|
936 | - 'Unable to prepare data for persistence to the database.', |
|
937 | - 'event_espresso' |
|
938 | - ) |
|
939 | - ); |
|
940 | - } else { |
|
941 | - //make sure that the data handler is cached on the message as well |
|
942 | - $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name(); |
|
943 | - } |
|
944 | - |
|
945 | - $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send); |
|
946 | - } |
|
16 | + /** |
|
17 | + * @type EE_Messages_Data_Handler_Collection |
|
18 | + */ |
|
19 | + protected $_data_handler_collection; |
|
20 | + |
|
21 | + /** |
|
22 | + * @type EE_Message_Template_Group_Collection |
|
23 | + */ |
|
24 | + protected $_template_collection; |
|
25 | + |
|
26 | + /** |
|
27 | + * This will hold the data handler for the current EE_Message being generated. |
|
28 | + * |
|
29 | + * @type EE_Messages_incoming_data |
|
30 | + */ |
|
31 | + protected $_current_data_handler; |
|
32 | + |
|
33 | + /** |
|
34 | + * This holds the EE_Messages_Queue that contains the messages to generate. |
|
35 | + * |
|
36 | + * @type EE_Messages_Queue |
|
37 | + */ |
|
38 | + protected $_generation_queue; |
|
39 | + |
|
40 | + /** |
|
41 | + * This holds the EE_Messages_Queue that will store the generated EE_Message objects. |
|
42 | + * |
|
43 | + * @type EE_Messages_Queue |
|
44 | + */ |
|
45 | + protected $_ready_queue; |
|
46 | + |
|
47 | + /** |
|
48 | + * This is a container for any error messages that get created through the generation |
|
49 | + * process. |
|
50 | + * |
|
51 | + * @type array |
|
52 | + */ |
|
53 | + protected $_error_msg = array(); |
|
54 | + |
|
55 | + /** |
|
56 | + * Flag used to set when the current EE_Message in the generation queue has been verified. |
|
57 | + * |
|
58 | + * @type bool |
|
59 | + */ |
|
60 | + protected $_verified = false; |
|
61 | + |
|
62 | + /** |
|
63 | + * This will hold the current messenger object corresponding with the current EE_Message in the generation queue. |
|
64 | + * |
|
65 | + * @type EE_messenger |
|
66 | + */ |
|
67 | + protected $_current_messenger; |
|
68 | + |
|
69 | + /** |
|
70 | + * This will hold the current message type object corresponding with the current EE_Message in the generation queue. |
|
71 | + * |
|
72 | + * @type EE_message_type |
|
73 | + */ |
|
74 | + protected $_current_message_type; |
|
75 | + |
|
76 | + /** |
|
77 | + * @type EEH_Parse_Shortcodes |
|
78 | + */ |
|
79 | + protected $_shortcode_parser; |
|
80 | + |
|
81 | + |
|
82 | + /** |
|
83 | + * @param EE_Messages_Queue $generation_queue |
|
84 | + * @param \EE_Messages_Queue $ready_queue |
|
85 | + * @param \EE_Messages_Data_Handler_Collection $data_handler_collection |
|
86 | + * @param \EE_Message_Template_Group_Collection $template_collection |
|
87 | + * @param \EEH_Parse_Shortcodes $shortcode_parser |
|
88 | + */ |
|
89 | + public function __construct( |
|
90 | + EE_Messages_Queue $generation_queue, |
|
91 | + EE_Messages_Queue $ready_queue, |
|
92 | + EE_Messages_Data_Handler_Collection $data_handler_collection, |
|
93 | + EE_Message_Template_Group_Collection $template_collection, |
|
94 | + EEH_Parse_Shortcodes $shortcode_parser |
|
95 | + ) { |
|
96 | + $this->_generation_queue = $generation_queue; |
|
97 | + $this->_ready_queue = $ready_queue; |
|
98 | + $this->_data_handler_collection = $data_handler_collection; |
|
99 | + $this->_template_collection = $template_collection; |
|
100 | + $this->_shortcode_parser = $shortcode_parser; |
|
101 | + } |
|
102 | + |
|
103 | + |
|
104 | + /** |
|
105 | + * @return EE_Messages_Queue |
|
106 | + */ |
|
107 | + public function generation_queue() |
|
108 | + { |
|
109 | + return $this->_generation_queue; |
|
110 | + } |
|
111 | + |
|
112 | + |
|
113 | + /** |
|
114 | + * This iterates through the provided queue and generates the EE_Message objects. |
|
115 | + * When iterating through the queue, the queued item that served as the base for generating other EE_Message |
|
116 | + * objects gets removed and the new EE_Message objects get added to a NEW queue. The NEW queue is then returned |
|
117 | + * for the caller to decide what to do with it. |
|
118 | + * |
|
119 | + * @param bool $save Whether to save the EE_Message objects in the new queue or just return. |
|
120 | + * @return EE_Messages_Queue The new queue for holding generated EE_Message objects. |
|
121 | + */ |
|
122 | + public function generate($save = true) |
|
123 | + { |
|
124 | + //iterate through the messages in the queue, generate, and add to new queue. |
|
125 | + $this->_generation_queue->get_message_repository()->rewind(); |
|
126 | + while ($this->_generation_queue->get_message_repository()->valid()) { |
|
127 | + //reset "current" properties |
|
128 | + $this->_reset_current_properties(); |
|
129 | + |
|
130 | + /** @type EE_Message $msg */ |
|
131 | + $msg = $this->_generation_queue->get_message_repository()->current(); |
|
132 | + |
|
133 | + /** |
|
134 | + * need to get the next object and capture it for setting manually after deletes. The reason is that when |
|
135 | + * an object is removed from the repo then valid for the next object will fail. |
|
136 | + */ |
|
137 | + $this->_generation_queue->get_message_repository()->next(); |
|
138 | + $next_msg = $this->_generation_queue->get_message_repository()->current(); |
|
139 | + //restore pointer to current item |
|
140 | + $this->_generation_queue->get_message_repository()->set_current($msg); |
|
141 | + |
|
142 | + //skip and delete if the current $msg is NOT incomplete (queued for generation) |
|
143 | + if ($msg->STS_ID() !== EEM_Message::status_incomplete) { |
|
144 | + //we keep this item in the db just remove from the repo. |
|
145 | + $this->_generation_queue->get_message_repository()->remove($msg); |
|
146 | + //next item |
|
147 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
148 | + continue; |
|
149 | + } |
|
150 | + |
|
151 | + if ($this->_verify()) { |
|
152 | + //let's get generating! |
|
153 | + $this->_generate(); |
|
154 | + } |
|
155 | + |
|
156 | + //don't persist debug_only messages if the messages system is not in debug mode. |
|
157 | + if ($msg->STS_ID() === EEM_Message::status_debug_only |
|
158 | + && ! EEM_Message::debug() |
|
159 | + ) { |
|
160 | + do_action( |
|
161 | + 'AHEE__EE_Messages_Generator__generate__before_debug_delete', |
|
162 | + $msg, |
|
163 | + $this->_error_msg, |
|
164 | + $this->_current_messenger, |
|
165 | + $this->_current_message_type, |
|
166 | + $this->_current_data_handler |
|
167 | + ); |
|
168 | + $this->_generation_queue->get_message_repository()->delete(); |
|
169 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
170 | + continue; |
|
171 | + } |
|
172 | + |
|
173 | + //if there are error messages then let's set the status and the error message. |
|
174 | + if ($this->_error_msg) { |
|
175 | + //if the status is already debug only, then let's leave it at that. |
|
176 | + if ($msg->STS_ID() !== EEM_Message::status_debug_only) { |
|
177 | + $msg->set_STS_ID(EEM_Message::status_failed); |
|
178 | + } |
|
179 | + do_action( |
|
180 | + 'AHEE__EE_Messages_Generator__generate__processing_failed_message', |
|
181 | + $msg, |
|
182 | + $this->_error_msg, |
|
183 | + $this->_current_messenger, |
|
184 | + $this->_current_message_type, |
|
185 | + $this->_current_data_handler |
|
186 | + ); |
|
187 | + $msg->set_error_message( |
|
188 | + esc_html__('Message failed to generate for the following reasons: ', 'event_espresso') |
|
189 | + . "\n" |
|
190 | + . implode("\n", $this->_error_msg) |
|
191 | + ); |
|
192 | + $msg->set_modified(time()); |
|
193 | + } else { |
|
194 | + do_action( |
|
195 | + 'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete', |
|
196 | + $msg, |
|
197 | + $this->_error_msg, |
|
198 | + $this->_current_messenger, |
|
199 | + $this->_current_message_type, |
|
200 | + $this->_current_data_handler |
|
201 | + ); |
|
202 | + //remove from db |
|
203 | + $this->_generation_queue->get_message_repository()->delete(); |
|
204 | + } |
|
205 | + //next item |
|
206 | + $this->_generation_queue->get_message_repository()->set_current($next_msg); |
|
207 | + } |
|
208 | + |
|
209 | + //generation queue is ALWAYS saved to record any errors in the generation process. |
|
210 | + $this->_generation_queue->save(); |
|
211 | + |
|
212 | + /** |
|
213 | + * save _ready_queue if flag set. |
|
214 | + * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method. This |
|
215 | + * means if a field was added that is not a valid database column. The EE_Message was already saved to the db |
|
216 | + * so a EE_Extra_Meta entry could be created and attached to the EE_Message. In those cases the save flag is |
|
217 | + * irrelevant. |
|
218 | + */ |
|
219 | + if ($save) { |
|
220 | + $this->_ready_queue->save(); |
|
221 | + } |
|
222 | + |
|
223 | + //final reset of properties |
|
224 | + $this->_reset_current_properties(); |
|
225 | + |
|
226 | + return $this->_ready_queue; |
|
227 | + } |
|
228 | + |
|
229 | + |
|
230 | + /** |
|
231 | + * This resets all the properties used for holding "current" values corresponding to the current EE_Message object |
|
232 | + * in the generation queue. |
|
233 | + */ |
|
234 | + protected function _reset_current_properties() |
|
235 | + { |
|
236 | + $this->_verified = false; |
|
237 | + //make sure any _data value in the current message type is reset |
|
238 | + if ($this->_current_message_type instanceof EE_message_type) { |
|
239 | + $this->_current_message_type->reset_data(); |
|
240 | + } |
|
241 | + $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null; |
|
242 | + } |
|
243 | + |
|
244 | + |
|
245 | + /** |
|
246 | + * This proceeds with the actual generation of a message. By the time this is called, there should already be a |
|
247 | + * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the |
|
248 | + * _generating_queue. |
|
249 | + * |
|
250 | + * @return bool Whether the message was successfully generated or not. |
|
251 | + * @throws EE_Error |
|
252 | + */ |
|
253 | + protected function _generate() |
|
254 | + { |
|
255 | + //double check verification has run and that everything is ready to work with (saves us having to validate |
|
256 | + // everything again). |
|
257 | + if (! $this->_verified) { |
|
258 | + return false; //get out because we don't have a valid setup to work with. |
|
259 | + } |
|
260 | + |
|
261 | + |
|
262 | + try { |
|
263 | + $addressees = $this->_current_message_type->get_addressees( |
|
264 | + $this->_current_data_handler, |
|
265 | + $this->_generation_queue->get_message_repository()->current()->context() |
|
266 | + ); |
|
267 | + } catch (EE_Error $e) { |
|
268 | + $this->_error_msg[] = $e->getMessage(); |
|
269 | + return false; |
|
270 | + } |
|
271 | + |
|
272 | + |
|
273 | + //if no addressees then get out because there is nothing to generation (possible bad data). |
|
274 | + if (! $this->_valid_addressees($addressees)) { |
|
275 | + do_action( |
|
276 | + 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
|
277 | + $this->_generation_queue->get_message_repository()->current(), |
|
278 | + $addressees, |
|
279 | + $this->_current_messenger, |
|
280 | + $this->_current_message_type, |
|
281 | + $this->_current_data_handler |
|
282 | + ); |
|
283 | + $this->_generation_queue->get_message_repository()->current()->set_STS_ID( |
|
284 | + EEM_Message::status_debug_only |
|
285 | + ); |
|
286 | + $this->_error_msg[] = esc_html__( |
|
287 | + '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.', |
|
288 | + 'event_espresso' |
|
289 | + ); |
|
290 | + return false; |
|
291 | + } |
|
292 | + |
|
293 | + $message_template_group = $this->_get_message_template_group(); |
|
294 | + |
|
295 | + //in the unlikely event there is no EE_Message_Template_Group available, get out! |
|
296 | + if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
297 | + $this->_error_msg[] = esc_html__( |
|
298 | + 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
|
299 | + 'event_espresso' |
|
300 | + ); |
|
301 | + return false; |
|
302 | + } |
|
303 | + |
|
304 | + //get formatted templates for using to parse and setup EE_Message objects. |
|
305 | + $templates = $this->_get_templates($message_template_group); |
|
306 | + |
|
307 | + |
|
308 | + //setup new EE_Message objects (and add to _ready_queue) |
|
309 | + return $this->_assemble_messages($addressees, $templates, $message_template_group); |
|
310 | + } |
|
311 | + |
|
312 | + |
|
313 | + /** |
|
314 | + * Retrieves the message template group being used for generating messages. |
|
315 | + * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times. |
|
316 | + * |
|
317 | + * @return EE_Message_Template_Group|null |
|
318 | + * @throws EE_Error |
|
319 | + */ |
|
320 | + protected function _get_message_template_group() |
|
321 | + { |
|
322 | + //first see if there is a specific message template group requested (current message in the queue has a specific |
|
323 | + //GRP_ID |
|
324 | + $message_template_group = $this->_specific_message_template_group_from_queue(); |
|
325 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
326 | + return $message_template_group; |
|
327 | + } |
|
328 | + |
|
329 | + //get event_ids from the datahandler so we can check to see if there's already a message template group for them |
|
330 | + //in the collection. |
|
331 | + $event_ids = $this->_get_event_ids_from_current_data_handler(); |
|
332 | + $message_template_group = $this->_template_collection->get_by_key( |
|
333 | + $this->_template_collection->getKey( |
|
334 | + $this->_current_messenger->name, |
|
335 | + $this->_current_message_type->name, |
|
336 | + $event_ids |
|
337 | + ) |
|
338 | + ); |
|
339 | + |
|
340 | + //if we have a message template group then no need to hit the database, just return it. |
|
341 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
342 | + return $message_template_group; |
|
343 | + } |
|
344 | + |
|
345 | + //okay made it here, so let's get the global group first for this messenger and message type to ensure |
|
346 | + //there is no override set. |
|
347 | + $global_message_template_group = $this->_get_global_message_template_group_for_current_messenger_and_message_type(); |
|
348 | + |
|
349 | + if ($global_message_template_group instanceof EE_Message_Template_Group |
|
350 | + && $global_message_template_group->get('MTP_is_override') |
|
351 | + ) { |
|
352 | + return $global_message_template_group; |
|
353 | + } |
|
354 | + |
|
355 | + //if we're still here, that means there was no message template group for the events in the collection and |
|
356 | + //the global message template group for the messenger and message type is not set for override. So next step is |
|
357 | + //to see if there is a common shared custom message template group for this set of events. |
|
358 | + $message_template_group = $this->_get_shared_message_template_for_events($event_ids); |
|
359 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
360 | + return $message_template_group; |
|
361 | + } |
|
362 | + |
|
363 | + //STILL here? Okay that means the fallback is to just use the global message template group for this event set. |
|
364 | + //So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this request) |
|
365 | + //and return it. |
|
366 | + if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
367 | + $this->_template_collection->add( |
|
368 | + $global_message_template_group, |
|
369 | + $event_ids |
|
370 | + ); |
|
371 | + return $global_message_template_group; |
|
372 | + } |
|
373 | + |
|
374 | + //if we land here that means there's NO active message template group for this set. |
|
375 | + //TODO this will be a good target for some optimization down the road. Whenever there is no active message |
|
376 | + //template group for a given event set then cache that result so we don't repeat the logic. However, for now, |
|
377 | + //this should likely bit hit rarely enough that it's not a significant issue. |
|
378 | + return null; |
|
379 | + } |
|
380 | + |
|
381 | + |
|
382 | + /** |
|
383 | + * This checks the current message in the queue and determines if there is a specific Message Template Group |
|
384 | + * requested for that message. |
|
385 | + * |
|
386 | + * @return EE_Message_Template_Group|null |
|
387 | + */ |
|
388 | + protected function _specific_message_template_group_from_queue() |
|
389 | + { |
|
390 | + //is there a GRP_ID already on the EE_Message object? If there is, then a specific template has been requested |
|
391 | + //so let's use that. |
|
392 | + $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID(); |
|
393 | + |
|
394 | + if ($GRP_ID) { |
|
395 | + //attempt to retrieve from repo first |
|
396 | + $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
|
397 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
398 | + return $message_template_group; //got it! |
|
399 | + } |
|
400 | + |
|
401 | + //nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
|
402 | + //is not valid, so we'll continue on in the code assuming there's NO GRP_ID. |
|
403 | + $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID); |
|
404 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
405 | + $this->_template_collection->add($message_template_group); |
|
406 | + return $message_template_group; |
|
407 | + } |
|
408 | + } |
|
409 | + return null; |
|
410 | + } |
|
411 | + |
|
412 | + |
|
413 | + /** |
|
414 | + * Returns whether the event ids passed in all share the same message template group for the current message type |
|
415 | + * and messenger. |
|
416 | + * |
|
417 | + * @param array $event_ids |
|
418 | + * @return bool true means they DO share the same message template group, false means they don't. |
|
419 | + * @throws EE_Error |
|
420 | + */ |
|
421 | + protected function _queue_shares_same_message_template_group_for_events(array $event_ids) |
|
422 | + { |
|
423 | + foreach ($this->_current_data_handler->events as $event) { |
|
424 | + $event_ids[$event['ID']] = $event['ID']; |
|
425 | + } |
|
426 | + $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count( |
|
427 | + array( |
|
428 | + array( |
|
429 | + 'Event.EVT_ID' => array('IN', $event_ids), |
|
430 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
431 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
432 | + ), |
|
433 | + ), |
|
434 | + 'GRP_ID', |
|
435 | + true |
|
436 | + ); |
|
437 | + return $count_of_message_template_groups === 1; |
|
438 | + } |
|
439 | + |
|
440 | + |
|
441 | + /** |
|
442 | + * This will get the shared message template group for events that are in the current data handler but ONLY if |
|
443 | + * there's a single shared message template group among all the events. Otherwise it returns null. |
|
444 | + * |
|
445 | + * @param array $event_ids |
|
446 | + * @return EE_Message_Template_Group|null |
|
447 | + * @throws EE_Error |
|
448 | + */ |
|
449 | + protected function _get_shared_message_template_for_events(array $event_ids) |
|
450 | + { |
|
451 | + $message_template_group = null; |
|
452 | + if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) { |
|
453 | + $message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
454 | + array( |
|
455 | + array( |
|
456 | + 'Event.EVT_ID' => array('IN', $event_ids), |
|
457 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
458 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
459 | + 'MTP_is_active' => true, |
|
460 | + ), |
|
461 | + 'group_by' => 'GRP_ID', |
|
462 | + ) |
|
463 | + ); |
|
464 | + //store this in the collection if its valid |
|
465 | + if ($message_template_group instanceof EE_Message_Template_Group) { |
|
466 | + $this->_template_collection->add( |
|
467 | + $message_template_group, |
|
468 | + $event_ids |
|
469 | + ); |
|
470 | + } |
|
471 | + } |
|
472 | + return $message_template_group; |
|
473 | + } |
|
474 | + |
|
475 | + |
|
476 | + /** |
|
477 | + * Retrieves the global message template group for the current messenger and message type. |
|
478 | + * |
|
479 | + * @return EE_Message_Template_Group|null |
|
480 | + * @throws EE_Error |
|
481 | + */ |
|
482 | + protected function _get_global_message_template_group_for_current_messenger_and_message_type() |
|
483 | + { |
|
484 | + //first check the collection (we use an array with 0 in it to represent global groups). |
|
485 | + $global_message_template_group = $this->_template_collection->get_by_key( |
|
486 | + $this->_template_collection->getKey( |
|
487 | + $this->_current_messenger->name, |
|
488 | + $this->_current_message_type->name, |
|
489 | + array(0) |
|
490 | + ) |
|
491 | + ); |
|
492 | + |
|
493 | + //if we don't have a group lets hit the db. |
|
494 | + if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
495 | + $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
|
496 | + array( |
|
497 | + array( |
|
498 | + 'MTP_messenger' => $this->_current_messenger->name, |
|
499 | + 'MTP_message_type' => $this->_current_message_type->name, |
|
500 | + 'MTP_is_active' => true, |
|
501 | + 'MTP_is_global' => true, |
|
502 | + ), |
|
503 | + ) |
|
504 | + ); |
|
505 | + //if we have a group, add it to the collection. |
|
506 | + if ($global_message_template_group instanceof EE_Message_Template_Group) { |
|
507 | + $this->_template_collection->add( |
|
508 | + $global_message_template_group, |
|
509 | + array(0) |
|
510 | + ); |
|
511 | + } |
|
512 | + } |
|
513 | + return $global_message_template_group; |
|
514 | + } |
|
515 | + |
|
516 | + |
|
517 | + /** |
|
518 | + * Returns an array of event ids for all the events within the current data handler. |
|
519 | + * |
|
520 | + * @return array |
|
521 | + */ |
|
522 | + protected function _get_event_ids_from_current_data_handler() |
|
523 | + { |
|
524 | + $event_ids = array(); |
|
525 | + foreach ($this->_current_data_handler->events as $event) { |
|
526 | + $event_ids[$event['ID']] = $event['ID']; |
|
527 | + } |
|
528 | + return $event_ids; |
|
529 | + } |
|
530 | + |
|
531 | + |
|
532 | + /** |
|
533 | + * Retrieves formatted array of template information for each context specific to the given |
|
534 | + * EE_Message_Template_Group |
|
535 | + * |
|
536 | + * @param EE_Message_Template_Group $message_template_group |
|
537 | + * @return array The returned array is in this structure: |
|
538 | + * array( |
|
539 | + * 'field_name' => array( |
|
540 | + * 'context' => 'content' |
|
541 | + * ) |
|
542 | + * ) |
|
543 | + * @throws EE_Error |
|
544 | + */ |
|
545 | + protected function _get_templates(EE_Message_Template_Group $message_template_group) |
|
546 | + { |
|
547 | + $templates = array(); |
|
548 | + $context_templates = $message_template_group->context_templates(); |
|
549 | + foreach ($context_templates as $context => $template_fields) { |
|
550 | + foreach ($template_fields as $template_field => $template_obj) { |
|
551 | + if (! $template_obj instanceof EE_Message_Template) { |
|
552 | + continue; |
|
553 | + } |
|
554 | + $templates[$template_field][$context] = $template_obj->get('MTP_content'); |
|
555 | + } |
|
556 | + } |
|
557 | + return $templates; |
|
558 | + } |
|
559 | + |
|
560 | + |
|
561 | + /** |
|
562 | + * Assembles new fully generated EE_Message objects and adds to _ready_queue |
|
563 | + * |
|
564 | + * @param array $addressees Array of EE_Messages_Addressee objects indexed by message type |
|
565 | + * context. |
|
566 | + * @param array $templates formatted array of templates used for parsing data. |
|
567 | + * @param EE_Message_Template_Group $message_template_group |
|
568 | + * @return bool true if message generation went a-ok. false if some sort of exception occurred. Note: The |
|
569 | + * method will attempt to generate ALL EE_Message objects and add to |
|
570 | + * the _ready_queue. Successfully generated messages get added to the |
|
571 | + * queue with EEM_Message::status_idle, unsuccessfully generated |
|
572 | + * messages will get added to the queue as EEM_Message::status_failed. |
|
573 | + * Very rarely should "false" be returned from this method. |
|
574 | + */ |
|
575 | + protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group) |
|
576 | + { |
|
577 | + |
|
578 | + //if templates are empty then get out because we can't generate anything. |
|
579 | + if (! $templates) { |
|
580 | + $this->_error_msg[] = esc_html__( |
|
581 | + 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
|
582 | + 'event_espresso' |
|
583 | + ); |
|
584 | + return false; |
|
585 | + } |
|
586 | + |
|
587 | + //We use this as the counter for generated messages because don't forget we may be executing this inside of a |
|
588 | + //generation_queue. So _ready_queue may have generated EE_Message objects already. |
|
589 | + $generated_count = 0; |
|
590 | + foreach ($addressees as $context => $recipients) { |
|
591 | + foreach ($recipients as $recipient) { |
|
592 | + $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group); |
|
593 | + if ($message instanceof EE_Message) { |
|
594 | + $this->_ready_queue->add( |
|
595 | + $message, |
|
596 | + array(), |
|
597 | + $this->_generation_queue->get_message_repository()->is_preview(), |
|
598 | + $this->_generation_queue->get_message_repository()->is_test_send() |
|
599 | + ); |
|
600 | + $generated_count++; |
|
601 | + } |
|
602 | + |
|
603 | + //if the current MSG being generated is for a test send then we'll only use ONE message in the generation. |
|
604 | + if ($this->_generation_queue->get_message_repository()->is_test_send()) { |
|
605 | + break 2; |
|
606 | + } |
|
607 | + } |
|
608 | + } |
|
609 | + |
|
610 | + //if there are no generated messages then something else fatal went wrong. |
|
611 | + return $generated_count > 0; |
|
612 | + } |
|
613 | + |
|
614 | + |
|
615 | + /** |
|
616 | + * @param string $context The context for the generated message. |
|
617 | + * @param EE_Messages_Addressee $recipient |
|
618 | + * @param array $templates formatted array of templates used for parsing data. |
|
619 | + * @param EE_Message_Template_Group $message_template_group |
|
620 | + * @return bool|EE_Message |
|
621 | + * @throws EE_Error |
|
622 | + */ |
|
623 | + protected function _setup_message_object( |
|
624 | + $context, |
|
625 | + EE_Messages_Addressee $recipient, |
|
626 | + $templates, |
|
627 | + EE_Message_Template_Group $message_template_group |
|
628 | + ) { |
|
629 | + //stuff we already know |
|
630 | + $transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0; |
|
631 | + $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction |
|
632 | + ? $this->_current_data_handler->txn->ID() |
|
633 | + : $transaction_id; |
|
634 | + $message_fields = array( |
|
635 | + 'GRP_ID' => $message_template_group->ID(), |
|
636 | + 'TXN_ID' => $transaction_id, |
|
637 | + 'MSG_messenger' => $this->_current_messenger->name, |
|
638 | + 'MSG_message_type' => $this->_current_message_type->name, |
|
639 | + 'MSG_context' => $context, |
|
640 | + ); |
|
641 | + |
|
642 | + //recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab |
|
643 | + // the info from the att_obj found in the EE_Messages_Addressee object. |
|
644 | + if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) { |
|
645 | + $message_fields['MSG_recipient_ID'] = $recipient->att_obj instanceof EE_Attendee |
|
646 | + ? $recipient->att_obj->ID() |
|
647 | + : 0; |
|
648 | + $message_fields['MSG_recipient_type'] = 'Attendee'; |
|
649 | + } else { |
|
650 | + $message_fields['MSG_recipient_ID'] = $recipient->recipient_id; |
|
651 | + $message_fields['MSG_recipient_type'] = $recipient->recipient_type; |
|
652 | + } |
|
653 | + $message = EE_Message_Factory::create($message_fields); |
|
654 | + |
|
655 | + //grab valid shortcodes for shortcode parser |
|
656 | + $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes(); |
|
657 | + $m_shortcodes = $this->_current_messenger->get_valid_shortcodes(); |
|
658 | + |
|
659 | + //if the 'to' field is empty (messages will ALWAYS have a "to" field, then we get out because that means this |
|
660 | + //context is turned off) EXCEPT if we're previewing |
|
661 | + if (empty($templates['to'][$context]) |
|
662 | + && ! $this->_generation_queue->get_message_repository()->is_preview() |
|
663 | + && ! $this->_current_messenger->allow_empty_to_field() |
|
664 | + ) { |
|
665 | + //we silently exit here and do NOT record a fail because the message is "turned off" by having no "to" |
|
666 | + //field. |
|
667 | + return false; |
|
668 | + } |
|
669 | + $error_msg = array(); |
|
670 | + foreach ($templates as $field => $field_context) { |
|
671 | + $error_msg = array(); |
|
672 | + //let's setup the valid shortcodes for the incoming context. |
|
673 | + $valid_shortcodes = $mt_shortcodes[$context]; |
|
674 | + //merge in valid shortcodes for the field. |
|
675 | + $shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes; |
|
676 | + if (isset($templates[$field][$context])) { |
|
677 | + //prefix field. |
|
678 | + $column_name = 'MSG_' . $field; |
|
679 | + try { |
|
680 | + $content = $this->_shortcode_parser->parse_message_template( |
|
681 | + $templates[$field][$context], |
|
682 | + $recipient, |
|
683 | + $shortcodes, |
|
684 | + $this->_current_message_type, |
|
685 | + $this->_current_messenger, |
|
686 | + $message |
|
687 | + ); |
|
688 | + $message->set_field_or_extra_meta($column_name, $content); |
|
689 | + } catch (EE_Error $e) { |
|
690 | + $error_msg[] = sprintf( |
|
691 | + esc_html__( |
|
692 | + 'There was a problem generating the content for the field %s: %s', |
|
693 | + 'event_espresso' |
|
694 | + ), |
|
695 | + $field, |
|
696 | + $e->getMessage() |
|
697 | + ); |
|
698 | + $message->set_STS_ID(EEM_Message::status_failed); |
|
699 | + } |
|
700 | + } |
|
701 | + } |
|
702 | + |
|
703 | + if ($message->STS_ID() === EEM_Message::status_failed) { |
|
704 | + $error_msg = esc_html__('There were problems generating this message:', 'event_espresso') |
|
705 | + . "\n" |
|
706 | + . implode("\n", $error_msg); |
|
707 | + $message->set_error_message($error_msg); |
|
708 | + } else { |
|
709 | + $message->set_STS_ID(EEM_Message::status_idle); |
|
710 | + } |
|
711 | + return $message; |
|
712 | + } |
|
713 | + |
|
714 | + |
|
715 | + /** |
|
716 | + * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate |
|
717 | + * error message if either is missing. |
|
718 | + * |
|
719 | + * @return bool true means there were no errors, false means there were errors. |
|
720 | + */ |
|
721 | + protected function _verify() |
|
722 | + { |
|
723 | + //reset error message to an empty array. |
|
724 | + $this->_error_msg = array(); |
|
725 | + $valid = true; |
|
726 | + $valid = $valid ? $this->_validate_messenger_and_message_type() : $valid; |
|
727 | + $valid = $valid ? $this->_validate_and_setup_data() : $valid; |
|
728 | + |
|
729 | + //set the verified flag so we know everything has been validated. |
|
730 | + $this->_verified = $valid; |
|
731 | + |
|
732 | + return $valid; |
|
733 | + } |
|
734 | + |
|
735 | + |
|
736 | + /** |
|
737 | + * This accepts an array and validates that it is an array indexed by context with each value being an array of |
|
738 | + * EE_Messages_Addressee objects. |
|
739 | + * |
|
740 | + * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[] |
|
741 | + * @return bool |
|
742 | + */ |
|
743 | + protected function _valid_addressees($addressees) |
|
744 | + { |
|
745 | + if (! $addressees || ! is_array($addressees)) { |
|
746 | + return false; |
|
747 | + } |
|
748 | + |
|
749 | + foreach ($addressees as $addressee_array) { |
|
750 | + foreach ($addressee_array as $addressee) { |
|
751 | + if (! $addressee instanceof EE_Messages_Addressee) { |
|
752 | + return false; |
|
753 | + } |
|
754 | + } |
|
755 | + } |
|
756 | + return true; |
|
757 | + } |
|
758 | + |
|
759 | + |
|
760 | + /** |
|
761 | + * This validates the messenger, message type, and presences of generation data for the current EE_Message in the |
|
762 | + * queue. This process sets error messages if something is wrong. |
|
763 | + * |
|
764 | + * @return bool true is if there are no errors. false is if there is. |
|
765 | + */ |
|
766 | + protected function _validate_messenger_and_message_type() |
|
767 | + { |
|
768 | + |
|
769 | + //first are there any existing error messages? If so then return. |
|
770 | + if ($this->_error_msg) { |
|
771 | + return false; |
|
772 | + } |
|
773 | + /** @type EE_Message $message */ |
|
774 | + $message = $this->_generation_queue->get_message_repository()->current(); |
|
775 | + try { |
|
776 | + $this->_current_messenger = $message->valid_messenger(true) |
|
777 | + ? $message->messenger_object() |
|
778 | + : null; |
|
779 | + } catch (Exception $e) { |
|
780 | + $this->_error_msg[] = $e->getMessage(); |
|
781 | + } |
|
782 | + try { |
|
783 | + $this->_current_message_type = $message->valid_message_type(true) |
|
784 | + ? $message->message_type_object() |
|
785 | + : null; |
|
786 | + } catch (Exception $e) { |
|
787 | + $this->_error_msg[] = $e->getMessage(); |
|
788 | + } |
|
789 | + |
|
790 | + /** |
|
791 | + * Check if there is any generation data, but only if this is not for a preview. |
|
792 | + */ |
|
793 | + if (! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
794 | + && ( |
|
795 | + ! $this->_generation_queue->get_message_repository()->is_preview() |
|
796 | + && $this->_generation_queue->get_message_repository()->get_data_handler() |
|
797 | + !== 'EE_Messages_Preview_incoming_data' |
|
798 | + ) |
|
799 | + ) { |
|
800 | + $this->_error_msg[] = esc_html__( |
|
801 | + 'There is no generation data for this message. Unable to generate.', |
|
802 | + 'event_espresso' |
|
803 | + ); |
|
804 | + } |
|
805 | + |
|
806 | + return empty($this->_error_msg); |
|
807 | + } |
|
808 | + |
|
809 | + |
|
810 | + /** |
|
811 | + * This method retrieves the expected data handler for the message type and validates the generation data for that |
|
812 | + * data handler. |
|
813 | + * |
|
814 | + * @return bool true means there are no errors. false means there were errors (and handler did not get setup). |
|
815 | + */ |
|
816 | + protected function _validate_and_setup_data() |
|
817 | + { |
|
818 | + |
|
819 | + //First, are there any existing error messages? If so, return because if there were errors elsewhere this can't |
|
820 | + //be used anyways. |
|
821 | + if ($this->_error_msg) { |
|
822 | + return false; |
|
823 | + } |
|
824 | + |
|
825 | + $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data(); |
|
826 | + |
|
827 | + /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */ |
|
828 | + $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
|
829 | + ? $this->_generation_queue->get_message_repository()->get_data_handler() |
|
830 | + : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
831 | + |
|
832 | + //If this EE_Message is for a preview, then let's switch out to the preview data handler. |
|
833 | + if ($this->_generation_queue->get_message_repository()->is_preview()) { |
|
834 | + $data_handler_class_name = 'EE_Messages_Preview_incoming_data'; |
|
835 | + } |
|
836 | + |
|
837 | + //First get the class name for the data handler (and also verifies it exists. |
|
838 | + if (! class_exists($data_handler_class_name)) { |
|
839 | + $this->_error_msg[] = sprintf( |
|
840 | + esc_html__( |
|
841 | + 'The included data handler class name does not match any valid, accessible, "%1$s" classes. Looking for %2$s.', |
|
842 | + 'event_espresso' |
|
843 | + ), |
|
844 | + 'EE_Messages_incoming_data', |
|
845 | + $data_handler_class_name |
|
846 | + ); |
|
847 | + return false; |
|
848 | + } |
|
849 | + |
|
850 | + //convert generation_data for data_handler_instantiation. |
|
851 | + $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data); |
|
852 | + |
|
853 | + //note, this may set error messages as well. |
|
854 | + $this->_set_data_handler($generation_data, $data_handler_class_name); |
|
855 | + |
|
856 | + return empty($this->_error_msg); |
|
857 | + } |
|
858 | + |
|
859 | + |
|
860 | + /** |
|
861 | + * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and |
|
862 | + * adds it to the _data repository. |
|
863 | + * |
|
864 | + * @param mixed $generating_data This is data expected by the instantiated data handler. |
|
865 | + * @param string $data_handler_class_name This is the reference string indicating what data handler is being |
|
866 | + * instantiated. |
|
867 | + * @return void . |
|
868 | + * @throws EE_Error |
|
869 | + * @throws ReflectionException |
|
870 | + */ |
|
871 | + protected function _set_data_handler($generating_data, $data_handler_class_name) |
|
872 | + { |
|
873 | + //valid classname for the data handler. Now let's setup the key for the data handler repository to see if there |
|
874 | + //is already a ready data handler in the repository. |
|
875 | + $this->_current_data_handler = $this->_data_handler_collection->get_by_key( |
|
876 | + $this->_data_handler_collection->get_key( |
|
877 | + $data_handler_class_name, |
|
878 | + $generating_data |
|
879 | + ) |
|
880 | + ); |
|
881 | + if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
882 | + //no saved data_handler in the repo so let's set one up and add it to the repo. |
|
883 | + try { |
|
884 | + $this->_current_data_handler = new $data_handler_class_name($generating_data); |
|
885 | + $this->_data_handler_collection->add($this->_current_data_handler, $generating_data); |
|
886 | + } catch (EE_Error $e) { |
|
887 | + $this->_error_msg[] = $e->get_error(); |
|
888 | + } |
|
889 | + } |
|
890 | + } |
|
891 | + |
|
892 | + |
|
893 | + /** |
|
894 | + * The queued EE_Message for generation does not save the data used for generation as objects |
|
895 | + * because serialization of those objects could be problematic if the data is saved to the db. |
|
896 | + * So this method calls the static method on the associated data_handler for the given message_type |
|
897 | + * and that preps the data for later instantiation when generating. |
|
898 | + * |
|
899 | + * @param EE_Message_To_Generate $message_to_generate |
|
900 | + * @param bool $preview Indicate whether this is being used for a preview or not. |
|
901 | + * @return mixed Prepped data for persisting to the queue. false is returned if unable to prep data. |
|
902 | + */ |
|
903 | + protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview) |
|
904 | + { |
|
905 | + /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
|
906 | + $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
|
907 | + if (! $message_to_generate->valid()) { |
|
908 | + return false; //unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
|
909 | + } |
|
910 | + return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
|
911 | + } |
|
912 | + |
|
913 | + |
|
914 | + /** |
|
915 | + * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue. |
|
916 | + * |
|
917 | + * @param EE_Message_To_Generate $message_to_generate |
|
918 | + * @param bool $test_send Whether this is just a test send or not. Typically used for previews. |
|
919 | + */ |
|
920 | + public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false) |
|
921 | + { |
|
922 | + //prep data |
|
923 | + $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview()); |
|
924 | + |
|
925 | + $message = $message_to_generate->get_EE_Message(); |
|
926 | + |
|
927 | + //is there a GRP_ID in the request? |
|
928 | + if ($GRP_ID = EE_Registry::instance()->REQ->get('GRP_ID')) { |
|
929 | + $message->set_GRP_ID($GRP_ID); |
|
930 | + } |
|
931 | + |
|
932 | + if ($data === false) { |
|
933 | + $message->set_STS_ID(EEM_Message::status_failed); |
|
934 | + $message->set_error_message( |
|
935 | + esc_html__( |
|
936 | + 'Unable to prepare data for persistence to the database.', |
|
937 | + 'event_espresso' |
|
938 | + ) |
|
939 | + ); |
|
940 | + } else { |
|
941 | + //make sure that the data handler is cached on the message as well |
|
942 | + $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name(); |
|
943 | + } |
|
944 | + |
|
945 | + $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send); |
|
946 | + } |
|
947 | 947 | } |
@@ -254,7 +254,7 @@ discard block |
||
254 | 254 | { |
255 | 255 | //double check verification has run and that everything is ready to work with (saves us having to validate |
256 | 256 | // everything again). |
257 | - if (! $this->_verified) { |
|
257 | + if ( ! $this->_verified) { |
|
258 | 258 | return false; //get out because we don't have a valid setup to work with. |
259 | 259 | } |
260 | 260 | |
@@ -271,7 +271,7 @@ discard block |
||
271 | 271 | |
272 | 272 | |
273 | 273 | //if no addressees then get out because there is nothing to generation (possible bad data). |
274 | - if (! $this->_valid_addressees($addressees)) { |
|
274 | + if ( ! $this->_valid_addressees($addressees)) { |
|
275 | 275 | do_action( |
276 | 276 | 'AHEE__EE_Messages_Generator___generate__invalid_addressees', |
277 | 277 | $this->_generation_queue->get_message_repository()->current(), |
@@ -293,7 +293,7 @@ discard block |
||
293 | 293 | $message_template_group = $this->_get_message_template_group(); |
294 | 294 | |
295 | 295 | //in the unlikely event there is no EE_Message_Template_Group available, get out! |
296 | - if (! $message_template_group instanceof EE_Message_Template_Group) { |
|
296 | + if ( ! $message_template_group instanceof EE_Message_Template_Group) { |
|
297 | 297 | $this->_error_msg[] = esc_html__( |
298 | 298 | 'Unable to get the Message Templates for the Message being generated. No message template group accessible.', |
299 | 299 | 'event_espresso' |
@@ -395,7 +395,7 @@ discard block |
||
395 | 395 | //attempt to retrieve from repo first |
396 | 396 | $message_template_group = $this->_template_collection->get_by_ID($GRP_ID); |
397 | 397 | if ($message_template_group instanceof EE_Message_Template_Group) { |
398 | - return $message_template_group; //got it! |
|
398 | + return $message_template_group; //got it! |
|
399 | 399 | } |
400 | 400 | |
401 | 401 | //nope don't have it yet. Get from DB then add to repo if its not here, then that means the current GRP_ID |
@@ -491,7 +491,7 @@ discard block |
||
491 | 491 | ); |
492 | 492 | |
493 | 493 | //if we don't have a group lets hit the db. |
494 | - if (! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
494 | + if ( ! $global_message_template_group instanceof EE_Message_Template_Group) { |
|
495 | 495 | $global_message_template_group = EEM_Message_Template_Group::instance()->get_one( |
496 | 496 | array( |
497 | 497 | array( |
@@ -548,7 +548,7 @@ discard block |
||
548 | 548 | $context_templates = $message_template_group->context_templates(); |
549 | 549 | foreach ($context_templates as $context => $template_fields) { |
550 | 550 | foreach ($template_fields as $template_field => $template_obj) { |
551 | - if (! $template_obj instanceof EE_Message_Template) { |
|
551 | + if ( ! $template_obj instanceof EE_Message_Template) { |
|
552 | 552 | continue; |
553 | 553 | } |
554 | 554 | $templates[$template_field][$context] = $template_obj->get('MTP_content'); |
@@ -576,7 +576,7 @@ discard block |
||
576 | 576 | { |
577 | 577 | |
578 | 578 | //if templates are empty then get out because we can't generate anything. |
579 | - if (! $templates) { |
|
579 | + if ( ! $templates) { |
|
580 | 580 | $this->_error_msg[] = esc_html__( |
581 | 581 | 'Unable to assemble messages because there are no templates retrieved for generating the messages with', |
582 | 582 | 'event_espresso' |
@@ -675,7 +675,7 @@ discard block |
||
675 | 675 | $shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes; |
676 | 676 | if (isset($templates[$field][$context])) { |
677 | 677 | //prefix field. |
678 | - $column_name = 'MSG_' . $field; |
|
678 | + $column_name = 'MSG_'.$field; |
|
679 | 679 | try { |
680 | 680 | $content = $this->_shortcode_parser->parse_message_template( |
681 | 681 | $templates[$field][$context], |
@@ -742,13 +742,13 @@ discard block |
||
742 | 742 | */ |
743 | 743 | protected function _valid_addressees($addressees) |
744 | 744 | { |
745 | - if (! $addressees || ! is_array($addressees)) { |
|
745 | + if ( ! $addressees || ! is_array($addressees)) { |
|
746 | 746 | return false; |
747 | 747 | } |
748 | 748 | |
749 | 749 | foreach ($addressees as $addressee_array) { |
750 | 750 | foreach ($addressee_array as $addressee) { |
751 | - if (! $addressee instanceof EE_Messages_Addressee) { |
|
751 | + if ( ! $addressee instanceof EE_Messages_Addressee) { |
|
752 | 752 | return false; |
753 | 753 | } |
754 | 754 | } |
@@ -790,7 +790,7 @@ discard block |
||
790 | 790 | /** |
791 | 791 | * Check if there is any generation data, but only if this is not for a preview. |
792 | 792 | */ |
793 | - if (! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
793 | + if ( ! $this->_generation_queue->get_message_repository()->get_generation_data() |
|
794 | 794 | && ( |
795 | 795 | ! $this->_generation_queue->get_message_repository()->is_preview() |
796 | 796 | && $this->_generation_queue->get_message_repository()->get_data_handler() |
@@ -827,7 +827,7 @@ discard block |
||
827 | 827 | /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually */ |
828 | 828 | $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler() |
829 | 829 | ? $this->_generation_queue->get_message_repository()->get_data_handler() |
830 | - : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data'; |
|
830 | + : 'EE_Messages_'.$this->_current_message_type->get_data_handler($generation_data).'_incoming_data'; |
|
831 | 831 | |
832 | 832 | //If this EE_Message is for a preview, then let's switch out to the preview data handler. |
833 | 833 | if ($this->_generation_queue->get_message_repository()->is_preview()) { |
@@ -835,7 +835,7 @@ discard block |
||
835 | 835 | } |
836 | 836 | |
837 | 837 | //First get the class name for the data handler (and also verifies it exists. |
838 | - if (! class_exists($data_handler_class_name)) { |
|
838 | + if ( ! class_exists($data_handler_class_name)) { |
|
839 | 839 | $this->_error_msg[] = sprintf( |
840 | 840 | esc_html__( |
841 | 841 | 'The included data handler class name does not match any valid, accessible, "%1$s" classes. Looking for %2$s.', |
@@ -878,7 +878,7 @@ discard block |
||
878 | 878 | $generating_data |
879 | 879 | ) |
880 | 880 | ); |
881 | - if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
881 | + if ( ! $this->_current_data_handler instanceof EE_Messages_incoming_data) { |
|
882 | 882 | //no saved data_handler in the repo so let's set one up and add it to the repo. |
883 | 883 | try { |
884 | 884 | $this->_current_data_handler = new $data_handler_class_name($generating_data); |
@@ -904,7 +904,7 @@ discard block |
||
904 | 904 | { |
905 | 905 | /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */ |
906 | 906 | $data_handler = $message_to_generate->get_data_handler_class_name($preview); |
907 | - if (! $message_to_generate->valid()) { |
|
907 | + if ( ! $message_to_generate->valid()) { |
|
908 | 908 | return false; //unable to get the data because the info in the EE_Message_To_Generate class is invalid. |
909 | 909 | } |
910 | 910 | return $data_handler::convert_data_for_persistent_storage($message_to_generate->data()); |
@@ -18,14 +18,14 @@ discard block |
||
18 | 18 | $event_one_link = $event_two_link = $event_three_link = ''; |
19 | 19 | |
20 | 20 | $I->wantTo( |
21 | - 'Test that when registrations for multiple events are completed, and those events share the same custom' |
|
22 | - . 'template, that that custom template will be used.' |
|
21 | + 'Test that when registrations for multiple events are completed, and those events share the same custom' |
|
22 | + . 'template, that that custom template will be used.' |
|
23 | 23 | ); |
24 | 24 | |
25 | 25 | //need the MER plugin active for this test (we'll deactivate it after). |
26 | 26 | $I->ensurePluginActive( |
27 | - 'event-espresso-mer-multi-event-registration', |
|
28 | - 'activated' |
|
27 | + 'event-espresso-mer-multi-event-registration', |
|
28 | + 'activated' |
|
29 | 29 | ); |
30 | 30 | |
31 | 31 | $I->loginAsAdmin(); |
@@ -83,9 +83,9 @@ discard block |
||
83 | 83 | |
84 | 84 | |
85 | 85 | $test_registration_details = array( |
86 | - 'fname' => 'CTGuy', |
|
87 | - 'lname' => 'Dude', |
|
88 | - 'email' => '[email protected]' |
|
86 | + 'fname' => 'CTGuy', |
|
87 | + 'lname' => 'Dude', |
|
88 | + 'email' => '[email protected]' |
|
89 | 89 | ); |
90 | 90 | |
91 | 91 | $I->amGoingTo('Register for Event One and Event Two and verify Custom Template A was used.'); |
@@ -111,24 +111,24 @@ discard block |
||
111 | 111 | $I->loginAsAdmin(); |
112 | 112 | $I->amOnMessagesActivityListTablePage(); |
113 | 113 | $I->viewMessageInMessagesListTableFor( |
114 | - 'Registration Approved', |
|
115 | - MessagesAdmin::MESSAGE_STATUS_SENT, |
|
116 | - 'Email', |
|
117 | - 'Registrant' |
|
114 | + 'Registration Approved', |
|
115 | + MessagesAdmin::MESSAGE_STATUS_SENT, |
|
116 | + 'Email', |
|
117 | + 'Registrant' |
|
118 | 118 | ); |
119 | 119 | $I->seeTextInViewMessageModal($custom_template_a_label); |
120 | 120 | //closes view window |
121 | 121 | $I->click('#espresso-admin-page-overlay-dv'); |
122 | 122 | $I->deleteMessageInMessagesListTableFor( |
123 | - 'Registration Approved', |
|
124 | - MessagesAdmin::MESSAGE_STATUS_SENT, |
|
125 | - 'Email', |
|
126 | - 'Registrant' |
|
123 | + 'Registration Approved', |
|
124 | + MessagesAdmin::MESSAGE_STATUS_SENT, |
|
125 | + 'Email', |
|
126 | + 'Registrant' |
|
127 | 127 | ); |
128 | 128 | |
129 | 129 | //verify admin context |
130 | 130 | $I->viewMessageInMessagesListTableFor( |
131 | - 'Registration Approved' |
|
131 | + 'Registration Approved' |
|
132 | 132 | ); |
133 | 133 | $I->seeTextInViewMessageModal($custom_template_a_label); |
134 | 134 | $I->click('#espresso-admin-page-overlay-dv'); |
@@ -157,10 +157,10 @@ discard block |
||
157 | 157 | $I->loginAsAdmin(); |
158 | 158 | $I->amOnMessagesActivityListTablePage(); |
159 | 159 | $I->viewMessageInMessagesListTableFor( |
160 | - 'Registration Approved', |
|
161 | - MessagesAdmin::MESSAGE_STATUS_SENT, |
|
162 | - 'Email', |
|
163 | - 'Registrant' |
|
160 | + 'Registration Approved', |
|
161 | + MessagesAdmin::MESSAGE_STATUS_SENT, |
|
162 | + 'Email', |
|
163 | + 'Registrant' |
|
164 | 164 | ); |
165 | 165 | $I->waitForElementVisible(MessagesAdmin::MESSAGES_LIST_TABLE_VIEW_MESSAGE_DIALOG_CONTAINER_SELECTOR); |
166 | 166 | $I->dontSeeTextInViewMessageModal($custom_template_a_label); |
@@ -168,15 +168,15 @@ discard block |
||
168 | 168 | //closes view window |
169 | 169 | $I->click('#espresso-admin-page-overlay-dv'); |
170 | 170 | $I->deleteMessageInMessagesListTableFor( |
171 | - 'Registration Approved', |
|
172 | - MessagesAdmin::MESSAGE_STATUS_SENT, |
|
173 | - 'Email', |
|
174 | - 'Registrant' |
|
171 | + 'Registration Approved', |
|
172 | + MessagesAdmin::MESSAGE_STATUS_SENT, |
|
173 | + 'Email', |
|
174 | + 'Registrant' |
|
175 | 175 | ); |
176 | 176 | |
177 | 177 | //verify admin context |
178 | 178 | $I->viewMessageInMessagesListTableFor( |
179 | - 'Registration Approved' |
|
179 | + 'Registration Approved' |
|
180 | 180 | ); |
181 | 181 | $I->waitForElementVisible(MessagesAdmin::MESSAGES_LIST_TABLE_VIEW_MESSAGE_DIALOG_CONTAINER_SELECTOR); |
182 | 182 | $I->dontSee($custom_template_a_label); |
@@ -188,6 +188,6 @@ discard block |
||
188 | 188 | |
189 | 189 | //deactivate MER plugin so its not active for future tests |
190 | 190 | $I->ensurePluginDeactivated( |
191 | - 'event-espresso-mer-multi-event-registration', |
|
192 | - 'Plugin deactivated' |
|
191 | + 'event-espresso-mer-multi-event-registration', |
|
192 | + 'Plugin deactivated' |
|
193 | 193 | ); |
194 | 194 | \ No newline at end of file |
@@ -7,7 +7,7 @@ discard block |
||
7 | 7 | * @since 4.5.0 |
8 | 8 | */ |
9 | 9 | if (! defined('EVENT_ESPRESSO_VERSION')) { |
10 | - exit('No direct script access allowed'); |
|
10 | + exit('No direct script access allowed'); |
|
11 | 11 | } |
12 | 12 | |
13 | 13 | /** |
@@ -21,166 +21,166 @@ discard block |
||
21 | 21 | class EE_Register_Capabilities implements EEI_Plugin_API |
22 | 22 | { |
23 | 23 | |
24 | - /** |
|
25 | - * Holds the settings for a specific registration. |
|
26 | - * |
|
27 | - * @var array |
|
28 | - */ |
|
29 | - protected static $_registry = array(); |
|
24 | + /** |
|
25 | + * Holds the settings for a specific registration. |
|
26 | + * |
|
27 | + * @var array |
|
28 | + */ |
|
29 | + protected static $_registry = array(); |
|
30 | 30 | |
31 | 31 | |
32 | - /** |
|
33 | - * Used to register capability items with EE core. |
|
34 | - * |
|
35 | - * @since 4.5.0 |
|
36 | - * @param string $cap_reference usually will be a class name |
|
37 | - * that references capability |
|
38 | - * related items setup for |
|
39 | - * something. |
|
40 | - * @param array $setup_args { |
|
41 | - * An array of items related to |
|
42 | - * registering capabilities. |
|
43 | - * @type array $capabilities An array mapping capability |
|
44 | - * strings to core WP Role. Something like: array( |
|
45 | - * 'administrator' => array( |
|
46 | - * 'read_cap', 'edit_cap', |
|
47 | - * 'delete_cap'), |
|
48 | - * 'author' => |
|
49 | - * array( 'read_cap' ) |
|
50 | - * ). |
|
51 | - * @type array $capability_maps EE_Meta_Capability_Map[] |
|
52 | - * @see EE_Capabilities.php for php docs on these objects. |
|
53 | - * Should be indexed by the |
|
54 | - * classname for the capability |
|
55 | - * map and values representing |
|
56 | - * the arguments for the map. |
|
57 | - * } |
|
58 | - * @throws EE_Error |
|
59 | - * @return void |
|
60 | - */ |
|
61 | - public static function register($cap_reference = null, $setup_args = array()) |
|
62 | - { |
|
63 | - //required fields MUST be present, so let's make sure they are. |
|
64 | - if (! isset($cap_reference) || ! is_array($setup_args) || empty($setup_args['capabilities'])) { |
|
65 | - throw new EE_Error( |
|
66 | - __('In order to register capabilities with EE_Register_Capabilities::register, you must include a unique name to reference the capabilities being registered, plus an array containing the following keys: "capabilities".', |
|
67 | - 'event_espresso') |
|
68 | - ); |
|
69 | - } |
|
70 | - //make sure we don't register twice |
|
71 | - if (isset(self::$_registry[$cap_reference])) { |
|
72 | - return; |
|
73 | - } |
|
74 | - //make sure this is not registered too late or too early. |
|
75 | - if (! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) { |
|
76 | - EE_Error::doing_it_wrong(__METHOD__, |
|
77 | - sprintf(__('%s has been registered too late. Please ensure that EE_Register_Capabilities::register has been called at some point before the "AHEE__EE_System___detect_if_activation_or_upgrade__begin" action hook has been called.', |
|
78 | - 'event_espresso'), $cap_reference), '4.5.0'); |
|
79 | - } |
|
80 | - //some preliminary sanitization and setting to the $_registry property |
|
81 | - self::$_registry[$cap_reference] = array( |
|
82 | - 'caps' => isset($setup_args['capabilities']) && is_array($setup_args['capabilities']) ? $setup_args['capabilities'] : array(), |
|
83 | - 'cap_maps' => isset($setup_args['capability_maps']) ? $setup_args['capability_maps'] : array(), |
|
84 | - ); |
|
85 | - //set initial caps (note that EE_Capabilities takes care of making sure that the caps get added only once) |
|
86 | - add_filter('FHEE__EE_Capabilities__init_caps_map__caps', |
|
87 | - array('EE_Register_Capabilities', 'register_capabilities'), 10); |
|
88 | - //add filter for cap maps |
|
89 | - add_filter('FHEE__EE_Capabilities___set_meta_caps__meta_caps', |
|
90 | - array('EE_Register_Capabilities', 'register_cap_maps'), 10); |
|
91 | - //init_role_caps to register new capabilities |
|
92 | - if (is_admin()) { |
|
93 | - EE_Registry::instance()->load_core('Capabilities'); |
|
94 | - EE_Capabilities::instance()->init_caps(); |
|
95 | - } |
|
96 | - } |
|
32 | + /** |
|
33 | + * Used to register capability items with EE core. |
|
34 | + * |
|
35 | + * @since 4.5.0 |
|
36 | + * @param string $cap_reference usually will be a class name |
|
37 | + * that references capability |
|
38 | + * related items setup for |
|
39 | + * something. |
|
40 | + * @param array $setup_args { |
|
41 | + * An array of items related to |
|
42 | + * registering capabilities. |
|
43 | + * @type array $capabilities An array mapping capability |
|
44 | + * strings to core WP Role. Something like: array( |
|
45 | + * 'administrator' => array( |
|
46 | + * 'read_cap', 'edit_cap', |
|
47 | + * 'delete_cap'), |
|
48 | + * 'author' => |
|
49 | + * array( 'read_cap' ) |
|
50 | + * ). |
|
51 | + * @type array $capability_maps EE_Meta_Capability_Map[] |
|
52 | + * @see EE_Capabilities.php for php docs on these objects. |
|
53 | + * Should be indexed by the |
|
54 | + * classname for the capability |
|
55 | + * map and values representing |
|
56 | + * the arguments for the map. |
|
57 | + * } |
|
58 | + * @throws EE_Error |
|
59 | + * @return void |
|
60 | + */ |
|
61 | + public static function register($cap_reference = null, $setup_args = array()) |
|
62 | + { |
|
63 | + //required fields MUST be present, so let's make sure they are. |
|
64 | + if (! isset($cap_reference) || ! is_array($setup_args) || empty($setup_args['capabilities'])) { |
|
65 | + throw new EE_Error( |
|
66 | + __('In order to register capabilities with EE_Register_Capabilities::register, you must include a unique name to reference the capabilities being registered, plus an array containing the following keys: "capabilities".', |
|
67 | + 'event_espresso') |
|
68 | + ); |
|
69 | + } |
|
70 | + //make sure we don't register twice |
|
71 | + if (isset(self::$_registry[$cap_reference])) { |
|
72 | + return; |
|
73 | + } |
|
74 | + //make sure this is not registered too late or too early. |
|
75 | + if (! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) { |
|
76 | + EE_Error::doing_it_wrong(__METHOD__, |
|
77 | + sprintf(__('%s has been registered too late. Please ensure that EE_Register_Capabilities::register has been called at some point before the "AHEE__EE_System___detect_if_activation_or_upgrade__begin" action hook has been called.', |
|
78 | + 'event_espresso'), $cap_reference), '4.5.0'); |
|
79 | + } |
|
80 | + //some preliminary sanitization and setting to the $_registry property |
|
81 | + self::$_registry[$cap_reference] = array( |
|
82 | + 'caps' => isset($setup_args['capabilities']) && is_array($setup_args['capabilities']) ? $setup_args['capabilities'] : array(), |
|
83 | + 'cap_maps' => isset($setup_args['capability_maps']) ? $setup_args['capability_maps'] : array(), |
|
84 | + ); |
|
85 | + //set initial caps (note that EE_Capabilities takes care of making sure that the caps get added only once) |
|
86 | + add_filter('FHEE__EE_Capabilities__init_caps_map__caps', |
|
87 | + array('EE_Register_Capabilities', 'register_capabilities'), 10); |
|
88 | + //add filter for cap maps |
|
89 | + add_filter('FHEE__EE_Capabilities___set_meta_caps__meta_caps', |
|
90 | + array('EE_Register_Capabilities', 'register_cap_maps'), 10); |
|
91 | + //init_role_caps to register new capabilities |
|
92 | + if (is_admin()) { |
|
93 | + EE_Registry::instance()->load_core('Capabilities'); |
|
94 | + EE_Capabilities::instance()->init_caps(); |
|
95 | + } |
|
96 | + } |
|
97 | 97 | |
98 | 98 | |
99 | - /** |
|
100 | - * callback for FHEE__EE_Capabilities__init_caps_map__caps filter. |
|
101 | - * Takes care of registering additional capabilities to the caps map. Note, that this also on the initial |
|
102 | - * registration ensures that new capabilities are added to existing roles. |
|
103 | - * |
|
104 | - * @param array $incoming_caps The original caps map. |
|
105 | - * @return array merged in new caps. |
|
106 | - */ |
|
107 | - public static function register_capabilities($incoming_caps) |
|
108 | - { |
|
109 | - foreach (self::$_registry as $ref => $caps_and_cap_map) { |
|
110 | - $incoming_caps = array_merge_recursive($incoming_caps, $caps_and_cap_map['caps']); |
|
111 | - } |
|
112 | - return $incoming_caps; |
|
113 | - } |
|
99 | + /** |
|
100 | + * callback for FHEE__EE_Capabilities__init_caps_map__caps filter. |
|
101 | + * Takes care of registering additional capabilities to the caps map. Note, that this also on the initial |
|
102 | + * registration ensures that new capabilities are added to existing roles. |
|
103 | + * |
|
104 | + * @param array $incoming_caps The original caps map. |
|
105 | + * @return array merged in new caps. |
|
106 | + */ |
|
107 | + public static function register_capabilities($incoming_caps) |
|
108 | + { |
|
109 | + foreach (self::$_registry as $ref => $caps_and_cap_map) { |
|
110 | + $incoming_caps = array_merge_recursive($incoming_caps, $caps_and_cap_map['caps']); |
|
111 | + } |
|
112 | + return $incoming_caps; |
|
113 | + } |
|
114 | 114 | |
115 | 115 | |
116 | - /** |
|
117 | - * Callback for the 'FHEE__EE_Capabilities___set_meta_caps__meta_caps' filter which registers an array of |
|
118 | - * capability maps for the WP meta_caps filter called in EE_Capabilities. |
|
119 | - * |
|
120 | - * @since 4.5.0 |
|
121 | - * @param EE_Meta_Capability_Map[] $cap_maps The existing cap maps array. |
|
122 | - * @return EE_Meta_Capability_Map[] |
|
123 | - * @throws EE_Error |
|
124 | - */ |
|
125 | - public static function register_cap_maps($cap_maps) |
|
126 | - { |
|
127 | - //loop through and instantiate cap maps. |
|
128 | - foreach (self::$_registry as $cap_reference => $setup) { |
|
129 | - if (! isset($setup['cap_maps'])) { |
|
130 | - continue; |
|
131 | - } |
|
132 | - foreach ($setup['cap_maps'] as $cap_class => $args) { |
|
116 | + /** |
|
117 | + * Callback for the 'FHEE__EE_Capabilities___set_meta_caps__meta_caps' filter which registers an array of |
|
118 | + * capability maps for the WP meta_caps filter called in EE_Capabilities. |
|
119 | + * |
|
120 | + * @since 4.5.0 |
|
121 | + * @param EE_Meta_Capability_Map[] $cap_maps The existing cap maps array. |
|
122 | + * @return EE_Meta_Capability_Map[] |
|
123 | + * @throws EE_Error |
|
124 | + */ |
|
125 | + public static function register_cap_maps($cap_maps) |
|
126 | + { |
|
127 | + //loop through and instantiate cap maps. |
|
128 | + foreach (self::$_registry as $cap_reference => $setup) { |
|
129 | + if (! isset($setup['cap_maps'])) { |
|
130 | + continue; |
|
131 | + } |
|
132 | + foreach ($setup['cap_maps'] as $cap_class => $args) { |
|
133 | 133 | |
134 | - /** |
|
135 | - * account for cases where capability maps may be indexed |
|
136 | - * numerically to allow for the same map class to be utilized |
|
137 | - * In those cases, maps will be setup in an array like: |
|
138 | - * array( |
|
139 | - * 0 => array( 'EE_Meta_Capability' => array( |
|
140 | - * 'ee_edit_cap', array( 'Object_Name', |
|
141 | - * 'ee_edit_published_cap', |
|
142 | - * 'ee_edit_others_cap', 'ee_edit_private_cap' ) |
|
143 | - * ) ) |
|
144 | - * 1 => ... |
|
145 | - * ) |
|
146 | - * instead of: |
|
147 | - * array( |
|
148 | - * 'EE_Meta_Capability' => array( |
|
149 | - * 'ee_edit_cap', array( 'Object_Name', |
|
150 | - * 'ee_edit_published_cap', |
|
151 | - * 'ee_edit_others_cap', 'ee_edit_private_cap' ) |
|
152 | - * ), |
|
153 | - * ... |
|
154 | - * ) |
|
155 | - */ |
|
156 | - if (is_numeric($cap_class)) { |
|
157 | - $cap_class = key($args); |
|
158 | - $args = $args[$cap_class]; |
|
159 | - } |
|
134 | + /** |
|
135 | + * account for cases where capability maps may be indexed |
|
136 | + * numerically to allow for the same map class to be utilized |
|
137 | + * In those cases, maps will be setup in an array like: |
|
138 | + * array( |
|
139 | + * 0 => array( 'EE_Meta_Capability' => array( |
|
140 | + * 'ee_edit_cap', array( 'Object_Name', |
|
141 | + * 'ee_edit_published_cap', |
|
142 | + * 'ee_edit_others_cap', 'ee_edit_private_cap' ) |
|
143 | + * ) ) |
|
144 | + * 1 => ... |
|
145 | + * ) |
|
146 | + * instead of: |
|
147 | + * array( |
|
148 | + * 'EE_Meta_Capability' => array( |
|
149 | + * 'ee_edit_cap', array( 'Object_Name', |
|
150 | + * 'ee_edit_published_cap', |
|
151 | + * 'ee_edit_others_cap', 'ee_edit_private_cap' ) |
|
152 | + * ), |
|
153 | + * ... |
|
154 | + * ) |
|
155 | + */ |
|
156 | + if (is_numeric($cap_class)) { |
|
157 | + $cap_class = key($args); |
|
158 | + $args = $args[$cap_class]; |
|
159 | + } |
|
160 | 160 | |
161 | - if (! class_exists($cap_class)) { |
|
162 | - throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly. Capability map arrays must be indexed by capability map classname, and an array for the class arguments', |
|
163 | - 'event_espresso'), $cap_reference)); |
|
164 | - } |
|
161 | + if (! class_exists($cap_class)) { |
|
162 | + throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly. Capability map arrays must be indexed by capability map classname, and an array for the class arguments', |
|
163 | + 'event_espresso'), $cap_reference)); |
|
164 | + } |
|
165 | 165 | |
166 | - if (count($args) !== 2) { |
|
167 | - throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly. Capability map arrays must be indexed by capability map classname, and an array for the class arguments. The array should have two values the first being a string and the second an array.', |
|
168 | - 'event_espresso'), $cap_reference)); |
|
169 | - } |
|
170 | - $cap_maps[] = new $cap_class($args[0], $args[1]); |
|
171 | - } |
|
172 | - } |
|
173 | - return $cap_maps; |
|
174 | - } |
|
166 | + if (count($args) !== 2) { |
|
167 | + throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly. Capability map arrays must be indexed by capability map classname, and an array for the class arguments. The array should have two values the first being a string and the second an array.', |
|
168 | + 'event_espresso'), $cap_reference)); |
|
169 | + } |
|
170 | + $cap_maps[] = new $cap_class($args[0], $args[1]); |
|
171 | + } |
|
172 | + } |
|
173 | + return $cap_maps; |
|
174 | + } |
|
175 | 175 | |
176 | 176 | |
177 | - public static function deregister($cap_reference = null) |
|
178 | - { |
|
179 | - if (! empty(self::$_registry[$cap_reference])) { |
|
180 | - unset(self::$_registry[$cap_reference]); |
|
181 | - } |
|
177 | + public static function deregister($cap_reference = null) |
|
178 | + { |
|
179 | + if (! empty(self::$_registry[$cap_reference])) { |
|
180 | + unset(self::$_registry[$cap_reference]); |
|
181 | + } |
|
182 | 182 | |
183 | - //re init caps to grab the changes due to removed caps. |
|
184 | - EE_Capabilities::instance()->init_caps(); |
|
185 | - } |
|
183 | + //re init caps to grab the changes due to removed caps. |
|
184 | + EE_Capabilities::instance()->init_caps(); |
|
185 | + } |
|
186 | 186 | } |
@@ -6,7 +6,7 @@ discard block |
||
6 | 6 | * @subpackage plugin api, capabilities |
7 | 7 | * @since 4.5.0 |
8 | 8 | */ |
9 | -if (! defined('EVENT_ESPRESSO_VERSION')) { |
|
9 | +if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
|
10 | 10 | exit('No direct script access allowed'); |
11 | 11 | } |
12 | 12 | |
@@ -61,7 +61,7 @@ discard block |
||
61 | 61 | public static function register($cap_reference = null, $setup_args = array()) |
62 | 62 | { |
63 | 63 | //required fields MUST be present, so let's make sure they are. |
64 | - if (! isset($cap_reference) || ! is_array($setup_args) || empty($setup_args['capabilities'])) { |
|
64 | + if ( ! isset($cap_reference) || ! is_array($setup_args) || empty($setup_args['capabilities'])) { |
|
65 | 65 | throw new EE_Error( |
66 | 66 | __('In order to register capabilities with EE_Register_Capabilities::register, you must include a unique name to reference the capabilities being registered, plus an array containing the following keys: "capabilities".', |
67 | 67 | 'event_espresso') |
@@ -72,7 +72,7 @@ discard block |
||
72 | 72 | return; |
73 | 73 | } |
74 | 74 | //make sure this is not registered too late or too early. |
75 | - if (! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) { |
|
75 | + if ( ! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) { |
|
76 | 76 | EE_Error::doing_it_wrong(__METHOD__, |
77 | 77 | sprintf(__('%s has been registered too late. Please ensure that EE_Register_Capabilities::register has been called at some point before the "AHEE__EE_System___detect_if_activation_or_upgrade__begin" action hook has been called.', |
78 | 78 | 'event_espresso'), $cap_reference), '4.5.0'); |
@@ -126,7 +126,7 @@ discard block |
||
126 | 126 | { |
127 | 127 | //loop through and instantiate cap maps. |
128 | 128 | foreach (self::$_registry as $cap_reference => $setup) { |
129 | - if (! isset($setup['cap_maps'])) { |
|
129 | + if ( ! isset($setup['cap_maps'])) { |
|
130 | 130 | continue; |
131 | 131 | } |
132 | 132 | foreach ($setup['cap_maps'] as $cap_class => $args) { |
@@ -158,7 +158,7 @@ discard block |
||
158 | 158 | $args = $args[$cap_class]; |
159 | 159 | } |
160 | 160 | |
161 | - if (! class_exists($cap_class)) { |
|
161 | + if ( ! class_exists($cap_class)) { |
|
162 | 162 | throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly. Capability map arrays must be indexed by capability map classname, and an array for the class arguments', |
163 | 163 | 'event_espresso'), $cap_reference)); |
164 | 164 | } |
@@ -176,7 +176,7 @@ discard block |
||
176 | 176 | |
177 | 177 | public static function deregister($cap_reference = null) |
178 | 178 | { |
179 | - if (! empty(self::$_registry[$cap_reference])) { |
|
179 | + if ( ! empty(self::$_registry[$cap_reference])) { |
|
180 | 180 | unset(self::$_registry[$cap_reference]); |
181 | 181 | } |
182 | 182 |
@@ -16,7 +16,7 @@ discard block |
||
16 | 16 | use WP_Post; |
17 | 17 | |
18 | 18 | if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) { |
19 | - exit( 'No direct script access allowed' ); |
|
19 | + exit( 'No direct script access allowed' ); |
|
20 | 20 | } |
21 | 21 | |
22 | 22 | |
@@ -33,679 +33,679 @@ discard block |
||
33 | 33 | class DisplayTicketSelector |
34 | 34 | { |
35 | 35 | |
36 | - /** |
|
37 | - * event that ticket selector is being generated for |
|
38 | - * |
|
39 | - * @access protected |
|
40 | - * @var EE_Event $event |
|
41 | - */ |
|
42 | - protected $event; |
|
43 | - |
|
44 | - /** |
|
45 | - * Used to flag when the ticket selector is being called from an external iframe. |
|
46 | - * |
|
47 | - * @var bool $iframe |
|
48 | - */ |
|
49 | - protected $iframe = false; |
|
50 | - |
|
51 | - /** |
|
52 | - * max attendees that can register for event at one time |
|
53 | - * |
|
54 | - * @var int $max_attendees |
|
55 | - */ |
|
56 | - private $max_attendees = EE_INF; |
|
57 | - |
|
58 | - /** |
|
59 | - *@var string $date_format |
|
60 | - */ |
|
61 | - private $date_format; |
|
62 | - |
|
63 | - /** |
|
64 | - *@var string $time_format |
|
65 | - */ |
|
66 | - private $time_format; |
|
67 | - |
|
68 | - |
|
69 | - |
|
70 | - /** |
|
71 | - * DisplayTicketSelector constructor. |
|
72 | - */ |
|
73 | - public function __construct() |
|
74 | - { |
|
75 | - $this->date_format = apply_filters( |
|
76 | - 'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format', |
|
77 | - get_option('date_format') |
|
78 | - ); |
|
79 | - $this->time_format = apply_filters( |
|
80 | - 'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format', |
|
81 | - get_option('time_format') |
|
82 | - ); |
|
83 | - } |
|
84 | - |
|
85 | - |
|
86 | - |
|
87 | - /** |
|
88 | - * @param boolean $iframe |
|
89 | - */ |
|
90 | - public function setIframe( $iframe = true ) |
|
91 | - { |
|
92 | - $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN ); |
|
93 | - } |
|
94 | - |
|
95 | - |
|
96 | - /** |
|
97 | - * finds and sets the \EE_Event object for use throughout class |
|
98 | - * |
|
99 | - * @param mixed $event |
|
100 | - * @return bool |
|
101 | - * @throws EE_Error |
|
102 | - */ |
|
103 | - protected function setEvent( $event = null ) |
|
104 | - { |
|
105 | - if ( $event === null ) { |
|
106 | - global $post; |
|
107 | - $event = $post; |
|
108 | - } |
|
109 | - if ( $event instanceof EE_Event ) { |
|
110 | - $this->event = $event; |
|
111 | - } else if ( $event instanceof WP_Post ) { |
|
112 | - if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) { |
|
113 | - $this->event = $event->EE_Event; |
|
114 | - } else if ( $event->post_type === 'espresso_events' ) { |
|
115 | - $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event ); |
|
116 | - $this->event = $event->EE_Event; |
|
117 | - } |
|
118 | - } else { |
|
119 | - $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' ); |
|
120 | - $dev_msg = $user_msg . __( |
|
121 | - 'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.', |
|
122 | - 'event_espresso' |
|
123 | - ); |
|
124 | - EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ ); |
|
125 | - return false; |
|
126 | - } |
|
127 | - return true; |
|
128 | - } |
|
129 | - |
|
130 | - |
|
131 | - |
|
132 | - /** |
|
133 | - * @return int |
|
134 | - */ |
|
135 | - public function getMaxAttendees() |
|
136 | - { |
|
137 | - return $this->max_attendees; |
|
138 | - } |
|
139 | - |
|
140 | - |
|
141 | - |
|
142 | - /** |
|
143 | - * @param int $max_attendees |
|
144 | - */ |
|
145 | - public function setMaxAttendees($max_attendees) |
|
146 | - { |
|
147 | - $this->max_attendees = absint( |
|
148 | - apply_filters( |
|
149 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets', |
|
150 | - $max_attendees |
|
151 | - ) |
|
152 | - ); |
|
153 | - } |
|
154 | - |
|
155 | - |
|
156 | - |
|
157 | - /** |
|
158 | - * creates buttons for selecting number of attendees for an event |
|
159 | - * |
|
160 | - * @param WP_Post|int $event |
|
161 | - * @param bool $view_details |
|
162 | - * @return string |
|
163 | - * @throws EE_Error |
|
164 | - */ |
|
165 | - public function display( $event = null, $view_details = false ) |
|
166 | - { |
|
167 | - // reset filter for displaying submit button |
|
168 | - remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' ); |
|
169 | - // poke and prod incoming event till it tells us what it is |
|
170 | - if ( ! $this->setEvent( $event ) ) { |
|
171 | - return false; |
|
172 | - } |
|
173 | - // begin gathering template arguments by getting event status |
|
174 | - $template_args = array( 'event_status' => $this->event->get_active_status() ); |
|
175 | - if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) { |
|
176 | - return ! is_single() ? $this->displayViewDetailsButton() : ''; |
|
177 | - } |
|
178 | - // filter the maximum qty that can appear in the Ticket Selector qty dropdowns |
|
179 | - $this->setMaxAttendees($this->event->additional_limit()); |
|
180 | - if ($this->getMaxAttendees() < 1) { |
|
181 | - return $this->ticketSalesClosedMessage(); |
|
182 | - } |
|
183 | - // is the event expired ? |
|
184 | - $template_args['event_is_expired'] = $this->event->is_expired(); |
|
185 | - if ( $template_args[ 'event_is_expired' ] ) { |
|
186 | - return $this->expiredEventMessage(); |
|
187 | - } |
|
188 | - // get all tickets for this event ordered by the datetime |
|
189 | - $tickets = $this->getTickets(); |
|
190 | - if (count($tickets) < 1) { |
|
191 | - return $this->noTicketAvailableMessage(); |
|
192 | - } |
|
193 | - if (EED_Events_Archive::is_iframe()){ |
|
194 | - $this->setIframe(); |
|
195 | - } |
|
196 | - // redirecting to another site for registration ?? |
|
197 | - $external_url = (string) $this->event->external_url(); |
|
198 | - // if redirecting to another site for registration, then we don't load the TS |
|
199 | - $ticket_selector = $external_url |
|
200 | - ? $this->externalEventRegistration() |
|
201 | - : $this->loadTicketSelector($tickets,$template_args); |
|
202 | - // now set up the form (but not for the admin) |
|
203 | - $ticket_selector = ! is_admin() |
|
204 | - ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
205 | - : $ticket_selector; |
|
206 | - // submit button and form close tag |
|
207 | - $ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : ''; |
|
208 | - return $ticket_selector; |
|
209 | - } |
|
210 | - |
|
211 | - |
|
212 | - |
|
213 | - /** |
|
214 | - * displayTicketSelector |
|
215 | - * examines the event properties and determines whether a Ticket Selector should be displayed |
|
216 | - * |
|
217 | - * @param WP_Post|int $event |
|
218 | - * @param string $_event_active_status |
|
219 | - * @param bool $view_details |
|
220 | - * @return bool |
|
221 | - * @throws EE_Error |
|
222 | - */ |
|
223 | - protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details) |
|
224 | - { |
|
225 | - $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event; |
|
226 | - return ! is_admin() |
|
227 | - && ( |
|
228 | - ! $this->event->display_ticket_selector() |
|
229 | - || $view_details |
|
230 | - || post_password_required($event_post) |
|
231 | - || ( |
|
232 | - $_event_active_status !== EE_Datetime::active |
|
233 | - && $_event_active_status !== EE_Datetime::upcoming |
|
234 | - && $_event_active_status !== EE_Datetime::sold_out |
|
235 | - && ! ( |
|
236 | - $_event_active_status === EE_Datetime::inactive |
|
237 | - && is_user_logged_in() |
|
238 | - ) |
|
239 | - ) |
|
240 | - ); |
|
241 | - } |
|
242 | - |
|
243 | - |
|
244 | - |
|
245 | - /** |
|
246 | - * noTicketAvailableMessage |
|
247 | - * notice displayed if event is expired |
|
248 | - * |
|
249 | - * @return string |
|
250 | - * @throws EE_Error |
|
251 | - */ |
|
252 | - protected function expiredEventMessage() |
|
253 | - { |
|
254 | - return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
255 | - 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
|
256 | - 'event_espresso' |
|
257 | - ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
258 | - } |
|
259 | - |
|
260 | - |
|
261 | - |
|
262 | - /** |
|
263 | - * noTicketAvailableMessage |
|
264 | - * notice displayed if event has no more tickets available |
|
265 | - * |
|
266 | - * @return string |
|
267 | - * @throws EE_Error |
|
268 | - */ |
|
269 | - protected function noTicketAvailableMessage() |
|
270 | - { |
|
271 | - $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' ); |
|
272 | - if (current_user_can('edit_post', $this->event->ID())) { |
|
273 | - $no_ticket_available_msg .= sprintf( |
|
274 | - esc_html__( |
|
275 | - '%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s', |
|
276 | - 'event_espresso' |
|
277 | - ), |
|
278 | - '<div class="ee-attention" style="text-align: left;"><b>', |
|
279 | - '</b><br />', |
|
280 | - '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
281 | - '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->' |
|
282 | - ); |
|
283 | - } |
|
284 | - return ' |
|
36 | + /** |
|
37 | + * event that ticket selector is being generated for |
|
38 | + * |
|
39 | + * @access protected |
|
40 | + * @var EE_Event $event |
|
41 | + */ |
|
42 | + protected $event; |
|
43 | + |
|
44 | + /** |
|
45 | + * Used to flag when the ticket selector is being called from an external iframe. |
|
46 | + * |
|
47 | + * @var bool $iframe |
|
48 | + */ |
|
49 | + protected $iframe = false; |
|
50 | + |
|
51 | + /** |
|
52 | + * max attendees that can register for event at one time |
|
53 | + * |
|
54 | + * @var int $max_attendees |
|
55 | + */ |
|
56 | + private $max_attendees = EE_INF; |
|
57 | + |
|
58 | + /** |
|
59 | + *@var string $date_format |
|
60 | + */ |
|
61 | + private $date_format; |
|
62 | + |
|
63 | + /** |
|
64 | + *@var string $time_format |
|
65 | + */ |
|
66 | + private $time_format; |
|
67 | + |
|
68 | + |
|
69 | + |
|
70 | + /** |
|
71 | + * DisplayTicketSelector constructor. |
|
72 | + */ |
|
73 | + public function __construct() |
|
74 | + { |
|
75 | + $this->date_format = apply_filters( |
|
76 | + 'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format', |
|
77 | + get_option('date_format') |
|
78 | + ); |
|
79 | + $this->time_format = apply_filters( |
|
80 | + 'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format', |
|
81 | + get_option('time_format') |
|
82 | + ); |
|
83 | + } |
|
84 | + |
|
85 | + |
|
86 | + |
|
87 | + /** |
|
88 | + * @param boolean $iframe |
|
89 | + */ |
|
90 | + public function setIframe( $iframe = true ) |
|
91 | + { |
|
92 | + $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN ); |
|
93 | + } |
|
94 | + |
|
95 | + |
|
96 | + /** |
|
97 | + * finds and sets the \EE_Event object for use throughout class |
|
98 | + * |
|
99 | + * @param mixed $event |
|
100 | + * @return bool |
|
101 | + * @throws EE_Error |
|
102 | + */ |
|
103 | + protected function setEvent( $event = null ) |
|
104 | + { |
|
105 | + if ( $event === null ) { |
|
106 | + global $post; |
|
107 | + $event = $post; |
|
108 | + } |
|
109 | + if ( $event instanceof EE_Event ) { |
|
110 | + $this->event = $event; |
|
111 | + } else if ( $event instanceof WP_Post ) { |
|
112 | + if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) { |
|
113 | + $this->event = $event->EE_Event; |
|
114 | + } else if ( $event->post_type === 'espresso_events' ) { |
|
115 | + $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event ); |
|
116 | + $this->event = $event->EE_Event; |
|
117 | + } |
|
118 | + } else { |
|
119 | + $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' ); |
|
120 | + $dev_msg = $user_msg . __( |
|
121 | + 'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.', |
|
122 | + 'event_espresso' |
|
123 | + ); |
|
124 | + EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ ); |
|
125 | + return false; |
|
126 | + } |
|
127 | + return true; |
|
128 | + } |
|
129 | + |
|
130 | + |
|
131 | + |
|
132 | + /** |
|
133 | + * @return int |
|
134 | + */ |
|
135 | + public function getMaxAttendees() |
|
136 | + { |
|
137 | + return $this->max_attendees; |
|
138 | + } |
|
139 | + |
|
140 | + |
|
141 | + |
|
142 | + /** |
|
143 | + * @param int $max_attendees |
|
144 | + */ |
|
145 | + public function setMaxAttendees($max_attendees) |
|
146 | + { |
|
147 | + $this->max_attendees = absint( |
|
148 | + apply_filters( |
|
149 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets', |
|
150 | + $max_attendees |
|
151 | + ) |
|
152 | + ); |
|
153 | + } |
|
154 | + |
|
155 | + |
|
156 | + |
|
157 | + /** |
|
158 | + * creates buttons for selecting number of attendees for an event |
|
159 | + * |
|
160 | + * @param WP_Post|int $event |
|
161 | + * @param bool $view_details |
|
162 | + * @return string |
|
163 | + * @throws EE_Error |
|
164 | + */ |
|
165 | + public function display( $event = null, $view_details = false ) |
|
166 | + { |
|
167 | + // reset filter for displaying submit button |
|
168 | + remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' ); |
|
169 | + // poke and prod incoming event till it tells us what it is |
|
170 | + if ( ! $this->setEvent( $event ) ) { |
|
171 | + return false; |
|
172 | + } |
|
173 | + // begin gathering template arguments by getting event status |
|
174 | + $template_args = array( 'event_status' => $this->event->get_active_status() ); |
|
175 | + if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) { |
|
176 | + return ! is_single() ? $this->displayViewDetailsButton() : ''; |
|
177 | + } |
|
178 | + // filter the maximum qty that can appear in the Ticket Selector qty dropdowns |
|
179 | + $this->setMaxAttendees($this->event->additional_limit()); |
|
180 | + if ($this->getMaxAttendees() < 1) { |
|
181 | + return $this->ticketSalesClosedMessage(); |
|
182 | + } |
|
183 | + // is the event expired ? |
|
184 | + $template_args['event_is_expired'] = $this->event->is_expired(); |
|
185 | + if ( $template_args[ 'event_is_expired' ] ) { |
|
186 | + return $this->expiredEventMessage(); |
|
187 | + } |
|
188 | + // get all tickets for this event ordered by the datetime |
|
189 | + $tickets = $this->getTickets(); |
|
190 | + if (count($tickets) < 1) { |
|
191 | + return $this->noTicketAvailableMessage(); |
|
192 | + } |
|
193 | + if (EED_Events_Archive::is_iframe()){ |
|
194 | + $this->setIframe(); |
|
195 | + } |
|
196 | + // redirecting to another site for registration ?? |
|
197 | + $external_url = (string) $this->event->external_url(); |
|
198 | + // if redirecting to another site for registration, then we don't load the TS |
|
199 | + $ticket_selector = $external_url |
|
200 | + ? $this->externalEventRegistration() |
|
201 | + : $this->loadTicketSelector($tickets,$template_args); |
|
202 | + // now set up the form (but not for the admin) |
|
203 | + $ticket_selector = ! is_admin() |
|
204 | + ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
205 | + : $ticket_selector; |
|
206 | + // submit button and form close tag |
|
207 | + $ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : ''; |
|
208 | + return $ticket_selector; |
|
209 | + } |
|
210 | + |
|
211 | + |
|
212 | + |
|
213 | + /** |
|
214 | + * displayTicketSelector |
|
215 | + * examines the event properties and determines whether a Ticket Selector should be displayed |
|
216 | + * |
|
217 | + * @param WP_Post|int $event |
|
218 | + * @param string $_event_active_status |
|
219 | + * @param bool $view_details |
|
220 | + * @return bool |
|
221 | + * @throws EE_Error |
|
222 | + */ |
|
223 | + protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details) |
|
224 | + { |
|
225 | + $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event; |
|
226 | + return ! is_admin() |
|
227 | + && ( |
|
228 | + ! $this->event->display_ticket_selector() |
|
229 | + || $view_details |
|
230 | + || post_password_required($event_post) |
|
231 | + || ( |
|
232 | + $_event_active_status !== EE_Datetime::active |
|
233 | + && $_event_active_status !== EE_Datetime::upcoming |
|
234 | + && $_event_active_status !== EE_Datetime::sold_out |
|
235 | + && ! ( |
|
236 | + $_event_active_status === EE_Datetime::inactive |
|
237 | + && is_user_logged_in() |
|
238 | + ) |
|
239 | + ) |
|
240 | + ); |
|
241 | + } |
|
242 | + |
|
243 | + |
|
244 | + |
|
245 | + /** |
|
246 | + * noTicketAvailableMessage |
|
247 | + * notice displayed if event is expired |
|
248 | + * |
|
249 | + * @return string |
|
250 | + * @throws EE_Error |
|
251 | + */ |
|
252 | + protected function expiredEventMessage() |
|
253 | + { |
|
254 | + return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
255 | + 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
|
256 | + 'event_espresso' |
|
257 | + ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
258 | + } |
|
259 | + |
|
260 | + |
|
261 | + |
|
262 | + /** |
|
263 | + * noTicketAvailableMessage |
|
264 | + * notice displayed if event has no more tickets available |
|
265 | + * |
|
266 | + * @return string |
|
267 | + * @throws EE_Error |
|
268 | + */ |
|
269 | + protected function noTicketAvailableMessage() |
|
270 | + { |
|
271 | + $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' ); |
|
272 | + if (current_user_can('edit_post', $this->event->ID())) { |
|
273 | + $no_ticket_available_msg .= sprintf( |
|
274 | + esc_html__( |
|
275 | + '%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s', |
|
276 | + 'event_espresso' |
|
277 | + ), |
|
278 | + '<div class="ee-attention" style="text-align: left;"><b>', |
|
279 | + '</b><br />', |
|
280 | + '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
281 | + '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->' |
|
282 | + ); |
|
283 | + } |
|
284 | + return ' |
|
285 | 285 | <div class="ee-event-expired-notice"> |
286 | 286 | <span class="important-notice">' . $no_ticket_available_msg . '</span> |
287 | 287 | </div><!-- .ee-event-expired-notice -->'; |
288 | - } |
|
289 | - |
|
290 | - |
|
291 | - |
|
292 | - /** |
|
293 | - * ticketSalesClosed |
|
294 | - * notice displayed if event ticket sales are turned off |
|
295 | - * |
|
296 | - * @return string |
|
297 | - * @throws EE_Error |
|
298 | - */ |
|
299 | - protected function ticketSalesClosedMessage() |
|
300 | - { |
|
301 | - $sales_closed_msg = esc_html__( |
|
302 | - 'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.', |
|
303 | - 'event_espresso' |
|
304 | - ); |
|
305 | - if (current_user_can('edit_post', $this->event->ID())) { |
|
306 | - $sales_closed_msg .= sprintf( |
|
307 | - esc_html__( |
|
308 | - '%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s', |
|
309 | - 'event_espresso' |
|
310 | - ), |
|
311 | - '<div class="ee-attention" style="text-align: left;"><b>', |
|
312 | - '</b><br />', |
|
313 | - '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
314 | - '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
|
315 | - ); |
|
316 | - } |
|
317 | - return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
318 | - } |
|
319 | - |
|
320 | - |
|
321 | - |
|
322 | - /** |
|
323 | - * getTickets |
|
324 | - * |
|
325 | - * @return \EE_Base_Class[]|\EE_Ticket[] |
|
326 | - * @throws EE_Error |
|
327 | - */ |
|
328 | - protected function getTickets() |
|
329 | - { |
|
330 | - $ticket_query_args = array( |
|
331 | - array('Datetime.EVT_ID' => $this->event->ID()), |
|
332 | - 'order_by' => array( |
|
333 | - 'TKT_order' => 'ASC', |
|
334 | - 'TKT_required' => 'DESC', |
|
335 | - 'TKT_start_date' => 'ASC', |
|
336 | - 'TKT_end_date' => 'ASC', |
|
337 | - 'Datetime.DTT_EVT_start' => 'DESC', |
|
338 | - ), |
|
339 | - ); |
|
340 | - if ( ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets) { |
|
341 | - //use the correct applicable time query depending on what version of core is being run. |
|
342 | - $current_time = method_exists('EEM_Datetime', 'current_time_for_query') |
|
343 | - ? time() |
|
344 | - : current_time('timestamp'); |
|
345 | - $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time); |
|
346 | - } |
|
347 | - return EEM_Ticket::instance()->get_all($ticket_query_args); |
|
348 | - } |
|
349 | - |
|
350 | - |
|
351 | - |
|
352 | - /** |
|
353 | - * loadTicketSelector |
|
354 | - * begins to assemble template arguments |
|
355 | - * and decides whether to load a "simple" ticket selector, or the standard |
|
356 | - * |
|
357 | - * @param \EE_Ticket[] $tickets |
|
358 | - * @param array $template_args |
|
359 | - * @return string |
|
360 | - * @throws EE_Error |
|
361 | - */ |
|
362 | - protected function loadTicketSelector(array $tickets, array $template_args) |
|
363 | - { |
|
364 | - $template_args['event'] = $this->event; |
|
365 | - $template_args['EVT_ID'] = $this->event->ID(); |
|
366 | - $template_args['event_is_expired'] = $this->event->is_expired(); |
|
367 | - $template_args['max_atndz'] = $this->getMaxAttendees(); |
|
368 | - $template_args['date_format'] = $this->date_format; |
|
369 | - $template_args['time_format'] = $this->time_format; |
|
370 | - /** |
|
371 | - * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected |
|
372 | - * |
|
373 | - * @since 4.9.13 |
|
374 | - * @param string '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to |
|
375 | - * @param int $EVT_ID The Event ID |
|
376 | - */ |
|
377 | - $template_args['anchor_id'] = apply_filters( |
|
378 | - 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
|
379 | - '#tkt-slctr-tbl-' . $this->event->ID(), |
|
380 | - $this->event->ID() |
|
381 | - ); |
|
382 | - $template_args['tickets'] = $tickets; |
|
383 | - $template_args['ticket_count'] = count($tickets); |
|
384 | - $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args); |
|
385 | - return $ticket_selector instanceof TicketSelectorSimple |
|
386 | - ? $ticket_selector |
|
387 | - : new TicketSelectorStandard( |
|
388 | - $this->event, |
|
389 | - $tickets, |
|
390 | - $this->getMaxAttendees(), |
|
391 | - $template_args, |
|
392 | - $this->date_format, |
|
393 | - $this->time_format |
|
394 | - ); |
|
395 | - } |
|
396 | - |
|
397 | - |
|
398 | - |
|
399 | - /** |
|
400 | - * simpleTicketSelector |
|
401 | - * there's one ticket, and max attendees is set to one, |
|
402 | - * so if the event is free, then this is a "simple" ticket selector |
|
403 | - * a.k.a. "Dude Where's my Ticket Selector?" |
|
404 | - * |
|
405 | - * @param \EE_Ticket[] $tickets |
|
406 | - * @param array $template_args |
|
407 | - * @return string |
|
408 | - * @throws EE_Error |
|
409 | - */ |
|
410 | - protected function simpleTicketSelector($tickets, array $template_args) |
|
411 | - { |
|
412 | - // if there is only ONE ticket with a max qty of ONE |
|
413 | - if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) { |
|
414 | - return ''; |
|
415 | - } |
|
416 | - /** @var \EE_Ticket $ticket */ |
|
417 | - $ticket = reset($tickets); |
|
418 | - // if the ticket is free... then not much need for the ticket selector |
|
419 | - if ( |
|
420 | - apply_filters( |
|
421 | - 'FHEE__ticket_selector_chart_template__hide_ticket_selector', |
|
422 | - $ticket->is_free(), |
|
423 | - $this->event->ID() |
|
424 | - ) |
|
425 | - ) { |
|
426 | - return new TicketSelectorSimple( |
|
427 | - $this->event, |
|
428 | - $ticket, |
|
429 | - $this->getMaxAttendees(), |
|
430 | - $template_args |
|
431 | - ); |
|
432 | - } |
|
433 | - return ''; |
|
434 | - } |
|
435 | - |
|
436 | - |
|
437 | - |
|
438 | - /** |
|
439 | - * externalEventRegistration |
|
440 | - * |
|
441 | - * @return string |
|
442 | - */ |
|
443 | - public function externalEventRegistration() |
|
444 | - { |
|
445 | - // if not we still need to trigger the display of the submit button |
|
446 | - add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
447 | - //display notice to admin that registration is external |
|
448 | - return is_admin() |
|
449 | - ? esc_html__( |
|
450 | - 'Registration is at an external URL for this event.', |
|
451 | - 'event_espresso' |
|
452 | - ) |
|
453 | - : ''; |
|
454 | - } |
|
455 | - |
|
456 | - |
|
457 | - |
|
458 | - /** |
|
459 | - * formOpen |
|
460 | - * |
|
461 | - * @param int $ID |
|
462 | - * @param string $external_url |
|
463 | - * @return string |
|
464 | - */ |
|
465 | - public function formOpen( $ID = 0, $external_url = '' ) |
|
466 | - { |
|
467 | - // if redirecting, we don't need any anything else |
|
468 | - if ( $external_url ) { |
|
469 | - $html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"'; |
|
470 | - // open link in new window ? |
|
471 | - $html .= apply_filters( |
|
472 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
|
473 | - EED_Events_Archive::is_iframe() |
|
474 | - ) |
|
475 | - ? ' target="_blank"' |
|
476 | - : ''; |
|
477 | - $html .= '>'; |
|
478 | - $query_args = EEH_URL::get_query_string( $external_url ); |
|
479 | - foreach ( (array)$query_args as $query_arg => $value ) { |
|
480 | - $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
481 | - } |
|
482 | - return $html; |
|
483 | - } |
|
484 | - // if there is no submit button, then don't start building a form |
|
485 | - // because the "View Details" button will build its own form |
|
486 | - if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) { |
|
487 | - return ''; |
|
488 | - } |
|
489 | - $checkout_url = EEH_Event_View::event_link_url( $ID ); |
|
490 | - if ( ! $checkout_url ) { |
|
491 | - EE_Error::add_error( |
|
492 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
493 | - __FILE__, |
|
494 | - __FUNCTION__, |
|
495 | - __LINE__ |
|
496 | - ); |
|
497 | - } |
|
498 | - // set no cache headers and constants |
|
499 | - EE_System::do_not_cache(); |
|
500 | - $extra_params = $this->iframe ? ' target="_blank"' : ''; |
|
501 | - $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>'; |
|
502 | - $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
|
503 | - $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event ); |
|
504 | - return $html; |
|
505 | - } |
|
506 | - |
|
507 | - |
|
508 | - |
|
509 | - /** |
|
510 | - * displaySubmitButton |
|
511 | - * |
|
512 | - * @param string $external_url |
|
513 | - * @return string |
|
514 | - * @throws EE_Error |
|
515 | - */ |
|
516 | - public function displaySubmitButton($external_url = '') |
|
517 | - { |
|
518 | - $html = ''; |
|
519 | - if ( ! is_admin()) { |
|
520 | - // standard TS displayed with submit button, ie: "Register Now" |
|
521 | - if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
522 | - $html .= $this->displayRegisterNowButton(); |
|
523 | - $html .= empty($external_url) |
|
524 | - ? $this->ticketSelectorEndDiv() |
|
525 | - : $this->clearTicketSelector(); |
|
526 | - $html .= '<br/>' . $this->formClose(); |
|
527 | - } else if ($this->getMaxAttendees() === 1) { |
|
528 | - // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
|
529 | - if ($this->event->is_sold_out()) { |
|
530 | - // then instead of a View Details or Submit button, just display a "Sold Out" message |
|
531 | - $html .= apply_filters( |
|
532 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg', |
|
533 | - sprintf( |
|
534 | - __( |
|
535 | - '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s', |
|
536 | - 'event_espresso' |
|
537 | - ), |
|
538 | - '<p class="no-ticket-selector-msg clear-float">', |
|
539 | - $this->event->name(), |
|
540 | - '</p>', |
|
541 | - '<br />' |
|
542 | - ), |
|
543 | - $this->event |
|
544 | - ); |
|
545 | - if ( |
|
546 | - apply_filters( |
|
547 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
548 | - false, |
|
549 | - $this->event |
|
550 | - ) |
|
551 | - ) { |
|
552 | - $html .= $this->displayRegisterNowButton(); |
|
553 | - } |
|
554 | - // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
|
555 | - $html .= $this->ticketSelectorEndDiv(); |
|
556 | - } else if ( |
|
557 | - apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
|
558 | - && ! is_single() |
|
559 | - ) { |
|
560 | - // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event, |
|
561 | - // but no tickets are available, so display event's "View Details" button. |
|
562 | - // it is being viewed via somewhere other than a single post |
|
563 | - $html .= $this->displayViewDetailsButton(true); |
|
564 | - } else { |
|
565 | - $html .= $this->ticketSelectorEndDiv(); |
|
566 | - } |
|
567 | - } else if (is_archive()) { |
|
568 | - // event list, no tickets available so display event's "View Details" button |
|
569 | - $html .= $this->ticketSelectorEndDiv(); |
|
570 | - $html .= $this->displayViewDetailsButton(); |
|
571 | - } else { |
|
572 | - if ( |
|
573 | - apply_filters( |
|
574 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
575 | - false, |
|
576 | - $this->event |
|
577 | - ) |
|
578 | - ) { |
|
579 | - $html .= $this->displayRegisterNowButton(); |
|
580 | - } |
|
581 | - // no submit or view details button, and no additional content |
|
582 | - $html .= $this->ticketSelectorEndDiv(); |
|
583 | - } |
|
584 | - if ( ! $this->iframe && ! is_archive()) { |
|
585 | - $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector')); |
|
586 | - } |
|
587 | - } |
|
588 | - return $html; |
|
589 | - } |
|
590 | - |
|
591 | - |
|
592 | - |
|
593 | - /** |
|
594 | - * @return string |
|
595 | - * @throws EE_Error |
|
596 | - */ |
|
597 | - public function displayRegisterNowButton() |
|
598 | - { |
|
599 | - $btn_text = apply_filters( |
|
600 | - 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text', |
|
601 | - __('Register Now', 'event_espresso'), |
|
602 | - $this->event |
|
603 | - ); |
|
604 | - $external_url = $this->event->external_url(); |
|
605 | - $html = EEH_HTML::div( |
|
606 | - '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
607 | - ); |
|
608 | - $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
609 | - $html .= ' class="ticket-selector-submit-btn '; |
|
610 | - $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
|
611 | - $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
612 | - $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
613 | - $html .= apply_filters( |
|
614 | - 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
|
615 | - '', |
|
616 | - $this->event |
|
617 | - ); |
|
618 | - return $html; |
|
619 | - } |
|
620 | - |
|
621 | - |
|
622 | - /** |
|
623 | - * displayViewDetailsButton |
|
624 | - * |
|
625 | - * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event |
|
626 | - * (ie: $_max_atndz === 1) where there are no available tickets, |
|
627 | - * either because they are sold out, expired, or not yet on sale. |
|
628 | - * In this case, we need to close the form BEFORE adding any closing divs |
|
629 | - * @return string |
|
630 | - * @throws EE_Error |
|
631 | - */ |
|
632 | - public function displayViewDetailsButton( $DWMTS = false ) |
|
633 | - { |
|
634 | - if ( ! $this->event->get_permalink() ) { |
|
635 | - EE_Error::add_error( |
|
636 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
637 | - __FILE__, __FUNCTION__, __LINE__ |
|
638 | - ); |
|
639 | - } |
|
640 | - $view_details_btn = '<form method="POST" action="'; |
|
641 | - $view_details_btn .= apply_filters( |
|
642 | - 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url', |
|
643 | - $this->event->get_permalink(), |
|
644 | - $this->event |
|
645 | - ); |
|
646 | - $view_details_btn .= '"'; |
|
647 | - // open link in new window ? |
|
648 | - $view_details_btn .= apply_filters( |
|
649 | - 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank', |
|
650 | - EED_Events_Archive::is_iframe() |
|
651 | - ) |
|
652 | - ? ' target="_blank"' |
|
653 | - : ''; |
|
654 | - $view_details_btn .='>'; |
|
655 | - $btn_text = apply_filters( |
|
656 | - 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
|
657 | - esc_html__('View Details', 'event_espresso'), |
|
658 | - $this->event |
|
659 | - ); |
|
660 | - $view_details_btn .= '<input id="ticket-selector-submit-' |
|
661 | - . $this->event->ID() |
|
662 | - . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
|
663 | - . $btn_text |
|
664 | - . '" />'; |
|
665 | - $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event ); |
|
666 | - if ($DWMTS) { |
|
667 | - $view_details_btn .= $this->formClose(); |
|
668 | - $view_details_btn .= $this->ticketSelectorEndDiv(); |
|
669 | - $view_details_btn .= '<br/>'; |
|
670 | - } else { |
|
671 | - $view_details_btn .= $this->clearTicketSelector(); |
|
672 | - $view_details_btn .= '<br/>'; |
|
673 | - $view_details_btn .= $this->formClose(); |
|
674 | - } |
|
675 | - return $view_details_btn; |
|
676 | - } |
|
677 | - |
|
678 | - |
|
679 | - |
|
680 | - /** |
|
681 | - * @return string |
|
682 | - */ |
|
683 | - public function ticketSelectorEndDiv() |
|
684 | - { |
|
685 | - return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
686 | - } |
|
687 | - |
|
688 | - |
|
689 | - |
|
690 | - /** |
|
691 | - * @return string |
|
692 | - */ |
|
693 | - public function clearTicketSelector() |
|
694 | - { |
|
695 | - // standard TS displayed, appears after a "Register Now" or "view Details" button |
|
696 | - return '<div class="clear"></div><!-- clearTicketSelector -->'; |
|
697 | - } |
|
698 | - |
|
699 | - |
|
700 | - |
|
701 | - /** |
|
702 | - * @access public |
|
703 | - * @return string |
|
704 | - */ |
|
705 | - public function formClose() |
|
706 | - { |
|
707 | - return '</form>'; |
|
708 | - } |
|
288 | + } |
|
289 | + |
|
290 | + |
|
291 | + |
|
292 | + /** |
|
293 | + * ticketSalesClosed |
|
294 | + * notice displayed if event ticket sales are turned off |
|
295 | + * |
|
296 | + * @return string |
|
297 | + * @throws EE_Error |
|
298 | + */ |
|
299 | + protected function ticketSalesClosedMessage() |
|
300 | + { |
|
301 | + $sales_closed_msg = esc_html__( |
|
302 | + 'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.', |
|
303 | + 'event_espresso' |
|
304 | + ); |
|
305 | + if (current_user_can('edit_post', $this->event->ID())) { |
|
306 | + $sales_closed_msg .= sprintf( |
|
307 | + esc_html__( |
|
308 | + '%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s', |
|
309 | + 'event_espresso' |
|
310 | + ), |
|
311 | + '<div class="ee-attention" style="text-align: left;"><b>', |
|
312 | + '</b><br />', |
|
313 | + '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">', |
|
314 | + '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
|
315 | + ); |
|
316 | + } |
|
317 | + return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
318 | + } |
|
319 | + |
|
320 | + |
|
321 | + |
|
322 | + /** |
|
323 | + * getTickets |
|
324 | + * |
|
325 | + * @return \EE_Base_Class[]|\EE_Ticket[] |
|
326 | + * @throws EE_Error |
|
327 | + */ |
|
328 | + protected function getTickets() |
|
329 | + { |
|
330 | + $ticket_query_args = array( |
|
331 | + array('Datetime.EVT_ID' => $this->event->ID()), |
|
332 | + 'order_by' => array( |
|
333 | + 'TKT_order' => 'ASC', |
|
334 | + 'TKT_required' => 'DESC', |
|
335 | + 'TKT_start_date' => 'ASC', |
|
336 | + 'TKT_end_date' => 'ASC', |
|
337 | + 'Datetime.DTT_EVT_start' => 'DESC', |
|
338 | + ), |
|
339 | + ); |
|
340 | + if ( ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets) { |
|
341 | + //use the correct applicable time query depending on what version of core is being run. |
|
342 | + $current_time = method_exists('EEM_Datetime', 'current_time_for_query') |
|
343 | + ? time() |
|
344 | + : current_time('timestamp'); |
|
345 | + $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time); |
|
346 | + } |
|
347 | + return EEM_Ticket::instance()->get_all($ticket_query_args); |
|
348 | + } |
|
349 | + |
|
350 | + |
|
351 | + |
|
352 | + /** |
|
353 | + * loadTicketSelector |
|
354 | + * begins to assemble template arguments |
|
355 | + * and decides whether to load a "simple" ticket selector, or the standard |
|
356 | + * |
|
357 | + * @param \EE_Ticket[] $tickets |
|
358 | + * @param array $template_args |
|
359 | + * @return string |
|
360 | + * @throws EE_Error |
|
361 | + */ |
|
362 | + protected function loadTicketSelector(array $tickets, array $template_args) |
|
363 | + { |
|
364 | + $template_args['event'] = $this->event; |
|
365 | + $template_args['EVT_ID'] = $this->event->ID(); |
|
366 | + $template_args['event_is_expired'] = $this->event->is_expired(); |
|
367 | + $template_args['max_atndz'] = $this->getMaxAttendees(); |
|
368 | + $template_args['date_format'] = $this->date_format; |
|
369 | + $template_args['time_format'] = $this->time_format; |
|
370 | + /** |
|
371 | + * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected |
|
372 | + * |
|
373 | + * @since 4.9.13 |
|
374 | + * @param string '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to |
|
375 | + * @param int $EVT_ID The Event ID |
|
376 | + */ |
|
377 | + $template_args['anchor_id'] = apply_filters( |
|
378 | + 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
|
379 | + '#tkt-slctr-tbl-' . $this->event->ID(), |
|
380 | + $this->event->ID() |
|
381 | + ); |
|
382 | + $template_args['tickets'] = $tickets; |
|
383 | + $template_args['ticket_count'] = count($tickets); |
|
384 | + $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args); |
|
385 | + return $ticket_selector instanceof TicketSelectorSimple |
|
386 | + ? $ticket_selector |
|
387 | + : new TicketSelectorStandard( |
|
388 | + $this->event, |
|
389 | + $tickets, |
|
390 | + $this->getMaxAttendees(), |
|
391 | + $template_args, |
|
392 | + $this->date_format, |
|
393 | + $this->time_format |
|
394 | + ); |
|
395 | + } |
|
396 | + |
|
397 | + |
|
398 | + |
|
399 | + /** |
|
400 | + * simpleTicketSelector |
|
401 | + * there's one ticket, and max attendees is set to one, |
|
402 | + * so if the event is free, then this is a "simple" ticket selector |
|
403 | + * a.k.a. "Dude Where's my Ticket Selector?" |
|
404 | + * |
|
405 | + * @param \EE_Ticket[] $tickets |
|
406 | + * @param array $template_args |
|
407 | + * @return string |
|
408 | + * @throws EE_Error |
|
409 | + */ |
|
410 | + protected function simpleTicketSelector($tickets, array $template_args) |
|
411 | + { |
|
412 | + // if there is only ONE ticket with a max qty of ONE |
|
413 | + if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) { |
|
414 | + return ''; |
|
415 | + } |
|
416 | + /** @var \EE_Ticket $ticket */ |
|
417 | + $ticket = reset($tickets); |
|
418 | + // if the ticket is free... then not much need for the ticket selector |
|
419 | + if ( |
|
420 | + apply_filters( |
|
421 | + 'FHEE__ticket_selector_chart_template__hide_ticket_selector', |
|
422 | + $ticket->is_free(), |
|
423 | + $this->event->ID() |
|
424 | + ) |
|
425 | + ) { |
|
426 | + return new TicketSelectorSimple( |
|
427 | + $this->event, |
|
428 | + $ticket, |
|
429 | + $this->getMaxAttendees(), |
|
430 | + $template_args |
|
431 | + ); |
|
432 | + } |
|
433 | + return ''; |
|
434 | + } |
|
435 | + |
|
436 | + |
|
437 | + |
|
438 | + /** |
|
439 | + * externalEventRegistration |
|
440 | + * |
|
441 | + * @return string |
|
442 | + */ |
|
443 | + public function externalEventRegistration() |
|
444 | + { |
|
445 | + // if not we still need to trigger the display of the submit button |
|
446 | + add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
447 | + //display notice to admin that registration is external |
|
448 | + return is_admin() |
|
449 | + ? esc_html__( |
|
450 | + 'Registration is at an external URL for this event.', |
|
451 | + 'event_espresso' |
|
452 | + ) |
|
453 | + : ''; |
|
454 | + } |
|
455 | + |
|
456 | + |
|
457 | + |
|
458 | + /** |
|
459 | + * formOpen |
|
460 | + * |
|
461 | + * @param int $ID |
|
462 | + * @param string $external_url |
|
463 | + * @return string |
|
464 | + */ |
|
465 | + public function formOpen( $ID = 0, $external_url = '' ) |
|
466 | + { |
|
467 | + // if redirecting, we don't need any anything else |
|
468 | + if ( $external_url ) { |
|
469 | + $html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"'; |
|
470 | + // open link in new window ? |
|
471 | + $html .= apply_filters( |
|
472 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
|
473 | + EED_Events_Archive::is_iframe() |
|
474 | + ) |
|
475 | + ? ' target="_blank"' |
|
476 | + : ''; |
|
477 | + $html .= '>'; |
|
478 | + $query_args = EEH_URL::get_query_string( $external_url ); |
|
479 | + foreach ( (array)$query_args as $query_arg => $value ) { |
|
480 | + $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
481 | + } |
|
482 | + return $html; |
|
483 | + } |
|
484 | + // if there is no submit button, then don't start building a form |
|
485 | + // because the "View Details" button will build its own form |
|
486 | + if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) { |
|
487 | + return ''; |
|
488 | + } |
|
489 | + $checkout_url = EEH_Event_View::event_link_url( $ID ); |
|
490 | + if ( ! $checkout_url ) { |
|
491 | + EE_Error::add_error( |
|
492 | + esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
493 | + __FILE__, |
|
494 | + __FUNCTION__, |
|
495 | + __LINE__ |
|
496 | + ); |
|
497 | + } |
|
498 | + // set no cache headers and constants |
|
499 | + EE_System::do_not_cache(); |
|
500 | + $extra_params = $this->iframe ? ' target="_blank"' : ''; |
|
501 | + $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>'; |
|
502 | + $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
|
503 | + $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event ); |
|
504 | + return $html; |
|
505 | + } |
|
506 | + |
|
507 | + |
|
508 | + |
|
509 | + /** |
|
510 | + * displaySubmitButton |
|
511 | + * |
|
512 | + * @param string $external_url |
|
513 | + * @return string |
|
514 | + * @throws EE_Error |
|
515 | + */ |
|
516 | + public function displaySubmitButton($external_url = '') |
|
517 | + { |
|
518 | + $html = ''; |
|
519 | + if ( ! is_admin()) { |
|
520 | + // standard TS displayed with submit button, ie: "Register Now" |
|
521 | + if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
522 | + $html .= $this->displayRegisterNowButton(); |
|
523 | + $html .= empty($external_url) |
|
524 | + ? $this->ticketSelectorEndDiv() |
|
525 | + : $this->clearTicketSelector(); |
|
526 | + $html .= '<br/>' . $this->formClose(); |
|
527 | + } else if ($this->getMaxAttendees() === 1) { |
|
528 | + // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
|
529 | + if ($this->event->is_sold_out()) { |
|
530 | + // then instead of a View Details or Submit button, just display a "Sold Out" message |
|
531 | + $html .= apply_filters( |
|
532 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg', |
|
533 | + sprintf( |
|
534 | + __( |
|
535 | + '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s', |
|
536 | + 'event_espresso' |
|
537 | + ), |
|
538 | + '<p class="no-ticket-selector-msg clear-float">', |
|
539 | + $this->event->name(), |
|
540 | + '</p>', |
|
541 | + '<br />' |
|
542 | + ), |
|
543 | + $this->event |
|
544 | + ); |
|
545 | + if ( |
|
546 | + apply_filters( |
|
547 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
548 | + false, |
|
549 | + $this->event |
|
550 | + ) |
|
551 | + ) { |
|
552 | + $html .= $this->displayRegisterNowButton(); |
|
553 | + } |
|
554 | + // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
|
555 | + $html .= $this->ticketSelectorEndDiv(); |
|
556 | + } else if ( |
|
557 | + apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
|
558 | + && ! is_single() |
|
559 | + ) { |
|
560 | + // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event, |
|
561 | + // but no tickets are available, so display event's "View Details" button. |
|
562 | + // it is being viewed via somewhere other than a single post |
|
563 | + $html .= $this->displayViewDetailsButton(true); |
|
564 | + } else { |
|
565 | + $html .= $this->ticketSelectorEndDiv(); |
|
566 | + } |
|
567 | + } else if (is_archive()) { |
|
568 | + // event list, no tickets available so display event's "View Details" button |
|
569 | + $html .= $this->ticketSelectorEndDiv(); |
|
570 | + $html .= $this->displayViewDetailsButton(); |
|
571 | + } else { |
|
572 | + if ( |
|
573 | + apply_filters( |
|
574 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button', |
|
575 | + false, |
|
576 | + $this->event |
|
577 | + ) |
|
578 | + ) { |
|
579 | + $html .= $this->displayRegisterNowButton(); |
|
580 | + } |
|
581 | + // no submit or view details button, and no additional content |
|
582 | + $html .= $this->ticketSelectorEndDiv(); |
|
583 | + } |
|
584 | + if ( ! $this->iframe && ! is_archive()) { |
|
585 | + $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector')); |
|
586 | + } |
|
587 | + } |
|
588 | + return $html; |
|
589 | + } |
|
590 | + |
|
591 | + |
|
592 | + |
|
593 | + /** |
|
594 | + * @return string |
|
595 | + * @throws EE_Error |
|
596 | + */ |
|
597 | + public function displayRegisterNowButton() |
|
598 | + { |
|
599 | + $btn_text = apply_filters( |
|
600 | + 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text', |
|
601 | + __('Register Now', 'event_espresso'), |
|
602 | + $this->event |
|
603 | + ); |
|
604 | + $external_url = $this->event->external_url(); |
|
605 | + $html = EEH_HTML::div( |
|
606 | + '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
607 | + ); |
|
608 | + $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
609 | + $html .= ' class="ticket-selector-submit-btn '; |
|
610 | + $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
|
611 | + $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
612 | + $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
613 | + $html .= apply_filters( |
|
614 | + 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
|
615 | + '', |
|
616 | + $this->event |
|
617 | + ); |
|
618 | + return $html; |
|
619 | + } |
|
620 | + |
|
621 | + |
|
622 | + /** |
|
623 | + * displayViewDetailsButton |
|
624 | + * |
|
625 | + * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event |
|
626 | + * (ie: $_max_atndz === 1) where there are no available tickets, |
|
627 | + * either because they are sold out, expired, or not yet on sale. |
|
628 | + * In this case, we need to close the form BEFORE adding any closing divs |
|
629 | + * @return string |
|
630 | + * @throws EE_Error |
|
631 | + */ |
|
632 | + public function displayViewDetailsButton( $DWMTS = false ) |
|
633 | + { |
|
634 | + if ( ! $this->event->get_permalink() ) { |
|
635 | + EE_Error::add_error( |
|
636 | + esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
637 | + __FILE__, __FUNCTION__, __LINE__ |
|
638 | + ); |
|
639 | + } |
|
640 | + $view_details_btn = '<form method="POST" action="'; |
|
641 | + $view_details_btn .= apply_filters( |
|
642 | + 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url', |
|
643 | + $this->event->get_permalink(), |
|
644 | + $this->event |
|
645 | + ); |
|
646 | + $view_details_btn .= '"'; |
|
647 | + // open link in new window ? |
|
648 | + $view_details_btn .= apply_filters( |
|
649 | + 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank', |
|
650 | + EED_Events_Archive::is_iframe() |
|
651 | + ) |
|
652 | + ? ' target="_blank"' |
|
653 | + : ''; |
|
654 | + $view_details_btn .='>'; |
|
655 | + $btn_text = apply_filters( |
|
656 | + 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
|
657 | + esc_html__('View Details', 'event_espresso'), |
|
658 | + $this->event |
|
659 | + ); |
|
660 | + $view_details_btn .= '<input id="ticket-selector-submit-' |
|
661 | + . $this->event->ID() |
|
662 | + . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
|
663 | + . $btn_text |
|
664 | + . '" />'; |
|
665 | + $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event ); |
|
666 | + if ($DWMTS) { |
|
667 | + $view_details_btn .= $this->formClose(); |
|
668 | + $view_details_btn .= $this->ticketSelectorEndDiv(); |
|
669 | + $view_details_btn .= '<br/>'; |
|
670 | + } else { |
|
671 | + $view_details_btn .= $this->clearTicketSelector(); |
|
672 | + $view_details_btn .= '<br/>'; |
|
673 | + $view_details_btn .= $this->formClose(); |
|
674 | + } |
|
675 | + return $view_details_btn; |
|
676 | + } |
|
677 | + |
|
678 | + |
|
679 | + |
|
680 | + /** |
|
681 | + * @return string |
|
682 | + */ |
|
683 | + public function ticketSelectorEndDiv() |
|
684 | + { |
|
685 | + return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
686 | + } |
|
687 | + |
|
688 | + |
|
689 | + |
|
690 | + /** |
|
691 | + * @return string |
|
692 | + */ |
|
693 | + public function clearTicketSelector() |
|
694 | + { |
|
695 | + // standard TS displayed, appears after a "Register Now" or "view Details" button |
|
696 | + return '<div class="clear"></div><!-- clearTicketSelector -->'; |
|
697 | + } |
|
698 | + |
|
699 | + |
|
700 | + |
|
701 | + /** |
|
702 | + * @access public |
|
703 | + * @return string |
|
704 | + */ |
|
705 | + public function formClose() |
|
706 | + { |
|
707 | + return '</form>'; |
|
708 | + } |
|
709 | 709 | |
710 | 710 | |
711 | 711 |
@@ -15,8 +15,8 @@ discard block |
||
15 | 15 | use EEM_Ticket; |
16 | 16 | use WP_Post; |
17 | 17 | |
18 | -if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) { |
|
19 | - exit( 'No direct script access allowed' ); |
|
18 | +if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
|
19 | + exit('No direct script access allowed'); |
|
20 | 20 | } |
21 | 21 | |
22 | 22 | |
@@ -87,9 +87,9 @@ discard block |
||
87 | 87 | /** |
88 | 88 | * @param boolean $iframe |
89 | 89 | */ |
90 | - public function setIframe( $iframe = true ) |
|
90 | + public function setIframe($iframe = true) |
|
91 | 91 | { |
92 | - $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN ); |
|
92 | + $this->iframe = filter_var($iframe, FILTER_VALIDATE_BOOLEAN); |
|
93 | 93 | } |
94 | 94 | |
95 | 95 | |
@@ -100,28 +100,28 @@ discard block |
||
100 | 100 | * @return bool |
101 | 101 | * @throws EE_Error |
102 | 102 | */ |
103 | - protected function setEvent( $event = null ) |
|
103 | + protected function setEvent($event = null) |
|
104 | 104 | { |
105 | - if ( $event === null ) { |
|
105 | + if ($event === null) { |
|
106 | 106 | global $post; |
107 | 107 | $event = $post; |
108 | 108 | } |
109 | - if ( $event instanceof EE_Event ) { |
|
109 | + if ($event instanceof EE_Event) { |
|
110 | 110 | $this->event = $event; |
111 | - } else if ( $event instanceof WP_Post ) { |
|
112 | - if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) { |
|
111 | + } else if ($event instanceof WP_Post) { |
|
112 | + if (isset($event->EE_Event) && $event->EE_Event instanceof EE_Event) { |
|
113 | 113 | $this->event = $event->EE_Event; |
114 | - } else if ( $event->post_type === 'espresso_events' ) { |
|
115 | - $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event ); |
|
114 | + } else if ($event->post_type === 'espresso_events') { |
|
115 | + $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object($event); |
|
116 | 116 | $this->event = $event->EE_Event; |
117 | 117 | } |
118 | 118 | } else { |
119 | - $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' ); |
|
120 | - $dev_msg = $user_msg . __( |
|
119 | + $user_msg = __('No Event object or an invalid Event object was supplied.', 'event_espresso'); |
|
120 | + $dev_msg = $user_msg.__( |
|
121 | 121 | 'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.', |
122 | 122 | 'event_espresso' |
123 | 123 | ); |
124 | - EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ ); |
|
124 | + EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__); |
|
125 | 125 | return false; |
126 | 126 | } |
127 | 127 | return true; |
@@ -162,17 +162,17 @@ discard block |
||
162 | 162 | * @return string |
163 | 163 | * @throws EE_Error |
164 | 164 | */ |
165 | - public function display( $event = null, $view_details = false ) |
|
165 | + public function display($event = null, $view_details = false) |
|
166 | 166 | { |
167 | 167 | // reset filter for displaying submit button |
168 | - remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' ); |
|
168 | + remove_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true'); |
|
169 | 169 | // poke and prod incoming event till it tells us what it is |
170 | - if ( ! $this->setEvent( $event ) ) { |
|
170 | + if ( ! $this->setEvent($event)) { |
|
171 | 171 | return false; |
172 | 172 | } |
173 | 173 | // begin gathering template arguments by getting event status |
174 | - $template_args = array( 'event_status' => $this->event->get_active_status() ); |
|
175 | - if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) { |
|
174 | + $template_args = array('event_status' => $this->event->get_active_status()); |
|
175 | + if ($this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details)) { |
|
176 | 176 | return ! is_single() ? $this->displayViewDetailsButton() : ''; |
177 | 177 | } |
178 | 178 | // filter the maximum qty that can appear in the Ticket Selector qty dropdowns |
@@ -182,7 +182,7 @@ discard block |
||
182 | 182 | } |
183 | 183 | // is the event expired ? |
184 | 184 | $template_args['event_is_expired'] = $this->event->is_expired(); |
185 | - if ( $template_args[ 'event_is_expired' ] ) { |
|
185 | + if ($template_args['event_is_expired']) { |
|
186 | 186 | return $this->expiredEventMessage(); |
187 | 187 | } |
188 | 188 | // get all tickets for this event ordered by the datetime |
@@ -190,7 +190,7 @@ discard block |
||
190 | 190 | if (count($tickets) < 1) { |
191 | 191 | return $this->noTicketAvailableMessage(); |
192 | 192 | } |
193 | - if (EED_Events_Archive::is_iframe()){ |
|
193 | + if (EED_Events_Archive::is_iframe()) { |
|
194 | 194 | $this->setIframe(); |
195 | 195 | } |
196 | 196 | // redirecting to another site for registration ?? |
@@ -198,10 +198,10 @@ discard block |
||
198 | 198 | // if redirecting to another site for registration, then we don't load the TS |
199 | 199 | $ticket_selector = $external_url |
200 | 200 | ? $this->externalEventRegistration() |
201 | - : $this->loadTicketSelector($tickets,$template_args); |
|
201 | + : $this->loadTicketSelector($tickets, $template_args); |
|
202 | 202 | // now set up the form (but not for the admin) |
203 | 203 | $ticket_selector = ! is_admin() |
204 | - ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector |
|
204 | + ? $this->formOpen($this->event->ID(), $external_url).$ticket_selector |
|
205 | 205 | : $ticket_selector; |
206 | 206 | // submit button and form close tag |
207 | 207 | $ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : ''; |
@@ -251,10 +251,10 @@ discard block |
||
251 | 251 | */ |
252 | 252 | protected function expiredEventMessage() |
253 | 253 | { |
254 | - return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__( |
|
254 | + return '<div class="ee-event-expired-notice"><span class="important-notice">'.esc_html__( |
|
255 | 255 | 'We\'re sorry, but all tickets sales have ended because the event is expired.', |
256 | 256 | 'event_espresso' |
257 | - ) . '</span></div><!-- .ee-event-expired-notice -->'; |
|
257 | + ).'</span></div><!-- .ee-event-expired-notice -->'; |
|
258 | 258 | } |
259 | 259 | |
260 | 260 | |
@@ -268,7 +268,7 @@ discard block |
||
268 | 268 | */ |
269 | 269 | protected function noTicketAvailableMessage() |
270 | 270 | { |
271 | - $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' ); |
|
271 | + $no_ticket_available_msg = esc_html__('We\'re sorry, but all ticket sales have ended.', 'event_espresso'); |
|
272 | 272 | if (current_user_can('edit_post', $this->event->ID())) { |
273 | 273 | $no_ticket_available_msg .= sprintf( |
274 | 274 | esc_html__( |
@@ -283,7 +283,7 @@ discard block |
||
283 | 283 | } |
284 | 284 | return ' |
285 | 285 | <div class="ee-event-expired-notice"> |
286 | - <span class="important-notice">' . $no_ticket_available_msg . '</span> |
|
286 | + <span class="important-notice">' . $no_ticket_available_msg.'</span> |
|
287 | 287 | </div><!-- .ee-event-expired-notice -->'; |
288 | 288 | } |
289 | 289 | |
@@ -314,7 +314,7 @@ discard block |
||
314 | 314 | '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->' |
315 | 315 | ); |
316 | 316 | } |
317 | - return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>'; |
|
317 | + return '<p><span class="important-notice">'.$sales_closed_msg.'</span></p>'; |
|
318 | 318 | } |
319 | 319 | |
320 | 320 | |
@@ -376,12 +376,12 @@ discard block |
||
376 | 376 | */ |
377 | 377 | $template_args['anchor_id'] = apply_filters( |
378 | 378 | 'FHEE__EE_Ticket_Selector__redirect_anchor_id', |
379 | - '#tkt-slctr-tbl-' . $this->event->ID(), |
|
379 | + '#tkt-slctr-tbl-'.$this->event->ID(), |
|
380 | 380 | $this->event->ID() |
381 | 381 | ); |
382 | 382 | $template_args['tickets'] = $tickets; |
383 | 383 | $template_args['ticket_count'] = count($tickets); |
384 | - $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args); |
|
384 | + $ticket_selector = $this->simpleTicketSelector($tickets, $template_args); |
|
385 | 385 | return $ticket_selector instanceof TicketSelectorSimple |
386 | 386 | ? $ticket_selector |
387 | 387 | : new TicketSelectorStandard( |
@@ -462,11 +462,11 @@ discard block |
||
462 | 462 | * @param string $external_url |
463 | 463 | * @return string |
464 | 464 | */ |
465 | - public function formOpen( $ID = 0, $external_url = '' ) |
|
465 | + public function formOpen($ID = 0, $external_url = '') |
|
466 | 466 | { |
467 | 467 | // if redirecting, we don't need any anything else |
468 | - if ( $external_url ) { |
|
469 | - $html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"'; |
|
468 | + if ($external_url) { |
|
469 | + $html = '<form method="GET" action="'.EEH_URL::refactor_url($external_url).'"'; |
|
470 | 470 | // open link in new window ? |
471 | 471 | $html .= apply_filters( |
472 | 472 | 'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank', |
@@ -475,21 +475,21 @@ discard block |
||
475 | 475 | ? ' target="_blank"' |
476 | 476 | : ''; |
477 | 477 | $html .= '>'; |
478 | - $query_args = EEH_URL::get_query_string( $external_url ); |
|
479 | - foreach ( (array)$query_args as $query_arg => $value ) { |
|
480 | - $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">'; |
|
478 | + $query_args = EEH_URL::get_query_string($external_url); |
|
479 | + foreach ((array) $query_args as $query_arg => $value) { |
|
480 | + $html .= '<input type="hidden" name="'.$query_arg.'" value="'.$value.'">'; |
|
481 | 481 | } |
482 | 482 | return $html; |
483 | 483 | } |
484 | 484 | // if there is no submit button, then don't start building a form |
485 | 485 | // because the "View Details" button will build its own form |
486 | - if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) { |
|
486 | + if ( ! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) { |
|
487 | 487 | return ''; |
488 | 488 | } |
489 | - $checkout_url = EEH_Event_View::event_link_url( $ID ); |
|
490 | - if ( ! $checkout_url ) { |
|
489 | + $checkout_url = EEH_Event_View::event_link_url($ID); |
|
490 | + if ( ! $checkout_url) { |
|
491 | 491 | EE_Error::add_error( |
492 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
492 | + esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
493 | 493 | __FILE__, |
494 | 494 | __FUNCTION__, |
495 | 495 | __LINE__ |
@@ -498,9 +498,9 @@ discard block |
||
498 | 498 | // set no cache headers and constants |
499 | 499 | EE_System::do_not_cache(); |
500 | 500 | $extra_params = $this->iframe ? ' target="_blank"' : ''; |
501 | - $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>'; |
|
501 | + $html = '<form method="POST" action="'.$checkout_url.'"'.$extra_params.'>'; |
|
502 | 502 | $html .= '<input type="hidden" name="ee" value="process_ticket_selections">'; |
503 | - $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event ); |
|
503 | + $html = apply_filters('FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event); |
|
504 | 504 | return $html; |
505 | 505 | } |
506 | 506 | |
@@ -523,7 +523,7 @@ discard block |
||
523 | 523 | $html .= empty($external_url) |
524 | 524 | ? $this->ticketSelectorEndDiv() |
525 | 525 | : $this->clearTicketSelector(); |
526 | - $html .= '<br/>' . $this->formClose(); |
|
526 | + $html .= '<br/>'.$this->formClose(); |
|
527 | 527 | } else if ($this->getMaxAttendees() === 1) { |
528 | 528 | // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1) |
529 | 529 | if ($this->event->is_sold_out()) { |
@@ -552,7 +552,7 @@ discard block |
||
552 | 552 | $html .= $this->displayRegisterNowButton(); |
553 | 553 | } |
554 | 554 | // sold out DWMTS event, no TS, no submit or view details button, but has additional content |
555 | - $html .= $this->ticketSelectorEndDiv(); |
|
555 | + $html .= $this->ticketSelectorEndDiv(); |
|
556 | 556 | } else if ( |
557 | 557 | apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false) |
558 | 558 | && ! is_single() |
@@ -603,13 +603,13 @@ discard block |
||
603 | 603 | ); |
604 | 604 | $external_url = $this->event->external_url(); |
605 | 605 | $html = EEH_HTML::div( |
606 | - '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
606 | + '', 'ticket-selector-submit-'.$this->event->ID().'-btn-wrap', 'ticket-selector-submit-btn-wrap' |
|
607 | 607 | ); |
608 | - $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"'; |
|
608 | + $html .= '<input id="ticket-selector-submit-'.$this->event->ID().'-btn"'; |
|
609 | 609 | $html .= ' class="ticket-selector-submit-btn '; |
610 | 610 | $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"'; |
611 | - $html .= ' type="submit" value="' . $btn_text . '" />'; |
|
612 | - $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->'; |
|
611 | + $html .= ' type="submit" value="'.$btn_text.'" />'; |
|
612 | + $html .= EEH_HTML::divx().'<!-- .ticket-selector-submit-btn-wrap -->'; |
|
613 | 613 | $html .= apply_filters( |
614 | 614 | 'FHEE__EE_Ticket_Selector__after_ticket_selector_submit', |
615 | 615 | '', |
@@ -629,11 +629,11 @@ discard block |
||
629 | 629 | * @return string |
630 | 630 | * @throws EE_Error |
631 | 631 | */ |
632 | - public function displayViewDetailsButton( $DWMTS = false ) |
|
632 | + public function displayViewDetailsButton($DWMTS = false) |
|
633 | 633 | { |
634 | - if ( ! $this->event->get_permalink() ) { |
|
634 | + if ( ! $this->event->get_permalink()) { |
|
635 | 635 | EE_Error::add_error( |
636 | - esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ), |
|
636 | + esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'), |
|
637 | 637 | __FILE__, __FUNCTION__, __LINE__ |
638 | 638 | ); |
639 | 639 | } |
@@ -651,7 +651,7 @@ discard block |
||
651 | 651 | ) |
652 | 652 | ? ' target="_blank"' |
653 | 653 | : ''; |
654 | - $view_details_btn .='>'; |
|
654 | + $view_details_btn .= '>'; |
|
655 | 655 | $btn_text = apply_filters( |
656 | 656 | 'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text', |
657 | 657 | esc_html__('View Details', 'event_espresso'), |
@@ -662,7 +662,7 @@ discard block |
||
662 | 662 | . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="' |
663 | 663 | . $btn_text |
664 | 664 | . '" />'; |
665 | - $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event ); |
|
665 | + $view_details_btn .= apply_filters('FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event); |
|
666 | 666 | if ($DWMTS) { |
667 | 667 | $view_details_btn .= $this->formClose(); |
668 | 668 | $view_details_btn .= $this->ticketSelectorEndDiv(); |
@@ -682,7 +682,7 @@ discard block |
||
682 | 682 | */ |
683 | 683 | public function ticketSelectorEndDiv() |
684 | 684 | { |
685 | - return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->'; |
|
685 | + return $this->clearTicketSelector().'</div><!-- ticketSelectorEndDiv -->'; |
|
686 | 686 | } |
687 | 687 | |
688 | 688 |
@@ -2,7 +2,7 @@ discard block |
||
2 | 2 | namespace EventEspresso\modules\ticket_selector; |
3 | 3 | |
4 | 4 | if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
5 | - exit('No direct script access allowed'); |
|
5 | + exit('No direct script access allowed'); |
|
6 | 6 | } |
7 | 7 | |
8 | 8 | |
@@ -19,570 +19,570 @@ discard block |
||
19 | 19 | class ProcessTicketSelector |
20 | 20 | { |
21 | 21 | |
22 | - /** |
|
23 | - * array of datetimes and the spaces available for them |
|
24 | - * |
|
25 | - * @access private |
|
26 | - * @var array |
|
27 | - */ |
|
28 | - private static $_available_spaces = array(); |
|
29 | - |
|
30 | - |
|
31 | - |
|
32 | - /** |
|
33 | - * cancelTicketSelections |
|
34 | - * |
|
35 | - * @return string |
|
36 | - */ |
|
37 | - public function cancelTicketSelections() |
|
38 | - { |
|
39 | - // check nonce |
|
40 | - if ( ! $this->processTicketSelectorNonce('cancel_ticket_selections')) { |
|
41 | - return false; |
|
42 | - } |
|
43 | - \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
44 | - if (\EE_Registry::instance()->REQ->is_set('event_id')) { |
|
45 | - wp_safe_redirect( |
|
46 | - \EEH_Event_View::event_link_url( |
|
47 | - \EE_Registry::instance()->REQ->get('event_id') |
|
48 | - ) |
|
49 | - ); |
|
50 | - } else { |
|
51 | - wp_safe_redirect( |
|
52 | - site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/') |
|
53 | - ); |
|
54 | - } |
|
55 | - exit(); |
|
56 | - } |
|
57 | - |
|
58 | - |
|
59 | - |
|
60 | - /** |
|
61 | - * processTicketSelectorNonce |
|
62 | - * |
|
63 | - * @param string $nonce_name |
|
64 | - * @param string $id |
|
65 | - * @return bool |
|
66 | - */ |
|
67 | - private function processTicketSelectorNonce($nonce_name, $id = '') |
|
68 | - { |
|
69 | - $nonce_name_with_id = ! empty($id) ? "{$nonce_name}_nonce_{$id}" : "{$nonce_name}_nonce"; |
|
70 | - if ( |
|
71 | - ! is_admin() |
|
72 | - && ( |
|
73 | - ! \EE_Registry::instance()->REQ->is_set($nonce_name_with_id) |
|
74 | - || ! wp_verify_nonce( |
|
75 | - \EE_Registry::instance()->REQ->get($nonce_name_with_id), |
|
76 | - $nonce_name |
|
77 | - ) |
|
78 | - ) |
|
79 | - ) { |
|
80 | - \EE_Error::add_error( |
|
81 | - sprintf( |
|
82 | - __( |
|
83 | - 'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.', |
|
84 | - 'event_espresso' |
|
85 | - ), |
|
86 | - '<br/>' |
|
87 | - ), |
|
88 | - __FILE__, |
|
89 | - __FUNCTION__, |
|
90 | - __LINE__ |
|
91 | - ); |
|
92 | - return false; |
|
93 | - } |
|
94 | - return true; |
|
95 | - } |
|
96 | - |
|
97 | - |
|
98 | - |
|
99 | - /** |
|
100 | - * process_ticket_selections |
|
101 | - * |
|
102 | - * @return array|bool |
|
103 | - * @throws \EE_Error |
|
104 | - */ |
|
105 | - public function processTicketSelections() |
|
106 | - { |
|
107 | - do_action('EED_Ticket_Selector__process_ticket_selections__before'); |
|
108 | - // do we have an event id? |
|
109 | - if ( ! \EE_Registry::instance()->REQ->is_set('tkt-slctr-event-id')) { |
|
110 | - // $_POST['tkt-slctr-event-id'] was not set ?!?!?!? |
|
111 | - \EE_Error::add_error( |
|
112 | - sprintf( |
|
113 | - __( |
|
114 | - 'An event id was not provided or was not received.%sPlease click the back button on your browser and try again.', |
|
115 | - 'event_espresso' |
|
116 | - ), |
|
117 | - '<br/>' |
|
118 | - ), |
|
119 | - __FILE__, |
|
120 | - __FUNCTION__, |
|
121 | - __LINE__ |
|
122 | - ); |
|
123 | - } |
|
124 | - //if event id is valid |
|
125 | - $id = absint(\EE_Registry::instance()->REQ->get('tkt-slctr-event-id')); |
|
126 | - // d( \EE_Registry::instance()->REQ ); |
|
127 | - self::$_available_spaces = array( |
|
128 | - 'tickets' => array(), |
|
129 | - 'datetimes' => array(), |
|
130 | - ); |
|
131 | - //we should really only have 1 registration in the works now (ie, no MER) so clear any previous items in the cart. |
|
132 | - // When MER happens this will probably need to be tweaked, possibly wrapped in a conditional checking for some constant defined in MER etc. |
|
133 | - \EE_Registry::instance()->load_core('Session'); |
|
134 | - // unless otherwise requested, clear the session |
|
135 | - if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) { |
|
136 | - \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
137 | - } |
|
138 | - //d( \EE_Registry::instance()->SSN ); |
|
139 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
140 | - // validate/sanitize data |
|
141 | - $valid = $this->validatePostData($id); |
|
142 | - //EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
143 | - //EEH_Debug_Tools::printr( $valid, '$valid', __FILE__, __LINE__ ); |
|
144 | - //EEH_Debug_Tools::printr( $valid[ 'total_tickets' ], 'total_tickets', __FILE__, __LINE__ ); |
|
145 | - //EEH_Debug_Tools::printr( $valid[ 'max_atndz' ], 'max_atndz', __FILE__, __LINE__ ); |
|
146 | - //check total tickets ordered vs max number of attendees that can register |
|
147 | - if ($valid['total_tickets'] > $valid['max_atndz']) { |
|
148 | - // ordering too many tickets !!! |
|
149 | - $total_tickets_string = _n( |
|
150 | - 'You have attempted to purchase %s ticket.', |
|
151 | - 'You have attempted to purchase %s tickets.', |
|
152 | - $valid['total_tickets'], |
|
153 | - 'event_espresso' |
|
154 | - ); |
|
155 | - $limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']); |
|
156 | - // dev only message |
|
157 | - $max_atndz_string = _n( |
|
158 | - 'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
159 | - 'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
160 | - $valid['max_atndz'], |
|
161 | - 'event_espresso' |
|
162 | - ); |
|
163 | - $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']); |
|
164 | - \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__); |
|
165 | - } else { |
|
166 | - // all data appears to be valid |
|
167 | - $tckts_slctd = false; |
|
168 | - $tickets_added = 0; |
|
169 | - $valid = apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data', $valid); |
|
170 | - if ($valid['total_tickets'] > 0) { |
|
171 | - // load cart |
|
172 | - \EE_Registry::instance()->load_core('Cart'); |
|
173 | - // cycle thru the number of data rows sent from the event listing |
|
174 | - for ($x = 0; $x < $valid['rows']; $x++) { |
|
175 | - // does this row actually contain a ticket quantity? |
|
176 | - if (isset($valid['qty'][$x]) && $valid['qty'][$x] > 0) { |
|
177 | - // YES we have a ticket quantity |
|
178 | - $tckts_slctd = true; |
|
179 | - // d( $valid['ticket_obj'][$x] ); |
|
180 | - if ($valid['ticket_obj'][$x] instanceof \EE_Ticket) { |
|
181 | - // then add ticket to cart |
|
182 | - $tickets_added += $this->addTicketToCart( |
|
183 | - $valid['ticket_obj'][$x], |
|
184 | - $valid['qty'][$x] |
|
185 | - ); |
|
186 | - if (\EE_Error::has_error()) { |
|
187 | - break; |
|
188 | - } |
|
189 | - } else { |
|
190 | - // nothing added to cart retrieved |
|
191 | - \EE_Error::add_error( |
|
192 | - sprintf( |
|
193 | - __( |
|
194 | - 'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.', |
|
195 | - 'event_espresso' |
|
196 | - ), |
|
197 | - '<br/>' |
|
198 | - ), |
|
199 | - __FILE__, __FUNCTION__, __LINE__ |
|
200 | - ); |
|
201 | - } |
|
202 | - } |
|
203 | - } |
|
204 | - } |
|
205 | - do_action( |
|
206 | - 'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart', |
|
207 | - \EE_Registry::instance()->CART, |
|
208 | - $this |
|
209 | - ); |
|
210 | - //d( \EE_Registry::instance()->CART ); |
|
211 | - //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE |
|
212 | - if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tckts_slctd)) { |
|
213 | - if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) { |
|
214 | - do_action( |
|
215 | - 'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout', |
|
216 | - \EE_Registry::instance()->CART, |
|
217 | - $this |
|
218 | - ); |
|
219 | - \EE_Registry::instance()->CART->recalculate_all_cart_totals(); |
|
220 | - \EE_Registry::instance()->CART->save_cart(false); |
|
221 | - // exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<< OR HERE TO KILL REDIRECT AFTER CART UPDATE |
|
222 | - // just return TRUE for registrations being made from admin |
|
223 | - if (is_admin()) { |
|
224 | - return true; |
|
225 | - } |
|
226 | - \EE_Error::get_notices(false, true); |
|
227 | - wp_safe_redirect( |
|
228 | - apply_filters( |
|
229 | - 'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url', |
|
230 | - \EE_Registry::instance()->CFG->core->reg_page_url() |
|
231 | - ) |
|
232 | - ); |
|
233 | - exit(); |
|
234 | - } else { |
|
235 | - if ( ! \EE_Error::has_error() && ! \EE_Error::has_error(true, 'attention')) { |
|
236 | - // nothing added to cart |
|
237 | - \EE_Error::add_attention(__('No tickets were added for the event', 'event_espresso'), |
|
238 | - __FILE__, __FUNCTION__, __LINE__); |
|
239 | - } |
|
240 | - } |
|
241 | - } else { |
|
242 | - // no ticket quantities were selected |
|
243 | - \EE_Error::add_error(__('You need to select a ticket quantity before you can proceed.', |
|
244 | - 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
245 | - } |
|
246 | - } |
|
247 | - //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT |
|
248 | - // at this point, just return if registration is being made from admin |
|
249 | - if (is_admin()) { |
|
250 | - return false; |
|
251 | - } |
|
252 | - if ($valid['return_url']) { |
|
253 | - \EE_Error::get_notices(false, true); |
|
254 | - wp_safe_redirect($valid['return_url']); |
|
255 | - exit(); |
|
256 | - } elseif (isset($event_to_add['id'])) { |
|
257 | - \EE_Error::get_notices(false, true); |
|
258 | - wp_safe_redirect(get_permalink($event_to_add['id'])); |
|
259 | - exit(); |
|
260 | - } else { |
|
261 | - echo \EE_Error::get_notices(); |
|
262 | - } |
|
263 | - return false; |
|
264 | - } |
|
265 | - |
|
266 | - |
|
267 | - |
|
268 | - /** |
|
269 | - * validate_post_data |
|
270 | - * |
|
271 | - * @param int $id |
|
272 | - * @return array|FALSE |
|
273 | - */ |
|
274 | - private function validatePostData($id = 0) |
|
275 | - { |
|
276 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
277 | - if ( ! $id) { |
|
278 | - \EE_Error::add_error( |
|
279 | - __('The event id provided was not valid.', 'event_espresso'), |
|
280 | - __FILE__, |
|
281 | - __FUNCTION__, |
|
282 | - __LINE__ |
|
283 | - ); |
|
284 | - return false; |
|
285 | - } |
|
286 | - // start with an empty array() |
|
287 | - $valid_data = array(); |
|
288 | - // grab valid id |
|
289 | - $valid_data['id'] = $id; |
|
290 | - // array of other form names |
|
291 | - $inputs_to_clean = array( |
|
292 | - 'event_id' => 'tkt-slctr-event-id', |
|
293 | - 'max_atndz' => 'tkt-slctr-max-atndz-', |
|
294 | - 'rows' => 'tkt-slctr-rows-', |
|
295 | - 'qty' => 'tkt-slctr-qty-', |
|
296 | - 'ticket_id' => 'tkt-slctr-ticket-id-', |
|
297 | - 'return_url' => 'tkt-slctr-return-url-', |
|
298 | - ); |
|
299 | - // let's track the total number of tickets ordered.' |
|
300 | - $valid_data['total_tickets'] = 0; |
|
301 | - // cycle through $inputs_to_clean array |
|
302 | - foreach ($inputs_to_clean as $what => $input_to_clean) { |
|
303 | - // check for POST data |
|
304 | - if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) { |
|
305 | - // grab value |
|
306 | - $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id); |
|
307 | - switch ($what) { |
|
308 | - // integers |
|
309 | - case 'event_id': |
|
310 | - $valid_data[$what] = absint($input_value); |
|
311 | - // get event via the event id we put in the form |
|
312 | - $valid_data['event'] = \EE_Registry::instance() |
|
313 | - ->load_model('Event') |
|
314 | - ->get_one_by_ID($valid_data['event_id']); |
|
315 | - break; |
|
316 | - case 'rows': |
|
317 | - case 'max_atndz': |
|
318 | - $valid_data[$what] = absint($input_value); |
|
319 | - break; |
|
320 | - // arrays of integers |
|
321 | - case 'qty': |
|
322 | - /** @var array $row_qty */ |
|
323 | - $row_qty = $input_value; |
|
324 | - // if qty is coming from a radio button input, then we need to assemble an array of rows |
|
325 | - if ( ! is_array($row_qty)) { |
|
326 | - // get number of rows |
|
327 | - $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id) |
|
328 | - ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id)) |
|
329 | - : 1; |
|
330 | - // explode ints by the dash |
|
331 | - $row_qty = explode('-', $row_qty); |
|
332 | - $row = isset($row_qty[0]) ? absint($row_qty[0]) : 1; |
|
333 | - $qty = isset($row_qty[1]) ? absint($row_qty[1]) : 0; |
|
334 | - $row_qty = array($row => $qty); |
|
335 | - for ($x = 1; $x <= $rows; $x++) { |
|
336 | - if ( ! isset($row_qty[$x])) { |
|
337 | - $row_qty[$x] = 0; |
|
338 | - } |
|
339 | - } |
|
340 | - } |
|
341 | - ksort($row_qty); |
|
342 | - // cycle thru values |
|
343 | - foreach ($row_qty as $qty) { |
|
344 | - $qty = absint($qty); |
|
345 | - // sanitize as integers |
|
346 | - $valid_data[$what][] = $qty; |
|
347 | - $valid_data['total_tickets'] += $qty; |
|
348 | - } |
|
349 | - break; |
|
350 | - // array of integers |
|
351 | - case 'ticket_id': |
|
352 | - $value_array = array(); |
|
353 | - // cycle thru values |
|
354 | - foreach ((array)$input_value as $key => $value) { |
|
355 | - // allow only numbers, letters, spaces, commas and dashes |
|
356 | - $value_array[$key] = wp_strip_all_tags($value); |
|
357 | - // get ticket via the ticket id we put in the form |
|
358 | - $ticket_obj = \EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($value); |
|
359 | - $valid_data['ticket_obj'][$key] = $ticket_obj; |
|
360 | - } |
|
361 | - $valid_data[$what] = $value_array; |
|
362 | - break; |
|
363 | - case 'return_url' : |
|
364 | - // grab and sanitize return-url |
|
365 | - $input_value = esc_url_raw($input_value); |
|
366 | - // was the request coming from an iframe ? if so, then: |
|
367 | - if (strpos($input_value, 'event_list=iframe')) { |
|
368 | - // get anchor fragment |
|
369 | - $input_value = explode('#', $input_value); |
|
370 | - $input_value = end($input_value); |
|
371 | - // use event list url instead, but append anchor |
|
372 | - $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value; |
|
373 | - } |
|
374 | - $valid_data[$what] = $input_value; |
|
375 | - break; |
|
376 | - } // end switch $what |
|
377 | - } |
|
378 | - } // end foreach $inputs_to_clean |
|
379 | - return $valid_data; |
|
380 | - } |
|
381 | - |
|
382 | - |
|
383 | - |
|
384 | - /** |
|
385 | - * adds a ticket to the cart |
|
386 | - * |
|
387 | - * @param \EE_Ticket $ticket |
|
388 | - * @param int $qty |
|
389 | - * @return TRUE on success, FALSE on fail |
|
390 | - * @throws \EE_Error |
|
391 | - */ |
|
392 | - private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1) |
|
393 | - { |
|
394 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
395 | - // get the number of spaces left for this datetime ticket |
|
396 | - $available_spaces = $this->ticketDatetimeAvailability($ticket); |
|
397 | - // compare available spaces against the number of tickets being purchased |
|
398 | - if ($available_spaces >= $qty) { |
|
399 | - // allow addons to prevent a ticket from being added to cart |
|
400 | - if ( |
|
401 | - ! apply_filters( |
|
402 | - 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart', |
|
403 | - true, |
|
404 | - $ticket, |
|
405 | - $qty, |
|
406 | - $available_spaces |
|
407 | - ) |
|
408 | - ) { |
|
409 | - return false; |
|
410 | - } |
|
411 | - $qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket)); |
|
412 | - // add event to cart |
|
413 | - if (\EE_Registry::instance()->CART->add_ticket_to_cart($ticket, $qty)) { |
|
414 | - $this->recalculateTicketDatetimeAvailability($ticket, $qty); |
|
415 | - return true; |
|
416 | - } |
|
417 | - return false; |
|
418 | - } |
|
419 | - // tickets can not be purchased but let's find the exact number left |
|
420 | - // for the last ticket selected PRIOR to subtracting tickets |
|
421 | - $available_spaces = $this->ticketDatetimeAvailability($ticket, true); |
|
422 | - // greedy greedy greedy eh? |
|
423 | - if ($available_spaces > 0) { |
|
424 | - if ( |
|
425 | - apply_filters( |
|
426 | - 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_display_availability_error', |
|
427 | - true, |
|
428 | - $ticket, |
|
429 | - $qty, |
|
430 | - $available_spaces |
|
431 | - ) |
|
432 | - ) { |
|
433 | - $this->displayAvailabilityError($available_spaces); |
|
434 | - } |
|
435 | - } else { |
|
436 | - \EE_Error::add_error( |
|
437 | - __( |
|
438 | - 'We\'re sorry, but there are no available spaces left for this event at this particular date and time.', |
|
439 | - 'event_espresso' |
|
440 | - ), |
|
441 | - __FILE__, __FUNCTION__, __LINE__ |
|
442 | - ); |
|
443 | - } |
|
444 | - return false; |
|
445 | - } |
|
446 | - |
|
447 | - |
|
448 | - |
|
449 | - /** |
|
450 | - * @param int $available_spaces |
|
451 | - * @throws \EE_Error |
|
452 | - */ |
|
453 | - private function displayAvailabilityError($available_spaces = 1) |
|
454 | - { |
|
455 | - // add error messaging - we're using the _n function that will generate |
|
456 | - // the appropriate singular or plural message based on the number of $available_spaces |
|
457 | - if (\EE_Registry::instance()->CART->all_ticket_quantity_count()) { |
|
458 | - $msg = sprintf( |
|
459 | - _n( |
|
460 | - 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
461 | - 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
462 | - $available_spaces, |
|
463 | - 'event_espresso' |
|
464 | - ), |
|
465 | - $available_spaces, |
|
466 | - '<br />' |
|
467 | - ); |
|
468 | - } else { |
|
469 | - $msg = sprintf( |
|
470 | - _n( |
|
471 | - 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
472 | - 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
473 | - $available_spaces, |
|
474 | - 'event_espresso' |
|
475 | - ), |
|
476 | - $available_spaces, |
|
477 | - '<br />' |
|
478 | - ); |
|
479 | - } |
|
480 | - \EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
481 | - } |
|
482 | - |
|
483 | - |
|
484 | - |
|
485 | - /** |
|
486 | - * ticketDatetimeAvailability |
|
487 | - * creates an array of tickets plus all of the datetimes available to each ticket |
|
488 | - * and tracks the spaces remaining for each of those datetimes |
|
489 | - * |
|
490 | - * @param \EE_Ticket $ticket - selected ticket |
|
491 | - * @param bool $get_original_ticket_spaces |
|
492 | - * @return int |
|
493 | - * @throws \EE_Error |
|
494 | - */ |
|
495 | - private function ticketDatetimeAvailability(\EE_Ticket $ticket, $get_original_ticket_spaces = false) |
|
496 | - { |
|
497 | - // if the $_available_spaces array has not been set up yet... |
|
498 | - if ( ! isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
499 | - $this->setInitialTicketDatetimeAvailability($ticket); |
|
500 | - } |
|
501 | - $available_spaces = $ticket->qty() - $ticket->sold(); |
|
502 | - if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
503 | - // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
504 | - foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
505 | - // if we want the original datetime availability BEFORE we started subtracting tickets ? |
|
506 | - if ($get_original_ticket_spaces) { |
|
507 | - // then grab the available spaces from the "tickets" array |
|
508 | - // and compare with the above to get the lowest number |
|
509 | - $available_spaces = min( |
|
510 | - $available_spaces, |
|
511 | - self::$_available_spaces['tickets'][$ticket->ID()][$DTD_ID] |
|
512 | - ); |
|
513 | - } else { |
|
514 | - // we want the updated ticket availability as stored in the "datetimes" array |
|
515 | - $available_spaces = min($available_spaces, self::$_available_spaces['datetimes'][$DTD_ID]); |
|
516 | - } |
|
517 | - } |
|
518 | - } |
|
519 | - return $available_spaces; |
|
520 | - } |
|
521 | - |
|
522 | - |
|
523 | - |
|
524 | - /** |
|
525 | - * @param \EE_Ticket $ticket |
|
526 | - * @return void |
|
527 | - * @throws \EE_Error |
|
528 | - */ |
|
529 | - private function setInitialTicketDatetimeAvailability(\EE_Ticket $ticket) |
|
530 | - { |
|
531 | - // first, get all of the datetimes that are available to this ticket |
|
532 | - $datetimes = $ticket->get_many_related( |
|
533 | - 'Datetime', |
|
534 | - array( |
|
535 | - array( |
|
536 | - 'DTT_EVT_end' => array( |
|
537 | - '>=', |
|
538 | - \EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
539 | - ), |
|
540 | - ), |
|
541 | - 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
542 | - ) |
|
543 | - ); |
|
544 | - if ( ! empty($datetimes)) { |
|
545 | - // now loop thru all of the datetimes |
|
546 | - foreach ($datetimes as $datetime) { |
|
547 | - if ($datetime instanceof \EE_Datetime) { |
|
548 | - // the number of spaces available for the datetime without considering individual ticket quantities |
|
549 | - $spaces_remaining = $datetime->spaces_remaining(); |
|
550 | - // save the total available spaces ( the lesser of the ticket qty minus the number of tickets sold |
|
551 | - // or the datetime spaces remaining) to this ticket using the datetime ID as the key |
|
552 | - self::$_available_spaces['tickets'][$ticket->ID()][$datetime->ID()] = min( |
|
553 | - $ticket->qty() - $ticket->sold(), |
|
554 | - $spaces_remaining |
|
555 | - ); |
|
556 | - // if the remaining spaces for this datetime is already set, |
|
557 | - // then compare that against the datetime spaces remaining, and take the lowest number, |
|
558 | - // else just take the datetime spaces remaining, and assign to the datetimes array |
|
559 | - self::$_available_spaces['datetimes'][$datetime->ID()] = isset( |
|
560 | - self::$_available_spaces['datetimes'][$datetime->ID()] |
|
561 | - ) |
|
562 | - ? min(self::$_available_spaces['datetimes'][$datetime->ID()], $spaces_remaining) |
|
563 | - : $spaces_remaining; |
|
564 | - } |
|
565 | - } |
|
566 | - } |
|
567 | - } |
|
568 | - |
|
569 | - |
|
570 | - |
|
571 | - /** |
|
572 | - * @param \EE_Ticket $ticket |
|
573 | - * @param int $qty |
|
574 | - * @return void |
|
575 | - */ |
|
576 | - private function recalculateTicketDatetimeAvailability(\EE_Ticket $ticket, $qty = 0) |
|
577 | - { |
|
578 | - if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
579 | - // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
580 | - foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
581 | - // subtract the qty of selected tickets from each datetime's available spaces this ticket has access to, |
|
582 | - self::$_available_spaces['datetimes'][$DTD_ID] -= $qty; |
|
583 | - } |
|
584 | - } |
|
585 | - } |
|
22 | + /** |
|
23 | + * array of datetimes and the spaces available for them |
|
24 | + * |
|
25 | + * @access private |
|
26 | + * @var array |
|
27 | + */ |
|
28 | + private static $_available_spaces = array(); |
|
29 | + |
|
30 | + |
|
31 | + |
|
32 | + /** |
|
33 | + * cancelTicketSelections |
|
34 | + * |
|
35 | + * @return string |
|
36 | + */ |
|
37 | + public function cancelTicketSelections() |
|
38 | + { |
|
39 | + // check nonce |
|
40 | + if ( ! $this->processTicketSelectorNonce('cancel_ticket_selections')) { |
|
41 | + return false; |
|
42 | + } |
|
43 | + \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
44 | + if (\EE_Registry::instance()->REQ->is_set('event_id')) { |
|
45 | + wp_safe_redirect( |
|
46 | + \EEH_Event_View::event_link_url( |
|
47 | + \EE_Registry::instance()->REQ->get('event_id') |
|
48 | + ) |
|
49 | + ); |
|
50 | + } else { |
|
51 | + wp_safe_redirect( |
|
52 | + site_url('/' . \EE_Registry::instance()->CFG->core->event_cpt_slug . '/') |
|
53 | + ); |
|
54 | + } |
|
55 | + exit(); |
|
56 | + } |
|
57 | + |
|
58 | + |
|
59 | + |
|
60 | + /** |
|
61 | + * processTicketSelectorNonce |
|
62 | + * |
|
63 | + * @param string $nonce_name |
|
64 | + * @param string $id |
|
65 | + * @return bool |
|
66 | + */ |
|
67 | + private function processTicketSelectorNonce($nonce_name, $id = '') |
|
68 | + { |
|
69 | + $nonce_name_with_id = ! empty($id) ? "{$nonce_name}_nonce_{$id}" : "{$nonce_name}_nonce"; |
|
70 | + if ( |
|
71 | + ! is_admin() |
|
72 | + && ( |
|
73 | + ! \EE_Registry::instance()->REQ->is_set($nonce_name_with_id) |
|
74 | + || ! wp_verify_nonce( |
|
75 | + \EE_Registry::instance()->REQ->get($nonce_name_with_id), |
|
76 | + $nonce_name |
|
77 | + ) |
|
78 | + ) |
|
79 | + ) { |
|
80 | + \EE_Error::add_error( |
|
81 | + sprintf( |
|
82 | + __( |
|
83 | + 'We\'re sorry but your request failed to pass a security check.%sPlease click the back button on your browser and try again.', |
|
84 | + 'event_espresso' |
|
85 | + ), |
|
86 | + '<br/>' |
|
87 | + ), |
|
88 | + __FILE__, |
|
89 | + __FUNCTION__, |
|
90 | + __LINE__ |
|
91 | + ); |
|
92 | + return false; |
|
93 | + } |
|
94 | + return true; |
|
95 | + } |
|
96 | + |
|
97 | + |
|
98 | + |
|
99 | + /** |
|
100 | + * process_ticket_selections |
|
101 | + * |
|
102 | + * @return array|bool |
|
103 | + * @throws \EE_Error |
|
104 | + */ |
|
105 | + public function processTicketSelections() |
|
106 | + { |
|
107 | + do_action('EED_Ticket_Selector__process_ticket_selections__before'); |
|
108 | + // do we have an event id? |
|
109 | + if ( ! \EE_Registry::instance()->REQ->is_set('tkt-slctr-event-id')) { |
|
110 | + // $_POST['tkt-slctr-event-id'] was not set ?!?!?!? |
|
111 | + \EE_Error::add_error( |
|
112 | + sprintf( |
|
113 | + __( |
|
114 | + 'An event id was not provided or was not received.%sPlease click the back button on your browser and try again.', |
|
115 | + 'event_espresso' |
|
116 | + ), |
|
117 | + '<br/>' |
|
118 | + ), |
|
119 | + __FILE__, |
|
120 | + __FUNCTION__, |
|
121 | + __LINE__ |
|
122 | + ); |
|
123 | + } |
|
124 | + //if event id is valid |
|
125 | + $id = absint(\EE_Registry::instance()->REQ->get('tkt-slctr-event-id')); |
|
126 | + // d( \EE_Registry::instance()->REQ ); |
|
127 | + self::$_available_spaces = array( |
|
128 | + 'tickets' => array(), |
|
129 | + 'datetimes' => array(), |
|
130 | + ); |
|
131 | + //we should really only have 1 registration in the works now (ie, no MER) so clear any previous items in the cart. |
|
132 | + // When MER happens this will probably need to be tweaked, possibly wrapped in a conditional checking for some constant defined in MER etc. |
|
133 | + \EE_Registry::instance()->load_core('Session'); |
|
134 | + // unless otherwise requested, clear the session |
|
135 | + if (apply_filters('FHEE__EE_Ticket_Selector__process_ticket_selections__clear_session', true)) { |
|
136 | + \EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__); |
|
137 | + } |
|
138 | + //d( \EE_Registry::instance()->SSN ); |
|
139 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
140 | + // validate/sanitize data |
|
141 | + $valid = $this->validatePostData($id); |
|
142 | + //EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
143 | + //EEH_Debug_Tools::printr( $valid, '$valid', __FILE__, __LINE__ ); |
|
144 | + //EEH_Debug_Tools::printr( $valid[ 'total_tickets' ], 'total_tickets', __FILE__, __LINE__ ); |
|
145 | + //EEH_Debug_Tools::printr( $valid[ 'max_atndz' ], 'max_atndz', __FILE__, __LINE__ ); |
|
146 | + //check total tickets ordered vs max number of attendees that can register |
|
147 | + if ($valid['total_tickets'] > $valid['max_atndz']) { |
|
148 | + // ordering too many tickets !!! |
|
149 | + $total_tickets_string = _n( |
|
150 | + 'You have attempted to purchase %s ticket.', |
|
151 | + 'You have attempted to purchase %s tickets.', |
|
152 | + $valid['total_tickets'], |
|
153 | + 'event_espresso' |
|
154 | + ); |
|
155 | + $limit_error_1 = sprintf($total_tickets_string, $valid['total_tickets']); |
|
156 | + // dev only message |
|
157 | + $max_atndz_string = _n( |
|
158 | + 'The registration limit for this event is %s ticket per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
159 | + 'The registration limit for this event is %s tickets per registration, therefore the total number of tickets you may purchase at a time can not exceed %s.', |
|
160 | + $valid['max_atndz'], |
|
161 | + 'event_espresso' |
|
162 | + ); |
|
163 | + $limit_error_2 = sprintf($max_atndz_string, $valid['max_atndz'], $valid['max_atndz']); |
|
164 | + \EE_Error::add_error($limit_error_1 . '<br/>' . $limit_error_2, __FILE__, __FUNCTION__, __LINE__); |
|
165 | + } else { |
|
166 | + // all data appears to be valid |
|
167 | + $tckts_slctd = false; |
|
168 | + $tickets_added = 0; |
|
169 | + $valid = apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data', $valid); |
|
170 | + if ($valid['total_tickets'] > 0) { |
|
171 | + // load cart |
|
172 | + \EE_Registry::instance()->load_core('Cart'); |
|
173 | + // cycle thru the number of data rows sent from the event listing |
|
174 | + for ($x = 0; $x < $valid['rows']; $x++) { |
|
175 | + // does this row actually contain a ticket quantity? |
|
176 | + if (isset($valid['qty'][$x]) && $valid['qty'][$x] > 0) { |
|
177 | + // YES we have a ticket quantity |
|
178 | + $tckts_slctd = true; |
|
179 | + // d( $valid['ticket_obj'][$x] ); |
|
180 | + if ($valid['ticket_obj'][$x] instanceof \EE_Ticket) { |
|
181 | + // then add ticket to cart |
|
182 | + $tickets_added += $this->addTicketToCart( |
|
183 | + $valid['ticket_obj'][$x], |
|
184 | + $valid['qty'][$x] |
|
185 | + ); |
|
186 | + if (\EE_Error::has_error()) { |
|
187 | + break; |
|
188 | + } |
|
189 | + } else { |
|
190 | + // nothing added to cart retrieved |
|
191 | + \EE_Error::add_error( |
|
192 | + sprintf( |
|
193 | + __( |
|
194 | + 'A valid ticket could not be retrieved for the event.%sPlease click the back button on your browser and try again.', |
|
195 | + 'event_espresso' |
|
196 | + ), |
|
197 | + '<br/>' |
|
198 | + ), |
|
199 | + __FILE__, __FUNCTION__, __LINE__ |
|
200 | + ); |
|
201 | + } |
|
202 | + } |
|
203 | + } |
|
204 | + } |
|
205 | + do_action( |
|
206 | + 'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart', |
|
207 | + \EE_Registry::instance()->CART, |
|
208 | + $this |
|
209 | + ); |
|
210 | + //d( \EE_Registry::instance()->CART ); |
|
211 | + //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL REDIRECT HERE BEFORE CART UPDATE |
|
212 | + if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', $tckts_slctd)) { |
|
213 | + if (apply_filters('FHEE__EED_Ticket_Selector__process_ticket_selections__success', $tickets_added)) { |
|
214 | + do_action( |
|
215 | + 'FHEE__EE_Ticket_Selector__process_ticket_selections__before_redirecting_to_checkout', |
|
216 | + \EE_Registry::instance()->CART, |
|
217 | + $this |
|
218 | + ); |
|
219 | + \EE_Registry::instance()->CART->recalculate_all_cart_totals(); |
|
220 | + \EE_Registry::instance()->CART->save_cart(false); |
|
221 | + // exit('KILL REDIRECT AFTER CART UPDATE'); // <<<<<<<< OR HERE TO KILL REDIRECT AFTER CART UPDATE |
|
222 | + // just return TRUE for registrations being made from admin |
|
223 | + if (is_admin()) { |
|
224 | + return true; |
|
225 | + } |
|
226 | + \EE_Error::get_notices(false, true); |
|
227 | + wp_safe_redirect( |
|
228 | + apply_filters( |
|
229 | + 'FHEE__EE_Ticket_Selector__process_ticket_selections__success_redirect_url', |
|
230 | + \EE_Registry::instance()->CFG->core->reg_page_url() |
|
231 | + ) |
|
232 | + ); |
|
233 | + exit(); |
|
234 | + } else { |
|
235 | + if ( ! \EE_Error::has_error() && ! \EE_Error::has_error(true, 'attention')) { |
|
236 | + // nothing added to cart |
|
237 | + \EE_Error::add_attention(__('No tickets were added for the event', 'event_espresso'), |
|
238 | + __FILE__, __FUNCTION__, __LINE__); |
|
239 | + } |
|
240 | + } |
|
241 | + } else { |
|
242 | + // no ticket quantities were selected |
|
243 | + \EE_Error::add_error(__('You need to select a ticket quantity before you can proceed.', |
|
244 | + 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); |
|
245 | + } |
|
246 | + } |
|
247 | + //die(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< KILL BEFORE REDIRECT |
|
248 | + // at this point, just return if registration is being made from admin |
|
249 | + if (is_admin()) { |
|
250 | + return false; |
|
251 | + } |
|
252 | + if ($valid['return_url']) { |
|
253 | + \EE_Error::get_notices(false, true); |
|
254 | + wp_safe_redirect($valid['return_url']); |
|
255 | + exit(); |
|
256 | + } elseif (isset($event_to_add['id'])) { |
|
257 | + \EE_Error::get_notices(false, true); |
|
258 | + wp_safe_redirect(get_permalink($event_to_add['id'])); |
|
259 | + exit(); |
|
260 | + } else { |
|
261 | + echo \EE_Error::get_notices(); |
|
262 | + } |
|
263 | + return false; |
|
264 | + } |
|
265 | + |
|
266 | + |
|
267 | + |
|
268 | + /** |
|
269 | + * validate_post_data |
|
270 | + * |
|
271 | + * @param int $id |
|
272 | + * @return array|FALSE |
|
273 | + */ |
|
274 | + private function validatePostData($id = 0) |
|
275 | + { |
|
276 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
277 | + if ( ! $id) { |
|
278 | + \EE_Error::add_error( |
|
279 | + __('The event id provided was not valid.', 'event_espresso'), |
|
280 | + __FILE__, |
|
281 | + __FUNCTION__, |
|
282 | + __LINE__ |
|
283 | + ); |
|
284 | + return false; |
|
285 | + } |
|
286 | + // start with an empty array() |
|
287 | + $valid_data = array(); |
|
288 | + // grab valid id |
|
289 | + $valid_data['id'] = $id; |
|
290 | + // array of other form names |
|
291 | + $inputs_to_clean = array( |
|
292 | + 'event_id' => 'tkt-slctr-event-id', |
|
293 | + 'max_atndz' => 'tkt-slctr-max-atndz-', |
|
294 | + 'rows' => 'tkt-slctr-rows-', |
|
295 | + 'qty' => 'tkt-slctr-qty-', |
|
296 | + 'ticket_id' => 'tkt-slctr-ticket-id-', |
|
297 | + 'return_url' => 'tkt-slctr-return-url-', |
|
298 | + ); |
|
299 | + // let's track the total number of tickets ordered.' |
|
300 | + $valid_data['total_tickets'] = 0; |
|
301 | + // cycle through $inputs_to_clean array |
|
302 | + foreach ($inputs_to_clean as $what => $input_to_clean) { |
|
303 | + // check for POST data |
|
304 | + if (\EE_Registry::instance()->REQ->is_set($input_to_clean . $id)) { |
|
305 | + // grab value |
|
306 | + $input_value = \EE_Registry::instance()->REQ->get($input_to_clean . $id); |
|
307 | + switch ($what) { |
|
308 | + // integers |
|
309 | + case 'event_id': |
|
310 | + $valid_data[$what] = absint($input_value); |
|
311 | + // get event via the event id we put in the form |
|
312 | + $valid_data['event'] = \EE_Registry::instance() |
|
313 | + ->load_model('Event') |
|
314 | + ->get_one_by_ID($valid_data['event_id']); |
|
315 | + break; |
|
316 | + case 'rows': |
|
317 | + case 'max_atndz': |
|
318 | + $valid_data[$what] = absint($input_value); |
|
319 | + break; |
|
320 | + // arrays of integers |
|
321 | + case 'qty': |
|
322 | + /** @var array $row_qty */ |
|
323 | + $row_qty = $input_value; |
|
324 | + // if qty is coming from a radio button input, then we need to assemble an array of rows |
|
325 | + if ( ! is_array($row_qty)) { |
|
326 | + // get number of rows |
|
327 | + $rows = \EE_Registry::instance()->REQ->is_set('tkt-slctr-rows-' . $id) |
|
328 | + ? absint(\EE_Registry::instance()->REQ->get('tkt-slctr-rows-' . $id)) |
|
329 | + : 1; |
|
330 | + // explode ints by the dash |
|
331 | + $row_qty = explode('-', $row_qty); |
|
332 | + $row = isset($row_qty[0]) ? absint($row_qty[0]) : 1; |
|
333 | + $qty = isset($row_qty[1]) ? absint($row_qty[1]) : 0; |
|
334 | + $row_qty = array($row => $qty); |
|
335 | + for ($x = 1; $x <= $rows; $x++) { |
|
336 | + if ( ! isset($row_qty[$x])) { |
|
337 | + $row_qty[$x] = 0; |
|
338 | + } |
|
339 | + } |
|
340 | + } |
|
341 | + ksort($row_qty); |
|
342 | + // cycle thru values |
|
343 | + foreach ($row_qty as $qty) { |
|
344 | + $qty = absint($qty); |
|
345 | + // sanitize as integers |
|
346 | + $valid_data[$what][] = $qty; |
|
347 | + $valid_data['total_tickets'] += $qty; |
|
348 | + } |
|
349 | + break; |
|
350 | + // array of integers |
|
351 | + case 'ticket_id': |
|
352 | + $value_array = array(); |
|
353 | + // cycle thru values |
|
354 | + foreach ((array)$input_value as $key => $value) { |
|
355 | + // allow only numbers, letters, spaces, commas and dashes |
|
356 | + $value_array[$key] = wp_strip_all_tags($value); |
|
357 | + // get ticket via the ticket id we put in the form |
|
358 | + $ticket_obj = \EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($value); |
|
359 | + $valid_data['ticket_obj'][$key] = $ticket_obj; |
|
360 | + } |
|
361 | + $valid_data[$what] = $value_array; |
|
362 | + break; |
|
363 | + case 'return_url' : |
|
364 | + // grab and sanitize return-url |
|
365 | + $input_value = esc_url_raw($input_value); |
|
366 | + // was the request coming from an iframe ? if so, then: |
|
367 | + if (strpos($input_value, 'event_list=iframe')) { |
|
368 | + // get anchor fragment |
|
369 | + $input_value = explode('#', $input_value); |
|
370 | + $input_value = end($input_value); |
|
371 | + // use event list url instead, but append anchor |
|
372 | + $input_value = \EEH_Event_View::event_archive_url() . '#' . $input_value; |
|
373 | + } |
|
374 | + $valid_data[$what] = $input_value; |
|
375 | + break; |
|
376 | + } // end switch $what |
|
377 | + } |
|
378 | + } // end foreach $inputs_to_clean |
|
379 | + return $valid_data; |
|
380 | + } |
|
381 | + |
|
382 | + |
|
383 | + |
|
384 | + /** |
|
385 | + * adds a ticket to the cart |
|
386 | + * |
|
387 | + * @param \EE_Ticket $ticket |
|
388 | + * @param int $qty |
|
389 | + * @return TRUE on success, FALSE on fail |
|
390 | + * @throws \EE_Error |
|
391 | + */ |
|
392 | + private function addTicketToCart(\EE_Ticket $ticket = null, $qty = 1) |
|
393 | + { |
|
394 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
395 | + // get the number of spaces left for this datetime ticket |
|
396 | + $available_spaces = $this->ticketDatetimeAvailability($ticket); |
|
397 | + // compare available spaces against the number of tickets being purchased |
|
398 | + if ($available_spaces >= $qty) { |
|
399 | + // allow addons to prevent a ticket from being added to cart |
|
400 | + if ( |
|
401 | + ! apply_filters( |
|
402 | + 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_add_to_cart', |
|
403 | + true, |
|
404 | + $ticket, |
|
405 | + $qty, |
|
406 | + $available_spaces |
|
407 | + ) |
|
408 | + ) { |
|
409 | + return false; |
|
410 | + } |
|
411 | + $qty = absint(apply_filters('FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty', $qty, $ticket)); |
|
412 | + // add event to cart |
|
413 | + if (\EE_Registry::instance()->CART->add_ticket_to_cart($ticket, $qty)) { |
|
414 | + $this->recalculateTicketDatetimeAvailability($ticket, $qty); |
|
415 | + return true; |
|
416 | + } |
|
417 | + return false; |
|
418 | + } |
|
419 | + // tickets can not be purchased but let's find the exact number left |
|
420 | + // for the last ticket selected PRIOR to subtracting tickets |
|
421 | + $available_spaces = $this->ticketDatetimeAvailability($ticket, true); |
|
422 | + // greedy greedy greedy eh? |
|
423 | + if ($available_spaces > 0) { |
|
424 | + if ( |
|
425 | + apply_filters( |
|
426 | + 'FHEE__EE_Ticket_Selector___add_ticket_to_cart__allow_display_availability_error', |
|
427 | + true, |
|
428 | + $ticket, |
|
429 | + $qty, |
|
430 | + $available_spaces |
|
431 | + ) |
|
432 | + ) { |
|
433 | + $this->displayAvailabilityError($available_spaces); |
|
434 | + } |
|
435 | + } else { |
|
436 | + \EE_Error::add_error( |
|
437 | + __( |
|
438 | + 'We\'re sorry, but there are no available spaces left for this event at this particular date and time.', |
|
439 | + 'event_espresso' |
|
440 | + ), |
|
441 | + __FILE__, __FUNCTION__, __LINE__ |
|
442 | + ); |
|
443 | + } |
|
444 | + return false; |
|
445 | + } |
|
446 | + |
|
447 | + |
|
448 | + |
|
449 | + /** |
|
450 | + * @param int $available_spaces |
|
451 | + * @throws \EE_Error |
|
452 | + */ |
|
453 | + private function displayAvailabilityError($available_spaces = 1) |
|
454 | + { |
|
455 | + // add error messaging - we're using the _n function that will generate |
|
456 | + // the appropriate singular or plural message based on the number of $available_spaces |
|
457 | + if (\EE_Registry::instance()->CART->all_ticket_quantity_count()) { |
|
458 | + $msg = sprintf( |
|
459 | + _n( |
|
460 | + 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
461 | + 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets by cancelling the current selection and choosing again, or proceed to registration.', |
|
462 | + $available_spaces, |
|
463 | + 'event_espresso' |
|
464 | + ), |
|
465 | + $available_spaces, |
|
466 | + '<br />' |
|
467 | + ); |
|
468 | + } else { |
|
469 | + $msg = sprintf( |
|
470 | + _n( |
|
471 | + 'We\'re sorry, but there is only %1$s available space left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
472 | + 'We\'re sorry, but there are only %1$s available spaces left for this event at this particular date and time. Please select a different number (or different combination) of tickets.', |
|
473 | + $available_spaces, |
|
474 | + 'event_espresso' |
|
475 | + ), |
|
476 | + $available_spaces, |
|
477 | + '<br />' |
|
478 | + ); |
|
479 | + } |
|
480 | + \EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
481 | + } |
|
482 | + |
|
483 | + |
|
484 | + |
|
485 | + /** |
|
486 | + * ticketDatetimeAvailability |
|
487 | + * creates an array of tickets plus all of the datetimes available to each ticket |
|
488 | + * and tracks the spaces remaining for each of those datetimes |
|
489 | + * |
|
490 | + * @param \EE_Ticket $ticket - selected ticket |
|
491 | + * @param bool $get_original_ticket_spaces |
|
492 | + * @return int |
|
493 | + * @throws \EE_Error |
|
494 | + */ |
|
495 | + private function ticketDatetimeAvailability(\EE_Ticket $ticket, $get_original_ticket_spaces = false) |
|
496 | + { |
|
497 | + // if the $_available_spaces array has not been set up yet... |
|
498 | + if ( ! isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
499 | + $this->setInitialTicketDatetimeAvailability($ticket); |
|
500 | + } |
|
501 | + $available_spaces = $ticket->qty() - $ticket->sold(); |
|
502 | + if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
503 | + // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
504 | + foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
505 | + // if we want the original datetime availability BEFORE we started subtracting tickets ? |
|
506 | + if ($get_original_ticket_spaces) { |
|
507 | + // then grab the available spaces from the "tickets" array |
|
508 | + // and compare with the above to get the lowest number |
|
509 | + $available_spaces = min( |
|
510 | + $available_spaces, |
|
511 | + self::$_available_spaces['tickets'][$ticket->ID()][$DTD_ID] |
|
512 | + ); |
|
513 | + } else { |
|
514 | + // we want the updated ticket availability as stored in the "datetimes" array |
|
515 | + $available_spaces = min($available_spaces, self::$_available_spaces['datetimes'][$DTD_ID]); |
|
516 | + } |
|
517 | + } |
|
518 | + } |
|
519 | + return $available_spaces; |
|
520 | + } |
|
521 | + |
|
522 | + |
|
523 | + |
|
524 | + /** |
|
525 | + * @param \EE_Ticket $ticket |
|
526 | + * @return void |
|
527 | + * @throws \EE_Error |
|
528 | + */ |
|
529 | + private function setInitialTicketDatetimeAvailability(\EE_Ticket $ticket) |
|
530 | + { |
|
531 | + // first, get all of the datetimes that are available to this ticket |
|
532 | + $datetimes = $ticket->get_many_related( |
|
533 | + 'Datetime', |
|
534 | + array( |
|
535 | + array( |
|
536 | + 'DTT_EVT_end' => array( |
|
537 | + '>=', |
|
538 | + \EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
539 | + ), |
|
540 | + ), |
|
541 | + 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
542 | + ) |
|
543 | + ); |
|
544 | + if ( ! empty($datetimes)) { |
|
545 | + // now loop thru all of the datetimes |
|
546 | + foreach ($datetimes as $datetime) { |
|
547 | + if ($datetime instanceof \EE_Datetime) { |
|
548 | + // the number of spaces available for the datetime without considering individual ticket quantities |
|
549 | + $spaces_remaining = $datetime->spaces_remaining(); |
|
550 | + // save the total available spaces ( the lesser of the ticket qty minus the number of tickets sold |
|
551 | + // or the datetime spaces remaining) to this ticket using the datetime ID as the key |
|
552 | + self::$_available_spaces['tickets'][$ticket->ID()][$datetime->ID()] = min( |
|
553 | + $ticket->qty() - $ticket->sold(), |
|
554 | + $spaces_remaining |
|
555 | + ); |
|
556 | + // if the remaining spaces for this datetime is already set, |
|
557 | + // then compare that against the datetime spaces remaining, and take the lowest number, |
|
558 | + // else just take the datetime spaces remaining, and assign to the datetimes array |
|
559 | + self::$_available_spaces['datetimes'][$datetime->ID()] = isset( |
|
560 | + self::$_available_spaces['datetimes'][$datetime->ID()] |
|
561 | + ) |
|
562 | + ? min(self::$_available_spaces['datetimes'][$datetime->ID()], $spaces_remaining) |
|
563 | + : $spaces_remaining; |
|
564 | + } |
|
565 | + } |
|
566 | + } |
|
567 | + } |
|
568 | + |
|
569 | + |
|
570 | + |
|
571 | + /** |
|
572 | + * @param \EE_Ticket $ticket |
|
573 | + * @param int $qty |
|
574 | + * @return void |
|
575 | + */ |
|
576 | + private function recalculateTicketDatetimeAvailability(\EE_Ticket $ticket, $qty = 0) |
|
577 | + { |
|
578 | + if (isset(self::$_available_spaces['tickets'][$ticket->ID()])) { |
|
579 | + // loop thru tickets, which will ALSO include individual ticket records AND a total |
|
580 | + foreach (self::$_available_spaces['tickets'][$ticket->ID()] as $DTD_ID => $spaces) { |
|
581 | + // subtract the qty of selected tickets from each datetime's available spaces this ticket has access to, |
|
582 | + self::$_available_spaces['datetimes'][$DTD_ID] -= $qty; |
|
583 | + } |
|
584 | + } |
|
585 | + } |
|
586 | 586 | |
587 | 587 | |
588 | 588 | } |
@@ -24,59 +24,59 @@ |
||
24 | 24 | class CoreLoader implements LoaderDecoratorInterface |
25 | 25 | { |
26 | 26 | |
27 | - /** |
|
28 | - * @var EE_Registry|CoffeeShop $generator |
|
29 | - */ |
|
30 | - private $generator; |
|
31 | - |
|
32 | - |
|
33 | - |
|
34 | - /** |
|
35 | - * CoreLoader constructor. |
|
36 | - * |
|
37 | - * @param EE_Registry|CoffeeShop $generator |
|
38 | - * @throws InvalidArgumentException |
|
39 | - */ |
|
40 | - public function __construct($generator) |
|
41 | - { |
|
42 | - if(!($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) { |
|
43 | - throw new InvalidArgumentException( |
|
44 | - esc_html__( |
|
45 | - 'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.', |
|
46 | - 'event_espresso' |
|
47 | - ) |
|
48 | - ); |
|
49 | - } |
|
50 | - $this->generator = $generator; |
|
51 | - } |
|
52 | - |
|
53 | - |
|
54 | - |
|
55 | - /** |
|
56 | - * @param string $fqcn |
|
57 | - * @param array $arguments |
|
58 | - * @return mixed |
|
59 | - * @throws EE_Error |
|
60 | - * @throws ServiceNotFoundException |
|
61 | - */ |
|
62 | - public function load($fqcn, $arguments = array()) |
|
63 | - { |
|
64 | - return $this->generator instanceof EE_Registry |
|
65 | - ? $this->generator->create($fqcn, $arguments) |
|
66 | - : $this->generator->brew($fqcn, $arguments); |
|
67 | - } |
|
68 | - |
|
69 | - |
|
70 | - |
|
71 | - /** |
|
72 | - * calls reset() on generator if method exists |
|
73 | - */ |
|
74 | - public function reset() |
|
75 | - { |
|
76 | - if (method_exists($this->generator, 'reset')) { |
|
77 | - $this->generator->reset(); |
|
78 | - } |
|
79 | - } |
|
27 | + /** |
|
28 | + * @var EE_Registry|CoffeeShop $generator |
|
29 | + */ |
|
30 | + private $generator; |
|
31 | + |
|
32 | + |
|
33 | + |
|
34 | + /** |
|
35 | + * CoreLoader constructor. |
|
36 | + * |
|
37 | + * @param EE_Registry|CoffeeShop $generator |
|
38 | + * @throws InvalidArgumentException |
|
39 | + */ |
|
40 | + public function __construct($generator) |
|
41 | + { |
|
42 | + if(!($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) { |
|
43 | + throw new InvalidArgumentException( |
|
44 | + esc_html__( |
|
45 | + 'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.', |
|
46 | + 'event_espresso' |
|
47 | + ) |
|
48 | + ); |
|
49 | + } |
|
50 | + $this->generator = $generator; |
|
51 | + } |
|
52 | + |
|
53 | + |
|
54 | + |
|
55 | + /** |
|
56 | + * @param string $fqcn |
|
57 | + * @param array $arguments |
|
58 | + * @return mixed |
|
59 | + * @throws EE_Error |
|
60 | + * @throws ServiceNotFoundException |
|
61 | + */ |
|
62 | + public function load($fqcn, $arguments = array()) |
|
63 | + { |
|
64 | + return $this->generator instanceof EE_Registry |
|
65 | + ? $this->generator->create($fqcn, $arguments) |
|
66 | + : $this->generator->brew($fqcn, $arguments); |
|
67 | + } |
|
68 | + |
|
69 | + |
|
70 | + |
|
71 | + /** |
|
72 | + * calls reset() on generator if method exists |
|
73 | + */ |
|
74 | + public function reset() |
|
75 | + { |
|
76 | + if (method_exists($this->generator, 'reset')) { |
|
77 | + $this->generator->reset(); |
|
78 | + } |
|
79 | + } |
|
80 | 80 | |
81 | 81 | } |
82 | 82 | // End of file CoreLoader.php |