@@ -92,14 +92,14 @@ discard block |
||
92 | 92 | { |
93 | 93 | wp_register_style( |
94 | 94 | 'eed-event-single-sortable', |
95 | - EVENT_SINGLE_CAFF_ASSETS_URL . 'eed_event_single_sortable.css', |
|
95 | + EVENT_SINGLE_CAFF_ASSETS_URL.'eed_event_single_sortable.css', |
|
96 | 96 | array(), |
97 | 97 | EVENT_ESPRESSO_VERSION |
98 | 98 | ); |
99 | 99 | wp_enqueue_style('eed-event-single-sortable'); |
100 | 100 | wp_register_script( |
101 | 101 | 'eed-event-single-sortable', |
102 | - EVENT_SINGLE_CAFF_ASSETS_URL . 'eed_event_single_sortable.js', |
|
102 | + EVENT_SINGLE_CAFF_ASSETS_URL.'eed_event_single_sortable.js', |
|
103 | 103 | array('jquery-ui-sortable'), |
104 | 104 | EVENT_ESPRESSO_VERSION, |
105 | 105 | true |
@@ -113,9 +113,9 @@ discard block |
||
113 | 113 | */ |
114 | 114 | public static function setDefinitions() |
115 | 115 | { |
116 | - if (! defined('EVENT_SINGLE_CAFF_TEMPLATES_PATH')) { |
|
117 | - define('EVENT_SINGLE_CAFF_TEMPLATES_PATH', plugin_dir_path(__FILE__) . 'templates/'); |
|
118 | - define('EVENT_SINGLE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
116 | + if ( ! defined('EVENT_SINGLE_CAFF_TEMPLATES_PATH')) { |
|
117 | + define('EVENT_SINGLE_CAFF_TEMPLATES_PATH', plugin_dir_path(__FILE__).'templates/'); |
|
118 | + define('EVENT_SINGLE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__).'assets/'); |
|
119 | 119 | } |
120 | 120 | } |
121 | 121 | |
@@ -137,10 +137,10 @@ discard block |
||
137 | 137 | $config = apply_filters('FHEE__EED_Event_Single__template_settings_form__event_list_config', $config); |
138 | 138 | |
139 | 139 | $event_single_order_array = array(); |
140 | - $event_single_order_array[ $config->display_order_tickets ] = 'tickets'; |
|
141 | - $event_single_order_array[ $config->display_order_datetimes ] = 'datetimes'; |
|
142 | - $event_single_order_array[ $config->display_order_event ] = 'event'; |
|
143 | - $event_single_order_array[ $config->display_order_venue ] = 'venue'; |
|
140 | + $event_single_order_array[$config->display_order_tickets] = 'tickets'; |
|
141 | + $event_single_order_array[$config->display_order_datetimes] = 'datetimes'; |
|
142 | + $event_single_order_array[$config->display_order_event] = 'event'; |
|
143 | + $event_single_order_array[$config->display_order_venue] = 'venue'; |
|
144 | 144 | // get template parts |
145 | 145 | $template_parts = EED_Event_Single::instance()->initialize_template_parts($config); |
146 | 146 | // convert to array so that we can add more properties |
@@ -151,7 +151,7 @@ discard block |
||
151 | 151 | 'single-sortable-li single-sortable-js' |
152 | 152 | ); |
153 | 153 | EEH_Template::display_template( |
154 | - EVENT_SINGLE_CAFF_TEMPLATES_PATH . 'admin-event-single-settings.template.php', |
|
154 | + EVENT_SINGLE_CAFF_TEMPLATES_PATH.'admin-event-single-settings.template.php', |
|
155 | 155 | $config |
156 | 156 | ); |
157 | 157 | } |
@@ -166,7 +166,7 @@ discard block |
||
166 | 166 | */ |
167 | 167 | public static function update_template_settings(EE_Template_Config $CFG, $REQ) |
168 | 168 | { |
169 | - if (! $CFG->EED_Event_Single instanceof EE_Event_Single_Config) { |
|
169 | + if ( ! $CFG->EED_Event_Single instanceof EE_Event_Single_Config) { |
|
170 | 170 | $CFG->EED_Event_Single = new EE_Event_Single_Config(); |
171 | 171 | } |
172 | 172 | $display_order_event = $CFG->EED_Event_Single->display_order_event !== null |
@@ -215,7 +215,7 @@ discard block |
||
215 | 215 | { |
216 | 216 | $config_saved = false; |
217 | 217 | $template_parts = EED_Event_Single_Caff::getRequest()->getRequestParam('elements'); |
218 | - if (! empty($template_parts)) { |
|
218 | + if ( ! empty($template_parts)) { |
|
219 | 219 | $template_parts = explode(',', trim($template_parts, ',')); |
220 | 220 | foreach ($template_parts as $key => $template_part) { |
221 | 221 | $template_part = "display_order_$template_part"; |
@@ -24,228 +24,228 @@ |
||
24 | 24 | */ |
25 | 25 | class EED_Event_Single_Caff extends EED_Event_Single |
26 | 26 | { |
27 | - /** |
|
28 | - * @return EED_Event_Single_Caff |
|
29 | - */ |
|
30 | - public static function instance() |
|
31 | - { |
|
32 | - return parent::get_instance(__CLASS__); |
|
33 | - } |
|
34 | - |
|
35 | - |
|
36 | - /** |
|
37 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
38 | - * |
|
39 | - * @access public |
|
40 | - * @return void |
|
41 | - */ |
|
42 | - public static function set_hooks() |
|
43 | - { |
|
44 | - } |
|
45 | - |
|
46 | - /** |
|
47 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
48 | - * |
|
49 | - * @access public |
|
50 | - * @return void |
|
51 | - */ |
|
52 | - public static function set_hooks_admin() |
|
53 | - { |
|
54 | - self::setDefinitions(); |
|
55 | - add_action( |
|
56 | - 'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_events__template_settings', |
|
57 | - array('EED_Event_Single_Caff', 'load_scripts_styles'), |
|
58 | - 10 |
|
59 | - ); |
|
60 | - add_action( |
|
61 | - 'AHEE__template_settings__template__before_settings_form', |
|
62 | - array('EED_Event_Single_Caff', 'template_settings_form'), |
|
63 | - 10 |
|
64 | - ); |
|
65 | - add_filter( |
|
66 | - 'FHEE__General_Settings_Admin_Page__update_template_settings__data', |
|
67 | - array('EED_Event_Single_Caff', 'update_template_settings'), |
|
68 | - 10, |
|
69 | - 2 |
|
70 | - ); |
|
71 | - // AJAX |
|
72 | - add_action( |
|
73 | - 'wp_ajax_espresso_update_event_single_order', |
|
74 | - array('EED_Event_Single_Caff', 'update_event_single_order') |
|
75 | - ); |
|
76 | - add_action( |
|
77 | - 'wp_ajax_nopriv_espresso_update_event_single_order', |
|
78 | - array('EED_Event_Single_Caff', 'update_event_single_order') |
|
79 | - ); |
|
80 | - } |
|
81 | - |
|
82 | - |
|
83 | - public static function load_scripts_styles() |
|
84 | - { |
|
85 | - add_action('admin_enqueue_scripts', array('EED_Event_Single_Caff', 'enqueue_scripts_styles'), 10); |
|
86 | - } |
|
87 | - |
|
88 | - |
|
89 | - public static function enqueue_scripts_styles() |
|
90 | - { |
|
91 | - wp_register_style( |
|
92 | - 'eed-event-single-sortable', |
|
93 | - EVENT_SINGLE_CAFF_ASSETS_URL . 'eed_event_single_sortable.css', |
|
94 | - array(), |
|
95 | - EVENT_ESPRESSO_VERSION |
|
96 | - ); |
|
97 | - wp_enqueue_style('eed-event-single-sortable'); |
|
98 | - wp_register_script( |
|
99 | - 'eed-event-single-sortable', |
|
100 | - EVENT_SINGLE_CAFF_ASSETS_URL . 'eed_event_single_sortable.js', |
|
101 | - array('jquery-ui-sortable'), |
|
102 | - EVENT_ESPRESSO_VERSION, |
|
103 | - true |
|
104 | - ); |
|
105 | - wp_enqueue_script('eed-event-single-sortable'); |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * Set constants only if they haven't been set yet. |
|
111 | - */ |
|
112 | - public static function setDefinitions() |
|
113 | - { |
|
114 | - if (! defined('EVENT_SINGLE_CAFF_TEMPLATES_PATH')) { |
|
115 | - define('EVENT_SINGLE_CAFF_TEMPLATES_PATH', plugin_dir_path(__FILE__) . 'templates/'); |
|
116 | - define('EVENT_SINGLE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
117 | - } |
|
118 | - } |
|
119 | - |
|
120 | - |
|
121 | - /** |
|
122 | - * template_settings_form |
|
123 | - * |
|
124 | - * @access public |
|
125 | - * @static |
|
126 | - * @return void |
|
127 | - */ |
|
128 | - public static function template_settings_form() |
|
129 | - { |
|
130 | - $config = EE_Registry::instance()->CFG->template_settings; |
|
131 | - $config = isset($config->EED_Event_Single) && $config->EED_Event_Single instanceof EE_Event_Single_Config |
|
132 | - ? $config->EED_Event_Single : new EE_Event_Single_Config(); |
|
133 | - $config->use_sortable_display_order = isset($config->use_sortable_display_order) |
|
134 | - ? $config->use_sortable_display_order : false; |
|
135 | - $config = apply_filters('FHEE__EED_Event_Single__template_settings_form__event_list_config', $config); |
|
136 | - |
|
137 | - $event_single_order_array = array(); |
|
138 | - $event_single_order_array[ $config->display_order_tickets ] = 'tickets'; |
|
139 | - $event_single_order_array[ $config->display_order_datetimes ] = 'datetimes'; |
|
140 | - $event_single_order_array[ $config->display_order_event ] = 'event'; |
|
141 | - $event_single_order_array[ $config->display_order_venue ] = 'venue'; |
|
142 | - // get template parts |
|
143 | - $template_parts = EED_Event_Single::instance()->initialize_template_parts($config); |
|
144 | - // convert to array so that we can add more properties |
|
145 | - $config = get_object_vars($config); |
|
146 | - $config['event_single_display_order'] = $template_parts->generate_sortable_list_of_template_parts( |
|
147 | - 'event-single-sortable-js', |
|
148 | - '', |
|
149 | - 'single-sortable-li single-sortable-js' |
|
150 | - ); |
|
151 | - EEH_Template::display_template( |
|
152 | - EVENT_SINGLE_CAFF_TEMPLATES_PATH . 'admin-event-single-settings.template.php', |
|
153 | - $config |
|
154 | - ); |
|
155 | - } |
|
156 | - |
|
157 | - |
|
158 | - /** |
|
159 | - * update_template_settings |
|
160 | - * |
|
161 | - * @param EE_Template_Config $CFG |
|
162 | - * @param array $REQ |
|
163 | - * @return EE_Template_Config |
|
164 | - */ |
|
165 | - public static function update_template_settings(EE_Template_Config $CFG, $REQ) |
|
166 | - { |
|
167 | - if (! $CFG->EED_Event_Single instanceof EE_Event_Single_Config) { |
|
168 | - $CFG->EED_Event_Single = new EE_Event_Single_Config(); |
|
169 | - } |
|
170 | - $display_order_event = $CFG->EED_Event_Single->display_order_event !== null |
|
171 | - ? $CFG->EED_Event_Single->display_order_event |
|
172 | - : EED_Event_Single::EVENT_DETAILS_PRIORITY; |
|
173 | - $display_order_datetimes = $CFG->EED_Event_Single->display_order_datetimes !== null |
|
174 | - ? $CFG->EED_Event_Single->display_order_datetimes |
|
175 | - : EED_Event_Single::EVENT_DATETIMES_PRIORITY; |
|
176 | - $display_order_tickets = $CFG->EED_Event_Single->display_order_tickets !== null |
|
177 | - ? $CFG->EED_Event_Single->display_order_tickets |
|
178 | - : EED_Event_Single::EVENT_TICKETS_PRIORITY; |
|
179 | - $display_order_venue = $CFG->EED_Event_Single->display_order_venue !== null |
|
180 | - ? $CFG->EED_Event_Single->display_order_venue |
|
181 | - : EED_Event_Single::EVENT_VENUES_PRIORITY; |
|
182 | - $CFG->EED_Event_Single = new EE_Event_Single_Config(); |
|
183 | - $CFG->EED_Event_Single->display_status_banner_single = ! empty($REQ['display_status_banner_single']) |
|
184 | - && $REQ['display_status_banner_single']; |
|
185 | - $CFG->EED_Event_Single->display_venue = ! empty($REQ['display_venue']) && $REQ['display_venue']; |
|
186 | - $CFG->EED_Event_Single->use_sortable_display_order = ! empty($REQ['EED_Events_Single_use_sortable_display_order']) |
|
187 | - ? absint($REQ['EED_Events_Single_use_sortable_display_order']) |
|
188 | - : 0; |
|
189 | - $CFG->EED_Event_Single->display_order_event = $CFG->EED_Event_Single->use_sortable_display_order |
|
190 | - ? $display_order_event |
|
191 | - : EED_Event_Single::EVENT_DETAILS_PRIORITY; |
|
192 | - $CFG->EED_Event_Single->display_order_datetimes = $CFG->EED_Event_Single->use_sortable_display_order |
|
193 | - ? $display_order_datetimes |
|
194 | - : EED_Event_Single::EVENT_DATETIMES_PRIORITY; |
|
195 | - $CFG->EED_Event_Single->display_order_tickets = $CFG->EED_Event_Single->use_sortable_display_order |
|
196 | - ? $display_order_tickets |
|
197 | - : EED_Event_Single::EVENT_TICKETS_PRIORITY; |
|
198 | - $CFG->EED_Event_Single->display_order_venue = $CFG->EED_Event_Single->use_sortable_display_order |
|
199 | - ? $display_order_venue |
|
200 | - : EED_Event_Single::EVENT_VENUES_PRIORITY; |
|
201 | - do_action('AHEE__EED_Event_Single__update_template_settings__after_update', $CFG, $REQ); |
|
202 | - return $CFG; |
|
203 | - } |
|
204 | - |
|
205 | - |
|
206 | - /** |
|
207 | - * update_event_single_order |
|
208 | - * |
|
209 | - * @access public |
|
210 | - * @return void |
|
211 | - */ |
|
212 | - public static function update_event_single_order() |
|
213 | - { |
|
214 | - $config_saved = false; |
|
215 | - $template_parts = EED_Event_Single_Caff::getRequest()->getRequestParam('elements'); |
|
216 | - if (! empty($template_parts)) { |
|
217 | - $template_parts = explode(',', trim($template_parts, ',')); |
|
218 | - foreach ($template_parts as $key => $template_part) { |
|
219 | - $template_part = "display_order_$template_part"; |
|
220 | - $priority = ($key * 10) + EED_Event_Single::EVENT_DETAILS_PRIORITY; |
|
221 | - EE_Registry::instance()->CFG->template_settings->EED_Event_Single->{$template_part} = $priority; |
|
222 | - do_action("AHEE__EED_Event_Single__update_event_single_order__$template_part", $priority); |
|
223 | - } |
|
224 | - $config_saved = EE_Registry::instance()->CFG->update_espresso_config(false, false); |
|
225 | - } |
|
226 | - if ($config_saved) { |
|
227 | - EE_Error::add_success(esc_html__('Display Order has been successfully updated.', 'event_espresso')); |
|
228 | - } else { |
|
229 | - EE_Error::add_error( |
|
230 | - esc_html__('Display Order was not updated.', 'event_espresso'), |
|
231 | - __FILE__, |
|
232 | - __FUNCTION__, |
|
233 | - __LINE__ |
|
234 | - ); |
|
235 | - } |
|
236 | - echo wp_json_encode(EE_Error::get_notices(false)); |
|
237 | - exit(); |
|
238 | - } |
|
239 | - |
|
240 | - |
|
241 | - /** |
|
242 | - * run - initial module setup |
|
243 | - * |
|
244 | - * @access public |
|
245 | - * @param WP $WP |
|
246 | - * @return void |
|
247 | - */ |
|
248 | - public function run($WP) |
|
249 | - { |
|
250 | - } |
|
27 | + /** |
|
28 | + * @return EED_Event_Single_Caff |
|
29 | + */ |
|
30 | + public static function instance() |
|
31 | + { |
|
32 | + return parent::get_instance(__CLASS__); |
|
33 | + } |
|
34 | + |
|
35 | + |
|
36 | + /** |
|
37 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
38 | + * |
|
39 | + * @access public |
|
40 | + * @return void |
|
41 | + */ |
|
42 | + public static function set_hooks() |
|
43 | + { |
|
44 | + } |
|
45 | + |
|
46 | + /** |
|
47 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
48 | + * |
|
49 | + * @access public |
|
50 | + * @return void |
|
51 | + */ |
|
52 | + public static function set_hooks_admin() |
|
53 | + { |
|
54 | + self::setDefinitions(); |
|
55 | + add_action( |
|
56 | + 'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_events__template_settings', |
|
57 | + array('EED_Event_Single_Caff', 'load_scripts_styles'), |
|
58 | + 10 |
|
59 | + ); |
|
60 | + add_action( |
|
61 | + 'AHEE__template_settings__template__before_settings_form', |
|
62 | + array('EED_Event_Single_Caff', 'template_settings_form'), |
|
63 | + 10 |
|
64 | + ); |
|
65 | + add_filter( |
|
66 | + 'FHEE__General_Settings_Admin_Page__update_template_settings__data', |
|
67 | + array('EED_Event_Single_Caff', 'update_template_settings'), |
|
68 | + 10, |
|
69 | + 2 |
|
70 | + ); |
|
71 | + // AJAX |
|
72 | + add_action( |
|
73 | + 'wp_ajax_espresso_update_event_single_order', |
|
74 | + array('EED_Event_Single_Caff', 'update_event_single_order') |
|
75 | + ); |
|
76 | + add_action( |
|
77 | + 'wp_ajax_nopriv_espresso_update_event_single_order', |
|
78 | + array('EED_Event_Single_Caff', 'update_event_single_order') |
|
79 | + ); |
|
80 | + } |
|
81 | + |
|
82 | + |
|
83 | + public static function load_scripts_styles() |
|
84 | + { |
|
85 | + add_action('admin_enqueue_scripts', array('EED_Event_Single_Caff', 'enqueue_scripts_styles'), 10); |
|
86 | + } |
|
87 | + |
|
88 | + |
|
89 | + public static function enqueue_scripts_styles() |
|
90 | + { |
|
91 | + wp_register_style( |
|
92 | + 'eed-event-single-sortable', |
|
93 | + EVENT_SINGLE_CAFF_ASSETS_URL . 'eed_event_single_sortable.css', |
|
94 | + array(), |
|
95 | + EVENT_ESPRESSO_VERSION |
|
96 | + ); |
|
97 | + wp_enqueue_style('eed-event-single-sortable'); |
|
98 | + wp_register_script( |
|
99 | + 'eed-event-single-sortable', |
|
100 | + EVENT_SINGLE_CAFF_ASSETS_URL . 'eed_event_single_sortable.js', |
|
101 | + array('jquery-ui-sortable'), |
|
102 | + EVENT_ESPRESSO_VERSION, |
|
103 | + true |
|
104 | + ); |
|
105 | + wp_enqueue_script('eed-event-single-sortable'); |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * Set constants only if they haven't been set yet. |
|
111 | + */ |
|
112 | + public static function setDefinitions() |
|
113 | + { |
|
114 | + if (! defined('EVENT_SINGLE_CAFF_TEMPLATES_PATH')) { |
|
115 | + define('EVENT_SINGLE_CAFF_TEMPLATES_PATH', plugin_dir_path(__FILE__) . 'templates/'); |
|
116 | + define('EVENT_SINGLE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
117 | + } |
|
118 | + } |
|
119 | + |
|
120 | + |
|
121 | + /** |
|
122 | + * template_settings_form |
|
123 | + * |
|
124 | + * @access public |
|
125 | + * @static |
|
126 | + * @return void |
|
127 | + */ |
|
128 | + public static function template_settings_form() |
|
129 | + { |
|
130 | + $config = EE_Registry::instance()->CFG->template_settings; |
|
131 | + $config = isset($config->EED_Event_Single) && $config->EED_Event_Single instanceof EE_Event_Single_Config |
|
132 | + ? $config->EED_Event_Single : new EE_Event_Single_Config(); |
|
133 | + $config->use_sortable_display_order = isset($config->use_sortable_display_order) |
|
134 | + ? $config->use_sortable_display_order : false; |
|
135 | + $config = apply_filters('FHEE__EED_Event_Single__template_settings_form__event_list_config', $config); |
|
136 | + |
|
137 | + $event_single_order_array = array(); |
|
138 | + $event_single_order_array[ $config->display_order_tickets ] = 'tickets'; |
|
139 | + $event_single_order_array[ $config->display_order_datetimes ] = 'datetimes'; |
|
140 | + $event_single_order_array[ $config->display_order_event ] = 'event'; |
|
141 | + $event_single_order_array[ $config->display_order_venue ] = 'venue'; |
|
142 | + // get template parts |
|
143 | + $template_parts = EED_Event_Single::instance()->initialize_template_parts($config); |
|
144 | + // convert to array so that we can add more properties |
|
145 | + $config = get_object_vars($config); |
|
146 | + $config['event_single_display_order'] = $template_parts->generate_sortable_list_of_template_parts( |
|
147 | + 'event-single-sortable-js', |
|
148 | + '', |
|
149 | + 'single-sortable-li single-sortable-js' |
|
150 | + ); |
|
151 | + EEH_Template::display_template( |
|
152 | + EVENT_SINGLE_CAFF_TEMPLATES_PATH . 'admin-event-single-settings.template.php', |
|
153 | + $config |
|
154 | + ); |
|
155 | + } |
|
156 | + |
|
157 | + |
|
158 | + /** |
|
159 | + * update_template_settings |
|
160 | + * |
|
161 | + * @param EE_Template_Config $CFG |
|
162 | + * @param array $REQ |
|
163 | + * @return EE_Template_Config |
|
164 | + */ |
|
165 | + public static function update_template_settings(EE_Template_Config $CFG, $REQ) |
|
166 | + { |
|
167 | + if (! $CFG->EED_Event_Single instanceof EE_Event_Single_Config) { |
|
168 | + $CFG->EED_Event_Single = new EE_Event_Single_Config(); |
|
169 | + } |
|
170 | + $display_order_event = $CFG->EED_Event_Single->display_order_event !== null |
|
171 | + ? $CFG->EED_Event_Single->display_order_event |
|
172 | + : EED_Event_Single::EVENT_DETAILS_PRIORITY; |
|
173 | + $display_order_datetimes = $CFG->EED_Event_Single->display_order_datetimes !== null |
|
174 | + ? $CFG->EED_Event_Single->display_order_datetimes |
|
175 | + : EED_Event_Single::EVENT_DATETIMES_PRIORITY; |
|
176 | + $display_order_tickets = $CFG->EED_Event_Single->display_order_tickets !== null |
|
177 | + ? $CFG->EED_Event_Single->display_order_tickets |
|
178 | + : EED_Event_Single::EVENT_TICKETS_PRIORITY; |
|
179 | + $display_order_venue = $CFG->EED_Event_Single->display_order_venue !== null |
|
180 | + ? $CFG->EED_Event_Single->display_order_venue |
|
181 | + : EED_Event_Single::EVENT_VENUES_PRIORITY; |
|
182 | + $CFG->EED_Event_Single = new EE_Event_Single_Config(); |
|
183 | + $CFG->EED_Event_Single->display_status_banner_single = ! empty($REQ['display_status_banner_single']) |
|
184 | + && $REQ['display_status_banner_single']; |
|
185 | + $CFG->EED_Event_Single->display_venue = ! empty($REQ['display_venue']) && $REQ['display_venue']; |
|
186 | + $CFG->EED_Event_Single->use_sortable_display_order = ! empty($REQ['EED_Events_Single_use_sortable_display_order']) |
|
187 | + ? absint($REQ['EED_Events_Single_use_sortable_display_order']) |
|
188 | + : 0; |
|
189 | + $CFG->EED_Event_Single->display_order_event = $CFG->EED_Event_Single->use_sortable_display_order |
|
190 | + ? $display_order_event |
|
191 | + : EED_Event_Single::EVENT_DETAILS_PRIORITY; |
|
192 | + $CFG->EED_Event_Single->display_order_datetimes = $CFG->EED_Event_Single->use_sortable_display_order |
|
193 | + ? $display_order_datetimes |
|
194 | + : EED_Event_Single::EVENT_DATETIMES_PRIORITY; |
|
195 | + $CFG->EED_Event_Single->display_order_tickets = $CFG->EED_Event_Single->use_sortable_display_order |
|
196 | + ? $display_order_tickets |
|
197 | + : EED_Event_Single::EVENT_TICKETS_PRIORITY; |
|
198 | + $CFG->EED_Event_Single->display_order_venue = $CFG->EED_Event_Single->use_sortable_display_order |
|
199 | + ? $display_order_venue |
|
200 | + : EED_Event_Single::EVENT_VENUES_PRIORITY; |
|
201 | + do_action('AHEE__EED_Event_Single__update_template_settings__after_update', $CFG, $REQ); |
|
202 | + return $CFG; |
|
203 | + } |
|
204 | + |
|
205 | + |
|
206 | + /** |
|
207 | + * update_event_single_order |
|
208 | + * |
|
209 | + * @access public |
|
210 | + * @return void |
|
211 | + */ |
|
212 | + public static function update_event_single_order() |
|
213 | + { |
|
214 | + $config_saved = false; |
|
215 | + $template_parts = EED_Event_Single_Caff::getRequest()->getRequestParam('elements'); |
|
216 | + if (! empty($template_parts)) { |
|
217 | + $template_parts = explode(',', trim($template_parts, ',')); |
|
218 | + foreach ($template_parts as $key => $template_part) { |
|
219 | + $template_part = "display_order_$template_part"; |
|
220 | + $priority = ($key * 10) + EED_Event_Single::EVENT_DETAILS_PRIORITY; |
|
221 | + EE_Registry::instance()->CFG->template_settings->EED_Event_Single->{$template_part} = $priority; |
|
222 | + do_action("AHEE__EED_Event_Single__update_event_single_order__$template_part", $priority); |
|
223 | + } |
|
224 | + $config_saved = EE_Registry::instance()->CFG->update_espresso_config(false, false); |
|
225 | + } |
|
226 | + if ($config_saved) { |
|
227 | + EE_Error::add_success(esc_html__('Display Order has been successfully updated.', 'event_espresso')); |
|
228 | + } else { |
|
229 | + EE_Error::add_error( |
|
230 | + esc_html__('Display Order was not updated.', 'event_espresso'), |
|
231 | + __FILE__, |
|
232 | + __FUNCTION__, |
|
233 | + __LINE__ |
|
234 | + ); |
|
235 | + } |
|
236 | + echo wp_json_encode(EE_Error::get_notices(false)); |
|
237 | + exit(); |
|
238 | + } |
|
239 | + |
|
240 | + |
|
241 | + /** |
|
242 | + * run - initial module setup |
|
243 | + * |
|
244 | + * @access public |
|
245 | + * @param WP $WP |
|
246 | + * @return void |
|
247 | + */ |
|
248 | + public function run($WP) |
|
249 | + { |
|
250 | + } |
|
251 | 251 | } |
@@ -79,12 +79,12 @@ discard block |
||
79 | 79 | */ |
80 | 80 | public static function setDefinitions() |
81 | 81 | { |
82 | - if (! defined('EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH')) { |
|
82 | + if ( ! defined('EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH')) { |
|
83 | 83 | define( |
84 | 84 | 'EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH', |
85 | - str_replace('\\', DS, plugin_dir_path(__FILE__)) . 'templates/' |
|
85 | + str_replace('\\', DS, plugin_dir_path(__FILE__)).'templates/' |
|
86 | 86 | ); |
87 | - define('EVENT_ARCHIVE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
87 | + define('EVENT_ARCHIVE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__).'assets/'); |
|
88 | 88 | } |
89 | 89 | } |
90 | 90 | |
@@ -162,7 +162,7 @@ discard block |
||
162 | 162 | 'archive-sortable-li archive-sortable-js' |
163 | 163 | ); |
164 | 164 | EEH_Template::display_template( |
165 | - EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH . 'admin-event-list-settings.template.php', |
|
165 | + EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH.'admin-event-list-settings.template.php', |
|
166 | 166 | $config |
167 | 167 | ); |
168 | 168 | } |
@@ -240,7 +240,7 @@ discard block |
||
240 | 240 | $config = EE_Registry::instance()->CFG; |
241 | 241 | $config_saved = false; |
242 | 242 | $template_parts = EED_Events_Archive_Caff::getRequest()->getRequestParam('elements'); |
243 | - if (! empty($template_parts)) { |
|
243 | + if ( ! empty($template_parts)) { |
|
244 | 244 | $template_parts = explode(',', trim($template_parts, ',')); |
245 | 245 | foreach ($template_parts as $key => $template_part) { |
246 | 246 | $template_part = "display_order_$template_part"; |
@@ -13,268 +13,268 @@ |
||
13 | 13 | */ |
14 | 14 | class EED_Events_Archive_Caff extends EED_Events_Archive |
15 | 15 | { |
16 | - /** |
|
17 | - * @return EED_Events_Archive_Caff|EED_Module |
|
18 | - */ |
|
19 | - public static function instance() |
|
20 | - { |
|
21 | - return parent::get_instance(__CLASS__); |
|
22 | - } |
|
16 | + /** |
|
17 | + * @return EED_Events_Archive_Caff|EED_Module |
|
18 | + */ |
|
19 | + public static function instance() |
|
20 | + { |
|
21 | + return parent::get_instance(__CLASS__); |
|
22 | + } |
|
23 | 23 | |
24 | 24 | |
25 | - /** |
|
26 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
27 | - * |
|
28 | - * @return void |
|
29 | - */ |
|
30 | - public static function set_hooks() |
|
31 | - { |
|
32 | - } |
|
25 | + /** |
|
26 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
27 | + * |
|
28 | + * @return void |
|
29 | + */ |
|
30 | + public static function set_hooks() |
|
31 | + { |
|
32 | + } |
|
33 | 33 | |
34 | - /** |
|
35 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
36 | - * |
|
37 | - * @access public |
|
38 | - * @return void |
|
39 | - */ |
|
40 | - public static function set_hooks_admin() |
|
41 | - { |
|
42 | - self::setDefinitions(); |
|
43 | - add_action( |
|
44 | - 'AHEE__template_settings__template__before_settings_form', |
|
45 | - array('EED_Events_Archive_Caff', 'template_settings_form'), |
|
46 | - 10 |
|
47 | - ); |
|
48 | - add_filter( |
|
49 | - 'FHEE__General_Settings_Admin_Page__update_template_settings__data', |
|
50 | - array('EED_Events_Archive_Caff', 'update_template_settings'), |
|
51 | - 10, |
|
52 | - 2 |
|
53 | - ); |
|
54 | - // AJAX |
|
55 | - add_action( |
|
56 | - 'wp_ajax_espresso_update_event_archive_order', |
|
57 | - array('EED_Events_Archive_Caff', 'update_event_archive_order') |
|
58 | - ); |
|
59 | - add_action( |
|
60 | - 'wp_ajax_nopriv_espresso_update_event_archive_order', |
|
61 | - array('EED_Events_Archive_Caff', 'update_event_archive_order') |
|
62 | - ); |
|
63 | - } |
|
34 | + /** |
|
35 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
36 | + * |
|
37 | + * @access public |
|
38 | + * @return void |
|
39 | + */ |
|
40 | + public static function set_hooks_admin() |
|
41 | + { |
|
42 | + self::setDefinitions(); |
|
43 | + add_action( |
|
44 | + 'AHEE__template_settings__template__before_settings_form', |
|
45 | + array('EED_Events_Archive_Caff', 'template_settings_form'), |
|
46 | + 10 |
|
47 | + ); |
|
48 | + add_filter( |
|
49 | + 'FHEE__General_Settings_Admin_Page__update_template_settings__data', |
|
50 | + array('EED_Events_Archive_Caff', 'update_template_settings'), |
|
51 | + 10, |
|
52 | + 2 |
|
53 | + ); |
|
54 | + // AJAX |
|
55 | + add_action( |
|
56 | + 'wp_ajax_espresso_update_event_archive_order', |
|
57 | + array('EED_Events_Archive_Caff', 'update_event_archive_order') |
|
58 | + ); |
|
59 | + add_action( |
|
60 | + 'wp_ajax_nopriv_espresso_update_event_archive_order', |
|
61 | + array('EED_Events_Archive_Caff', 'update_event_archive_order') |
|
62 | + ); |
|
63 | + } |
|
64 | 64 | |
65 | 65 | |
66 | - /** |
|
67 | - * run - initial module setup |
|
68 | - * |
|
69 | - * @param WP $WP |
|
70 | - * @return void |
|
71 | - */ |
|
72 | - public function run($WP) |
|
73 | - { |
|
74 | - } |
|
66 | + /** |
|
67 | + * run - initial module setup |
|
68 | + * |
|
69 | + * @param WP $WP |
|
70 | + * @return void |
|
71 | + */ |
|
72 | + public function run($WP) |
|
73 | + { |
|
74 | + } |
|
75 | 75 | |
76 | 76 | |
77 | - /** |
|
78 | - * Conditionally set constants if they haven't been defined yet. |
|
79 | - */ |
|
80 | - public static function setDefinitions() |
|
81 | - { |
|
82 | - if (! defined('EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH')) { |
|
83 | - define( |
|
84 | - 'EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH', |
|
85 | - str_replace('\\', DS, plugin_dir_path(__FILE__)) . 'templates/' |
|
86 | - ); |
|
87 | - define('EVENT_ARCHIVE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
88 | - } |
|
89 | - } |
|
77 | + /** |
|
78 | + * Conditionally set constants if they haven't been defined yet. |
|
79 | + */ |
|
80 | + public static function setDefinitions() |
|
81 | + { |
|
82 | + if (! defined('EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH')) { |
|
83 | + define( |
|
84 | + 'EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH', |
|
85 | + str_replace('\\', DS, plugin_dir_path(__FILE__)) . 'templates/' |
|
86 | + ); |
|
87 | + define('EVENT_ARCHIVE_CAFF_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/'); |
|
88 | + } |
|
89 | + } |
|
90 | 90 | |
91 | 91 | |
92 | - /** |
|
93 | - * @return void |
|
94 | - * @throws DomainException |
|
95 | - * @throws InvalidArgumentException |
|
96 | - * @throws InvalidDataTypeException |
|
97 | - * @throws InvalidInterfaceException |
|
98 | - */ |
|
99 | - public static function template_settings_form() |
|
100 | - { |
|
101 | - /** @var EE_Admin_Page_Loader $admin_page_loader */ |
|
102 | - $admin_page_loader = LoaderFactory::getLoader()->getShared('EE_Admin_Page_Loader'); |
|
103 | - // grab general settings admin page and remove the existing hook callback |
|
104 | - $gen_set_admin = $admin_page_loader->get_admin_page_object('general_settings'); |
|
105 | - if ($gen_set_admin instanceof General_Settings_Admin_Page) { |
|
106 | - remove_action( |
|
107 | - 'AHEE__template_settings__template__before_settings_form', |
|
108 | - array($gen_set_admin, 'template_settings_caff_features'), |
|
109 | - 100 |
|
110 | - ); |
|
111 | - } |
|
112 | - // first just grab the template settings |
|
113 | - $config = EE_Registry::instance()->CFG->template_settings; |
|
114 | - // then if the Event Archive config is valid, use that, else create a new one |
|
115 | - $config = $config instanceof EE_Template_Config |
|
116 | - && $config->EED_Events_Archive instanceof EE_Events_Archive_Config |
|
117 | - ? $config->EED_Events_Archive |
|
118 | - : new EE_Events_Archive_Config(); |
|
119 | - $config = apply_filters( |
|
120 | - 'FHEE__EED_Events_Archive__template_settings_form__event_list_config', |
|
121 | - $config |
|
122 | - ); |
|
123 | - $config->display_status_banner = isset($config->display_status_banner) |
|
124 | - ? $config->display_status_banner |
|
125 | - : 0; |
|
126 | - $config->display_description = isset($config->display_description) |
|
127 | - ? $config->display_description |
|
128 | - : 1; |
|
129 | - $config->display_ticket_selector = isset($config->display_ticket_selector) |
|
130 | - ? $config->display_ticket_selector |
|
131 | - : 0; |
|
132 | - $config->display_datetimes = isset($config->display_datetimes) |
|
133 | - ? $config->display_datetimes |
|
134 | - : 1; |
|
135 | - $config->display_venue = isset($config->display_venue) |
|
136 | - ? $config->display_venue |
|
137 | - : 0; |
|
138 | - $config->display_expired_events = isset($config->display_expired_events) |
|
139 | - ? $config->display_expired_events |
|
140 | - : 0; |
|
141 | - // display order options |
|
142 | - $config->use_sortable_display_order = isset($config->use_sortable_display_order) |
|
143 | - ? $config->use_sortable_display_order |
|
144 | - : false; |
|
145 | - $config->display_order_tickets = isset($config->display_order_tickets) |
|
146 | - ? $config->display_order_tickets |
|
147 | - : 120; |
|
148 | - $config->display_order_datetimes = isset($config->display_order_datetimes) |
|
149 | - ? $config->display_order_datetimes |
|
150 | - : 110; |
|
151 | - $config->display_order_event = isset($config->display_order_event) |
|
152 | - ? $config->display_order_event |
|
153 | - : 100; |
|
154 | - $config->display_order_venue = isset($config->display_order_venue) |
|
155 | - ? $config->display_order_venue |
|
156 | - : 130; |
|
157 | - // get template parts |
|
158 | - $template_parts = EED_Events_Archive::instance()->initialize_template_parts($config); |
|
159 | - // convert to array so that we can add more properties |
|
160 | - $config = get_object_vars($config); |
|
161 | - $config['event_archive_display_order'] = $template_parts->generate_sortable_list_of_template_parts( |
|
162 | - 'event-archive-sortable-js', |
|
163 | - '', |
|
164 | - 'archive-sortable-li archive-sortable-js' |
|
165 | - ); |
|
166 | - EEH_Template::display_template( |
|
167 | - EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH . 'admin-event-list-settings.template.php', |
|
168 | - $config |
|
169 | - ); |
|
170 | - } |
|
92 | + /** |
|
93 | + * @return void |
|
94 | + * @throws DomainException |
|
95 | + * @throws InvalidArgumentException |
|
96 | + * @throws InvalidDataTypeException |
|
97 | + * @throws InvalidInterfaceException |
|
98 | + */ |
|
99 | + public static function template_settings_form() |
|
100 | + { |
|
101 | + /** @var EE_Admin_Page_Loader $admin_page_loader */ |
|
102 | + $admin_page_loader = LoaderFactory::getLoader()->getShared('EE_Admin_Page_Loader'); |
|
103 | + // grab general settings admin page and remove the existing hook callback |
|
104 | + $gen_set_admin = $admin_page_loader->get_admin_page_object('general_settings'); |
|
105 | + if ($gen_set_admin instanceof General_Settings_Admin_Page) { |
|
106 | + remove_action( |
|
107 | + 'AHEE__template_settings__template__before_settings_form', |
|
108 | + array($gen_set_admin, 'template_settings_caff_features'), |
|
109 | + 100 |
|
110 | + ); |
|
111 | + } |
|
112 | + // first just grab the template settings |
|
113 | + $config = EE_Registry::instance()->CFG->template_settings; |
|
114 | + // then if the Event Archive config is valid, use that, else create a new one |
|
115 | + $config = $config instanceof EE_Template_Config |
|
116 | + && $config->EED_Events_Archive instanceof EE_Events_Archive_Config |
|
117 | + ? $config->EED_Events_Archive |
|
118 | + : new EE_Events_Archive_Config(); |
|
119 | + $config = apply_filters( |
|
120 | + 'FHEE__EED_Events_Archive__template_settings_form__event_list_config', |
|
121 | + $config |
|
122 | + ); |
|
123 | + $config->display_status_banner = isset($config->display_status_banner) |
|
124 | + ? $config->display_status_banner |
|
125 | + : 0; |
|
126 | + $config->display_description = isset($config->display_description) |
|
127 | + ? $config->display_description |
|
128 | + : 1; |
|
129 | + $config->display_ticket_selector = isset($config->display_ticket_selector) |
|
130 | + ? $config->display_ticket_selector |
|
131 | + : 0; |
|
132 | + $config->display_datetimes = isset($config->display_datetimes) |
|
133 | + ? $config->display_datetimes |
|
134 | + : 1; |
|
135 | + $config->display_venue = isset($config->display_venue) |
|
136 | + ? $config->display_venue |
|
137 | + : 0; |
|
138 | + $config->display_expired_events = isset($config->display_expired_events) |
|
139 | + ? $config->display_expired_events |
|
140 | + : 0; |
|
141 | + // display order options |
|
142 | + $config->use_sortable_display_order = isset($config->use_sortable_display_order) |
|
143 | + ? $config->use_sortable_display_order |
|
144 | + : false; |
|
145 | + $config->display_order_tickets = isset($config->display_order_tickets) |
|
146 | + ? $config->display_order_tickets |
|
147 | + : 120; |
|
148 | + $config->display_order_datetimes = isset($config->display_order_datetimes) |
|
149 | + ? $config->display_order_datetimes |
|
150 | + : 110; |
|
151 | + $config->display_order_event = isset($config->display_order_event) |
|
152 | + ? $config->display_order_event |
|
153 | + : 100; |
|
154 | + $config->display_order_venue = isset($config->display_order_venue) |
|
155 | + ? $config->display_order_venue |
|
156 | + : 130; |
|
157 | + // get template parts |
|
158 | + $template_parts = EED_Events_Archive::instance()->initialize_template_parts($config); |
|
159 | + // convert to array so that we can add more properties |
|
160 | + $config = get_object_vars($config); |
|
161 | + $config['event_archive_display_order'] = $template_parts->generate_sortable_list_of_template_parts( |
|
162 | + 'event-archive-sortable-js', |
|
163 | + '', |
|
164 | + 'archive-sortable-li archive-sortable-js' |
|
165 | + ); |
|
166 | + EEH_Template::display_template( |
|
167 | + EVENTS_ARCHIVE_CAFF_TEMPLATES_PATH . 'admin-event-list-settings.template.php', |
|
168 | + $config |
|
169 | + ); |
|
170 | + } |
|
171 | 171 | |
172 | 172 | |
173 | - /** |
|
174 | - * @param EE_Template_Config $CFG |
|
175 | - * @param array $REQ |
|
176 | - * @return EE_Template_Config |
|
177 | - */ |
|
178 | - public static function update_template_settings($CFG, $REQ) |
|
179 | - { |
|
180 | - // unless we are resetting the config... |
|
181 | - if ( |
|
182 | - ! isset($REQ['EED_Events_Archive_reset_event_list_settings']) |
|
183 | - || absint($REQ['EED_Events_Archive_reset_event_list_settings']) !== 1 |
|
184 | - ) { |
|
185 | - /** @var EE_Events_Archive_Config $config */ |
|
186 | - $config = $CFG->EED_Events_Archive instanceof EE_Events_Archive_Config |
|
187 | - ? $CFG->EED_Events_Archive |
|
188 | - : new EE_Events_Archive_Config(); |
|
173 | + /** |
|
174 | + * @param EE_Template_Config $CFG |
|
175 | + * @param array $REQ |
|
176 | + * @return EE_Template_Config |
|
177 | + */ |
|
178 | + public static function update_template_settings($CFG, $REQ) |
|
179 | + { |
|
180 | + // unless we are resetting the config... |
|
181 | + if ( |
|
182 | + ! isset($REQ['EED_Events_Archive_reset_event_list_settings']) |
|
183 | + || absint($REQ['EED_Events_Archive_reset_event_list_settings']) !== 1 |
|
184 | + ) { |
|
185 | + /** @var EE_Events_Archive_Config $config */ |
|
186 | + $config = $CFG->EED_Events_Archive instanceof EE_Events_Archive_Config |
|
187 | + ? $CFG->EED_Events_Archive |
|
188 | + : new EE_Events_Archive_Config(); |
|
189 | 189 | |
190 | - $config->display_status_banner = isset($REQ['EED_Events_Archive_display_status_banner']) |
|
191 | - ? absint($REQ['EED_Events_Archive_display_status_banner']) |
|
192 | - : 0; |
|
193 | - $config->display_description = isset($REQ['EED_Events_Archive_display_description']) |
|
194 | - ? absint($REQ['EED_Events_Archive_display_description']) |
|
195 | - : 1; |
|
196 | - $config->display_ticket_selector = isset($REQ['EED_Events_Archive_display_ticket_selector']) |
|
197 | - ? absint($REQ['EED_Events_Archive_display_ticket_selector']) |
|
198 | - : 0; |
|
199 | - $config->display_datetimes = isset($REQ['EED_Events_Archive_display_datetimes']) |
|
200 | - ? absint($REQ['EED_Events_Archive_display_datetimes']) |
|
201 | - : 1; |
|
202 | - $config->display_venue = isset($REQ['EED_Events_Archive_display_venue']) |
|
203 | - ? absint($REQ['EED_Events_Archive_display_venue']) |
|
204 | - : 0; |
|
205 | - $config->display_expired_events = isset($REQ['EED_Events_Archive_display_expired_events']) |
|
206 | - ? absint($REQ['EED_Events_Archive_display_expired_events']) |
|
207 | - : 0; |
|
208 | - $config->use_sortable_display_order = isset($REQ['EED_Events_Archive_use_sortable_display_order']) |
|
209 | - ? absint($REQ['EED_Events_Archive_use_sortable_display_order']) |
|
210 | - : 0; |
|
211 | - $config->display_order_event = $config->display_order_event !== null |
|
212 | - && $config->use_sortable_display_order |
|
213 | - ? $config->display_order_event |
|
214 | - : EED_Events_Archive::EVENT_DETAILS_PRIORITY; |
|
215 | - $config->display_order_datetimes = $config->display_order_datetimes !== null |
|
216 | - && $config->use_sortable_display_order |
|
217 | - ? $config->display_order_datetimes |
|
218 | - : EED_Events_Archive::EVENT_DATETIMES_PRIORITY; |
|
219 | - $config->display_order_tickets = $config->display_order_tickets !== null |
|
220 | - && $config->use_sortable_display_order |
|
221 | - ? $config->display_order_tickets |
|
222 | - : EED_Events_Archive::EVENT_TICKETS_PRIORITY; |
|
223 | - $config->display_order_venue = $config->display_order_venue !== null |
|
224 | - && $config->use_sortable_display_order |
|
225 | - ? $config->display_order_venue |
|
226 | - : EED_Events_Archive::EVENT_VENUES_PRIORITY; |
|
227 | - } else { |
|
228 | - $config = new EE_Events_Archive_Config(); |
|
229 | - } |
|
190 | + $config->display_status_banner = isset($REQ['EED_Events_Archive_display_status_banner']) |
|
191 | + ? absint($REQ['EED_Events_Archive_display_status_banner']) |
|
192 | + : 0; |
|
193 | + $config->display_description = isset($REQ['EED_Events_Archive_display_description']) |
|
194 | + ? absint($REQ['EED_Events_Archive_display_description']) |
|
195 | + : 1; |
|
196 | + $config->display_ticket_selector = isset($REQ['EED_Events_Archive_display_ticket_selector']) |
|
197 | + ? absint($REQ['EED_Events_Archive_display_ticket_selector']) |
|
198 | + : 0; |
|
199 | + $config->display_datetimes = isset($REQ['EED_Events_Archive_display_datetimes']) |
|
200 | + ? absint($REQ['EED_Events_Archive_display_datetimes']) |
|
201 | + : 1; |
|
202 | + $config->display_venue = isset($REQ['EED_Events_Archive_display_venue']) |
|
203 | + ? absint($REQ['EED_Events_Archive_display_venue']) |
|
204 | + : 0; |
|
205 | + $config->display_expired_events = isset($REQ['EED_Events_Archive_display_expired_events']) |
|
206 | + ? absint($REQ['EED_Events_Archive_display_expired_events']) |
|
207 | + : 0; |
|
208 | + $config->use_sortable_display_order = isset($REQ['EED_Events_Archive_use_sortable_display_order']) |
|
209 | + ? absint($REQ['EED_Events_Archive_use_sortable_display_order']) |
|
210 | + : 0; |
|
211 | + $config->display_order_event = $config->display_order_event !== null |
|
212 | + && $config->use_sortable_display_order |
|
213 | + ? $config->display_order_event |
|
214 | + : EED_Events_Archive::EVENT_DETAILS_PRIORITY; |
|
215 | + $config->display_order_datetimes = $config->display_order_datetimes !== null |
|
216 | + && $config->use_sortable_display_order |
|
217 | + ? $config->display_order_datetimes |
|
218 | + : EED_Events_Archive::EVENT_DATETIMES_PRIORITY; |
|
219 | + $config->display_order_tickets = $config->display_order_tickets !== null |
|
220 | + && $config->use_sortable_display_order |
|
221 | + ? $config->display_order_tickets |
|
222 | + : EED_Events_Archive::EVENT_TICKETS_PRIORITY; |
|
223 | + $config->display_order_venue = $config->display_order_venue !== null |
|
224 | + && $config->use_sortable_display_order |
|
225 | + ? $config->display_order_venue |
|
226 | + : EED_Events_Archive::EVENT_VENUES_PRIORITY; |
|
227 | + } else { |
|
228 | + $config = new EE_Events_Archive_Config(); |
|
229 | + } |
|
230 | 230 | |
231 | - $CFG->EED_Events_Archive = $config; |
|
232 | - do_action('AHEE__EED_Events_Archive__update_template_settings__after_update', $CFG, $REQ); |
|
233 | - return $CFG; |
|
234 | - } |
|
231 | + $CFG->EED_Events_Archive = $config; |
|
232 | + do_action('AHEE__EED_Events_Archive__update_template_settings__after_update', $CFG, $REQ); |
|
233 | + return $CFG; |
|
234 | + } |
|
235 | 235 | |
236 | 236 | |
237 | - /** |
|
238 | - * @return void |
|
239 | - * @throws InvalidArgumentException |
|
240 | - * @throws InvalidDataTypeException |
|
241 | - * @throws InvalidInterfaceException |
|
242 | - */ |
|
243 | - public static function update_event_archive_order() |
|
244 | - { |
|
245 | - /** @var EE_Config $config */ |
|
246 | - $config = EE_Registry::instance()->CFG; |
|
247 | - $config_saved = false; |
|
248 | - $template_parts = EED_Events_Archive_Caff::getRequest()->getRequestParam('elements'); |
|
249 | - if (! empty($template_parts)) { |
|
250 | - $template_parts = explode(',', trim($template_parts, ',')); |
|
251 | - foreach ($template_parts as $key => $template_part) { |
|
252 | - $template_part = "display_order_$template_part"; |
|
253 | - $priority = ($key * 10) + EED_Events_Archive::EVENT_DETAILS_PRIORITY; |
|
254 | - if ( |
|
255 | - $config->template_settings->EED_Events_Archive instanceof EE_Events_Archive_Config |
|
256 | - && property_exists( |
|
257 | - $config->template_settings->EED_Events_Archive, |
|
258 | - $template_part |
|
259 | - ) |
|
260 | - ) { |
|
261 | - $config->template_settings->EED_Events_Archive->{$template_part} = $priority; |
|
262 | - } |
|
263 | - do_action("AHEE__EED_Events_Archive__update_event_archive_order__$template_part", $priority); |
|
264 | - } |
|
265 | - $config_saved = $config->update_espresso_config(false, false); |
|
266 | - } |
|
267 | - if ($config_saved) { |
|
268 | - EE_Error::add_success(esc_html__('Display Order has been successfully updated.', 'event_espresso')); |
|
269 | - } else { |
|
270 | - EE_Error::add_error( |
|
271 | - esc_html__('Display Order was not updated.', 'event_espresso'), |
|
272 | - __FILE__, |
|
273 | - __FUNCTION__, |
|
274 | - __LINE__ |
|
275 | - ); |
|
276 | - } |
|
277 | - echo wp_json_encode(EE_Error::get_notices(false)); |
|
278 | - exit(); |
|
279 | - } |
|
237 | + /** |
|
238 | + * @return void |
|
239 | + * @throws InvalidArgumentException |
|
240 | + * @throws InvalidDataTypeException |
|
241 | + * @throws InvalidInterfaceException |
|
242 | + */ |
|
243 | + public static function update_event_archive_order() |
|
244 | + { |
|
245 | + /** @var EE_Config $config */ |
|
246 | + $config = EE_Registry::instance()->CFG; |
|
247 | + $config_saved = false; |
|
248 | + $template_parts = EED_Events_Archive_Caff::getRequest()->getRequestParam('elements'); |
|
249 | + if (! empty($template_parts)) { |
|
250 | + $template_parts = explode(',', trim($template_parts, ',')); |
|
251 | + foreach ($template_parts as $key => $template_part) { |
|
252 | + $template_part = "display_order_$template_part"; |
|
253 | + $priority = ($key * 10) + EED_Events_Archive::EVENT_DETAILS_PRIORITY; |
|
254 | + if ( |
|
255 | + $config->template_settings->EED_Events_Archive instanceof EE_Events_Archive_Config |
|
256 | + && property_exists( |
|
257 | + $config->template_settings->EED_Events_Archive, |
|
258 | + $template_part |
|
259 | + ) |
|
260 | + ) { |
|
261 | + $config->template_settings->EED_Events_Archive->{$template_part} = $priority; |
|
262 | + } |
|
263 | + do_action("AHEE__EED_Events_Archive__update_event_archive_order__$template_part", $priority); |
|
264 | + } |
|
265 | + $config_saved = $config->update_espresso_config(false, false); |
|
266 | + } |
|
267 | + if ($config_saved) { |
|
268 | + EE_Error::add_success(esc_html__('Display Order has been successfully updated.', 'event_espresso')); |
|
269 | + } else { |
|
270 | + EE_Error::add_error( |
|
271 | + esc_html__('Display Order was not updated.', 'event_espresso'), |
|
272 | + __FILE__, |
|
273 | + __FUNCTION__, |
|
274 | + __LINE__ |
|
275 | + ); |
|
276 | + } |
|
277 | + echo wp_json_encode(EE_Error::get_notices(false)); |
|
278 | + exit(); |
|
279 | + } |
|
280 | 280 | } |
@@ -133,7 +133,7 @@ discard block |
||
133 | 133 | } |
134 | 134 | define( |
135 | 135 | 'RECAPTCHA_BASE_PATH', |
136 | - rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/') . '/' |
|
136 | + rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/').'/' |
|
137 | 137 | ); |
138 | 138 | define('RECAPTCHA_BASE_URL', plugin_dir_url(__FILE__)); |
139 | 139 | } |
@@ -187,14 +187,14 @@ discard block |
||
187 | 187 | { |
188 | 188 | wp_register_script( |
189 | 189 | 'espresso_recaptcha', |
190 | - RECAPTCHA_BASE_URL . 'scripts/espresso_recaptcha.js', |
|
190 | + RECAPTCHA_BASE_URL.'scripts/espresso_recaptcha.js', |
|
191 | 191 | array('single_page_checkout'), |
192 | 192 | EVENT_ESPRESSO_VERSION, |
193 | 193 | true |
194 | 194 | ); |
195 | 195 | wp_register_script( |
196 | 196 | 'google_recaptcha', |
197 | - 'https://www.google.com/recaptcha/api.js?hl=' . EED_Recaptcha::$config->recaptcha_language, |
|
197 | + 'https://www.google.com/recaptcha/api.js?hl='.EED_Recaptcha::$config->recaptcha_language, |
|
198 | 198 | array('espresso_recaptcha'), |
199 | 199 | EVENT_ESPRESSO_VERSION, |
200 | 200 | true |
@@ -253,7 +253,7 @@ discard block |
||
253 | 253 | if (EED_Recaptcha::useRecaptcha() && ! EED_Recaptcha::$_not_a_robot) { |
254 | 254 | // only display if they have NOT passed the test yet |
255 | 255 | EEH_Template::display_template( |
256 | - RECAPTCHA_BASE_PATH . '/templates/recaptcha.template.php', |
|
256 | + RECAPTCHA_BASE_PATH.'/templates/recaptcha.template.php', |
|
257 | 257 | array( |
258 | 258 | 'recaptcha_publickey' => EED_Recaptcha::$config->recaptcha_publickey, |
259 | 259 | 'recaptcha_theme' => EED_Recaptcha::$config->recaptcha_theme, |
@@ -298,7 +298,7 @@ discard block |
||
298 | 298 | $recaptcha_passed = filter_var($recaptcha_passed, FILTER_VALIDATE_BOOLEAN); |
299 | 299 | // verify recaptcha |
300 | 300 | EED_Recaptcha::_get_recaptcha_response(); |
301 | - if (! $recaptcha_passed && EED_Recaptcha::$_recaptcha_response) { |
|
301 | + if ( ! $recaptcha_passed && EED_Recaptcha::$_recaptcha_response) { |
|
302 | 302 | $recaptcha_passed = EED_Recaptcha::_process_recaptcha_response(); |
303 | 303 | EE_Registry::instance()->SSN->set_session_data(array('recaptcha_passed' => $recaptcha_passed)); |
304 | 304 | } |
@@ -375,8 +375,8 @@ discard block |
||
375 | 375 | private static function _process_recaptcha_response() |
376 | 376 | { |
377 | 377 | // verify library is loaded |
378 | - if (! class_exists('\ReCaptcha\ReCaptcha')) { |
|
379 | - require_once RECAPTCHA_BASE_PATH . '/autoload.php'; |
|
378 | + if ( ! class_exists('\ReCaptcha\ReCaptcha')) { |
|
379 | + require_once RECAPTCHA_BASE_PATH.'/autoload.php'; |
|
380 | 380 | } |
381 | 381 | // The response from reCAPTCHA |
382 | 382 | EED_Recaptcha::_get_recaptcha_response(); |
@@ -17,382 +17,382 @@ |
||
17 | 17 | */ |
18 | 18 | class EED_Recaptcha extends EED_Module |
19 | 19 | { |
20 | - /** |
|
21 | - * @var EE_Registration_Config $config |
|
22 | - */ |
|
23 | - private static $config; |
|
24 | - |
|
25 | - /** |
|
26 | - * @type bool $_not_a_robot |
|
27 | - */ |
|
28 | - private static $_not_a_robot; |
|
29 | - |
|
30 | - /** |
|
31 | - * @type string $_recaptcha_response |
|
32 | - */ |
|
33 | - private static $_recaptcha_response; |
|
34 | - |
|
35 | - |
|
36 | - /** |
|
37 | - * @return EED_Module|EED_Recaptcha |
|
38 | - */ |
|
39 | - public static function instance() |
|
40 | - { |
|
41 | - return parent::get_instance(__CLASS__); |
|
42 | - } |
|
43 | - |
|
44 | - |
|
45 | - /** |
|
46 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
47 | - * |
|
48 | - * @return void |
|
49 | - * @throws InvalidArgumentException |
|
50 | - * @throws InvalidInterfaceException |
|
51 | - * @throws InvalidDataTypeException |
|
52 | - */ |
|
53 | - public static function set_hooks() |
|
54 | - { |
|
55 | - EED_Recaptcha::$config = EE_Registry::instance()->CFG->registration; |
|
56 | - // use_captcha ? |
|
57 | - if ( |
|
58 | - EED_Recaptcha::useRecaptcha() |
|
59 | - && EED_Recaptcha::notPaymentOptionsRevisit() |
|
60 | - ) { |
|
61 | - EED_Recaptcha::set_definitions(); |
|
62 | - EED_Recaptcha::enqueue_styles_and_scripts(); |
|
63 | - add_action('wp', array('EED_Recaptcha', 'set_late_hooks'), 1, 0); |
|
64 | - add_action( |
|
65 | - 'AHEE__before_spco_whats_next_buttons', |
|
66 | - array('EED_Recaptcha', 'display_recaptcha'), |
|
67 | - 10, |
|
68 | - 0 |
|
69 | - ); |
|
70 | - add_filter( |
|
71 | - 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
72 | - array('EED_Recaptcha', 'not_a_robot') |
|
73 | - ); |
|
74 | - add_filter( |
|
75 | - 'FHEE__EE_SPCO_Reg_Step__set_completed___completed', |
|
76 | - array('EED_Recaptcha', 'not_a_robot') |
|
77 | - ); |
|
78 | - add_filter( |
|
79 | - 'FHEE__EE_SPCO_JSON_Response___toString__JSON_response', |
|
80 | - array('EED_Recaptcha', 'recaptcha_response') |
|
81 | - ); |
|
82 | - add_filter( |
|
83 | - 'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array', |
|
84 | - array('EED_Recaptcha', 'bypass_recaptcha_for_spco_load_payment_method') |
|
85 | - ); |
|
86 | - } |
|
87 | - } |
|
88 | - |
|
89 | - |
|
90 | - /** |
|
91 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
92 | - * |
|
93 | - * @return void |
|
94 | - * @throws InvalidArgumentException |
|
95 | - * @throws InvalidInterfaceException |
|
96 | - * @throws InvalidDataTypeException |
|
97 | - */ |
|
98 | - public static function set_hooks_admin() |
|
99 | - { |
|
100 | - EED_Recaptcha::$config = EE_Registry::instance()->CFG->registration; |
|
101 | - EED_Recaptcha::set_definitions(); |
|
102 | - // use_captcha ? |
|
103 | - if ( |
|
104 | - EED_Recaptcha::useRecaptcha() |
|
105 | - && EED_Recaptcha::notPaymentOptionsRevisit() |
|
106 | - && EED_Recaptcha::getRequest()->getRequestParam('step', '') !== '' |
|
107 | - ) { |
|
108 | - EED_Recaptcha::enqueue_styles_and_scripts(); |
|
109 | - add_filter( |
|
110 | - 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
111 | - array('EED_Recaptcha', 'not_a_robot') |
|
112 | - ); |
|
113 | - add_filter( |
|
114 | - 'FHEE__EE_SPCO_Reg_Step__set_completed___completed', |
|
115 | - array('EED_Recaptcha', 'not_a_robot') |
|
116 | - ); |
|
117 | - add_filter( |
|
118 | - 'FHEE__EE_SPCO_JSON_Response___toString__JSON_response', |
|
119 | - array('EED_Recaptcha', 'recaptcha_response') |
|
120 | - ); |
|
121 | - } |
|
122 | - } |
|
123 | - |
|
124 | - |
|
125 | - /** |
|
126 | - * @return void |
|
127 | - */ |
|
128 | - public static function set_definitions() |
|
129 | - { |
|
130 | - if (is_user_logged_in()) { |
|
131 | - EED_Recaptcha::$_not_a_robot = true; |
|
132 | - } |
|
133 | - define( |
|
134 | - 'RECAPTCHA_BASE_PATH', |
|
135 | - rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/') . '/' |
|
136 | - ); |
|
137 | - define('RECAPTCHA_BASE_URL', plugin_dir_url(__FILE__)); |
|
138 | - } |
|
139 | - |
|
140 | - |
|
141 | - /** |
|
142 | - * @return void |
|
143 | - */ |
|
144 | - public static function set_late_hooks() |
|
145 | - { |
|
146 | - add_filter( |
|
147 | - 'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', |
|
148 | - array('EED_Recaptcha', 'not_a_robot') |
|
149 | - ); |
|
150 | - } |
|
151 | - |
|
152 | - |
|
153 | - /** |
|
154 | - * @return boolean |
|
155 | - */ |
|
156 | - public static function useRecaptcha() |
|
157 | - { |
|
158 | - return EED_Recaptcha::$config->use_captcha |
|
159 | - && EED_Recaptcha::$config->recaptcha_theme !== 'invisible'; |
|
160 | - } |
|
161 | - |
|
162 | - |
|
163 | - /** |
|
164 | - * @return boolean |
|
165 | - * @throws InvalidArgumentException |
|
166 | - * @throws InvalidInterfaceException |
|
167 | - * @throws InvalidDataTypeException |
|
168 | - */ |
|
169 | - public static function notPaymentOptionsRevisit() |
|
170 | - { |
|
171 | - $request = EED_Recaptcha::getRequest(); |
|
172 | - return ! ( |
|
173 | - $request->getRequestParam('step', '') === 'payment_options' |
|
174 | - && $request->getRequestParam('revisit', false, 'bool') === true |
|
175 | - ); |
|
176 | - } |
|
177 | - |
|
178 | - |
|
179 | - /** |
|
180 | - * @return void |
|
181 | - * @throws InvalidArgumentException |
|
182 | - * @throws InvalidInterfaceException |
|
183 | - * @throws InvalidDataTypeException |
|
184 | - */ |
|
185 | - public static function enqueue_styles_and_scripts() |
|
186 | - { |
|
187 | - wp_register_script( |
|
188 | - 'espresso_recaptcha', |
|
189 | - RECAPTCHA_BASE_URL . 'scripts/espresso_recaptcha.js', |
|
190 | - array('single_page_checkout'), |
|
191 | - EVENT_ESPRESSO_VERSION, |
|
192 | - true |
|
193 | - ); |
|
194 | - wp_register_script( |
|
195 | - 'google_recaptcha', |
|
196 | - 'https://www.google.com/recaptcha/api.js?hl=' . EED_Recaptcha::$config->recaptcha_language, |
|
197 | - array('espresso_recaptcha'), |
|
198 | - EVENT_ESPRESSO_VERSION, |
|
199 | - true |
|
200 | - ); |
|
201 | - EE_Registry::$i18n_js_strings['no_SPCO_error'] = __( |
|
202 | - 'It appears the Single Page Checkout javascript was not loaded properly! Please refresh the page and try again or contact support.', |
|
203 | - 'event_espresso' |
|
204 | - ); |
|
205 | - EE_Registry::$i18n_js_strings['no_recaptcha_error'] = __( |
|
206 | - 'There appears to be a problem with the reCAPTCHA configuration! Please check the admin settings or contact support.', |
|
207 | - 'event_espresso' |
|
208 | - ); |
|
209 | - EE_Registry::$i18n_js_strings['recaptcha_fail'] = __( |
|
210 | - 'Please complete the anti-spam test before proceeding.', |
|
211 | - 'event_espresso' |
|
212 | - ); |
|
213 | - } |
|
214 | - |
|
215 | - |
|
216 | - /** |
|
217 | - * @param WP $WP |
|
218 | - */ |
|
219 | - public function run($WP) |
|
220 | - { |
|
221 | - } |
|
222 | - |
|
223 | - |
|
224 | - /** |
|
225 | - * @return boolean |
|
226 | - * @throws InvalidArgumentException |
|
227 | - * @throws InvalidInterfaceException |
|
228 | - * @throws InvalidDataTypeException |
|
229 | - */ |
|
230 | - public static function not_a_robot() |
|
231 | - { |
|
232 | - return is_bool(EED_Recaptcha::$_not_a_robot) |
|
233 | - ? EED_Recaptcha::$_not_a_robot |
|
234 | - : EED_Recaptcha::recaptcha_passed(); |
|
235 | - } |
|
236 | - |
|
237 | - |
|
238 | - /** |
|
239 | - * @return void |
|
240 | - * @throws DomainException |
|
241 | - * @throws InvalidArgumentException |
|
242 | - * @throws InvalidInterfaceException |
|
243 | - * @throws InvalidDataTypeException |
|
244 | - */ |
|
245 | - public static function display_recaptcha() |
|
246 | - { |
|
247 | - // logged in means you have already passed a turing test of sorts |
|
248 | - if (is_user_logged_in()) { |
|
249 | - return; |
|
250 | - } |
|
251 | - // don't display if not using recaptcha or user is logged in |
|
252 | - if (EED_Recaptcha::useRecaptcha() && ! EED_Recaptcha::$_not_a_robot) { |
|
253 | - // only display if they have NOT passed the test yet |
|
254 | - EEH_Template::display_template( |
|
255 | - RECAPTCHA_BASE_PATH . '/templates/recaptcha.template.php', |
|
256 | - array( |
|
257 | - 'recaptcha_publickey' => EED_Recaptcha::$config->recaptcha_publickey, |
|
258 | - 'recaptcha_theme' => EED_Recaptcha::$config->recaptcha_theme, |
|
259 | - 'recaptcha_type' => EED_Recaptcha::$config->recaptcha_type, |
|
260 | - ) |
|
261 | - ); |
|
262 | - wp_enqueue_script('google_recaptcha'); |
|
263 | - } |
|
264 | - } |
|
265 | - |
|
266 | - |
|
267 | - /** |
|
268 | - * @return array |
|
269 | - * @throws InvalidArgumentException |
|
270 | - * @throws InvalidInterfaceException |
|
271 | - * @throws InvalidDataTypeException |
|
272 | - */ |
|
273 | - public static function bypass_recaptcha_for_spco_load_payment_method() |
|
274 | - { |
|
275 | - return array( |
|
276 | - 'EESID' => EE_Registry::instance()->SSN->id(), |
|
277 | - 'step' => 'payment_options', |
|
278 | - 'action' => 'switch_spco_billing_form', |
|
279 | - ); |
|
280 | - } |
|
281 | - |
|
282 | - |
|
283 | - /** |
|
284 | - * @return boolean |
|
285 | - * @throws InvalidArgumentException |
|
286 | - * @throws InvalidInterfaceException |
|
287 | - * @throws InvalidDataTypeException |
|
288 | - */ |
|
289 | - public static function recaptcha_passed() |
|
290 | - { |
|
291 | - // logged in means you have already passed a turing test of sorts |
|
292 | - if (is_user_logged_in() || EED_Recaptcha::_bypass_recaptcha()) { |
|
293 | - return true; |
|
294 | - } |
|
295 | - // was test already passed? |
|
296 | - $recaptcha_passed = EE_Registry::instance()->SSN->get_session_data('recaptcha_passed'); |
|
297 | - $recaptcha_passed = filter_var($recaptcha_passed, FILTER_VALIDATE_BOOLEAN); |
|
298 | - // verify recaptcha |
|
299 | - EED_Recaptcha::_get_recaptcha_response(); |
|
300 | - if (! $recaptcha_passed && EED_Recaptcha::$_recaptcha_response) { |
|
301 | - $recaptcha_passed = EED_Recaptcha::_process_recaptcha_response(); |
|
302 | - EE_Registry::instance()->SSN->set_session_data(array('recaptcha_passed' => $recaptcha_passed)); |
|
303 | - } |
|
304 | - EED_Recaptcha::$_not_a_robot = $recaptcha_passed; |
|
305 | - return $recaptcha_passed; |
|
306 | - } |
|
307 | - |
|
308 | - |
|
309 | - /** |
|
310 | - * @param array $recaptcha_response |
|
311 | - * @return array |
|
312 | - */ |
|
313 | - public static function recaptcha_response($recaptcha_response = array()) |
|
314 | - { |
|
315 | - if (EED_Recaptcha::_bypass_recaptcha()) { |
|
316 | - $recaptcha_response['bypass_recaptcha'] = true; |
|
317 | - $recaptcha_response['recaptcha_passed'] = true; |
|
318 | - } else { |
|
319 | - $recaptcha_response['recaptcha_passed'] = EED_Recaptcha::$_not_a_robot; |
|
320 | - } |
|
321 | - return $recaptcha_response; |
|
322 | - } |
|
323 | - |
|
324 | - |
|
325 | - /** |
|
326 | - * @return boolean |
|
327 | - */ |
|
328 | - private static function _bypass_recaptcha() |
|
329 | - { |
|
330 | - // an array of key value pairs that must match exactly with the incoming request, |
|
331 | - // in order to bypass recaptcha for the current request ONLY |
|
332 | - $bypass_request_params_array = (array) apply_filters( |
|
333 | - 'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array', |
|
334 | - array() |
|
335 | - ); |
|
336 | - // does $bypass_request_params_array have any values ? |
|
337 | - if (empty($bypass_request_params_array)) { |
|
338 | - return false; |
|
339 | - } |
|
340 | - $request = EED_Recaptcha::getRequest(); |
|
341 | - // initially set bypass to TRUE |
|
342 | - $bypass_recaptcha = true; |
|
343 | - foreach ($bypass_request_params_array as $key => $value) { |
|
344 | - // if $key is not found or value doesn't match exactly, then toggle bypass to FALSE, |
|
345 | - // otherwise carry over it's value. This way, one missed setting results in no bypass |
|
346 | - $bypass_recaptcha = $request->getRequestParam($key) === $value |
|
347 | - ? $bypass_recaptcha |
|
348 | - : false; |
|
349 | - } |
|
350 | - return $bypass_recaptcha; |
|
351 | - } |
|
352 | - |
|
353 | - |
|
354 | - /** |
|
355 | - * @return void |
|
356 | - * @throws InvalidArgumentException |
|
357 | - * @throws InvalidInterfaceException |
|
358 | - * @throws InvalidDataTypeException |
|
359 | - */ |
|
360 | - private static function _get_recaptcha_response() |
|
361 | - { |
|
362 | - EED_Recaptcha::$_recaptcha_response = EED_Recaptcha::getRequest()->getRequestParam( |
|
363 | - 'g-recaptcha-response' |
|
364 | - ); |
|
365 | - } |
|
366 | - |
|
367 | - |
|
368 | - /** |
|
369 | - * @return boolean |
|
370 | - * @throws InvalidArgumentException |
|
371 | - * @throws InvalidInterfaceException |
|
372 | - * @throws InvalidDataTypeException |
|
373 | - */ |
|
374 | - private static function _process_recaptcha_response() |
|
375 | - { |
|
376 | - // verify library is loaded |
|
377 | - if (! class_exists('\ReCaptcha\ReCaptcha')) { |
|
378 | - require_once RECAPTCHA_BASE_PATH . '/autoload.php'; |
|
379 | - } |
|
380 | - // The response from reCAPTCHA |
|
381 | - EED_Recaptcha::_get_recaptcha_response(); |
|
382 | - $recaptcha_response = EED_Recaptcha::$_recaptcha_response; |
|
383 | - // Was there a reCAPTCHA response? |
|
384 | - if ($recaptcha_response) { |
|
385 | - // if allow_url_fopen is Off, then set a different request method |
|
386 | - $request_method = ! ini_get('allow_url_fopen') ? new SocketPost() : null; |
|
387 | - $recaptcha = new ReCaptcha( |
|
388 | - EED_Recaptcha::$config->recaptcha_privatekey, |
|
389 | - $request_method |
|
390 | - ); |
|
391 | - $recaptcha_response = $recaptcha->verify( |
|
392 | - EED_Recaptcha::$_recaptcha_response, |
|
393 | - EED_Recaptcha::getRequest()->getServerParam('REMOTE_ADDR') |
|
394 | - ); |
|
395 | - } |
|
396 | - return $recaptcha_response instanceof Response && $recaptcha_response->isSuccess(); |
|
397 | - } |
|
20 | + /** |
|
21 | + * @var EE_Registration_Config $config |
|
22 | + */ |
|
23 | + private static $config; |
|
24 | + |
|
25 | + /** |
|
26 | + * @type bool $_not_a_robot |
|
27 | + */ |
|
28 | + private static $_not_a_robot; |
|
29 | + |
|
30 | + /** |
|
31 | + * @type string $_recaptcha_response |
|
32 | + */ |
|
33 | + private static $_recaptcha_response; |
|
34 | + |
|
35 | + |
|
36 | + /** |
|
37 | + * @return EED_Module|EED_Recaptcha |
|
38 | + */ |
|
39 | + public static function instance() |
|
40 | + { |
|
41 | + return parent::get_instance(__CLASS__); |
|
42 | + } |
|
43 | + |
|
44 | + |
|
45 | + /** |
|
46 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
47 | + * |
|
48 | + * @return void |
|
49 | + * @throws InvalidArgumentException |
|
50 | + * @throws InvalidInterfaceException |
|
51 | + * @throws InvalidDataTypeException |
|
52 | + */ |
|
53 | + public static function set_hooks() |
|
54 | + { |
|
55 | + EED_Recaptcha::$config = EE_Registry::instance()->CFG->registration; |
|
56 | + // use_captcha ? |
|
57 | + if ( |
|
58 | + EED_Recaptcha::useRecaptcha() |
|
59 | + && EED_Recaptcha::notPaymentOptionsRevisit() |
|
60 | + ) { |
|
61 | + EED_Recaptcha::set_definitions(); |
|
62 | + EED_Recaptcha::enqueue_styles_and_scripts(); |
|
63 | + add_action('wp', array('EED_Recaptcha', 'set_late_hooks'), 1, 0); |
|
64 | + add_action( |
|
65 | + 'AHEE__before_spco_whats_next_buttons', |
|
66 | + array('EED_Recaptcha', 'display_recaptcha'), |
|
67 | + 10, |
|
68 | + 0 |
|
69 | + ); |
|
70 | + add_filter( |
|
71 | + 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
72 | + array('EED_Recaptcha', 'not_a_robot') |
|
73 | + ); |
|
74 | + add_filter( |
|
75 | + 'FHEE__EE_SPCO_Reg_Step__set_completed___completed', |
|
76 | + array('EED_Recaptcha', 'not_a_robot') |
|
77 | + ); |
|
78 | + add_filter( |
|
79 | + 'FHEE__EE_SPCO_JSON_Response___toString__JSON_response', |
|
80 | + array('EED_Recaptcha', 'recaptcha_response') |
|
81 | + ); |
|
82 | + add_filter( |
|
83 | + 'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array', |
|
84 | + array('EED_Recaptcha', 'bypass_recaptcha_for_spco_load_payment_method') |
|
85 | + ); |
|
86 | + } |
|
87 | + } |
|
88 | + |
|
89 | + |
|
90 | + /** |
|
91 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
92 | + * |
|
93 | + * @return void |
|
94 | + * @throws InvalidArgumentException |
|
95 | + * @throws InvalidInterfaceException |
|
96 | + * @throws InvalidDataTypeException |
|
97 | + */ |
|
98 | + public static function set_hooks_admin() |
|
99 | + { |
|
100 | + EED_Recaptcha::$config = EE_Registry::instance()->CFG->registration; |
|
101 | + EED_Recaptcha::set_definitions(); |
|
102 | + // use_captcha ? |
|
103 | + if ( |
|
104 | + EED_Recaptcha::useRecaptcha() |
|
105 | + && EED_Recaptcha::notPaymentOptionsRevisit() |
|
106 | + && EED_Recaptcha::getRequest()->getRequestParam('step', '') !== '' |
|
107 | + ) { |
|
108 | + EED_Recaptcha::enqueue_styles_and_scripts(); |
|
109 | + add_filter( |
|
110 | + 'FHEE__EED_Single_Page_Checkout__init___continue_reg', |
|
111 | + array('EED_Recaptcha', 'not_a_robot') |
|
112 | + ); |
|
113 | + add_filter( |
|
114 | + 'FHEE__EE_SPCO_Reg_Step__set_completed___completed', |
|
115 | + array('EED_Recaptcha', 'not_a_robot') |
|
116 | + ); |
|
117 | + add_filter( |
|
118 | + 'FHEE__EE_SPCO_JSON_Response___toString__JSON_response', |
|
119 | + array('EED_Recaptcha', 'recaptcha_response') |
|
120 | + ); |
|
121 | + } |
|
122 | + } |
|
123 | + |
|
124 | + |
|
125 | + /** |
|
126 | + * @return void |
|
127 | + */ |
|
128 | + public static function set_definitions() |
|
129 | + { |
|
130 | + if (is_user_logged_in()) { |
|
131 | + EED_Recaptcha::$_not_a_robot = true; |
|
132 | + } |
|
133 | + define( |
|
134 | + 'RECAPTCHA_BASE_PATH', |
|
135 | + rtrim(str_replace(array('\\', '/'), '/', plugin_dir_path(__FILE__)), '/') . '/' |
|
136 | + ); |
|
137 | + define('RECAPTCHA_BASE_URL', plugin_dir_url(__FILE__)); |
|
138 | + } |
|
139 | + |
|
140 | + |
|
141 | + /** |
|
142 | + * @return void |
|
143 | + */ |
|
144 | + public static function set_late_hooks() |
|
145 | + { |
|
146 | + add_filter( |
|
147 | + 'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit', |
|
148 | + array('EED_Recaptcha', 'not_a_robot') |
|
149 | + ); |
|
150 | + } |
|
151 | + |
|
152 | + |
|
153 | + /** |
|
154 | + * @return boolean |
|
155 | + */ |
|
156 | + public static function useRecaptcha() |
|
157 | + { |
|
158 | + return EED_Recaptcha::$config->use_captcha |
|
159 | + && EED_Recaptcha::$config->recaptcha_theme !== 'invisible'; |
|
160 | + } |
|
161 | + |
|
162 | + |
|
163 | + /** |
|
164 | + * @return boolean |
|
165 | + * @throws InvalidArgumentException |
|
166 | + * @throws InvalidInterfaceException |
|
167 | + * @throws InvalidDataTypeException |
|
168 | + */ |
|
169 | + public static function notPaymentOptionsRevisit() |
|
170 | + { |
|
171 | + $request = EED_Recaptcha::getRequest(); |
|
172 | + return ! ( |
|
173 | + $request->getRequestParam('step', '') === 'payment_options' |
|
174 | + && $request->getRequestParam('revisit', false, 'bool') === true |
|
175 | + ); |
|
176 | + } |
|
177 | + |
|
178 | + |
|
179 | + /** |
|
180 | + * @return void |
|
181 | + * @throws InvalidArgumentException |
|
182 | + * @throws InvalidInterfaceException |
|
183 | + * @throws InvalidDataTypeException |
|
184 | + */ |
|
185 | + public static function enqueue_styles_and_scripts() |
|
186 | + { |
|
187 | + wp_register_script( |
|
188 | + 'espresso_recaptcha', |
|
189 | + RECAPTCHA_BASE_URL . 'scripts/espresso_recaptcha.js', |
|
190 | + array('single_page_checkout'), |
|
191 | + EVENT_ESPRESSO_VERSION, |
|
192 | + true |
|
193 | + ); |
|
194 | + wp_register_script( |
|
195 | + 'google_recaptcha', |
|
196 | + 'https://www.google.com/recaptcha/api.js?hl=' . EED_Recaptcha::$config->recaptcha_language, |
|
197 | + array('espresso_recaptcha'), |
|
198 | + EVENT_ESPRESSO_VERSION, |
|
199 | + true |
|
200 | + ); |
|
201 | + EE_Registry::$i18n_js_strings['no_SPCO_error'] = __( |
|
202 | + 'It appears the Single Page Checkout javascript was not loaded properly! Please refresh the page and try again or contact support.', |
|
203 | + 'event_espresso' |
|
204 | + ); |
|
205 | + EE_Registry::$i18n_js_strings['no_recaptcha_error'] = __( |
|
206 | + 'There appears to be a problem with the reCAPTCHA configuration! Please check the admin settings or contact support.', |
|
207 | + 'event_espresso' |
|
208 | + ); |
|
209 | + EE_Registry::$i18n_js_strings['recaptcha_fail'] = __( |
|
210 | + 'Please complete the anti-spam test before proceeding.', |
|
211 | + 'event_espresso' |
|
212 | + ); |
|
213 | + } |
|
214 | + |
|
215 | + |
|
216 | + /** |
|
217 | + * @param WP $WP |
|
218 | + */ |
|
219 | + public function run($WP) |
|
220 | + { |
|
221 | + } |
|
222 | + |
|
223 | + |
|
224 | + /** |
|
225 | + * @return boolean |
|
226 | + * @throws InvalidArgumentException |
|
227 | + * @throws InvalidInterfaceException |
|
228 | + * @throws InvalidDataTypeException |
|
229 | + */ |
|
230 | + public static function not_a_robot() |
|
231 | + { |
|
232 | + return is_bool(EED_Recaptcha::$_not_a_robot) |
|
233 | + ? EED_Recaptcha::$_not_a_robot |
|
234 | + : EED_Recaptcha::recaptcha_passed(); |
|
235 | + } |
|
236 | + |
|
237 | + |
|
238 | + /** |
|
239 | + * @return void |
|
240 | + * @throws DomainException |
|
241 | + * @throws InvalidArgumentException |
|
242 | + * @throws InvalidInterfaceException |
|
243 | + * @throws InvalidDataTypeException |
|
244 | + */ |
|
245 | + public static function display_recaptcha() |
|
246 | + { |
|
247 | + // logged in means you have already passed a turing test of sorts |
|
248 | + if (is_user_logged_in()) { |
|
249 | + return; |
|
250 | + } |
|
251 | + // don't display if not using recaptcha or user is logged in |
|
252 | + if (EED_Recaptcha::useRecaptcha() && ! EED_Recaptcha::$_not_a_robot) { |
|
253 | + // only display if they have NOT passed the test yet |
|
254 | + EEH_Template::display_template( |
|
255 | + RECAPTCHA_BASE_PATH . '/templates/recaptcha.template.php', |
|
256 | + array( |
|
257 | + 'recaptcha_publickey' => EED_Recaptcha::$config->recaptcha_publickey, |
|
258 | + 'recaptcha_theme' => EED_Recaptcha::$config->recaptcha_theme, |
|
259 | + 'recaptcha_type' => EED_Recaptcha::$config->recaptcha_type, |
|
260 | + ) |
|
261 | + ); |
|
262 | + wp_enqueue_script('google_recaptcha'); |
|
263 | + } |
|
264 | + } |
|
265 | + |
|
266 | + |
|
267 | + /** |
|
268 | + * @return array |
|
269 | + * @throws InvalidArgumentException |
|
270 | + * @throws InvalidInterfaceException |
|
271 | + * @throws InvalidDataTypeException |
|
272 | + */ |
|
273 | + public static function bypass_recaptcha_for_spco_load_payment_method() |
|
274 | + { |
|
275 | + return array( |
|
276 | + 'EESID' => EE_Registry::instance()->SSN->id(), |
|
277 | + 'step' => 'payment_options', |
|
278 | + 'action' => 'switch_spco_billing_form', |
|
279 | + ); |
|
280 | + } |
|
281 | + |
|
282 | + |
|
283 | + /** |
|
284 | + * @return boolean |
|
285 | + * @throws InvalidArgumentException |
|
286 | + * @throws InvalidInterfaceException |
|
287 | + * @throws InvalidDataTypeException |
|
288 | + */ |
|
289 | + public static function recaptcha_passed() |
|
290 | + { |
|
291 | + // logged in means you have already passed a turing test of sorts |
|
292 | + if (is_user_logged_in() || EED_Recaptcha::_bypass_recaptcha()) { |
|
293 | + return true; |
|
294 | + } |
|
295 | + // was test already passed? |
|
296 | + $recaptcha_passed = EE_Registry::instance()->SSN->get_session_data('recaptcha_passed'); |
|
297 | + $recaptcha_passed = filter_var($recaptcha_passed, FILTER_VALIDATE_BOOLEAN); |
|
298 | + // verify recaptcha |
|
299 | + EED_Recaptcha::_get_recaptcha_response(); |
|
300 | + if (! $recaptcha_passed && EED_Recaptcha::$_recaptcha_response) { |
|
301 | + $recaptcha_passed = EED_Recaptcha::_process_recaptcha_response(); |
|
302 | + EE_Registry::instance()->SSN->set_session_data(array('recaptcha_passed' => $recaptcha_passed)); |
|
303 | + } |
|
304 | + EED_Recaptcha::$_not_a_robot = $recaptcha_passed; |
|
305 | + return $recaptcha_passed; |
|
306 | + } |
|
307 | + |
|
308 | + |
|
309 | + /** |
|
310 | + * @param array $recaptcha_response |
|
311 | + * @return array |
|
312 | + */ |
|
313 | + public static function recaptcha_response($recaptcha_response = array()) |
|
314 | + { |
|
315 | + if (EED_Recaptcha::_bypass_recaptcha()) { |
|
316 | + $recaptcha_response['bypass_recaptcha'] = true; |
|
317 | + $recaptcha_response['recaptcha_passed'] = true; |
|
318 | + } else { |
|
319 | + $recaptcha_response['recaptcha_passed'] = EED_Recaptcha::$_not_a_robot; |
|
320 | + } |
|
321 | + return $recaptcha_response; |
|
322 | + } |
|
323 | + |
|
324 | + |
|
325 | + /** |
|
326 | + * @return boolean |
|
327 | + */ |
|
328 | + private static function _bypass_recaptcha() |
|
329 | + { |
|
330 | + // an array of key value pairs that must match exactly with the incoming request, |
|
331 | + // in order to bypass recaptcha for the current request ONLY |
|
332 | + $bypass_request_params_array = (array) apply_filters( |
|
333 | + 'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array', |
|
334 | + array() |
|
335 | + ); |
|
336 | + // does $bypass_request_params_array have any values ? |
|
337 | + if (empty($bypass_request_params_array)) { |
|
338 | + return false; |
|
339 | + } |
|
340 | + $request = EED_Recaptcha::getRequest(); |
|
341 | + // initially set bypass to TRUE |
|
342 | + $bypass_recaptcha = true; |
|
343 | + foreach ($bypass_request_params_array as $key => $value) { |
|
344 | + // if $key is not found or value doesn't match exactly, then toggle bypass to FALSE, |
|
345 | + // otherwise carry over it's value. This way, one missed setting results in no bypass |
|
346 | + $bypass_recaptcha = $request->getRequestParam($key) === $value |
|
347 | + ? $bypass_recaptcha |
|
348 | + : false; |
|
349 | + } |
|
350 | + return $bypass_recaptcha; |
|
351 | + } |
|
352 | + |
|
353 | + |
|
354 | + /** |
|
355 | + * @return void |
|
356 | + * @throws InvalidArgumentException |
|
357 | + * @throws InvalidInterfaceException |
|
358 | + * @throws InvalidDataTypeException |
|
359 | + */ |
|
360 | + private static function _get_recaptcha_response() |
|
361 | + { |
|
362 | + EED_Recaptcha::$_recaptcha_response = EED_Recaptcha::getRequest()->getRequestParam( |
|
363 | + 'g-recaptcha-response' |
|
364 | + ); |
|
365 | + } |
|
366 | + |
|
367 | + |
|
368 | + /** |
|
369 | + * @return boolean |
|
370 | + * @throws InvalidArgumentException |
|
371 | + * @throws InvalidInterfaceException |
|
372 | + * @throws InvalidDataTypeException |
|
373 | + */ |
|
374 | + private static function _process_recaptcha_response() |
|
375 | + { |
|
376 | + // verify library is loaded |
|
377 | + if (! class_exists('\ReCaptcha\ReCaptcha')) { |
|
378 | + require_once RECAPTCHA_BASE_PATH . '/autoload.php'; |
|
379 | + } |
|
380 | + // The response from reCAPTCHA |
|
381 | + EED_Recaptcha::_get_recaptcha_response(); |
|
382 | + $recaptcha_response = EED_Recaptcha::$_recaptcha_response; |
|
383 | + // Was there a reCAPTCHA response? |
|
384 | + if ($recaptcha_response) { |
|
385 | + // if allow_url_fopen is Off, then set a different request method |
|
386 | + $request_method = ! ini_get('allow_url_fopen') ? new SocketPost() : null; |
|
387 | + $recaptcha = new ReCaptcha( |
|
388 | + EED_Recaptcha::$config->recaptcha_privatekey, |
|
389 | + $request_method |
|
390 | + ); |
|
391 | + $recaptcha_response = $recaptcha->verify( |
|
392 | + EED_Recaptcha::$_recaptcha_response, |
|
393 | + EED_Recaptcha::getRequest()->getServerParam('REMOTE_ADDR') |
|
394 | + ); |
|
395 | + } |
|
396 | + return $recaptcha_response instanceof Response && $recaptcha_response->isSuccess(); |
|
397 | + } |
|
398 | 398 | } |
@@ -15,7 +15,7 @@ discard block |
||
15 | 15 | { |
16 | 16 | $files = []; |
17 | 17 | // read our template dir and build an array of files |
18 | - $directory_handle = opendir(dirname($class_file) . '/lib/templates/css/'); |
|
18 | + $directory_handle = opendir(dirname($class_file).'/lib/templates/css/'); |
|
19 | 19 | //if we managed to open the directory |
20 | 20 | if ($directory_handle) { |
21 | 21 | /** @var RequestInterface $request */ |
@@ -34,7 +34,7 @@ discard block |
||
34 | 34 | while (false !== ($fname = readdir($directory_handle))) { |
35 | 35 | // if the file is not this file, and does not start with a '.' or '..', |
36 | 36 | // then store it for later display |
37 | - if (! in_array($fname, $skip, true)) { |
|
37 | + if ( ! in_array($fname, $skip, true)) { |
|
38 | 38 | $files[] = $fname; |
39 | 39 | } |
40 | 40 | } |
@@ -13,36 +13,36 @@ discard block |
||
13 | 13 | */ |
14 | 14 | function espresso_invoice_template_files($class_file) |
15 | 15 | { |
16 | - $files = []; |
|
17 | - // read our template dir and build an array of files |
|
18 | - $directory_handle = opendir(dirname($class_file) . '/lib/templates/css/'); |
|
19 | - //if we managed to open the directory |
|
20 | - if ($directory_handle) { |
|
21 | - /** @var RequestInterface $request */ |
|
22 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
23 | - $skip = [ |
|
24 | - '.', |
|
25 | - '..', |
|
26 | - '.DS_Store', |
|
27 | - '.svn', |
|
28 | - 'images', |
|
29 | - 'index.php', |
|
30 | - 'print', |
|
31 | - basename($request->getServerParam('PHP_SELF')), |
|
32 | - ]; |
|
33 | - // loop through all of the files |
|
34 | - while (false !== ($fname = readdir($directory_handle))) { |
|
35 | - // if the file is not this file, and does not start with a '.' or '..', |
|
36 | - // then store it for later display |
|
37 | - if (! in_array($fname, $skip, true)) { |
|
38 | - $files[] = $fname; |
|
39 | - } |
|
40 | - } |
|
41 | - // close the directory |
|
42 | - closedir($directory_handle); |
|
43 | - } |
|
16 | + $files = []; |
|
17 | + // read our template dir and build an array of files |
|
18 | + $directory_handle = opendir(dirname($class_file) . '/lib/templates/css/'); |
|
19 | + //if we managed to open the directory |
|
20 | + if ($directory_handle) { |
|
21 | + /** @var RequestInterface $request */ |
|
22 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
23 | + $skip = [ |
|
24 | + '.', |
|
25 | + '..', |
|
26 | + '.DS_Store', |
|
27 | + '.svn', |
|
28 | + 'images', |
|
29 | + 'index.php', |
|
30 | + 'print', |
|
31 | + basename($request->getServerParam('PHP_SELF')), |
|
32 | + ]; |
|
33 | + // loop through all of the files |
|
34 | + while (false !== ($fname = readdir($directory_handle))) { |
|
35 | + // if the file is not this file, and does not start with a '.' or '..', |
|
36 | + // then store it for later display |
|
37 | + if (! in_array($fname, $skip, true)) { |
|
38 | + $files[] = $fname; |
|
39 | + } |
|
40 | + } |
|
41 | + // close the directory |
|
42 | + closedir($directory_handle); |
|
43 | + } |
|
44 | 44 | |
45 | - return $files; |
|
45 | + return $files; |
|
46 | 46 | } |
47 | 47 | |
48 | 48 | |
@@ -56,8 +56,8 @@ discard block |
||
56 | 56 | */ |
57 | 57 | function espresso_invoice_is_selected($input_item, $selected = '') |
58 | 58 | { |
59 | - if ($input_item === $selected) { |
|
60 | - return 'selected'; |
|
61 | - } |
|
62 | - return ''; |
|
59 | + if ($input_item === $selected) { |
|
60 | + return 'selected'; |
|
61 | + } |
|
62 | + return ''; |
|
63 | 63 | } |
64 | 64 | \ No newline at end of file |
@@ -12,46 +12,46 @@ |
||
12 | 12 | */ |
13 | 13 | interface EncryptionMethodInterface |
14 | 14 | { |
15 | - /** |
|
16 | - * returns true if the encryption method is cryptographically secure |
|
17 | - * |
|
18 | - * @return bool |
|
19 | - */ |
|
20 | - public function isCryptographicallySecure(); |
|
21 | - |
|
22 | - |
|
23 | - /** |
|
24 | - * returns true if the method can be used on the current server |
|
25 | - * |
|
26 | - * @return bool |
|
27 | - */ |
|
28 | - public function canUse(); |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * returns a message explaining why the encryption method in question can or can not be used |
|
33 | - * |
|
34 | - * @return string |
|
35 | - */ |
|
36 | - public function canUseNotice(); |
|
37 | - |
|
38 | - |
|
39 | - /** |
|
40 | - * encrypts data |
|
41 | - * |
|
42 | - * @param string $text_to_encrypt - the text to be encrypted |
|
43 | - * @param string $encryption_key_identifier - name of the encryption key to use |
|
44 | - * @return string |
|
45 | - */ |
|
46 | - public function encrypt($text_to_encrypt, $encryption_key_identifier = ''); |
|
47 | - |
|
48 | - |
|
49 | - /** |
|
50 | - * decrypts data |
|
51 | - * |
|
52 | - * @param string $encrypted_text - the text to be decrypted |
|
53 | - * @param string $encryption_key_identifier - name of the encryption key to use |
|
54 | - * @return string |
|
55 | - */ |
|
56 | - public function decrypt($encrypted_text, $encryption_key_identifier = ''); |
|
15 | + /** |
|
16 | + * returns true if the encryption method is cryptographically secure |
|
17 | + * |
|
18 | + * @return bool |
|
19 | + */ |
|
20 | + public function isCryptographicallySecure(); |
|
21 | + |
|
22 | + |
|
23 | + /** |
|
24 | + * returns true if the method can be used on the current server |
|
25 | + * |
|
26 | + * @return bool |
|
27 | + */ |
|
28 | + public function canUse(); |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * returns a message explaining why the encryption method in question can or can not be used |
|
33 | + * |
|
34 | + * @return string |
|
35 | + */ |
|
36 | + public function canUseNotice(); |
|
37 | + |
|
38 | + |
|
39 | + /** |
|
40 | + * encrypts data |
|
41 | + * |
|
42 | + * @param string $text_to_encrypt - the text to be encrypted |
|
43 | + * @param string $encryption_key_identifier - name of the encryption key to use |
|
44 | + * @return string |
|
45 | + */ |
|
46 | + public function encrypt($text_to_encrypt, $encryption_key_identifier = ''); |
|
47 | + |
|
48 | + |
|
49 | + /** |
|
50 | + * decrypts data |
|
51 | + * |
|
52 | + * @param string $encrypted_text - the text to be decrypted |
|
53 | + * @param string $encryption_key_identifier - name of the encryption key to use |
|
54 | + * @return string |
|
55 | + */ |
|
56 | + public function decrypt($encrypted_text, $encryption_key_identifier = ''); |
|
57 | 57 | } |
@@ -120,7 +120,7 @@ discard block |
||
120 | 120 | */ |
121 | 121 | public function canUseNotice() |
122 | 122 | { |
123 | - if (! $this->openssl_installed) { |
|
123 | + if ( ! $this->openssl_installed) { |
|
124 | 124 | return esc_html__( |
125 | 125 | 'The PHP openssl server extension is required to use Openssl encryption. Please contact your hosting provider regarding this issue.', |
126 | 126 | 'event_espresso' |
@@ -219,7 +219,7 @@ discard block |
||
219 | 219 | */ |
220 | 220 | protected function getHashAlgorithm() |
221 | 221 | { |
222 | - if (! $this->hash_algorithm) { |
|
222 | + if ( ! $this->hash_algorithm) { |
|
223 | 223 | // get installed hashing algorithms |
224 | 224 | $hash_algorithms = hash_algos(); |
225 | 225 | // filter array for "sha" algorithms |
@@ -17,266 +17,266 @@ |
||
17 | 17 | */ |
18 | 18 | abstract class OpenSSL implements EncryptionMethodInterface |
19 | 19 | { |
20 | - /** |
|
21 | - * the default OPENSSL digest method to use |
|
22 | - */ |
|
23 | - const DEFAULT_DIGEST_METHOD = 'sha512'; |
|
24 | - |
|
25 | - /** |
|
26 | - * separates the encrypted text from the initialization vector |
|
27 | - */ |
|
28 | - const IV_DELIMITER = ':iv:'; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var Base64Encoder |
|
32 | - */ |
|
33 | - protected $base64_encoder; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var CipherMethod |
|
37 | - */ |
|
38 | - protected $cipher_method; |
|
39 | - |
|
40 | - /** |
|
41 | - * @var array $digest_methods |
|
42 | - */ |
|
43 | - private $digest_methods = []; |
|
44 | - |
|
45 | - /** |
|
46 | - * @var EncryptionKeyManagerInterface |
|
47 | - */ |
|
48 | - protected $encryption_key_manager; |
|
49 | - |
|
50 | - /** |
|
51 | - * @var boolean |
|
52 | - */ |
|
53 | - private $openssl_installed; |
|
54 | - |
|
55 | - /** |
|
56 | - * @var string |
|
57 | - */ |
|
58 | - private $min_php_version; |
|
59 | - |
|
60 | - /** |
|
61 | - * @var string |
|
62 | - */ |
|
63 | - private $hash_algorithm; |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * To use custom a cipher method and/or encryption keys: |
|
68 | - * - extend this class |
|
69 | - * - configure a new CipherMethod / EncryptionKeyManager in the constructor |
|
70 | - * - pass those to this constructor, like so: |
|
71 | - * |
|
72 | - * public function __construct(Base64Encoder $base64_encoder) { |
|
73 | - * parent::__construct( |
|
74 | - * $base64_encoder, |
|
75 | - * new CipherMethod(CIPHER_METHOD, CIPHER_METHOD_OPTION_NAME) |
|
76 | - * new EncryptionKeyManager(CUSTOM_KEY_ID, CUSTOM_KEYS_OPTION_NAME) |
|
77 | - * ); |
|
78 | - * } |
|
79 | - * |
|
80 | - * @param Base64Encoder $base64_encoder |
|
81 | - * @param CipherMethod $cipher_method |
|
82 | - * @param EncryptionKeyManagerInterface|null $encryption_key_manager |
|
83 | - * @param string $min_php_version |
|
84 | - */ |
|
85 | - protected function __construct( |
|
86 | - Base64Encoder $base64_encoder, |
|
87 | - CipherMethod $cipher_method, |
|
88 | - EncryptionKeyManagerInterface $encryption_key_manager, |
|
89 | - $min_php_version |
|
90 | - ) { |
|
91 | - $this->base64_encoder = $base64_encoder; |
|
92 | - $this->cipher_method = $cipher_method; |
|
93 | - $this->encryption_key_manager = $encryption_key_manager; |
|
94 | - $this->min_php_version = $min_php_version; |
|
95 | - $this->openssl_installed = extension_loaded('openssl'); |
|
96 | - } |
|
97 | - |
|
98 | - |
|
99 | - /** |
|
100 | - * @return bool |
|
101 | - */ |
|
102 | - public function isCryptographicallySecure() |
|
103 | - { |
|
104 | - return true; |
|
105 | - } |
|
106 | - |
|
107 | - |
|
108 | - /** |
|
109 | - * @return bool |
|
110 | - */ |
|
111 | - public function canUse() |
|
112 | - { |
|
113 | - return $this->openssl_installed && version_compare(PHP_VERSION, $this->min_php_version, '>='); |
|
114 | - } |
|
115 | - |
|
116 | - |
|
117 | - /** |
|
118 | - * @return string |
|
119 | - */ |
|
120 | - public function canUseNotice() |
|
121 | - { |
|
122 | - if (! $this->openssl_installed) { |
|
123 | - return esc_html__( |
|
124 | - 'The PHP openssl server extension is required to use Openssl encryption. Please contact your hosting provider regarding this issue.', |
|
125 | - 'event_espresso' |
|
126 | - ); |
|
127 | - } |
|
128 | - if (version_compare(PHP_VERSION, $this->min_php_version, '<')) { |
|
129 | - return sprintf( |
|
130 | - esc_html__( |
|
131 | - 'PHP version %1$s or greater is required to use Openssl encryption. Please contact your hosting provider regarding this issue.', |
|
132 | - 'event_espresso' |
|
133 | - ), |
|
134 | - $this->min_php_version |
|
135 | - ); |
|
136 | - } |
|
137 | - return sprintf( |
|
138 | - esc_html__('OpenSSL v1 encryption using %1$s is available for use.', 'event_espresso'), |
|
139 | - OpenSSLv1::CIPHER_METHOD |
|
140 | - ); |
|
141 | - } |
|
142 | - |
|
143 | - |
|
144 | - /** |
|
145 | - * Computes the digest hash value using the specified digest method. |
|
146 | - * If that digest method fails to produce a valid hash value, |
|
147 | - * then we'll grab the next digest method and recursively try again until something works. |
|
148 | - * |
|
149 | - * @param string $encryption_key |
|
150 | - * @param string $digest_method |
|
151 | - * @param bool $return_raw_data |
|
152 | - * @return string |
|
153 | - * @throws RuntimeException |
|
154 | - */ |
|
155 | - protected function getDigestHashValue( |
|
156 | - $encryption_key, |
|
157 | - $digest_method = OpenSSL::DEFAULT_DIGEST_METHOD, |
|
158 | - $return_raw_data = false |
|
159 | - ) { |
|
160 | - $digest_hash_value = openssl_digest($encryption_key, $digest_method, $return_raw_data); |
|
161 | - if ($digest_hash_value === false) { |
|
162 | - return $this->getDigestHashValue($this->getDigestMethod()); |
|
163 | - } |
|
164 | - return $digest_hash_value; |
|
165 | - } |
|
166 | - |
|
167 | - |
|
168 | - /** |
|
169 | - * Returns the NEXT element in the $digest_methods array. |
|
170 | - * If the $digest_methods array is empty, then we populate it |
|
171 | - * with the available values returned from openssl_get_md_methods(). |
|
172 | - * |
|
173 | - * @return string |
|
174 | - * @throws RuntimeException |
|
175 | - */ |
|
176 | - private function getDigestMethod() |
|
177 | - { |
|
178 | - $digest_method = prev($this->digest_methods); |
|
179 | - if (empty($this->digest_methods)) { |
|
180 | - $this->digest_methods = openssl_get_md_methods(); |
|
181 | - $digest_method = end($this->digest_methods); |
|
182 | - } |
|
183 | - if ($digest_method === false) { |
|
184 | - throw new RuntimeException( |
|
185 | - esc_html__( |
|
186 | - 'OpenSSL support appears to be enabled on the server, but no digest methods are available. Please contact the server administrator.', |
|
187 | - 'event_espresso' |
|
188 | - ) |
|
189 | - ); |
|
190 | - } |
|
191 | - return $digest_method; |
|
192 | - } |
|
193 | - |
|
194 | - |
|
195 | - /** |
|
196 | - * @param string $encryption_key |
|
197 | - * @return int |
|
198 | - */ |
|
199 | - protected function calculateHashLength($encryption_key) |
|
200 | - { |
|
201 | - // get existing key length |
|
202 | - $prev_key_length = $this->encryption_key_manager->keyLength(); |
|
203 | - // set it to something HUGE |
|
204 | - $this->encryption_key_manager->setKeyLength(512); |
|
205 | - // generate a new weak key, which should just be a really long random string |
|
206 | - $test_text = $this->encryption_key_manager->generateEncryptionKey(false); |
|
207 | - // generate a hash using our test string and our real $encryption_key |
|
208 | - $hash = hash_hmac($this->getHashAlgorithm(), $test_text, $encryption_key, true); |
|
209 | - // reset key length back to original value |
|
210 | - $this->encryption_key_manager->setKeyLength($prev_key_length); |
|
211 | - // return the length of the hash |
|
212 | - return strlen($hash); |
|
213 | - } |
|
214 | - |
|
215 | - |
|
216 | - /** |
|
217 | - * @return string |
|
218 | - */ |
|
219 | - protected function getHashAlgorithm() |
|
220 | - { |
|
221 | - if (! $this->hash_algorithm) { |
|
222 | - // get installed hashing algorithms |
|
223 | - $hash_algorithms = hash_algos(); |
|
224 | - // filter array for "sha" algorithms |
|
225 | - $hash_algorithms = preg_grep('/^sha\d{3}$/i', $hash_algorithms); |
|
226 | - // if no sha algorithms are installed, then just use md5 |
|
227 | - if (empty($hash_algorithms)) { |
|
228 | - $this->hash_algorithm = 'md5'; |
|
229 | - return $this->hash_algorithm; |
|
230 | - } |
|
231 | - // sort ascending using "natural ordering" |
|
232 | - sort($hash_algorithms, SORT_NATURAL); |
|
233 | - // return last item from array, which should be the strongest installed sha hash |
|
234 | - $this->hash_algorithm = array_pop($hash_algorithms); |
|
235 | - } |
|
236 | - return $this->hash_algorithm; |
|
237 | - } |
|
238 | - |
|
239 | - |
|
240 | - /** |
|
241 | - * @param string $encrypted_text |
|
242 | - * @throws RuntimeException |
|
243 | - */ |
|
244 | - protected function validateEncryption($encrypted_text) |
|
245 | - { |
|
246 | - if ($encrypted_text === false) { |
|
247 | - throw new RuntimeException( |
|
248 | - sprintf( |
|
249 | - esc_html__('The following error occurred during OpenSSL encryption: %1$s', 'event_espresso'), |
|
250 | - $this->getOpenSslError() |
|
251 | - ) |
|
252 | - ); |
|
253 | - } |
|
254 | - } |
|
255 | - |
|
256 | - |
|
257 | - /** |
|
258 | - * @return false|string |
|
259 | - */ |
|
260 | - private function getOpenSslError() |
|
261 | - { |
|
262 | - $error = openssl_error_string(); |
|
263 | - return $error ?: esc_html__('Unknown Error', 'event_espresso'); |
|
264 | - } |
|
265 | - |
|
266 | - |
|
267 | - /** |
|
268 | - * @param string $encrypted_text |
|
269 | - * @throws RuntimeException |
|
270 | - */ |
|
271 | - protected function validateDecryption($encrypted_text) |
|
272 | - { |
|
273 | - if ($encrypted_text === false) { |
|
274 | - throw new RuntimeException( |
|
275 | - sprintf( |
|
276 | - esc_html__('OpenSSL decryption failed for the following reason: %1$s', 'event_espresso'), |
|
277 | - $this->getOpenSslError() |
|
278 | - ) |
|
279 | - ); |
|
280 | - } |
|
281 | - } |
|
20 | + /** |
|
21 | + * the default OPENSSL digest method to use |
|
22 | + */ |
|
23 | + const DEFAULT_DIGEST_METHOD = 'sha512'; |
|
24 | + |
|
25 | + /** |
|
26 | + * separates the encrypted text from the initialization vector |
|
27 | + */ |
|
28 | + const IV_DELIMITER = ':iv:'; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var Base64Encoder |
|
32 | + */ |
|
33 | + protected $base64_encoder; |
|
34 | + |
|
35 | + /** |
|
36 | + * @var CipherMethod |
|
37 | + */ |
|
38 | + protected $cipher_method; |
|
39 | + |
|
40 | + /** |
|
41 | + * @var array $digest_methods |
|
42 | + */ |
|
43 | + private $digest_methods = []; |
|
44 | + |
|
45 | + /** |
|
46 | + * @var EncryptionKeyManagerInterface |
|
47 | + */ |
|
48 | + protected $encryption_key_manager; |
|
49 | + |
|
50 | + /** |
|
51 | + * @var boolean |
|
52 | + */ |
|
53 | + private $openssl_installed; |
|
54 | + |
|
55 | + /** |
|
56 | + * @var string |
|
57 | + */ |
|
58 | + private $min_php_version; |
|
59 | + |
|
60 | + /** |
|
61 | + * @var string |
|
62 | + */ |
|
63 | + private $hash_algorithm; |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * To use custom a cipher method and/or encryption keys: |
|
68 | + * - extend this class |
|
69 | + * - configure a new CipherMethod / EncryptionKeyManager in the constructor |
|
70 | + * - pass those to this constructor, like so: |
|
71 | + * |
|
72 | + * public function __construct(Base64Encoder $base64_encoder) { |
|
73 | + * parent::__construct( |
|
74 | + * $base64_encoder, |
|
75 | + * new CipherMethod(CIPHER_METHOD, CIPHER_METHOD_OPTION_NAME) |
|
76 | + * new EncryptionKeyManager(CUSTOM_KEY_ID, CUSTOM_KEYS_OPTION_NAME) |
|
77 | + * ); |
|
78 | + * } |
|
79 | + * |
|
80 | + * @param Base64Encoder $base64_encoder |
|
81 | + * @param CipherMethod $cipher_method |
|
82 | + * @param EncryptionKeyManagerInterface|null $encryption_key_manager |
|
83 | + * @param string $min_php_version |
|
84 | + */ |
|
85 | + protected function __construct( |
|
86 | + Base64Encoder $base64_encoder, |
|
87 | + CipherMethod $cipher_method, |
|
88 | + EncryptionKeyManagerInterface $encryption_key_manager, |
|
89 | + $min_php_version |
|
90 | + ) { |
|
91 | + $this->base64_encoder = $base64_encoder; |
|
92 | + $this->cipher_method = $cipher_method; |
|
93 | + $this->encryption_key_manager = $encryption_key_manager; |
|
94 | + $this->min_php_version = $min_php_version; |
|
95 | + $this->openssl_installed = extension_loaded('openssl'); |
|
96 | + } |
|
97 | + |
|
98 | + |
|
99 | + /** |
|
100 | + * @return bool |
|
101 | + */ |
|
102 | + public function isCryptographicallySecure() |
|
103 | + { |
|
104 | + return true; |
|
105 | + } |
|
106 | + |
|
107 | + |
|
108 | + /** |
|
109 | + * @return bool |
|
110 | + */ |
|
111 | + public function canUse() |
|
112 | + { |
|
113 | + return $this->openssl_installed && version_compare(PHP_VERSION, $this->min_php_version, '>='); |
|
114 | + } |
|
115 | + |
|
116 | + |
|
117 | + /** |
|
118 | + * @return string |
|
119 | + */ |
|
120 | + public function canUseNotice() |
|
121 | + { |
|
122 | + if (! $this->openssl_installed) { |
|
123 | + return esc_html__( |
|
124 | + 'The PHP openssl server extension is required to use Openssl encryption. Please contact your hosting provider regarding this issue.', |
|
125 | + 'event_espresso' |
|
126 | + ); |
|
127 | + } |
|
128 | + if (version_compare(PHP_VERSION, $this->min_php_version, '<')) { |
|
129 | + return sprintf( |
|
130 | + esc_html__( |
|
131 | + 'PHP version %1$s or greater is required to use Openssl encryption. Please contact your hosting provider regarding this issue.', |
|
132 | + 'event_espresso' |
|
133 | + ), |
|
134 | + $this->min_php_version |
|
135 | + ); |
|
136 | + } |
|
137 | + return sprintf( |
|
138 | + esc_html__('OpenSSL v1 encryption using %1$s is available for use.', 'event_espresso'), |
|
139 | + OpenSSLv1::CIPHER_METHOD |
|
140 | + ); |
|
141 | + } |
|
142 | + |
|
143 | + |
|
144 | + /** |
|
145 | + * Computes the digest hash value using the specified digest method. |
|
146 | + * If that digest method fails to produce a valid hash value, |
|
147 | + * then we'll grab the next digest method and recursively try again until something works. |
|
148 | + * |
|
149 | + * @param string $encryption_key |
|
150 | + * @param string $digest_method |
|
151 | + * @param bool $return_raw_data |
|
152 | + * @return string |
|
153 | + * @throws RuntimeException |
|
154 | + */ |
|
155 | + protected function getDigestHashValue( |
|
156 | + $encryption_key, |
|
157 | + $digest_method = OpenSSL::DEFAULT_DIGEST_METHOD, |
|
158 | + $return_raw_data = false |
|
159 | + ) { |
|
160 | + $digest_hash_value = openssl_digest($encryption_key, $digest_method, $return_raw_data); |
|
161 | + if ($digest_hash_value === false) { |
|
162 | + return $this->getDigestHashValue($this->getDigestMethod()); |
|
163 | + } |
|
164 | + return $digest_hash_value; |
|
165 | + } |
|
166 | + |
|
167 | + |
|
168 | + /** |
|
169 | + * Returns the NEXT element in the $digest_methods array. |
|
170 | + * If the $digest_methods array is empty, then we populate it |
|
171 | + * with the available values returned from openssl_get_md_methods(). |
|
172 | + * |
|
173 | + * @return string |
|
174 | + * @throws RuntimeException |
|
175 | + */ |
|
176 | + private function getDigestMethod() |
|
177 | + { |
|
178 | + $digest_method = prev($this->digest_methods); |
|
179 | + if (empty($this->digest_methods)) { |
|
180 | + $this->digest_methods = openssl_get_md_methods(); |
|
181 | + $digest_method = end($this->digest_methods); |
|
182 | + } |
|
183 | + if ($digest_method === false) { |
|
184 | + throw new RuntimeException( |
|
185 | + esc_html__( |
|
186 | + 'OpenSSL support appears to be enabled on the server, but no digest methods are available. Please contact the server administrator.', |
|
187 | + 'event_espresso' |
|
188 | + ) |
|
189 | + ); |
|
190 | + } |
|
191 | + return $digest_method; |
|
192 | + } |
|
193 | + |
|
194 | + |
|
195 | + /** |
|
196 | + * @param string $encryption_key |
|
197 | + * @return int |
|
198 | + */ |
|
199 | + protected function calculateHashLength($encryption_key) |
|
200 | + { |
|
201 | + // get existing key length |
|
202 | + $prev_key_length = $this->encryption_key_manager->keyLength(); |
|
203 | + // set it to something HUGE |
|
204 | + $this->encryption_key_manager->setKeyLength(512); |
|
205 | + // generate a new weak key, which should just be a really long random string |
|
206 | + $test_text = $this->encryption_key_manager->generateEncryptionKey(false); |
|
207 | + // generate a hash using our test string and our real $encryption_key |
|
208 | + $hash = hash_hmac($this->getHashAlgorithm(), $test_text, $encryption_key, true); |
|
209 | + // reset key length back to original value |
|
210 | + $this->encryption_key_manager->setKeyLength($prev_key_length); |
|
211 | + // return the length of the hash |
|
212 | + return strlen($hash); |
|
213 | + } |
|
214 | + |
|
215 | + |
|
216 | + /** |
|
217 | + * @return string |
|
218 | + */ |
|
219 | + protected function getHashAlgorithm() |
|
220 | + { |
|
221 | + if (! $this->hash_algorithm) { |
|
222 | + // get installed hashing algorithms |
|
223 | + $hash_algorithms = hash_algos(); |
|
224 | + // filter array for "sha" algorithms |
|
225 | + $hash_algorithms = preg_grep('/^sha\d{3}$/i', $hash_algorithms); |
|
226 | + // if no sha algorithms are installed, then just use md5 |
|
227 | + if (empty($hash_algorithms)) { |
|
228 | + $this->hash_algorithm = 'md5'; |
|
229 | + return $this->hash_algorithm; |
|
230 | + } |
|
231 | + // sort ascending using "natural ordering" |
|
232 | + sort($hash_algorithms, SORT_NATURAL); |
|
233 | + // return last item from array, which should be the strongest installed sha hash |
|
234 | + $this->hash_algorithm = array_pop($hash_algorithms); |
|
235 | + } |
|
236 | + return $this->hash_algorithm; |
|
237 | + } |
|
238 | + |
|
239 | + |
|
240 | + /** |
|
241 | + * @param string $encrypted_text |
|
242 | + * @throws RuntimeException |
|
243 | + */ |
|
244 | + protected function validateEncryption($encrypted_text) |
|
245 | + { |
|
246 | + if ($encrypted_text === false) { |
|
247 | + throw new RuntimeException( |
|
248 | + sprintf( |
|
249 | + esc_html__('The following error occurred during OpenSSL encryption: %1$s', 'event_espresso'), |
|
250 | + $this->getOpenSslError() |
|
251 | + ) |
|
252 | + ); |
|
253 | + } |
|
254 | + } |
|
255 | + |
|
256 | + |
|
257 | + /** |
|
258 | + * @return false|string |
|
259 | + */ |
|
260 | + private function getOpenSslError() |
|
261 | + { |
|
262 | + $error = openssl_error_string(); |
|
263 | + return $error ?: esc_html__('Unknown Error', 'event_espresso'); |
|
264 | + } |
|
265 | + |
|
266 | + |
|
267 | + /** |
|
268 | + * @param string $encrypted_text |
|
269 | + * @throws RuntimeException |
|
270 | + */ |
|
271 | + protected function validateDecryption($encrypted_text) |
|
272 | + { |
|
273 | + if ($encrypted_text === false) { |
|
274 | + throw new RuntimeException( |
|
275 | + sprintf( |
|
276 | + esc_html__('OpenSSL decryption failed for the following reason: %1$s', 'event_espresso'), |
|
277 | + $this->getOpenSslError() |
|
278 | + ) |
|
279 | + ); |
|
280 | + } |
|
281 | + } |
|
282 | 282 | } |
@@ -122,7 +122,7 @@ |
||
122 | 122 | // hash the raw encrypted text |
123 | 123 | $hmac = hash_hmac($this->getHashAlgorithm(), $encrypted_text, $key, true); |
124 | 124 | // concatenate everything into one big string and encode it again |
125 | - return $this->base64_encoder->encodeString($iv . $hmac . $encrypted_text); |
|
125 | + return $this->base64_encoder->encodeString($iv.$hmac.$encrypted_text); |
|
126 | 126 | } |
127 | 127 | |
128 | 128 |
@@ -17,155 +17,155 @@ |
||
17 | 17 | */ |
18 | 18 | class OpenSSLv1 extends OpenSSL |
19 | 19 | { |
20 | - /** |
|
21 | - * name used for a default encryption key in case no others are set |
|
22 | - */ |
|
23 | - const DEFAULT_ENCRYPTION_KEY_ID = 'default_openssl_v1_key'; |
|
20 | + /** |
|
21 | + * name used for a default encryption key in case no others are set |
|
22 | + */ |
|
23 | + const DEFAULT_ENCRYPTION_KEY_ID = 'default_openssl_v1_key'; |
|
24 | 24 | |
25 | - /** |
|
26 | - * name used for saving encryption keys to the wp_options table |
|
27 | - */ |
|
28 | - const ENCRYPTION_KEYS_OPTION_NAME = 'ee_openssl_v1_encryption_keys'; |
|
25 | + /** |
|
26 | + * name used for saving encryption keys to the wp_options table |
|
27 | + */ |
|
28 | + const ENCRYPTION_KEYS_OPTION_NAME = 'ee_openssl_v1_encryption_keys'; |
|
29 | 29 | |
30 | - /** |
|
31 | - * the OPENSSL cipher method used |
|
32 | - */ |
|
33 | - const CIPHER_METHOD = 'aes-128-cbc'; |
|
30 | + /** |
|
31 | + * the OPENSSL cipher method used |
|
32 | + */ |
|
33 | + const CIPHER_METHOD = 'aes-128-cbc'; |
|
34 | 34 | |
35 | - /** |
|
36 | - * WP "options_name" used to store a verified available cipher method |
|
37 | - */ |
|
38 | - const CIPHER_METHOD_OPTION_NAME = 'ee_openssl_v1_cipher_method'; |
|
35 | + /** |
|
36 | + * WP "options_name" used to store a verified available cipher method |
|
37 | + */ |
|
38 | + const CIPHER_METHOD_OPTION_NAME = 'ee_openssl_v1_cipher_method'; |
|
39 | 39 | |
40 | 40 | |
41 | - /** |
|
42 | - * To use custom a cipher method and/or encryption keys and/or minimum PHP version: |
|
43 | - * - extend this class |
|
44 | - * - configure a new CipherMethod / EncryptionKeyManager in the constructor |
|
45 | - * - pass those to this constructor, like so: |
|
46 | - * |
|
47 | - * public function __construct(Base64Encoder $base64_encoder) { |
|
48 | - * parent::__construct( |
|
49 | - * $base64_encoder, |
|
50 | - * new CipherMethod(CIPHER_METHOD, CIPHER_METHOD_OPTION_NAME), |
|
51 | - * new EncryptionKeyManager(CUSTOM_KEY_ID, CUSTOM_KEYS_OPTION_NAME), |
|
52 | - * '7.1.0' |
|
53 | - * ); |
|
54 | - * } |
|
55 | - * |
|
56 | - * @param Base64Encoder $base64_encoder |
|
57 | - * @param CipherMethod|null $cipher_method |
|
58 | - * @param EncryptionKeyManagerInterface|null $encryption_key_manager |
|
59 | - * @param string $min_php_version defaults to 5.3.0 (when openssl added) |
|
60 | - */ |
|
61 | - public function __construct( |
|
62 | - Base64Encoder $base64_encoder, |
|
63 | - CipherMethod $cipher_method = null, |
|
64 | - EncryptionKeyManagerInterface $encryption_key_manager = null, |
|
65 | - $min_php_version = '5.3.0' |
|
66 | - ) { |
|
67 | - parent::__construct( |
|
68 | - $base64_encoder, |
|
69 | - $cipher_method instanceof CipherMethod |
|
70 | - ? $cipher_method |
|
71 | - : new CipherMethod( |
|
72 | - OpenSSLv1::CIPHER_METHOD, |
|
73 | - OpenSSLv1::CIPHER_METHOD_OPTION_NAME |
|
74 | - ), |
|
75 | - $encryption_key_manager instanceof EncryptionKeyManager |
|
76 | - ? $encryption_key_manager |
|
77 | - : new EncryptionKeyManager( |
|
78 | - $base64_encoder, |
|
79 | - OpenSSLv1::DEFAULT_ENCRYPTION_KEY_ID, |
|
80 | - OpenSSLv1::ENCRYPTION_KEYS_OPTION_NAME |
|
81 | - ), |
|
82 | - $min_php_version |
|
83 | - ); |
|
84 | - } |
|
41 | + /** |
|
42 | + * To use custom a cipher method and/or encryption keys and/or minimum PHP version: |
|
43 | + * - extend this class |
|
44 | + * - configure a new CipherMethod / EncryptionKeyManager in the constructor |
|
45 | + * - pass those to this constructor, like so: |
|
46 | + * |
|
47 | + * public function __construct(Base64Encoder $base64_encoder) { |
|
48 | + * parent::__construct( |
|
49 | + * $base64_encoder, |
|
50 | + * new CipherMethod(CIPHER_METHOD, CIPHER_METHOD_OPTION_NAME), |
|
51 | + * new EncryptionKeyManager(CUSTOM_KEY_ID, CUSTOM_KEYS_OPTION_NAME), |
|
52 | + * '7.1.0' |
|
53 | + * ); |
|
54 | + * } |
|
55 | + * |
|
56 | + * @param Base64Encoder $base64_encoder |
|
57 | + * @param CipherMethod|null $cipher_method |
|
58 | + * @param EncryptionKeyManagerInterface|null $encryption_key_manager |
|
59 | + * @param string $min_php_version defaults to 5.3.0 (when openssl added) |
|
60 | + */ |
|
61 | + public function __construct( |
|
62 | + Base64Encoder $base64_encoder, |
|
63 | + CipherMethod $cipher_method = null, |
|
64 | + EncryptionKeyManagerInterface $encryption_key_manager = null, |
|
65 | + $min_php_version = '5.3.0' |
|
66 | + ) { |
|
67 | + parent::__construct( |
|
68 | + $base64_encoder, |
|
69 | + $cipher_method instanceof CipherMethod |
|
70 | + ? $cipher_method |
|
71 | + : new CipherMethod( |
|
72 | + OpenSSLv1::CIPHER_METHOD, |
|
73 | + OpenSSLv1::CIPHER_METHOD_OPTION_NAME |
|
74 | + ), |
|
75 | + $encryption_key_manager instanceof EncryptionKeyManager |
|
76 | + ? $encryption_key_manager |
|
77 | + : new EncryptionKeyManager( |
|
78 | + $base64_encoder, |
|
79 | + OpenSSLv1::DEFAULT_ENCRYPTION_KEY_ID, |
|
80 | + OpenSSLv1::ENCRYPTION_KEYS_OPTION_NAME |
|
81 | + ), |
|
82 | + $min_php_version |
|
83 | + ); |
|
84 | + } |
|
85 | 85 | |
86 | 86 | |
87 | - /** |
|
88 | - * encrypts data |
|
89 | - * |
|
90 | - * @param string $text_to_encrypt - the text to be encrypted |
|
91 | - * @param string $encryption_key_identifier - cryptographically secure passphrase. will generate if necessary |
|
92 | - * @return string |
|
93 | - */ |
|
94 | - public function encrypt($text_to_encrypt, $encryption_key_identifier = '') |
|
95 | - { |
|
96 | - $cipher_method = $this->cipher_method->getCipherMethod(); |
|
97 | - $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
98 | - // get initialization vector size |
|
99 | - $iv_length = openssl_cipher_iv_length($cipher_method); |
|
100 | - // generate initialization vector. |
|
101 | - // The second parameter ("crypto_strong") is passed by reference, |
|
102 | - // and is used to determines if the algorithm used was "cryptographically strong" |
|
103 | - // openssl_random_pseudo_bytes() will toggle it to either true or false |
|
104 | - $iv = openssl_random_pseudo_bytes($iv_length, $is_strong); |
|
105 | - if ($iv === false || $is_strong === false) { |
|
106 | - throw new RuntimeException( |
|
107 | - esc_html__('Failed to generate OpenSSL initialization vector.', 'event_espresso') |
|
108 | - ); |
|
109 | - } |
|
110 | - $key = $this->getDigestHashValue($encryption_key); |
|
111 | - // encrypt it |
|
112 | - $encrypted_text = openssl_encrypt( |
|
113 | - $this->base64_encoder->encodeString($text_to_encrypt), // encode to remove special characters |
|
114 | - $cipher_method, |
|
115 | - $key, |
|
116 | - 0, |
|
117 | - $iv |
|
118 | - ); |
|
119 | - $this->validateEncryption($encrypted_text); |
|
120 | - $encrypted_text = trim($encrypted_text); |
|
121 | - // hash the raw encrypted text |
|
122 | - $hmac = hash_hmac($this->getHashAlgorithm(), $encrypted_text, $key, true); |
|
123 | - // concatenate everything into one big string and encode it again |
|
124 | - return $this->base64_encoder->encodeString($iv . $hmac . $encrypted_text); |
|
125 | - } |
|
87 | + /** |
|
88 | + * encrypts data |
|
89 | + * |
|
90 | + * @param string $text_to_encrypt - the text to be encrypted |
|
91 | + * @param string $encryption_key_identifier - cryptographically secure passphrase. will generate if necessary |
|
92 | + * @return string |
|
93 | + */ |
|
94 | + public function encrypt($text_to_encrypt, $encryption_key_identifier = '') |
|
95 | + { |
|
96 | + $cipher_method = $this->cipher_method->getCipherMethod(); |
|
97 | + $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
98 | + // get initialization vector size |
|
99 | + $iv_length = openssl_cipher_iv_length($cipher_method); |
|
100 | + // generate initialization vector. |
|
101 | + // The second parameter ("crypto_strong") is passed by reference, |
|
102 | + // and is used to determines if the algorithm used was "cryptographically strong" |
|
103 | + // openssl_random_pseudo_bytes() will toggle it to either true or false |
|
104 | + $iv = openssl_random_pseudo_bytes($iv_length, $is_strong); |
|
105 | + if ($iv === false || $is_strong === false) { |
|
106 | + throw new RuntimeException( |
|
107 | + esc_html__('Failed to generate OpenSSL initialization vector.', 'event_espresso') |
|
108 | + ); |
|
109 | + } |
|
110 | + $key = $this->getDigestHashValue($encryption_key); |
|
111 | + // encrypt it |
|
112 | + $encrypted_text = openssl_encrypt( |
|
113 | + $this->base64_encoder->encodeString($text_to_encrypt), // encode to remove special characters |
|
114 | + $cipher_method, |
|
115 | + $key, |
|
116 | + 0, |
|
117 | + $iv |
|
118 | + ); |
|
119 | + $this->validateEncryption($encrypted_text); |
|
120 | + $encrypted_text = trim($encrypted_text); |
|
121 | + // hash the raw encrypted text |
|
122 | + $hmac = hash_hmac($this->getHashAlgorithm(), $encrypted_text, $key, true); |
|
123 | + // concatenate everything into one big string and encode it again |
|
124 | + return $this->base64_encoder->encodeString($iv . $hmac . $encrypted_text); |
|
125 | + } |
|
126 | 126 | |
127 | 127 | |
128 | - /** |
|
129 | - * decrypts data |
|
130 | - * |
|
131 | - * @param string $encrypted_text - the text to be decrypted |
|
132 | - * @param string $encryption_key_identifier - cryptographically secure passphrase. will use default if necessary |
|
133 | - * @return string |
|
134 | - */ |
|
135 | - public function decrypt($encrypted_text, $encryption_key_identifier = '') |
|
136 | - { |
|
137 | - $cipher_method = $this->cipher_method->getCipherMethod(); |
|
138 | - $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
139 | - $key = $this->getDigestHashValue($encryption_key); |
|
140 | - // decode our concatenated string |
|
141 | - $encrypted_text = $this->base64_encoder->decodeString($encrypted_text); |
|
142 | - // get the string lengths used for the hash and iv |
|
143 | - $hash_length = $this->calculateHashLength($encryption_key); |
|
144 | - $iv_length = openssl_cipher_iv_length($cipher_method); |
|
145 | - // use the above lengths to snip the required values from the decoded string |
|
146 | - $iv = substr($encrypted_text, 0, $iv_length); |
|
147 | - $hmac = substr($encrypted_text, $iv_length, $hash_length); |
|
148 | - $encrypted_text_raw = substr($encrypted_text, $iv_length + $hash_length); |
|
149 | - // rehash the original raw encrypted text |
|
150 | - $rehash_mac = hash_hmac($this->getHashAlgorithm(), $encrypted_text_raw, $key, true); |
|
151 | - // timing attack safe comparison to determine if anything has changed |
|
152 | - if (hash_equals($hmac, $rehash_mac)) { |
|
153 | - // looks good, decrypt it, trim it, and return it |
|
154 | - $decrypted_text = openssl_decrypt( |
|
155 | - $encrypted_text_raw, |
|
156 | - $this->cipher_method->getCipherMethod(), |
|
157 | - $key, |
|
158 | - 0, |
|
159 | - $iv |
|
160 | - ); |
|
161 | - $this->validateDecryption($decrypted_text); |
|
162 | - return trim($this->base64_encoder->decodeString($decrypted_text)); |
|
163 | - } |
|
164 | - throw new RuntimeException( |
|
165 | - esc_html__( |
|
166 | - 'Decryption failed because a hash comparison of the original text and the decrypted text was not the same, meaning something in the system or the encrypted data has changed.', |
|
167 | - 'event_espresso' |
|
168 | - ) |
|
169 | - ); |
|
170 | - } |
|
128 | + /** |
|
129 | + * decrypts data |
|
130 | + * |
|
131 | + * @param string $encrypted_text - the text to be decrypted |
|
132 | + * @param string $encryption_key_identifier - cryptographically secure passphrase. will use default if necessary |
|
133 | + * @return string |
|
134 | + */ |
|
135 | + public function decrypt($encrypted_text, $encryption_key_identifier = '') |
|
136 | + { |
|
137 | + $cipher_method = $this->cipher_method->getCipherMethod(); |
|
138 | + $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
139 | + $key = $this->getDigestHashValue($encryption_key); |
|
140 | + // decode our concatenated string |
|
141 | + $encrypted_text = $this->base64_encoder->decodeString($encrypted_text); |
|
142 | + // get the string lengths used for the hash and iv |
|
143 | + $hash_length = $this->calculateHashLength($encryption_key); |
|
144 | + $iv_length = openssl_cipher_iv_length($cipher_method); |
|
145 | + // use the above lengths to snip the required values from the decoded string |
|
146 | + $iv = substr($encrypted_text, 0, $iv_length); |
|
147 | + $hmac = substr($encrypted_text, $iv_length, $hash_length); |
|
148 | + $encrypted_text_raw = substr($encrypted_text, $iv_length + $hash_length); |
|
149 | + // rehash the original raw encrypted text |
|
150 | + $rehash_mac = hash_hmac($this->getHashAlgorithm(), $encrypted_text_raw, $key, true); |
|
151 | + // timing attack safe comparison to determine if anything has changed |
|
152 | + if (hash_equals($hmac, $rehash_mac)) { |
|
153 | + // looks good, decrypt it, trim it, and return it |
|
154 | + $decrypted_text = openssl_decrypt( |
|
155 | + $encrypted_text_raw, |
|
156 | + $this->cipher_method->getCipherMethod(), |
|
157 | + $key, |
|
158 | + 0, |
|
159 | + $iv |
|
160 | + ); |
|
161 | + $this->validateDecryption($decrypted_text); |
|
162 | + return trim($this->base64_encoder->decodeString($decrypted_text)); |
|
163 | + } |
|
164 | + throw new RuntimeException( |
|
165 | + esc_html__( |
|
166 | + 'Decryption failed because a hash comparison of the original text and the decrypted text was not the same, meaning something in the system or the encrypted data has changed.', |
|
167 | + 'event_espresso' |
|
168 | + ) |
|
169 | + ); |
|
170 | + } |
|
171 | 171 | } |
@@ -159,7 +159,7 @@ discard block |
||
159 | 159 | update_option($this->cipher_method_option_name, $cipher_method_to_test); |
160 | 160 | } |
161 | 161 | // if we previously removed this cipher method from the list of valid ones, then let's put it back |
162 | - if (! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
162 | + if ( ! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
163 | 163 | array_unshift($this->cipher_methods, $cipher_method_to_test); |
164 | 164 | } |
165 | 165 | return $cipher_method_to_test; |
@@ -189,7 +189,7 @@ discard block |
||
189 | 189 | ) { |
190 | 190 | return true; |
191 | 191 | } |
192 | - if (! $throw_exception) { |
|
192 | + if ( ! $throw_exception) { |
|
193 | 193 | return false; |
194 | 194 | } |
195 | 195 | throw new RuntimeException( |
@@ -14,206 +14,206 @@ |
||
14 | 14 | */ |
15 | 15 | class CipherMethod |
16 | 16 | { |
17 | - /** |
|
18 | - * @var string |
|
19 | - */ |
|
20 | - protected $cipher_method_option_name; |
|
21 | - |
|
22 | - /** |
|
23 | - * list of cipher methods that we consider usable, |
|
24 | - * essentially all of the installed_cipher_methods minus weak_algorithms |
|
25 | - * |
|
26 | - * @var array |
|
27 | - */ |
|
28 | - protected $cipher_methods = []; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var string |
|
32 | - */ |
|
33 | - protected $default_cipher_method; |
|
34 | - |
|
35 | - /** |
|
36 | - * list of ALL cipher methods available on the server |
|
37 | - * |
|
38 | - * @var array |
|
39 | - */ |
|
40 | - protected $installed_cipher_methods; |
|
41 | - |
|
42 | - /** |
|
43 | - * the OpenSSL cipher method to use. default: AES-128-CBC |
|
44 | - * |
|
45 | - * @var string |
|
46 | - */ |
|
47 | - protected $validated_cipher_method; |
|
48 | - |
|
49 | - /** |
|
50 | - * as early as Aug 2016, Openssl declared the following weak: RC2, RC4, DES, 3DES, MD5 based |
|
51 | - * and ECB mode should be avoided |
|
52 | - * |
|
53 | - * @var array |
|
54 | - */ |
|
55 | - protected $weak_algorithms = ['des', 'ecb', 'md5', 'rc2', 'rc4']; |
|
56 | - |
|
57 | - |
|
58 | - /** |
|
59 | - * @param string $default_cipher_method |
|
60 | - * @param string $cipher_method_option_name |
|
61 | - */ |
|
62 | - public function __construct($default_cipher_method, $cipher_method_option_name) |
|
63 | - { |
|
64 | - $this->default_cipher_method = $default_cipher_method; |
|
65 | - $this->cipher_method_option_name = $cipher_method_option_name; |
|
66 | - $this->installed_cipher_methods = openssl_get_cipher_methods(); |
|
67 | - } |
|
68 | - |
|
69 | - |
|
70 | - /** |
|
71 | - * Returns a cipher method that has been verified to work. |
|
72 | - * First checks if the cached cipher has been set already and if so, returns that. |
|
73 | - * Then tests the incoming default and returns that if it's good. |
|
74 | - * If not, then it retrieves the previously tested and saved cipher method. |
|
75 | - * But if that doesn't exist, then calls getAvailableCipherMethod() |
|
76 | - * to see what is available on the server, and returns the results. |
|
77 | - * |
|
78 | - * @param string $cipher_method |
|
79 | - * @param bool $load_alternate [optional] if TRUE, will load the default cipher method (or any strong algorithm) |
|
80 | - * if the requested cipher method is not installed or invalid. |
|
81 | - * if FALSE, will throw an exception if the requested cipher method is not valid. |
|
82 | - * @return string |
|
83 | - * @throws RuntimeException |
|
84 | - */ |
|
85 | - public function getCipherMethod($cipher_method = null, $load_alternate = true) |
|
86 | - { |
|
87 | - if (empty($cipher_method) && $this->validated_cipher_method !== null) { |
|
88 | - return $this->validated_cipher_method; |
|
89 | - } |
|
90 | - // if nothing specific was requested and it's ok to load an alternate, then grab the system default |
|
91 | - if (empty($cipher_method) && $load_alternate) { |
|
92 | - $cipher_method = $this->default_cipher_method; |
|
93 | - } |
|
94 | - // verify that the cipher method can produce an initialization vector. |
|
95 | - // but if the requested is invalid and we don't want to load an alternate, then throw an exception |
|
96 | - $throw_exception = ! $load_alternate; |
|
97 | - if ($this->validateCipherMethod($cipher_method, $throw_exception) === false) { |
|
98 | - // nope? ... ok let's see what we can find |
|
99 | - $cipher_method = $this->getAvailableCipherMethod(); |
|
100 | - } |
|
101 | - // if nothing has been previously validated, then save the currently requested cipher which appears to be good |
|
102 | - if ($this->validated_cipher_method === null) { |
|
103 | - $this->validated_cipher_method = $cipher_method; |
|
104 | - } |
|
105 | - return $cipher_method; |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * returns true if the selected cipher method either uses Galois/Counter Mode (GCM) |
|
111 | - * or Counter with CBC-MAC (CCM) authenticated encryption modes |
|
112 | - * (also need to be using PHP 7.1 or greater to actually use authenticated encryption modes) |
|
113 | - * |
|
114 | - * @return bool |
|
115 | - */ |
|
116 | - public function usesAuthenticatedEncryptionMode() |
|
117 | - { |
|
118 | - return PHP_VERSION_ID >= 70100 |
|
119 | - && ( |
|
120 | - stripos($this->validated_cipher_method, 'gcm') !== false |
|
121 | - || stripos($this->validated_cipher_method, 'ccm') !== false |
|
122 | - ); |
|
123 | - } |
|
124 | - |
|
125 | - |
|
126 | - /** |
|
127 | - * @param string $cipher_method |
|
128 | - * @return string |
|
129 | - * @throws RuntimeException |
|
130 | - */ |
|
131 | - protected function getAvailableCipherMethod($cipher_method = null) |
|
132 | - { |
|
133 | - // if nothing was supplied, the get what we found in the past to work |
|
134 | - $cipher_method_to_test = $cipher_method ?: get_option($this->cipher_method_option_name, ''); |
|
135 | - // verify that the incoming cipher method exists and can produce an initialization vector |
|
136 | - if ($this->validateCipherMethod($cipher_method_to_test) === false) { |
|
137 | - // what? there's no list? |
|
138 | - if (empty($this->cipher_methods)) { |
|
139 | - // generate that list and cache it |
|
140 | - $this->cipher_methods = $this->getAvailableStrongCipherMethods(); |
|
141 | - } |
|
142 | - // then grab the first item from the list (we'll add it back later if it is good) |
|
143 | - $cipher_method_to_test = array_shift($this->cipher_methods); |
|
144 | - if ($cipher_method_to_test === null) { |
|
145 | - throw new RuntimeException( |
|
146 | - esc_html__( |
|
147 | - 'OpenSSL support appears to be enabled on the server, but no cipher methods are available. Please contact the server administrator.', |
|
148 | - 'event_espresso' |
|
149 | - ) |
|
150 | - ); |
|
151 | - } |
|
152 | - // verify that the next cipher method works |
|
153 | - return $this->getAvailableCipherMethod($cipher_method_to_test); |
|
154 | - } |
|
155 | - // if we've gotten this far, then we found an available cipher method that works |
|
156 | - // so save that for next time, if it's not the same as what's there already |
|
157 | - if ($cipher_method_to_test !== $cipher_method) { |
|
158 | - update_option($this->cipher_method_option_name, $cipher_method_to_test); |
|
159 | - } |
|
160 | - // if we previously removed this cipher method from the list of valid ones, then let's put it back |
|
161 | - if (! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
162 | - array_unshift($this->cipher_methods, $cipher_method_to_test); |
|
163 | - } |
|
164 | - return $cipher_method_to_test; |
|
165 | - } |
|
166 | - |
|
167 | - |
|
168 | - /** |
|
169 | - * @return array |
|
170 | - */ |
|
171 | - protected function getAvailableStrongCipherMethods() |
|
172 | - { |
|
173 | - return array_filter($this->installed_cipher_methods, [$this, 'weakAlgorithmFilter']); |
|
174 | - } |
|
175 | - |
|
176 | - |
|
177 | - /** |
|
178 | - * @param string $cipher_method |
|
179 | - * @param false $throw_exception |
|
180 | - * @return bool |
|
181 | - */ |
|
182 | - protected function validateCipherMethod($cipher_method, $throw_exception = false) |
|
183 | - { |
|
184 | - // verify that the requested cipher method is actually installed and can produce an initialization vector |
|
185 | - if ( |
|
186 | - in_array($cipher_method, $this->installed_cipher_methods, true) |
|
187 | - && openssl_cipher_iv_length($cipher_method) !== false |
|
188 | - ) { |
|
189 | - return true; |
|
190 | - } |
|
191 | - if (! $throw_exception) { |
|
192 | - return false; |
|
193 | - } |
|
194 | - throw new RuntimeException( |
|
195 | - sprintf( |
|
196 | - esc_html__( |
|
197 | - 'The requested OpenSSL cipher method "%1$s" is invalid or not installed on the server. Please contact the server administrator.', |
|
198 | - 'event_espresso' |
|
199 | - ), |
|
200 | - $cipher_method |
|
201 | - ) |
|
202 | - ); |
|
203 | - } |
|
204 | - |
|
205 | - |
|
206 | - /** |
|
207 | - * @see https://www.php.net/manual/en/function.openssl-get-cipher-methods.php#example-890 |
|
208 | - * @param string $cipher_method |
|
209 | - */ |
|
210 | - protected function weakAlgorithmFilter($cipher_method) |
|
211 | - { |
|
212 | - foreach ($this->weak_algorithms as $weak_algorithm) { |
|
213 | - if (stripos($cipher_method, $weak_algorithm) !== false) { |
|
214 | - return false; |
|
215 | - } |
|
216 | - } |
|
217 | - return true; |
|
218 | - } |
|
17 | + /** |
|
18 | + * @var string |
|
19 | + */ |
|
20 | + protected $cipher_method_option_name; |
|
21 | + |
|
22 | + /** |
|
23 | + * list of cipher methods that we consider usable, |
|
24 | + * essentially all of the installed_cipher_methods minus weak_algorithms |
|
25 | + * |
|
26 | + * @var array |
|
27 | + */ |
|
28 | + protected $cipher_methods = []; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var string |
|
32 | + */ |
|
33 | + protected $default_cipher_method; |
|
34 | + |
|
35 | + /** |
|
36 | + * list of ALL cipher methods available on the server |
|
37 | + * |
|
38 | + * @var array |
|
39 | + */ |
|
40 | + protected $installed_cipher_methods; |
|
41 | + |
|
42 | + /** |
|
43 | + * the OpenSSL cipher method to use. default: AES-128-CBC |
|
44 | + * |
|
45 | + * @var string |
|
46 | + */ |
|
47 | + protected $validated_cipher_method; |
|
48 | + |
|
49 | + /** |
|
50 | + * as early as Aug 2016, Openssl declared the following weak: RC2, RC4, DES, 3DES, MD5 based |
|
51 | + * and ECB mode should be avoided |
|
52 | + * |
|
53 | + * @var array |
|
54 | + */ |
|
55 | + protected $weak_algorithms = ['des', 'ecb', 'md5', 'rc2', 'rc4']; |
|
56 | + |
|
57 | + |
|
58 | + /** |
|
59 | + * @param string $default_cipher_method |
|
60 | + * @param string $cipher_method_option_name |
|
61 | + */ |
|
62 | + public function __construct($default_cipher_method, $cipher_method_option_name) |
|
63 | + { |
|
64 | + $this->default_cipher_method = $default_cipher_method; |
|
65 | + $this->cipher_method_option_name = $cipher_method_option_name; |
|
66 | + $this->installed_cipher_methods = openssl_get_cipher_methods(); |
|
67 | + } |
|
68 | + |
|
69 | + |
|
70 | + /** |
|
71 | + * Returns a cipher method that has been verified to work. |
|
72 | + * First checks if the cached cipher has been set already and if so, returns that. |
|
73 | + * Then tests the incoming default and returns that if it's good. |
|
74 | + * If not, then it retrieves the previously tested and saved cipher method. |
|
75 | + * But if that doesn't exist, then calls getAvailableCipherMethod() |
|
76 | + * to see what is available on the server, and returns the results. |
|
77 | + * |
|
78 | + * @param string $cipher_method |
|
79 | + * @param bool $load_alternate [optional] if TRUE, will load the default cipher method (or any strong algorithm) |
|
80 | + * if the requested cipher method is not installed or invalid. |
|
81 | + * if FALSE, will throw an exception if the requested cipher method is not valid. |
|
82 | + * @return string |
|
83 | + * @throws RuntimeException |
|
84 | + */ |
|
85 | + public function getCipherMethod($cipher_method = null, $load_alternate = true) |
|
86 | + { |
|
87 | + if (empty($cipher_method) && $this->validated_cipher_method !== null) { |
|
88 | + return $this->validated_cipher_method; |
|
89 | + } |
|
90 | + // if nothing specific was requested and it's ok to load an alternate, then grab the system default |
|
91 | + if (empty($cipher_method) && $load_alternate) { |
|
92 | + $cipher_method = $this->default_cipher_method; |
|
93 | + } |
|
94 | + // verify that the cipher method can produce an initialization vector. |
|
95 | + // but if the requested is invalid and we don't want to load an alternate, then throw an exception |
|
96 | + $throw_exception = ! $load_alternate; |
|
97 | + if ($this->validateCipherMethod($cipher_method, $throw_exception) === false) { |
|
98 | + // nope? ... ok let's see what we can find |
|
99 | + $cipher_method = $this->getAvailableCipherMethod(); |
|
100 | + } |
|
101 | + // if nothing has been previously validated, then save the currently requested cipher which appears to be good |
|
102 | + if ($this->validated_cipher_method === null) { |
|
103 | + $this->validated_cipher_method = $cipher_method; |
|
104 | + } |
|
105 | + return $cipher_method; |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * returns true if the selected cipher method either uses Galois/Counter Mode (GCM) |
|
111 | + * or Counter with CBC-MAC (CCM) authenticated encryption modes |
|
112 | + * (also need to be using PHP 7.1 or greater to actually use authenticated encryption modes) |
|
113 | + * |
|
114 | + * @return bool |
|
115 | + */ |
|
116 | + public function usesAuthenticatedEncryptionMode() |
|
117 | + { |
|
118 | + return PHP_VERSION_ID >= 70100 |
|
119 | + && ( |
|
120 | + stripos($this->validated_cipher_method, 'gcm') !== false |
|
121 | + || stripos($this->validated_cipher_method, 'ccm') !== false |
|
122 | + ); |
|
123 | + } |
|
124 | + |
|
125 | + |
|
126 | + /** |
|
127 | + * @param string $cipher_method |
|
128 | + * @return string |
|
129 | + * @throws RuntimeException |
|
130 | + */ |
|
131 | + protected function getAvailableCipherMethod($cipher_method = null) |
|
132 | + { |
|
133 | + // if nothing was supplied, the get what we found in the past to work |
|
134 | + $cipher_method_to_test = $cipher_method ?: get_option($this->cipher_method_option_name, ''); |
|
135 | + // verify that the incoming cipher method exists and can produce an initialization vector |
|
136 | + if ($this->validateCipherMethod($cipher_method_to_test) === false) { |
|
137 | + // what? there's no list? |
|
138 | + if (empty($this->cipher_methods)) { |
|
139 | + // generate that list and cache it |
|
140 | + $this->cipher_methods = $this->getAvailableStrongCipherMethods(); |
|
141 | + } |
|
142 | + // then grab the first item from the list (we'll add it back later if it is good) |
|
143 | + $cipher_method_to_test = array_shift($this->cipher_methods); |
|
144 | + if ($cipher_method_to_test === null) { |
|
145 | + throw new RuntimeException( |
|
146 | + esc_html__( |
|
147 | + 'OpenSSL support appears to be enabled on the server, but no cipher methods are available. Please contact the server administrator.', |
|
148 | + 'event_espresso' |
|
149 | + ) |
|
150 | + ); |
|
151 | + } |
|
152 | + // verify that the next cipher method works |
|
153 | + return $this->getAvailableCipherMethod($cipher_method_to_test); |
|
154 | + } |
|
155 | + // if we've gotten this far, then we found an available cipher method that works |
|
156 | + // so save that for next time, if it's not the same as what's there already |
|
157 | + if ($cipher_method_to_test !== $cipher_method) { |
|
158 | + update_option($this->cipher_method_option_name, $cipher_method_to_test); |
|
159 | + } |
|
160 | + // if we previously removed this cipher method from the list of valid ones, then let's put it back |
|
161 | + if (! in_array($cipher_method_to_test, $this->cipher_methods, true)) { |
|
162 | + array_unshift($this->cipher_methods, $cipher_method_to_test); |
|
163 | + } |
|
164 | + return $cipher_method_to_test; |
|
165 | + } |
|
166 | + |
|
167 | + |
|
168 | + /** |
|
169 | + * @return array |
|
170 | + */ |
|
171 | + protected function getAvailableStrongCipherMethods() |
|
172 | + { |
|
173 | + return array_filter($this->installed_cipher_methods, [$this, 'weakAlgorithmFilter']); |
|
174 | + } |
|
175 | + |
|
176 | + |
|
177 | + /** |
|
178 | + * @param string $cipher_method |
|
179 | + * @param false $throw_exception |
|
180 | + * @return bool |
|
181 | + */ |
|
182 | + protected function validateCipherMethod($cipher_method, $throw_exception = false) |
|
183 | + { |
|
184 | + // verify that the requested cipher method is actually installed and can produce an initialization vector |
|
185 | + if ( |
|
186 | + in_array($cipher_method, $this->installed_cipher_methods, true) |
|
187 | + && openssl_cipher_iv_length($cipher_method) !== false |
|
188 | + ) { |
|
189 | + return true; |
|
190 | + } |
|
191 | + if (! $throw_exception) { |
|
192 | + return false; |
|
193 | + } |
|
194 | + throw new RuntimeException( |
|
195 | + sprintf( |
|
196 | + esc_html__( |
|
197 | + 'The requested OpenSSL cipher method "%1$s" is invalid or not installed on the server. Please contact the server administrator.', |
|
198 | + 'event_espresso' |
|
199 | + ), |
|
200 | + $cipher_method |
|
201 | + ) |
|
202 | + ); |
|
203 | + } |
|
204 | + |
|
205 | + |
|
206 | + /** |
|
207 | + * @see https://www.php.net/manual/en/function.openssl-get-cipher-methods.php#example-890 |
|
208 | + * @param string $cipher_method |
|
209 | + */ |
|
210 | + protected function weakAlgorithmFilter($cipher_method) |
|
211 | + { |
|
212 | + foreach ($this->weak_algorithms as $weak_algorithm) { |
|
213 | + if (stripos($cipher_method, $weak_algorithm) !== false) { |
|
214 | + return false; |
|
215 | + } |
|
216 | + } |
|
217 | + return true; |
|
218 | + } |
|
219 | 219 | } |
@@ -143,7 +143,7 @@ discard block |
||
143 | 143 | ); |
144 | 144 | $this->validateEncryption($encrypted_text); |
145 | 145 | // concatenate everything into one big string |
146 | - return $iv . $tag . $encrypted_text; |
|
146 | + return $iv.$tag.$encrypted_text; |
|
147 | 147 | } |
148 | 148 | |
149 | 149 | |
@@ -165,7 +165,7 @@ discard block |
||
165 | 165 | ); |
166 | 166 | $this->validateEncryption($encrypted_text); |
167 | 167 | // prepend the initialization vector |
168 | - return $iv . $encrypted_text; |
|
168 | + return $iv.$encrypted_text; |
|
169 | 169 | } |
170 | 170 | |
171 | 171 |
@@ -23,221 +23,221 @@ |
||
23 | 23 | */ |
24 | 24 | class OpenSSLv2 extends OpenSSL |
25 | 25 | { |
26 | - /** |
|
27 | - * name used for a default encryption key in case no others are set |
|
28 | - */ |
|
29 | - const DEFAULT_ENCRYPTION_KEY_ID = 'default_openssl_v2_key'; |
|
30 | - |
|
31 | - /** |
|
32 | - * name used for saving encryption keys to the wp_options table |
|
33 | - */ |
|
34 | - const ENCRYPTION_KEYS_OPTION_NAME = 'ee_openssl_v2_encryption_keys'; |
|
35 | - |
|
36 | - /** |
|
37 | - * the OPENSSL cipher method used |
|
38 | - */ |
|
39 | - const CIPHER_METHOD = 'aes-256-gcm'; |
|
40 | - |
|
41 | - /** |
|
42 | - * WP "options_name" used to store a verified available cipher method |
|
43 | - */ |
|
44 | - const CIPHER_METHOD_OPTION_NAME = 'ee_openssl_v2_cipher_method'; |
|
45 | - |
|
46 | - /** |
|
47 | - * The length of the authentication tag. Its value can be between 4 and 16 for GCM mode. |
|
48 | - */ |
|
49 | - const AUTH_TAG_LENGTH = 16; |
|
50 | - |
|
51 | - |
|
52 | - /** |
|
53 | - * To use custom a cipher method and/or encryption keys and/or minimum PHP version: |
|
54 | - * - extend this class |
|
55 | - * - configure a new CipherMethod / EncryptionKeyManager in the constructor |
|
56 | - * - pass those to this constructor, like so: |
|
57 | - * |
|
58 | - * public function __construct(Base64Encoder $base64_encoder) { |
|
59 | - * parent::__construct( |
|
60 | - * $base64_encoder, |
|
61 | - * new CipherMethod(CIPHER_METHOD, CIPHER_METHOD_OPTION_NAME), |
|
62 | - * new EncryptionKeyManager(CUSTOM_KEY_ID, CUSTOM_KEYS_OPTION_NAME), |
|
63 | - * '7.1.0' |
|
64 | - * ); |
|
65 | - * } |
|
66 | - * |
|
67 | - * @param Base64Encoder $base64_encoder |
|
68 | - * @param CipherMethod|null $cipher_method |
|
69 | - * @param EncryptionKeyManagerInterface|null $encryption_key_manager |
|
70 | - * @param string $min_php_version defaults to 7.1.0 |
|
71 | - * (when openssl auth tag and random_bytes() were added) |
|
72 | - */ |
|
73 | - public function __construct( |
|
74 | - Base64Encoder $base64_encoder, |
|
75 | - CipherMethod $cipher_method = null, |
|
76 | - EncryptionKeyManagerInterface $encryption_key_manager = null, |
|
77 | - $min_php_version = '7.1.0' |
|
78 | - ) { |
|
79 | - parent::__construct( |
|
80 | - $base64_encoder, |
|
81 | - $cipher_method instanceof CipherMethod |
|
82 | - ? $cipher_method |
|
83 | - : new CipherMethod( |
|
84 | - OpenSSLv2::CIPHER_METHOD, |
|
85 | - OpenSSLv2::CIPHER_METHOD_OPTION_NAME |
|
86 | - ), |
|
87 | - $encryption_key_manager instanceof EncryptionKeyManager |
|
88 | - ? $encryption_key_manager |
|
89 | - : new EncryptionKeyManager( |
|
90 | - $base64_encoder, |
|
91 | - OpenSSLv2::DEFAULT_ENCRYPTION_KEY_ID, |
|
92 | - OpenSSLv2::ENCRYPTION_KEYS_OPTION_NAME |
|
93 | - ), |
|
94 | - $min_php_version |
|
95 | - ); |
|
96 | - } |
|
97 | - |
|
98 | - |
|
99 | - /** |
|
100 | - * encrypts data |
|
101 | - * |
|
102 | - * @param string $text_to_encrypt - the text to be encrypted |
|
103 | - * @param string $encryption_key_identifier - [optional] cryptographically secure passphrase. generated if not set |
|
104 | - * @param string $aad - [optional] additional authentication data |
|
105 | - * @return string |
|
106 | - * @throws Exception |
|
107 | - */ |
|
108 | - public function encrypt($text_to_encrypt, $encryption_key_identifier = '', $aad = '') |
|
109 | - { |
|
110 | - $cipher_method = $this->cipher_method->getCipherMethod(); |
|
111 | - $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
112 | - // generate initialization vector for the cipher method. |
|
113 | - $iv = random_bytes(openssl_cipher_iv_length($cipher_method)); |
|
114 | - // encrypt it (encode to remove special characters) |
|
115 | - $text_to_encrypt = $this->base64_encoder->encodeString($text_to_encrypt); |
|
116 | - $encrypted_text = $this->cipher_method->usesAuthenticatedEncryptionMode() |
|
117 | - ? $this->authenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv, $aad) |
|
118 | - : $this->nonAuthenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv); |
|
119 | - return $this->base64_encoder->encodeString($encrypted_text); |
|
120 | - } |
|
121 | - |
|
122 | - |
|
123 | - /** |
|
124 | - * @param string $text_to_encrypt - the text to be encrypted |
|
125 | - * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
126 | - * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
127 | - * @param string $iv - the initialization vector |
|
128 | - * @param string $aad - additional authentication data |
|
129 | - * @return string |
|
130 | - */ |
|
131 | - private function authenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv, $aad) |
|
132 | - { |
|
133 | - $encrypted_text = openssl_encrypt( |
|
134 | - $text_to_encrypt, |
|
135 | - $cipher_method, |
|
136 | - $this->getDigestHashValue($encryption_key, OpenSSL::DEFAULT_DIGEST_METHOD, OPENSSL_RAW_DATA), |
|
137 | - 0, |
|
138 | - $iv, |
|
139 | - $tag, |
|
140 | - $aad, |
|
141 | - OpenSSLv2::AUTH_TAG_LENGTH |
|
142 | - ); |
|
143 | - $this->validateEncryption($encrypted_text); |
|
144 | - // concatenate everything into one big string |
|
145 | - return $iv . $tag . $encrypted_text; |
|
146 | - } |
|
147 | - |
|
148 | - |
|
149 | - /** |
|
150 | - * @param string $text_to_encrypt - the text to be encrypted |
|
151 | - * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
152 | - * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
153 | - * @param string $iv - the initialization vector |
|
154 | - * @return string |
|
155 | - */ |
|
156 | - private function nonAuthenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv) |
|
157 | - { |
|
158 | - $encrypted_text = openssl_encrypt( |
|
159 | - $text_to_encrypt, |
|
160 | - $cipher_method, |
|
161 | - $this->getDigestHashValue($encryption_key), |
|
162 | - 0, |
|
163 | - $iv |
|
164 | - ); |
|
165 | - $this->validateEncryption($encrypted_text); |
|
166 | - // prepend the initialization vector |
|
167 | - return $iv . $encrypted_text; |
|
168 | - } |
|
169 | - |
|
170 | - |
|
171 | - /** |
|
172 | - * decrypts data |
|
173 | - * |
|
174 | - * @param string $encrypted_text - the text to be decrypted |
|
175 | - * @param string $encryption_key_identifier - [optional] cryptographically secure passphrase uses default if not set |
|
176 | - * @param string $aad - [optional] additional authentication data |
|
177 | - * @return string |
|
178 | - */ |
|
179 | - public function decrypt($encrypted_text, $encryption_key_identifier = '', $aad = '') |
|
180 | - { |
|
181 | - $cipher_method = $this->cipher_method->getCipherMethod(); |
|
182 | - $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
183 | - // maybe decode |
|
184 | - $encrypted_text = $this->base64_encoder->decodeString($encrypted_text); |
|
185 | - $iv_length = openssl_cipher_iv_length($cipher_method); |
|
186 | - // use the iv length to snip it from the decoded string |
|
187 | - $iv = substr($encrypted_text, 0, $iv_length); |
|
188 | - // then remove it from the rest of the decoded string |
|
189 | - $encrypted_text = substr($encrypted_text, $iv_length); |
|
190 | - // decrypt it |
|
191 | - $decrypted_text = $this->cipher_method->usesAuthenticatedEncryptionMode() |
|
192 | - ? $this->authenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv, $aad) |
|
193 | - : $this->nonAuthenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv); |
|
194 | - |
|
195 | - $this->validateDecryption($decrypted_text); |
|
196 | - return trim($this->base64_encoder->decodeString($decrypted_text)); |
|
197 | - } |
|
198 | - |
|
199 | - |
|
200 | - /** |
|
201 | - * @param string $encrypted_text - the text to be decrypted |
|
202 | - * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
203 | - * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
204 | - * @param string $iv - the initialization vector |
|
205 | - * @param string $aad - additional authentication data |
|
206 | - * @return string|false |
|
207 | - */ |
|
208 | - private function authenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv, $aad) |
|
209 | - { |
|
210 | - // use the tag length to snip it from the decoded string |
|
211 | - $tag = substr($encrypted_text, 0, OpenSSLv2::AUTH_TAG_LENGTH); |
|
212 | - // then remove it from the rest of the decoded string |
|
213 | - $encrypted_text = substr($encrypted_text, OpenSSLv2::AUTH_TAG_LENGTH); |
|
214 | - return openssl_decrypt( |
|
215 | - $encrypted_text, |
|
216 | - $cipher_method, |
|
217 | - $this->getDigestHashValue($encryption_key, OpenSSL::DEFAULT_DIGEST_METHOD, OPENSSL_RAW_DATA), |
|
218 | - 0, |
|
219 | - $iv, |
|
220 | - $tag, |
|
221 | - $aad |
|
222 | - ); |
|
223 | - } |
|
224 | - |
|
225 | - |
|
226 | - /** |
|
227 | - * @param string $encrypted_text - the text to be decrypted |
|
228 | - * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
229 | - * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
230 | - * @param string $iv - the initialization vector |
|
231 | - * @return string|false |
|
232 | - */ |
|
233 | - private function nonAuthenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv) |
|
234 | - { |
|
235 | - return openssl_decrypt( |
|
236 | - $encrypted_text, |
|
237 | - $cipher_method, |
|
238 | - $this->getDigestHashValue($encryption_key), |
|
239 | - 0, |
|
240 | - $iv |
|
241 | - ); |
|
242 | - } |
|
26 | + /** |
|
27 | + * name used for a default encryption key in case no others are set |
|
28 | + */ |
|
29 | + const DEFAULT_ENCRYPTION_KEY_ID = 'default_openssl_v2_key'; |
|
30 | + |
|
31 | + /** |
|
32 | + * name used for saving encryption keys to the wp_options table |
|
33 | + */ |
|
34 | + const ENCRYPTION_KEYS_OPTION_NAME = 'ee_openssl_v2_encryption_keys'; |
|
35 | + |
|
36 | + /** |
|
37 | + * the OPENSSL cipher method used |
|
38 | + */ |
|
39 | + const CIPHER_METHOD = 'aes-256-gcm'; |
|
40 | + |
|
41 | + /** |
|
42 | + * WP "options_name" used to store a verified available cipher method |
|
43 | + */ |
|
44 | + const CIPHER_METHOD_OPTION_NAME = 'ee_openssl_v2_cipher_method'; |
|
45 | + |
|
46 | + /** |
|
47 | + * The length of the authentication tag. Its value can be between 4 and 16 for GCM mode. |
|
48 | + */ |
|
49 | + const AUTH_TAG_LENGTH = 16; |
|
50 | + |
|
51 | + |
|
52 | + /** |
|
53 | + * To use custom a cipher method and/or encryption keys and/or minimum PHP version: |
|
54 | + * - extend this class |
|
55 | + * - configure a new CipherMethod / EncryptionKeyManager in the constructor |
|
56 | + * - pass those to this constructor, like so: |
|
57 | + * |
|
58 | + * public function __construct(Base64Encoder $base64_encoder) { |
|
59 | + * parent::__construct( |
|
60 | + * $base64_encoder, |
|
61 | + * new CipherMethod(CIPHER_METHOD, CIPHER_METHOD_OPTION_NAME), |
|
62 | + * new EncryptionKeyManager(CUSTOM_KEY_ID, CUSTOM_KEYS_OPTION_NAME), |
|
63 | + * '7.1.0' |
|
64 | + * ); |
|
65 | + * } |
|
66 | + * |
|
67 | + * @param Base64Encoder $base64_encoder |
|
68 | + * @param CipherMethod|null $cipher_method |
|
69 | + * @param EncryptionKeyManagerInterface|null $encryption_key_manager |
|
70 | + * @param string $min_php_version defaults to 7.1.0 |
|
71 | + * (when openssl auth tag and random_bytes() were added) |
|
72 | + */ |
|
73 | + public function __construct( |
|
74 | + Base64Encoder $base64_encoder, |
|
75 | + CipherMethod $cipher_method = null, |
|
76 | + EncryptionKeyManagerInterface $encryption_key_manager = null, |
|
77 | + $min_php_version = '7.1.0' |
|
78 | + ) { |
|
79 | + parent::__construct( |
|
80 | + $base64_encoder, |
|
81 | + $cipher_method instanceof CipherMethod |
|
82 | + ? $cipher_method |
|
83 | + : new CipherMethod( |
|
84 | + OpenSSLv2::CIPHER_METHOD, |
|
85 | + OpenSSLv2::CIPHER_METHOD_OPTION_NAME |
|
86 | + ), |
|
87 | + $encryption_key_manager instanceof EncryptionKeyManager |
|
88 | + ? $encryption_key_manager |
|
89 | + : new EncryptionKeyManager( |
|
90 | + $base64_encoder, |
|
91 | + OpenSSLv2::DEFAULT_ENCRYPTION_KEY_ID, |
|
92 | + OpenSSLv2::ENCRYPTION_KEYS_OPTION_NAME |
|
93 | + ), |
|
94 | + $min_php_version |
|
95 | + ); |
|
96 | + } |
|
97 | + |
|
98 | + |
|
99 | + /** |
|
100 | + * encrypts data |
|
101 | + * |
|
102 | + * @param string $text_to_encrypt - the text to be encrypted |
|
103 | + * @param string $encryption_key_identifier - [optional] cryptographically secure passphrase. generated if not set |
|
104 | + * @param string $aad - [optional] additional authentication data |
|
105 | + * @return string |
|
106 | + * @throws Exception |
|
107 | + */ |
|
108 | + public function encrypt($text_to_encrypt, $encryption_key_identifier = '', $aad = '') |
|
109 | + { |
|
110 | + $cipher_method = $this->cipher_method->getCipherMethod(); |
|
111 | + $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
112 | + // generate initialization vector for the cipher method. |
|
113 | + $iv = random_bytes(openssl_cipher_iv_length($cipher_method)); |
|
114 | + // encrypt it (encode to remove special characters) |
|
115 | + $text_to_encrypt = $this->base64_encoder->encodeString($text_to_encrypt); |
|
116 | + $encrypted_text = $this->cipher_method->usesAuthenticatedEncryptionMode() |
|
117 | + ? $this->authenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv, $aad) |
|
118 | + : $this->nonAuthenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv); |
|
119 | + return $this->base64_encoder->encodeString($encrypted_text); |
|
120 | + } |
|
121 | + |
|
122 | + |
|
123 | + /** |
|
124 | + * @param string $text_to_encrypt - the text to be encrypted |
|
125 | + * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
126 | + * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
127 | + * @param string $iv - the initialization vector |
|
128 | + * @param string $aad - additional authentication data |
|
129 | + * @return string |
|
130 | + */ |
|
131 | + private function authenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv, $aad) |
|
132 | + { |
|
133 | + $encrypted_text = openssl_encrypt( |
|
134 | + $text_to_encrypt, |
|
135 | + $cipher_method, |
|
136 | + $this->getDigestHashValue($encryption_key, OpenSSL::DEFAULT_DIGEST_METHOD, OPENSSL_RAW_DATA), |
|
137 | + 0, |
|
138 | + $iv, |
|
139 | + $tag, |
|
140 | + $aad, |
|
141 | + OpenSSLv2::AUTH_TAG_LENGTH |
|
142 | + ); |
|
143 | + $this->validateEncryption($encrypted_text); |
|
144 | + // concatenate everything into one big string |
|
145 | + return $iv . $tag . $encrypted_text; |
|
146 | + } |
|
147 | + |
|
148 | + |
|
149 | + /** |
|
150 | + * @param string $text_to_encrypt - the text to be encrypted |
|
151 | + * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
152 | + * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
153 | + * @param string $iv - the initialization vector |
|
154 | + * @return string |
|
155 | + */ |
|
156 | + private function nonAuthenticatedEncrypt($text_to_encrypt, $cipher_method, $encryption_key, $iv) |
|
157 | + { |
|
158 | + $encrypted_text = openssl_encrypt( |
|
159 | + $text_to_encrypt, |
|
160 | + $cipher_method, |
|
161 | + $this->getDigestHashValue($encryption_key), |
|
162 | + 0, |
|
163 | + $iv |
|
164 | + ); |
|
165 | + $this->validateEncryption($encrypted_text); |
|
166 | + // prepend the initialization vector |
|
167 | + return $iv . $encrypted_text; |
|
168 | + } |
|
169 | + |
|
170 | + |
|
171 | + /** |
|
172 | + * decrypts data |
|
173 | + * |
|
174 | + * @param string $encrypted_text - the text to be decrypted |
|
175 | + * @param string $encryption_key_identifier - [optional] cryptographically secure passphrase uses default if not set |
|
176 | + * @param string $aad - [optional] additional authentication data |
|
177 | + * @return string |
|
178 | + */ |
|
179 | + public function decrypt($encrypted_text, $encryption_key_identifier = '', $aad = '') |
|
180 | + { |
|
181 | + $cipher_method = $this->cipher_method->getCipherMethod(); |
|
182 | + $encryption_key = $this->encryption_key_manager->getEncryptionKey($encryption_key_identifier); |
|
183 | + // maybe decode |
|
184 | + $encrypted_text = $this->base64_encoder->decodeString($encrypted_text); |
|
185 | + $iv_length = openssl_cipher_iv_length($cipher_method); |
|
186 | + // use the iv length to snip it from the decoded string |
|
187 | + $iv = substr($encrypted_text, 0, $iv_length); |
|
188 | + // then remove it from the rest of the decoded string |
|
189 | + $encrypted_text = substr($encrypted_text, $iv_length); |
|
190 | + // decrypt it |
|
191 | + $decrypted_text = $this->cipher_method->usesAuthenticatedEncryptionMode() |
|
192 | + ? $this->authenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv, $aad) |
|
193 | + : $this->nonAuthenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv); |
|
194 | + |
|
195 | + $this->validateDecryption($decrypted_text); |
|
196 | + return trim($this->base64_encoder->decodeString($decrypted_text)); |
|
197 | + } |
|
198 | + |
|
199 | + |
|
200 | + /** |
|
201 | + * @param string $encrypted_text - the text to be decrypted |
|
202 | + * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
203 | + * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
204 | + * @param string $iv - the initialization vector |
|
205 | + * @param string $aad - additional authentication data |
|
206 | + * @return string|false |
|
207 | + */ |
|
208 | + private function authenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv, $aad) |
|
209 | + { |
|
210 | + // use the tag length to snip it from the decoded string |
|
211 | + $tag = substr($encrypted_text, 0, OpenSSLv2::AUTH_TAG_LENGTH); |
|
212 | + // then remove it from the rest of the decoded string |
|
213 | + $encrypted_text = substr($encrypted_text, OpenSSLv2::AUTH_TAG_LENGTH); |
|
214 | + return openssl_decrypt( |
|
215 | + $encrypted_text, |
|
216 | + $cipher_method, |
|
217 | + $this->getDigestHashValue($encryption_key, OpenSSL::DEFAULT_DIGEST_METHOD, OPENSSL_RAW_DATA), |
|
218 | + 0, |
|
219 | + $iv, |
|
220 | + $tag, |
|
221 | + $aad |
|
222 | + ); |
|
223 | + } |
|
224 | + |
|
225 | + |
|
226 | + /** |
|
227 | + * @param string $encrypted_text - the text to be decrypted |
|
228 | + * @param string $cipher_method - the OpenSSL cipher method used during encryption |
|
229 | + * @param string $encryption_key - cryptographically secure passphrase uses default if not set |
|
230 | + * @param string $iv - the initialization vector |
|
231 | + * @return string|false |
|
232 | + */ |
|
233 | + private function nonAuthenticatedDecrypt($encrypted_text, $cipher_method, $encryption_key, $iv) |
|
234 | + { |
|
235 | + return openssl_decrypt( |
|
236 | + $encrypted_text, |
|
237 | + $cipher_method, |
|
238 | + $this->getDigestHashValue($encryption_key), |
|
239 | + 0, |
|
240 | + $iv |
|
241 | + ); |
|
242 | + } |
|
243 | 243 | } |