PluginProbe
seQura / 3.2.0
seQura v3.2.0
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 3.2.0, at src/Controllers/Hooks/Asset/class-assets-controller.php

470 lines 14.9 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\Core\Extension\Infrastructure\Configuration\Configuration;
13 use SeQura\WC\Services\Assets\Interface_Assets;
14 use SeQura\WC\Services\I18n\Interface_I18n;
15 use SeQura\WC\Services\Interface_Logger_Service;
16 use SeQura\WC\Services\Payment\Interface_Payment_Method_Service;
17 use SeQura\WC\Services\Regex\Interface_Regex;
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 Configuration
71 */
72 private $configuration;
73
74 /**
75 * Assets service
76 *
77 * @var Interface_Assets
78 */
79 private $assets;
80
81 /**
82 * Payment method service
83 *
84 * @var Interface_Payment_Method_Service
85 */
86 private $payment_method_service;
87
88 /**
89 * Regex service
90 *
91 * @var Interface_Regex
92 */
93 private $regex;
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 Configuration $configuration,
107 Interface_Assets $assets,
108 Interface_Payment_Method_Service $payment_method_service,
109 Interface_Regex $regex
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->configuration = $configuration;
118 $this->assets = $assets;
119 $this->payment_method_service = $payment_method_service;
120 $this->regex = $regex;
121 $this->wp_version = $wp_version;
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->configuration->is_settings_page() ) {
132 return;
133 }
134 // Styles.
135 \wp_enqueue_style( self::HANDLE_CORE, "{$this->assets_dir_url}/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 );
152 $payment_page_config = array_merge(
153 $connection_config,
154 array(
155 'getPaymentMethodsUrl' => \get_rest_url( null, 'sequra/v1/payment/methods/{storeId}/{merchantId}' ),
156 'getAllPaymentMethodsUrl' => \get_rest_url( null, 'sequra/v1/payment/methods/{storeId}' ),
157 'getSellingCountriesUrl' => \get_rest_url( null, 'sequra/v1/onboarding/countries/selling/{storeId}' ),
158 'getCountrySettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/countries/{storeId}' ),
159 'validateConnectionDataUrl' => \get_rest_url( null, 'sequra/v1/onboarding/data/validate/{storeId}' ),
160 )
161 );
162 $onboarding_page_config = array_merge(
163 $payment_page_config,
164 array(
165 'saveConnectionDataUrl' => \get_rest_url( null, 'sequra/v1/onboarding/data/{storeId}' ),
166 'saveCountrySettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/countries/{storeId}' ),
167 'getWidgetSettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/widgets/{storeId}' ),
168 'saveWidgetSettingsUrl' => \get_rest_url( null, 'sequra/v1/onboarding/widgets/{storeId}' ),
169 )
170 );
171 $page_config = array(
172 'onboarding' => $onboarding_page_config,
173 'settings' => array_merge(
174 $onboarding_page_config,
175 array(
176 'getShopPaymentMethodsUrl' => '', // Not used in this implementation.
177 'getShopCategoriesUrl' => \get_rest_url( null, 'sequra/v1/settings/shop-categories/{storeId}' ),
178 'getGeneralSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/general/{storeId}' ),
179 'saveGeneralSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/general/{storeId}' ),
180 'getShopOrderStatusesUrl' => \get_rest_url( null, 'sequra/v1/settings/order-status/list/{storeId}' ),
181 'getOrderStatusMappingSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/order-status/{storeId}' ),
182 'saveOrderStatusMappingSettingsUrl' => \get_rest_url( null, 'sequra/v1/settings/order-status/{storeId}' ),
183 'disconnectUrl' => \get_rest_url( null, 'sequra/v1/onboarding/data/disconnect/{storeId}' ),
184 )
185 ),
186 'payment' => $payment_page_config,
187 'transactions' => array_merge(
188 $connection_config,
189 array(
190 'getTransactionLogsUrl' => \get_rest_url( null, 'sequra/v1/log/{storeId}' ),
191 )
192 ),
193 'advanced' => array_merge(
194 $connection_config,
195 array(
196 'getLogsUrl' => \get_rest_url( null, 'sequra/v1/log/{storeId}' ),
197 'removeLogsUrl' => \get_rest_url( null, 'sequra/v1/log/{storeId}' ),
198 'getLogsSettingsUrl' => \get_rest_url( null, 'sequra/v1/log/settings/{storeId}' ),
199 'saveLogsSettingsUrl' => \get_rest_url( null, 'sequra/v1/log/settings/{storeId}' ),
200 )
201 ),
202 );
203
204 $state_controller = array(
205 'storesUrl' => \get_rest_url( null, 'sequra/v1/settings/stores/{storeId}' ),
206 'currentStoreUrl' => \get_rest_url( null, 'sequra/v1/settings/current-store' ),
207 'stateUrl' => \get_rest_url( null, 'sequra/v1/settings/state/{storeId}' ),
208 'versionUrl' => \get_rest_url( null, 'sequra/v1/settings/version/{storeId}' ),
209 'shopNameUrl' => \get_rest_url( null, 'sequra/v1/settings/shop-name/{storeId}' ),
210 'pageConfiguration' => $page_config,
211 );
212
213 $pages_payment = array( 'methods' );
214 $sequra_fe = array(
215 'translations' => array(
216 'default' => $this->load_translation(),
217 'current' => $this->load_translation( $this->i18n->get_lang() ),
218 ),
219 'pages' => array(
220 'onboarding' => array( 'connect', 'countries', 'widgets' ),
221 'settings' => array( 'general', 'connection', 'order_status', 'widget' ),
222 'payment' => $pages_payment,
223 'advanced' => array( 'debug' ),
224 ),
225 'integration' => array(
226 'authToken' => '', // Not used in this implementation.
227 'isMultistore' => count( $this->configuration->get_stores() ) > 1,
228 'hasVersion' => version_compare( $this->configuration->get_marketplace_version(), $this->configuration->get_module_version(), '>' ),
229 ),
230 'generalSettings' => array(
231 'useHostedPage' => false,
232 'useReplacementPaymentMethod' => false,
233 'useAllowedIPAddresses' => true,
234 'useOrderReporting' => false,
235 ),
236 'isPromotional' => false,
237 '_state_controller' => $state_controller,
238 'customHeader' => array( 'X-WP-Nonce' => \wp_create_nonce( 'wp_rest' ) ),
239
240 'regex' => array(
241 'ip' => $this->regex->ip( false ),
242 'dateOrDuration' => $this->regex->date_or_duration( false ),
243 ),
244 'miniWidgetLabels' => array(
245 'messages' => $this->configuration->get_mini_widget_default_messages(),
246 'messagesBelowLimit' => $this->configuration->get_mini_widget_default_messages_below_limit(),
247 ),
248 );
249
250 return $sequra_fe;
251 }
252
253 /**
254 * Get the SequraWidgetFacade object
255 *
256 * @return array<string, mixed>
257 */
258 private function get_sequra_widget_facade_l10n(): array {
259 return array(
260 'widgets' => array(),
261 'miniWidgets' => array(),
262 );
263 }
264
265 /**
266 * Get the SequraConfigParams object
267 *
268 * @return array<string, mixed>
269 */
270 private function get_sequra_config_params_l10n(): array {
271 $merchant = $this->configuration->get_merchant_ref( $this->i18n->get_current_country() );
272 $methods = $this->payment_method_service->get_all_widget_compatible_payment_methods( $this->configuration->get_store_id(), $merchant );
273 return array(
274 'scriptUri' => $this->assets->get_cdn_resource_uri( $this->configuration->get_env(), 'sequra-checkout.min.js' ),
275 'thousandSeparator' => \wc_get_price_thousand_separator(),
276 'decimalSeparator' => \wc_get_price_decimal_separator(),
277 'locale' => $this->i18n->get_locale(),
278 'merchant' => $merchant,
279 'assetKey' => $this->configuration->get_assets_key(),
280 'products' => array_column( $methods, 'product' ),
281 );
282 }
283
284 /**
285 * Get the script arguments to enqueue based on the WP version
286 *
287 * @return array|bool
288 */
289 private function get_script_args( string $strategy, bool $in_footer ) {
290 if ( version_compare( $this->wp_version, '6.3', '>=' ) ) {
291 return array(
292 'strategy' => $strategy,
293 'in_footer' => $in_footer,
294 );
295 }
296 return $in_footer;
297 }
298
299 /**
300 * Enqueue styles and scripts in Front-End for the checkout page
301 */
302 private function enqueue_front_checkout(): void {
303 \wp_enqueue_style( self::HANDLE_CHECKOUT, "{$this->assets_dir_url}/css/checkout.css", array(), $this->assets_version );
304 \wp_register_script(
305 self::HANDLE_CHECKOUT,
306 "{$this->assets_dir_url}/js/dist/page/checkout.min.js",
307 array( self::HANDLE_CONFIG_PARAMS ),
308 $this->assets_version,
309 $this->get_script_args( self::STRATEGY_DEFER, true )
310 );
311
312 /**
313 * Check if the checkout is a Gutenberg block based version
314 *
315 * @since 3.0.0
316 */
317 $is_block = apply_filters(
318 'sequra_is_block_checkout',
319 ! $this->payment_method_service->is_order_pay_page() // TODO: Remove this condition once the block checkout is implemented in the order pay page.
320 && class_exists( 'Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils' )
321 && method_exists( 'Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils', 'is_checkout_block_default' )
322 && \Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils::is_checkout_block_default()
323 );
324
325 /**
326 * Set the flag to delay the updated checkout event listener
327 *
328 * @since 3.2.0
329 * @param bool $is_updated_checkout_listener_delayed
330 * @return bool
331 */
332 $is_updated_checkout_listener_delayed = (bool) apply_filters( 'sequra_is_updated_checkout_listener_delayed', false );
333
334 /**
335 * Set the delay for the updated checkout event listener in milliseconds
336 *
337 * @since 3.2.0
338 * @param int $updated_checkout_listener_delay
339 * @return int
340 */
341 $updated_checkout_listener_delay = (int) apply_filters( 'sequra_updated_checkout_listener_delay', 0 );
342
343 \wp_localize_script(
344 self::HANDLE_CHECKOUT,
345 'SeQuraCheckout',
346 array(
347 'isBlockCheckout' => $is_block,
348 'isUpdatedCheckoutListenerDelayed' => $is_updated_checkout_listener_delayed,
349 'updatedCheckoutListenerDelay' => $updated_checkout_listener_delay,
350 )
351 );
352 \wp_enqueue_script( self::HANDLE_CHECKOUT );
353 }
354
355 /**
356 * Enqueue styles and scripts in Front-End for the widgets
357 */
358 private function enqueue_front_widgets(): void {
359 \wp_enqueue_style( self::HANDLE_WIDGET, "{$this->assets_dir_url}/css/widget.css", array(), $this->assets_version );
360 \wp_register_script(
361 self::HANDLE_WIDGET,
362 "{$this->assets_dir_url}/js/dist/page/widget-facade.min.js",
363 array( self::HANDLE_CONFIG_PARAMS ),
364 $this->assets_version,
365 $this->get_script_args( self::STRATEGY_DEFER, false )
366 );
367 \wp_localize_script( self::HANDLE_WIDGET, 'SequraWidgetFacade', $this->get_sequra_widget_facade_l10n() );
368 \wp_enqueue_script( self::HANDLE_WIDGET );
369 }
370
371 /**
372 * Check if the current post has the widget shortcode in its content
373 */
374 private function has_widget_shortcode(): bool {
375 if ( \is_checkout() || \is_cart() || ! \is_singular() ) {
376 return false;
377 }
378 global $post;
379 return \has_shortcode( $post->post_content, 'sequra_widget' );
380 }
381
382 /**
383 * Check if the current post has the cart widget shortcode in its content
384 */
385 private function has_cart_widget_shortcode(): bool {
386 if ( \is_checkout() || \is_product() || ! \is_page() ) {
387 return false;
388 }
389 global $post;
390 return \has_shortcode( $post->post_content, 'sequra_cart_widget' );
391 }
392
393 /**
394 * Check if the current post has the cart widget shortcode in its content
395 */
396 private function has_product_listing_widget_shortcode(): bool {
397 if ( \is_checkout() || \is_product() || \is_cart() || ! \is_page() ) {
398 return false;
399 }
400 global $post;
401 return \has_shortcode( $post->post_content, 'sequra_product_listing_widget' );
402 }
403
404 /**
405 * Enqueue styles and scripts in Front-End
406 *
407 * @return void
408 */
409 public function enqueue_front() {
410 $this->logger->log_debug( 'Hook executed', __FUNCTION__, __CLASS__ );
411
412 \wp_register_script(
413 self::HANDLE_CONFIG_PARAMS,
414 "{$this->assets_dir_url}/js/dist/page/sequra-config-params.min.js",
415 array(),
416 $this->assets_version,
417 $this->get_script_args( self::STRATEGY_DEFER, false )
418 );
419 \wp_localize_script( self::HANDLE_CONFIG_PARAMS, 'SequraConfigParams', $this->get_sequra_config_params_l10n() );
420
421 if ( $this->payment_method_service->is_checkout() ) {
422 $this->enqueue_front_checkout();
423 }
424
425 if ( \is_product()
426 || $this->has_widget_shortcode()
427 || \is_cart()
428 || $this->has_cart_widget_shortcode()
429 || \is_product_category()
430 || \is_product_tag()
431 || \is_shop()
432 || $this->has_product_listing_widget_shortcode() ) {
433 $this->enqueue_front_widgets();
434 }
435 }
436
437 /**
438 * Load translations from the .json file
439 *
440 * @param string $lang Language code.
441 * @return mixed[]
442 */
443 private function load_translation( $lang = 'en' ): array {
444 $path = "{$this->assets_dir_path}/lang/{$lang}.json";
445 $translations = array();
446
447 global $wp_filesystem;
448 require_once ABSPATH . '/wp-admin/includes/file.php';
449 if ( ! WP_Filesystem() ) {
450 return $translations;
451 }
452
453 if ( ! $wp_filesystem->exists( $path ) ) {
454 return $translations;
455 }
456
457 $content = $wp_filesystem->get_contents( $path );
458
459 if ( empty( $content ) ) {
460 return $translations;
461 }
462
463 $content = json_decode( $content, true );
464 if ( is_array( $content ) ) {
465 $translations = $content;
466 }
467 return $translations;
468 }
469 }
470