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

456 lines 14.4 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 'isAltPriceSelectorVisible' => true,
214 ),
215 'translations' => array(
216 'default' => $this->load_translation(),
217 'current' => $this->load_translation( $this->i18n->get_lang() ),
218 ),
219 'pages' => array(
220 'onboarding' => array( 'deployments', 'connect', 'countries', 'widgets' ),
221 'settings' => array( 'general', 'connection', 'order_status', 'widget' ),
222 'payment' => array( 'methods' ),
223 'advanced' => array( 'debug' ),
224 ),
225 'generalSettings' => array(
226 'useHostedPage' => false,
227 'useReplacementPaymentMethod' => false,
228 'useAllowedIPAddresses' => true,
229 'useOrderReporting' => false,
230 ),
231 'isPromotional' => false,
232 '_state_controller' => $state_controller,
233 'customHeader' => array( 'X-WP-Nonce' => \wp_create_nonce( 'wp_rest' ) ),
234 'regex' => $this->regex->toArray(),
235 );
236
237 return $sequra_fe;
238 }
239
240 /**
241 * Get the SequraWidgetFacade object
242 *
243 * @return array<string, mixed>
244 */
245 private function get_sequra_widget_facade_l10n(): array {
246 return array(
247 'widgets' => array(),
248 'miniWidgets' => array(),
249 );
250 }
251
252 /**
253 * Get the SequraConfigParams object
254 *
255 * @return array<string, mixed>
256 */
257 private function get_sequra_config_params_l10n(): array {
258 $data = $this->widgets_service->get_widget_config_params() ?? array();
259 return array(
260 'scriptUri' => $data['scriptUri'] ?? '',
261 'thousandSeparator' => $data['thousandSeparator'] ?? '',
262 'decimalSeparator' => $data['decimalSeparator'] ?? '',
263 'locale' => $data['locale'] ?? '',
264 'merchant' => $data['merchant'] ?? '',
265 'assetKey' => $data['assetKey'] ?? '',
266 'products' => $data['products'] ?? array(),
267 );
268 }
269
270 /**
271 * Get the script arguments to enqueue based on the WP version
272 *
273 * @return array|bool
274 */
275 private function get_script_args( string $strategy, bool $in_footer ) {
276 if ( version_compare( $this->wp_version, '6.3', '>=' ) ) {
277 return array(
278 'strategy' => $strategy,
279 'in_footer' => $in_footer,
280 );
281 }
282 return $in_footer;
283 }
284
285 /**
286 * Enqueue styles and scripts in Front-End for the checkout page
287 */
288 private function enqueue_front_checkout(): void {
289 \wp_enqueue_style( self::HANDLE_CHECKOUT, "{$this->assets_dir_url}/css/checkout.css", array(), $this->assets_version );
290 \wp_register_script(
291 self::HANDLE_CHECKOUT,
292 "{$this->assets_dir_url}/js/dist/page/checkout.min.js",
293 array( self::HANDLE_CONFIG_PARAMS ),
294 $this->assets_version,
295 $this->get_script_args( self::STRATEGY_DEFER, true )
296 );
297
298 /**
299 * Check if the checkout is a Gutenberg block based version
300 *
301 * @since 3.0.0
302 */
303 $is_block = apply_filters(
304 'sequra_is_block_checkout',
305 ! $this->payment_method_service->is_order_pay_page() // TODO: Remove this condition once the block checkout is implemented in the order pay page.
306 && class_exists( 'Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils' )
307 && method_exists( 'Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils', 'is_checkout_block_default' )
308 && \Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils::is_checkout_block_default()
309 );
310
311 /**
312 * Set the flag to delay the updated checkout event listener
313 *
314 * @since 3.2.0
315 * @param bool $is_updated_checkout_listener_delayed
316 * @return bool
317 */
318 $is_updated_checkout_listener_delayed = (bool) apply_filters( 'sequra_is_updated_checkout_listener_delayed', false );
319
320 /**
321 * Set the delay for the updated checkout event listener in milliseconds
322 *
323 * @since 3.2.0
324 * @param int $updated_checkout_listener_delay
325 * @return int
326 */
327 $updated_checkout_listener_delay = (int) apply_filters( 'sequra_updated_checkout_listener_delay', 0 );
328
329 \wp_localize_script(
330 self::HANDLE_CHECKOUT,
331 'SeQuraCheckout',
332 array(
333 'isBlockCheckout' => $is_block,
334 'isUpdatedCheckoutListenerDelayed' => $is_updated_checkout_listener_delayed,
335 'updatedCheckoutListenerDelay' => $updated_checkout_listener_delay,
336 )
337 );
338 \wp_enqueue_script( self::HANDLE_CHECKOUT );
339 }
340
341 /**
342 * Enqueue styles and scripts in Front-End for the widgets
343 */
344 private function enqueue_front_widgets(): void {
345 \wp_enqueue_style( self::HANDLE_WIDGET, "{$this->assets_dir_url}/css/widget.css", array(), $this->assets_version );
346 \wp_register_script(
347 self::HANDLE_WIDGET,
348 "{$this->assets_dir_url}/js/dist/page/widget-facade.min.js",
349 array( self::HANDLE_CONFIG_PARAMS ),
350 $this->assets_version,
351 $this->get_script_args( self::STRATEGY_DEFER, false )
352 );
353 \wp_localize_script( self::HANDLE_WIDGET, 'SequraWidgetFacade', $this->get_sequra_widget_facade_l10n() );
354 \wp_enqueue_script( self::HANDLE_WIDGET );
355 }
356
357 /**
358 * Check if the current post has the widget shortcode in its content
359 */
360 private function has_widget_shortcode(): bool {
361 if ( \is_checkout() || \is_cart() || ! \is_singular() ) {
362 return false;
363 }
364 global $post;
365 return \has_shortcode( $post->post_content, 'sequra_widget' );
366 }
367
368 /**
369 * Check if the current post has the cart widget shortcode in its content
370 */
371 private function has_cart_widget_shortcode(): bool {
372 if ( \is_checkout() || \is_product() || ! \is_page() ) {
373 return false;
374 }
375 global $post;
376 return \has_shortcode( $post->post_content, 'sequra_cart_widget' );
377 }
378
379 /**
380 * Check if the current post has the cart widget shortcode in its content
381 */
382 private function has_product_listing_widget_shortcode(): bool {
383 if ( \is_checkout() || \is_product() || \is_cart() || ! \is_page() ) {
384 return false;
385 }
386 global $post;
387 return \has_shortcode( $post->post_content, 'sequra_product_listing_widget' );
388 }
389
390 /**
391 * Enqueue styles and scripts in Front-End
392 *
393 * @return void
394 */
395 public function enqueue_front() {
396 $this->logger->log_debug( 'Hook executed', __FUNCTION__, __CLASS__ );
397
398 \wp_register_script(
399 self::HANDLE_CONFIG_PARAMS,
400 "{$this->assets_dir_url}/js/dist/page/sequra-config-params.min.js",
401 array(),
402 $this->assets_version,
403 $this->get_script_args( self::STRATEGY_DEFER, false )
404 );
405 \wp_localize_script( self::HANDLE_CONFIG_PARAMS, 'SequraConfigParams', $this->get_sequra_config_params_l10n() );
406
407 if ( $this->payment_method_service->is_checkout() ) {
408 $this->enqueue_front_checkout();
409 }
410
411 if ( \is_product()
412 || $this->has_widget_shortcode()
413 || \is_cart()
414 || $this->has_cart_widget_shortcode()
415 || \is_product_category()
416 || \is_product_tag()
417 || \is_shop()
418 || $this->has_product_listing_widget_shortcode() ) {
419 $this->enqueue_front_widgets();
420 }
421 }
422
423 /**
424 * Load translations from the .json file
425 *
426 * @param string $lang Language code.
427 * @return mixed[]
428 */
429 private function load_translation( $lang = 'en' ): array {
430 $path = "{$this->assets_dir_path}/integration-core-ui/lang/{$lang}.json";
431 $translations = array();
432
433 global $wp_filesystem;
434 require_once ABSPATH . '/wp-admin/includes/file.php';
435 if ( ! WP_Filesystem() ) {
436 return $translations;
437 }
438
439 if ( ! $wp_filesystem->exists( $path ) ) {
440 return $translations;
441 }
442
443 $content = $wp_filesystem->get_contents( $path );
444
445 if ( empty( $content ) ) {
446 return $translations;
447 }
448
449 $content = json_decode( $content, true );
450 if ( is_array( $content ) ) {
451 $translations = $content;
452 }
453 return $translations;
454 }
455 }
456