PluginProbe
seQura / 4.1.3
seQura v4.1.3
4.3.4 4.3.3 4.3.2 4.3.1 trunk 2.0.0 2.0.10 2.0.11 2.0.12 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.2 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 4.0.0 All 30 releases
sequra / src / Controllers / Hooks / Asset / class-assets-controller.php

class-assets-controller.php in seQura 4.1.3, at src/Controllers/Hooks/Asset/class-assets-controller.php

455 lines 14.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Assets Controller
4 *
5 * @package SeQura/WC
6 * @subpackage SeQura/WC/Controllers
7 */
8
9 namespace SeQura\WC\Controllers\Hooks\Asset;
10
11 use SeQura\WC\Controllers\Controller;
12 use SeQura\WC\Services\I18n\Interface_I18n;
13 use SeQura\WC\Services\Log\Interface_Logger_Service;
14 use SeQura\WC\Services\Payment\Interface_Payment_Method_Service;
15 use SeQura\Core\Infrastructure\Utility\RegexProvider;
16 use SeQura\WC\Services\Service\Interface_Settings_Service;
17 use SeQura\WC\Services\Widgets\Interface_Widgets_Service;
18
19 /**
20 * Define the assets related functionality
21 */
22 class Assets_Controller extends Controller implements Interface_Assets_Controller {
23
24 private const HANDLE_SETTINGS_PAGE = 'sequra-settings';
25 private const HANDLE_CHECKOUT = 'sequra-checkout';
26 private const HANDLE_WIDGET = 'sequra-widget';
27 private const HANDLE_CONFIG_PARAMS = 'sequra-config-params';
28 private const HANDLE_CORE = 'sequra-core';
29 private const INTEGRATION_CORE_VERSION = '1.0.0';
30 private const STRATEGY_DEFER = 'defer';
31
32 /**
33 * URL to the assets directory
34 *
35 * @var string
36 */
37 private $assets_dir_url;
38
39 /**
40 * Path to the assets directory
41 *
42 * @var string
43 */
44 private $assets_dir_path;
45
46 /**
47 * Version of the assets
48 *
49 * @var string
50 */
51 private $assets_version;
52
53 /**
54 * WP Version
55 *
56 * @var string
57 */
58 private $wp_version;
59
60 /**
61 * I18n service
62 *
63 * @var Interface_I18n
64 */
65 private $i18n;
66
67 /**
68 * Settings service
69 *
70 * @var Interface_Settings_Service
71 */
72 private $settings_service;
73
74 /**
75 * Payment method service
76 *
77 * @var Interface_Payment_Method_Service
78 */
79 private $payment_method_service;
80
81 /**
82 * Regex service
83 *
84 * @var RegexProvider
85 */
86 private $regex;
87
88 /**
89 * Widgets service
90 *
91 * @var Interface_Widgets_Service
92 */
93 private $widgets_service;
94
95 /**
96 * Constructor
97 */
98 public function __construct(
99 string $assets_dir_url,
100 string $assets_dir_path,
101 string $assets_version,
102 string $wp_version,
103 Interface_I18n $i18n,
104 Interface_Logger_Service $logger,
105 string $templates_path,
106 Interface_Settings_Service $settings_service,
107 Interface_Payment_Method_Service $payment_method_service,
108 RegexProvider $regex,
109 Interface_Widgets_Service $widgets_service
110 ) {
111 parent::__construct( $logger, $templates_path );
112 $this->assets_dir_url = $assets_dir_url;
113 $this->assets_dir_path = $assets_dir_path;
114 $this->assets_version = $assets_version;
115 $this->i18n = $i18n;
116 $this->logger = $logger;
117 $this->settings_service = $settings_service;
118 $this->payment_method_service = $payment_method_service;
119 $this->regex = $regex;
120 $this->wp_version = $wp_version;
121 $this->widgets_service = $widgets_service;
122 }
123
124 /**
125 * Enqueue styles and scripts in WP-Admin
126 *
127 * @return void
128 */
129 public function enqueue_admin() {
130 $this->logger->log_debug( 'Hook executed', __FUNCTION__, __CLASS__ );
131 if ( ! $this->settings_service->is_settings_page() ) {
132 return;
133 }
134 // Styles.
135 \wp_enqueue_style( self::HANDLE_CORE, "{$this->assets_dir_url}/integration-core-ui/css/sequra-core.css", array(), self::INTEGRATION_CORE_VERSION );
136
137 // Scripts.
138 \wp_register_script( self::HANDLE_SETTINGS_PAGE, "{$this->assets_dir_url}/js/dist/page/settings.min.js", array(), $this->assets_version, true );
139 \wp_localize_script( self::HANDLE_SETTINGS_PAGE, 'SequraFE', $this->get_sequra_fe_l10n() );
140 \wp_enqueue_script( self::HANDLE_SETTINGS_PAGE );
141 }
142
143 /**
144 * Get the SequraFE object
145 *
146 * @return mixed[]
147 */
148 private function get_sequra_fe_l10n(): array {
149 $connection_config = array(
150 'getConnectionDataUrl' => \get_rest_url( null, 'sequra/v1/onboarding/data/{storeId}' ),
151 'getDeploymentsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/deployments/{storeId}' ),
152 'getNotConnectedDeploymentsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/deployments/not-connected/{storeId}' ),
153 );
154 $payment_page_config = array_merge(
155 $connection_config,
156 array(
157 'getPaymentMethodsUrl' => \get_rest_url( null, 'sequra/v1/payment/methods/{storeId}/{merchantId}' ),
158 'getAllAvailablePaymentMethodsUrl' => \get_rest_url( null, 'sequra/v1/payment/methods/{storeId}' ),
159 'getSellingCountriesUrl' => \get_rest_url( null, 'sequra/v1/onboarding/countries/selling/{storeId}' ),
160 'getCountrySettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/countries/{storeId}' ),
161 'validateConnectionDataUrl' => \get_rest_url( null, 'sequra/v1/onboarding/data/validate/{storeId}' ),
162 )
163 );
164 $onboarding_page_config = array_merge(
165 $payment_page_config,
166 array(
167 'saveCountrySettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/countries/{storeId}' ),
168 'getWidgetSettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/widgets/{storeId}' ),
169 'saveWidgetSettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/widgets/{storeId}' ),
170 'disconnectUrl' => \get_rest_url( null, 'sequra/v1/onboarding/data/disconnect/{storeId}' ),
171 'connectUrl' => \get_rest_url( null, 'sequra/v1/onboarding/data/connect/{storeId}' ),
172 )
173 );
174 $page_config = array(
175 'onboarding' => $onboarding_page_config,
176 'settings' => array_merge(
177 $onboarding_page_config,
178 array(
179 'getShopCategoriesUrl' => \get_rest_url( null, 'sequra/v1/settings/shop-categories/{storeId}' ),
180 'getGeneralSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/general/{storeId}' ),
181 'saveGeneralSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/general/{storeId}' ),
182 'getShopOrderStatusesUrl' => \get_rest_url( null, 'sequra/v1/settings/order-status/list/{storeId}' ),
183 'getOrderStatusMappingSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/order-status/{storeId}' ),
184 'saveOrderStatusMappingSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/order-status/{storeId}' ),
185 )
186 ),
187 'payment' => $payment_page_config,
188 'advanced' => array_merge(
189 $connection_config,
190 array(
191 'getLogsUrl' => \get_rest_url( null, 'sequra/v1/log/{storeId}' ),
192 'removeLogsUrl' => \get_rest_url( null, 'sequra/v1/log/{storeId}' ),
193 'getLogsSettingsUrl' => \get_rest_url( null, 'sequra/v1/log/settings/{storeId}' ),
194 'saveLogsSettingsUrl' => \get_rest_url( null, 'sequra/v1/log/settings/{storeId}' ),
195 )
196 ),
197 );
198
199 $state_controller = array(
200 'storesUrl' => \get_rest_url( null, 'sequra/v1/settings/stores/{storeId}' ),
201 'currentStoreUrl' => \get_rest_url( null, 'sequra/v1/settings/current-store' ),
202 'stateUrl' => \get_rest_url( null, 'sequra/v1/settings/state/{storeId}' ),
203 'versionUrl' => \get_rest_url( null, 'sequra/v1/settings/version/{storeId}' ),
204 'shopNameUrl' => \get_rest_url( null, 'sequra/v1/settings/shop-name/{storeId}' ),
205 'pageConfiguration' => $page_config,
206 );
207
208 $sequra_fe = array(
209 'flags' => array(
210 'isShowCheckoutAsHostedPageFieldVisible' => false, // Not used in this implementation.
211 'configurableSelectorsForMiniWidgets' => true,
212 'isServiceSellingAllowed' => true,
213 ),
214 'translations' => array(
215 'default' => $this->load_translation(),
216 'current' => $this->load_translation( $this->i18n->get_lang() ),
217 ),
218 'pages' => array(
219 'onboarding' => array( 'deployments', 'connect', 'countries', 'widgets' ),
220 'settings' => array( 'general', 'connection', 'order_status', 'widget' ),
221 'payment' => array( 'methods' ),
222 'advanced' => array( 'debug' ),
223 ),
224 'generalSettings' => array(
225 'useHostedPage' => false,
226 'useReplacementPaymentMethod' => false,
227 'useAllowedIPAddresses' => true,
228 'useOrderReporting' => false,
229 ),
230 'isPromotional' => false,
231 '_state_controller' => $state_controller,
232 'customHeader' => array( 'X-WP-Nonce' => \wp_create_nonce( 'wp_rest' ) ),
233 'regex' => $this->regex->toArray(),
234 );
235
236 return $sequra_fe;
237 }
238
239 /**
240 * Get the SequraWidgetFacade object
241 *
242 * @return array<string, mixed>
243 */
244 private function get_sequra_widget_facade_l10n(): array {
245 return array(
246 'widgets' => array(),
247 'miniWidgets' => array(),
248 );
249 }
250
251 /**
252 * Get the SequraConfigParams object
253 *
254 * @return array<string, mixed>
255 */
256 private function get_sequra_config_params_l10n(): array {
257 $data = $this->widgets_service->get_widget_config_params() ?? array();
258 return array(
259 'scriptUri' => $data['scriptUri'] ?? '',
260 'thousandSeparator' => $data['thousandSeparator'] ?? '',
261 'decimalSeparator' => $data['decimalSeparator'] ?? '',
262 'locale' => $data['locale'] ?? '',
263 'merchant' => $data['merchant'] ?? '',
264 'assetKey' => $data['assetKey'] ?? '',
265 'products' => $data['products'] ?? array(),
266 );
267 }
268
269 /**
270 * Get the script arguments to enqueue based on the WP version
271 *
272 * @return array|bool
273 */
274 private function get_script_args( string $strategy, bool $in_footer ) {
275 if ( version_compare( $this->wp_version, '6.3', '>=' ) ) {
276 return array(
277 'strategy' => $strategy,
278 'in_footer' => $in_footer,
279 );
280 }
281 return $in_footer;
282 }
283
284 /**
285 * Enqueue styles and scripts in Front-End for the checkout page
286 */
287 private function enqueue_front_checkout(): void {
288 \wp_enqueue_style( self::HANDLE_CHECKOUT, "{$this->assets_dir_url}/css/checkout.css", array(), $this->assets_version );
289 \wp_register_script(
290 self::HANDLE_CHECKOUT,
291 "{$this->assets_dir_url}/js/dist/page/checkout.min.js",
292 array( self::HANDLE_CONFIG_PARAMS ),
293 $this->assets_version,
294 $this->get_script_args( self::STRATEGY_DEFER, true )
295 );
296
297 /**
298 * Check if the checkout is a Gutenberg block based version
299 *
300 * @since 3.0.0
301 */
302 $is_block = apply_filters(
303 'sequra_is_block_checkout',
304 ! $this->payment_method_service->is_order_pay_page() // TODO: Remove this condition once the block checkout is implemented in the order pay page.
305 && class_exists( 'Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils' )
306 && method_exists( 'Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils', 'is_checkout_block_default' )
307 && \Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils::is_checkout_block_default()
308 );
309
310 /**
311 * Set the flag to delay the updated checkout event listener
312 *
313 * @since 3.2.0
314 * @param bool $is_updated_checkout_listener_delayed
315 * @return bool
316 */
317 $is_updated_checkout_listener_delayed = (bool) apply_filters( 'sequra_is_updated_checkout_listener_delayed', false );
318
319 /**
320 * Set the delay for the updated checkout event listener in milliseconds
321 *
322 * @since 3.2.0
323 * @param int $updated_checkout_listener_delay
324 * @return int
325 */
326 $updated_checkout_listener_delay = (int) apply_filters( 'sequra_updated_checkout_listener_delay', 0 );
327
328 \wp_localize_script(
329 self::HANDLE_CHECKOUT,
330 'SeQuraCheckout',
331 array(
332 'isBlockCheckout' => $is_block,
333 'isUpdatedCheckoutListenerDelayed' => $is_updated_checkout_listener_delayed,
334 'updatedCheckoutListenerDelay' => $updated_checkout_listener_delay,
335 )
336 );
337 \wp_enqueue_script( self::HANDLE_CHECKOUT );
338 }
339
340 /**
341 * Enqueue styles and scripts in Front-End for the widgets
342 */
343 private function enqueue_front_widgets(): void {
344 \wp_enqueue_style( self::HANDLE_WIDGET, "{$this->assets_dir_url}/css/widget.css", array(), $this->assets_version );
345 \wp_register_script(
346 self::HANDLE_WIDGET,
347 "{$this->assets_dir_url}/js/dist/page/widget-facade.min.js",
348 array( self::HANDLE_CONFIG_PARAMS ),
349 $this->assets_version,
350 $this->get_script_args( self::STRATEGY_DEFER, false )
351 );
352 \wp_localize_script( self::HANDLE_WIDGET, 'SequraWidgetFacade', $this->get_sequra_widget_facade_l10n() );
353 \wp_enqueue_script( self::HANDLE_WIDGET );
354 }
355
356 /**
357 * Check if the current post has the widget shortcode in its content
358 */
359 private function has_widget_shortcode(): bool {
360 if ( \is_checkout() || \is_cart() || ! \is_singular() ) {
361 return false;
362 }
363 global $post;
364 return \has_shortcode( $post->post_content, 'sequra_widget' );
365 }
366
367 /**
368 * Check if the current post has the cart widget shortcode in its content
369 */
370 private function has_cart_widget_shortcode(): bool {
371 if ( \is_checkout() || \is_product() || ! \is_page() ) {
372 return false;
373 }
374 global $post;
375 return \has_shortcode( $post->post_content, 'sequra_cart_widget' );
376 }
377
378 /**
379 * Check if the current post has the cart widget shortcode in its content
380 */
381 private function has_product_listing_widget_shortcode(): bool {
382 if ( \is_checkout() || \is_product() || \is_cart() || ! \is_page() ) {
383 return false;
384 }
385 global $post;
386 return \has_shortcode( $post->post_content, 'sequra_product_listing_widget' );
387 }
388
389 /**
390 * Enqueue styles and scripts in Front-End
391 *
392 * @return void
393 */
394 public function enqueue_front() {
395 $this->logger->log_debug( 'Hook executed', __FUNCTION__, __CLASS__ );
396
397 \wp_register_script(
398 self::HANDLE_CONFIG_PARAMS,
399 "{$this->assets_dir_url}/js/dist/page/sequra-config-params.min.js",
400 array(),
401 $this->assets_version,
402 $this->get_script_args( self::STRATEGY_DEFER, false )
403 );
404 \wp_localize_script( self::HANDLE_CONFIG_PARAMS, 'SequraConfigParams', $this->get_sequra_config_params_l10n() );
405
406 if ( $this->payment_method_service->is_checkout() ) {
407 $this->enqueue_front_checkout();
408 }
409
410 if ( \is_product()
411 || $this->has_widget_shortcode()
412 || \is_cart()
413 || $this->has_cart_widget_shortcode()
414 || \is_product_category()
415 || \is_product_tag()
416 || \is_shop()
417 || $this->has_product_listing_widget_shortcode() ) {
418 $this->enqueue_front_widgets();
419 }
420 }
421
422 /**
423 * Load translations from the .json file
424 *
425 * @param string $lang Language code.
426 * @return mixed[]
427 */
428 private function load_translation( $lang = 'en' ): array {
429 $path = "{$this->assets_dir_path}/integration-core-ui/lang/{$lang}.json";
430 $translations = array();
431
432 global $wp_filesystem;
433 require_once ABSPATH . '/wp-admin/includes/file.php';
434 if ( ! WP_Filesystem() ) {
435 return $translations;
436 }
437
438 if ( ! $wp_filesystem->exists( $path ) ) {
439 return $translations;
440 }
441
442 $content = $wp_filesystem->get_contents( $path );
443
444 if ( empty( $content ) ) {
445 return $translations;
446 }
447
448 $content = json_decode( $content, true );
449 if ( is_array( $content ) ) {
450 $translations = $content;
451 }
452 return $translations;
453 }
454 }
455