PluginProbe
seQura / 3.0.2
seQura v3.0.2
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 / Core / Extension / Infrastructure / Configuration / class-configuration.php

class-configuration.php in seQura 3.0.2, at src/Core/Extension/Infrastructure/Configuration/class-configuration.php

746 lines 19.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Extends the Configuration class.
4 * Delegate to the ConfigurationManager instance to access the data in the database.
5 *
6 * @package SeQura\WC
7 */
8
9 namespace SeQura\WC\Core\Extension\Infrastructure\Configuration;
10
11 use SeQura\Core\BusinessLogic\AdminAPI\AdminAPI;
12 use SeQura\Core\BusinessLogic\Domain\OrderStatusSettings\Services\OrderStatusSettingsService;
13 use SeQura\Core\Infrastructure\Configuration\Configuration as CoreConfiguration;
14 use SeQura\Core\Infrastructure\ServiceRegister;
15 use SeQura\WC\Core\Extension\BusinessLogic\Domain\PromotionalWidgets\Models\Widget_Location;
16 use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Platform;
17 use Throwable;
18 use WP_Site;
19
20 /**
21 * Extends the Configuration class. Wrapper to ease the read and write of configuration values.
22 */
23 class Configuration extends CoreConfiguration {
24
25 private const CONF_DB_VERSION = 'dbVersion';
26
27 /**
28 * Marketplace version.
29 *
30 * @var ?string
31 */
32 private $marketplace_version;
33
34 /**
35 * Retrieves the store ID.
36 */
37 public function get_store_id(): string {
38 return (string) get_current_blog_id();
39 }
40
41 /**
42 * Retrieves integration name.
43 *
44 * @return string Integration name.
45 */
46 public function getIntegrationName() {
47 return 'WooCommerce';
48 }
49
50 /**
51 * Gets the current version of the module/integration.
52 */
53 public function get_module_version(): string {
54 return strval( $this->getConfigurationManager()->getConfigValue( 'version', '' ) );
55 }
56
57 /**
58 * Gets the current version of the module/integration.
59 *
60 * @param string $version The version number.
61 */
62 public function set_module_version( $version ): void {
63 $this->getConfigurationManager()->saveConfigValue( 'version', $version );
64 }
65
66 /**
67 * Returns async process starter url, always in http.
68 *
69 * @param string $guid Process identifier.
70 *
71 * @return string Formatted URL of async process starter endpoint.
72 */
73 public function getAsyncProcessUrl( $guid ) {
74 return ''; // Not used in this implementation.
75 }
76
77 /**
78 * Check if the current page is the settings page.
79 */
80 public function is_settings_page(): bool {
81 return is_admin() && isset( $_GET['page'] ) && $this->get_page() === $_GET['page']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
82 }
83
84 /**
85 * Get the configuration page slug.
86 */
87 public function get_page(): string {
88 return 'sequra';
89 }
90
91 /**
92 * Get the configuration page parent slug.
93 */
94 public function get_parent_page(): string {
95 return 'woocommerce';
96 }
97
98 /**
99 * Version published in the marketplace.
100 */
101 public function get_marketplace_version(): string {
102
103 if ( null !== $this->marketplace_version ) {
104 return $this->marketplace_version;
105 }
106
107 if ( ! function_exists( 'plugins_api' ) ) {
108 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
109 }
110 $response = plugins_api(
111 'plugin_information',
112 array(
113 'slug' => 'sequra',
114 'fields' => array( 'version' => true ),
115 )
116 );
117 if ( is_wp_error( $response ) || empty( $response->version ) ) {
118 return '';
119 }
120
121 $this->marketplace_version = $response->version;
122 return $this->marketplace_version;
123 }
124
125 /**
126 * Current store. Has keys storeId and storeName.
127 *
128 * @return array<string, mixed>
129 */
130 public function get_current_store(): array {
131 return array(
132 'storeId' => get_current_blog_id(),
133 'storeName' => get_bloginfo( 'name' ),
134 );
135 }
136
137 /**
138 * List of stores. Each store is an array with storeId and storeName.
139 *
140 * @return array<array<string, mixed>>
141 */
142 public function get_stores(): array {
143 $stores = array();
144 if ( function_exists( 'get_sites' ) ) {
145 /**
146 * Available sites
147 *
148 * @var WP_Site $site
149 */
150 foreach ( get_sites() as $site ) {
151 $stores[] = array(
152 'storeId' => $site->blog_id,
153 'storeName' => $site->blogname,
154 );
155 }
156 } else {
157 $stores[] = $this->get_current_store();
158 }
159 return $stores;
160 }
161
162 /**
163 * Get password from connection settings.
164 */
165 public function get_password(): string {
166
167 try {
168 $config = AdminAPI::get()
169 ->connection( $this->get_store_id() )
170 ->getOnboardingData()
171 ->toArray();
172
173 return $config['password'] ?? '';
174 } catch ( Throwable $e ) {
175 return '';
176 }
177 }
178
179 /**
180 * Get order status mappings.
181 *
182 * @return OrderStatusMapping[]
183 */
184 public function get_order_statuses(): array {
185 try {
186 $order_status_service = ServiceRegister::getService( OrderStatusSettingsService::class );
187 return $order_status_service->getOrderStatusSettings(); // @phpstan-ignore-line
188 } catch ( \Throwable $e ) {
189 return array();
190 }
191 }
192
193 /**
194 * Get enabledForServices from general settings.
195 */
196 public function is_enabled_for_services(): bool {
197 try {
198 $config = $this->get_general_settings();
199 return ! empty( $config['enabledForServices'] );
200 } catch ( Throwable $e ) {
201 return false;
202 }
203 }
204
205 /**
206 * Check if current IP is allowed to use the payment gateway.
207 */
208 public function is_available_for_ip(): bool {
209 try {
210 $config = $this->get_general_settings();
211 // phpcs:ignore WordPressVIPMinimum.Variables.ServerVariables.UserControlledHeaders, WordPressVIPMinimum.Variables.RestrictedVariables.cache_constraints___SERVER__REMOTE_ADDR__
212 $remote_addr = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
213
214 $allowed_ip_addresses = array();
215 if ( isset( $config['allowedIPAddresses'] ) && is_array( $config['allowedIPAddresses'] ) ) {
216 foreach ( $config['allowedIPAddresses'] as $ip ) {
217 $ip = trim( (string) $ip );
218 if ( ! empty( $ip ) ) {
219 $allowed_ip_addresses[] = $ip;
220 }
221 }
222 }
223
224 return empty( $allowed_ip_addresses ) || in_array( $remote_addr, $allowed_ip_addresses, true );
225 } catch ( Throwable $e ) {
226 return true;
227 }
228 }
229 /**
230 * Get allowFirstServicePaymentDelay from general settings.
231 */
232 public function allow_first_service_payment_delay(): bool {
233 try {
234 $config = $this->get_general_settings();
235 return ! empty( $config['allowFirstServicePaymentDelay'] );
236 } catch ( Throwable $e ) {
237 return false;
238 }
239 }
240
241 /**
242 * Get if registration items are allowed
243 */
244 public function allow_service_reg_items(): bool {
245 try {
246 $config = $this->get_general_settings();
247 return ! empty( $config['allowServiceRegItems'] );
248 } catch ( Throwable $e ) {
249 return false;
250 }
251 }
252
253 /**
254 * Get defaultServicesEndDate from general settings.
255 */
256 public function get_default_services_end_date(): string {
257 try {
258 $config = $this->get_general_settings();
259 return $config['defaultServicesEndDate'] ?? 'PY1';
260 } catch ( Throwable $e ) {
261 return 'PY1';
262 }
263 }
264
265 /**
266 * Get excludedProducts from general settings.
267 *
268 * @return array<string>
269 */
270 public function get_excluded_products(): array {
271 try {
272 $config = $this->get_general_settings();
273 if ( ! empty( $config['excludedProducts'] ) && is_array( $config['excludedProducts'] ) ) {
274 return $config['excludedProducts'];
275 }
276 return array();
277 } catch ( Throwable $e ) {
278 return array();
279 }
280 }
281
282 /**
283 * Get excludedCategories from general settings.
284 *
285 * @return array<int>
286 */
287 public function get_excluded_categories(): array {
288 try {
289 $config = $this->get_general_settings();
290 if ( ! empty( $config['excludedCategories'] ) && is_array( $config['excludedCategories'] ) ) {
291 return array_map( 'absint', $config['excludedCategories'] );
292 }
293 return array();
294 } catch ( Throwable $e ) {
295 return array();
296 }
297 }
298
299 /**
300 * Get general settings as array
301 *
302 * @throws Throwable
303 *
304 * @return array<string, mixed>
305 */
306 protected function get_general_settings(): array {
307 return AdminAPI::get()
308 ->generalSettings( $this->get_store_id() )
309 ->getGeneralSettings()
310 ->toArray();
311 }
312
313 /**
314 * URL to the marketplace's plugin page.
315 */
316 public function get_marketplace_url(): string {
317 return 'https://wordpress.org/plugins/sequra/';
318 }
319
320 /**
321 * Saves dbVersion in integration database.
322 */
323 public function save_db_version( string $db_version ): void {
324 $this->saveConfigValue( self::CONF_DB_VERSION, $db_version );
325 }
326
327 /**
328 * Retrieves dbVersion from integration database.
329 */
330 public function get_db_version(): string {
331 return $this->getConfigValue( self::CONF_DB_VERSION, '' );
332 }
333
334 /**
335 * Get general settings as array
336 *
337 * @throws Throwable
338 *
339 * @return array<string, mixed>
340 */
341 protected function get_widget_settings(): array {
342 return AdminAPI::get()
343 ->widgetConfiguration( $this->get_store_id() )
344 ->getWidgetSettings()
345 ->toArray();
346 }
347
348 /**
349 * Check if the widget is enabled.
350 */
351 public function is_widget_enabled( ?string $payment_method, ?string $campaign, ?string $country ): bool {
352 try {
353 $config = $this->get_widget_settings();
354 return ! empty( $config['useWidgets'] )
355 && ! empty( $config['displayWidgetOnProductPage'] )
356 && $this->is_widget_enabled_in_custom_locations( $payment_method, $campaign, $country );
357 } catch ( Throwable $e ) {
358 return false;
359 }
360 }
361
362 /**
363 * Look for the mini widget configuration for a country
364 *
365 * @param array<string, string> $mini_widgets Mini widgets configuration
366 */
367 protected function get_mini_widget( string $country, array $mini_widgets ): ?array {
368 foreach ( $mini_widgets as $mini_widget ) {
369 if ( isset( $mini_widget['countryCode'] ) && $mini_widget['countryCode'] === $country ) {
370 return $mini_widget;
371 }
372 }
373 return null;
374 }
375
376 /**
377 * Check if the cart widget is enabled.
378 */
379 public function is_cart_widget_enabled( string $country ): bool {
380 try {
381 $config = $this->get_widget_settings();
382 $is_valid = ! empty( $config['useWidgets'] )
383 && ! empty( $config['showInstallmentAmountInCartPage'] )
384 && isset(
385 $config['selForCartPrice'],
386 $config['selForCartLocation']
387 );
388
389 if ( $is_valid && isset( $config['cartMiniWidgets'] ) ) {
390 $mini_widget = $this->get_mini_widget( $country, (array) $config['cartMiniWidgets'] );
391 $is_valid = isset( $mini_widget['message'], $mini_widget['product'] );
392 }
393 return $is_valid;
394 } catch ( Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
395 return false;
396 }
397 }
398
399 /**
400 * Check if the product listing widget is enabled.
401 */
402 public function is_product_listing_widget_enabled( string $country ): bool {
403 try {
404 $config = $this->get_widget_settings();
405 $is_valid = ! empty( $config['useWidgets'] )
406 && ! empty( $config['showInstallmentAmountInProductListing'] )
407 && isset(
408 $config['selForListingPrice'],
409 $config['selForListingLocation']
410 );
411
412 if ( $is_valid && isset( $config['listingMiniWidgets'] ) ) {
413 $mini_widget = $this->get_mini_widget( $country, (array) $config['listingMiniWidgets'] );
414 $is_valid = isset( $mini_widget['message'], $mini_widget['product'] );
415 }
416 return $is_valid;
417 } catch ( Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
418 return false;
419 }
420 }
421
422 /**
423 * Get the cart widget configuration for a country as an array
424 *
425 * @return null|array<string, mixed> Contains the following keys:
426 * - selForPrice: string
427 * - selForLocation: string
428 * - message: string
429 * - messageBelowLimit: string
430 * - product: string
431 * - campaign: ?string
432 */
433 public function get_cart_widget_config( string $country ): ?array {
434 try {
435 $config = $this->get_widget_settings();
436 $mini_widget = $this->get_mini_widget( $country, $config['cartMiniWidgets'] ?? array() );
437
438 return array(
439 'selForPrice' => empty( $mini_widget['selForPrice'] ) ? ( $config['selForCartPrice'] ?? '' ) : $mini_widget['selForPrice'],
440 'selForLocation' => empty( $mini_widget['selForLocation'] ) ? ( $config['selForCartLocation'] ?? '' ) : $mini_widget['selForLocation'],
441 'message' => $mini_widget['message'] ?? $this->get_mini_widget_default_message( $country ),
442 'messageBelowLimit' => $mini_widget['messageBelowLimit'] ?? $this->get_mini_widget_default_message_below_limit( $country ),
443 'product' => $mini_widget['product'] ?? 'pp3',
444 'campaign' => $mini_widget['campaign'] ?? null,
445 // 'title' => $mini_widget['title'] ?? null,
446 );
447 } catch ( Throwable $e ) {
448 return null;
449 }
450 }
451
452 /**
453 * Get the product listing widget configuration for a country as an array
454 *
455 * @return null|array<string, mixed> Contains the following keys:
456 * - selForPrice: string
457 * - selForLocation: string
458 * - message: string
459 * - messageBelowLimit: string
460 * - product: string
461 * - campaign: ?string
462 */
463 public function get_product_listing_widget_config( string $country ): ?array {
464 try {
465 $config = $this->get_widget_settings();
466 $mini_widget = $this->get_mini_widget( $country, $config['listingMiniWidgets'] ?? array() );
467
468 return array(
469 'selForPrice' => empty( $mini_widget['selForPrice'] ) ? ( $config['selForListingPrice'] ?? '' ) : $mini_widget['selForPrice'],
470 'selForLocation' => empty( $mini_widget['selForLocation'] ) ? ( $config['selForListingLocation'] ?? '' ) : $mini_widget['selForLocation'],
471 'message' => $mini_widget['message'] ?? $this->get_mini_widget_default_message( $country ),
472 'messageBelowLimit' => $mini_widget['messageBelowLimit'] ?? $this->get_mini_widget_default_message_below_limit( $country ),
473 'product' => $mini_widget['product'] ?? 'pp3',
474 'campaign' => $mini_widget['campaign'] ?? null,
475 // 'title' => $mini_widget['title'] ?? null,
476 );
477 } catch ( Throwable $e ) {
478 return null;
479 }
480 }
481
482 /**
483 * Get the mini widget message
484 */
485 public function get_mini_widget_default_message( string $country ): string {
486 return $this->get_mini_widget_default_messages()[ $country ] ?? '';
487 }
488
489 /**
490 * Get the mini widget message
491 */
492 public function get_mini_widget_default_message_below_limit( string $country ): string {
493 return $this->get_mini_widget_default_messages_below_limit()[ $country ] ?? '';
494 }
495 /**
496 * Get the mini widget message
497 */
498 public function get_mini_widget_default_messages(): array {
499 /**
500 * Filter the default message below limit for the mini widget.
501 *
502 * @since 3.0.0
503 * @return string The default message below limit for the mini widget.
504 */
505 return apply_filters(
506 'sequra_mini_widget_default_message',
507 array(
508 'ES' => 'Desde %s/mes con seQura',
509 'FR' => 'À partir de %s/mois avec seQura',
510 'IT' => 'Da %s/mese con seQura',
511 'PT' => 'De %s/mês com seQura',
512 )
513 );
514 }
515
516 /**
517 * Get the mini widget message
518 */
519 public function get_mini_widget_default_messages_below_limit(): array {
520 /**
521 * Filter the default message below limit for the mini widget.
522 *
523 * @since 3.0.0
524 * @return string The default message below limit for the mini widget.
525 */
526 return apply_filters(
527 'sequra_mini_widget_default_message_below_limit',
528 array(
529 'ES' => 'Fracciona con seQura a partir de %s',
530 'FR' => 'Fraction avec seQura à partir de %s',
531 'IT' => 'Frazione con seQura da %s',
532 'PT' => 'Fração com seQura a partir de %s',
533 )
534 );
535 }
536
537 /**
538 * Check if the widget is enabled in custom locations.
539 */
540 private function is_widget_enabled_in_custom_locations( ?string $payment_method, ?string $campaign, ?string $country ): bool {
541 try {
542 $custom_location = $this->get_widget_custom_location( $payment_method, $campaign, $country );
543 return $custom_location ? $custom_location->get_display_widget() : true;
544 } catch ( Throwable $e ) {
545 return false;
546 }
547 }
548
549 /**
550 * Get the widget location selector
551 */
552 public function get_widget_dest_css_sel( ?string $payment_method, ?string $campaign, ?string $country ): string {
553 try {
554 $config = $this->get_widget_settings();
555 $sel = $config['selForDefaultLocation'];
556 $custom_location = $this->get_widget_custom_location( $payment_method, $campaign, $country );
557 return $custom_location ? $custom_location->get_sel_for_target() : $sel;
558 } catch ( Throwable $e ) {
559 return '';
560 }
561 }
562
563 /**
564 * Get the widget price selector
565 */
566 public function get_widget_price_css_sel(): string {
567 try {
568 $config = $this->get_widget_settings();
569 return $config['selForPrice'] ?? '';
570 } catch ( Throwable $e ) {
571 return '';
572 }
573 }
574
575 /**
576 * Get the widget alt price selector
577 */
578 public function get_widget_alt_price_css_sel(): string {
579 try {
580 $config = $this->get_widget_settings();
581 return $config['selForAltPrice'] ?? '';
582 } catch ( Throwable $e ) {
583 return '';
584 }
585 }
586
587 /**
588 * Get the selector used to check when the alt price should be displayed
589 */
590 public function get_widget_is_alt_price_css_sel(): string {
591 try {
592 $config = $this->get_widget_settings();
593 return $config['selForAltPriceTrigger'] ?? '';
594 } catch ( Throwable $e ) {
595 return '';
596 }
597 }
598
599 /**
600 * Get the widget custom location
601 */
602 private function get_widget_custom_location( ?string $payment_method, ?string $campaign, ?string $country ): ?Widget_Location {
603 $config = $this->get_widget_settings();
604 if ( ! empty( $payment_method ) && ! empty( $country ) && isset( $config['customLocations'] ) && is_array( $config['customLocations'] ) ) {
605 foreach ( $config['customLocations'] as $location ) {
606 $loc = Widget_Location::from_array( $location );
607 if ( null !== $loc
608 && $loc->get_product() === $payment_method
609 && $loc->get_country() === $country
610 && ( $loc->get_campaign() ?? null ) === $campaign ) {
611 return $loc;
612 }
613 }
614 }
615 return null;
616 }
617
618 /**
619 * Get widget theme
620 */
621 public function get_widget_theme( ?string $payment_method, ?string $campaign, ?string $country ): string {
622 try {
623 $config = $this->get_widget_settings();
624 $style = $config['widgetConfiguration'] ?? '';
625 $custom_location = $this->get_widget_custom_location( $payment_method, $campaign, $country );
626 return $custom_location ? $custom_location->get_widget_styles() : $style;
627 } catch ( Throwable $e ) {
628 return '';
629 }
630 }
631
632 /**
633 * Get asset key
634 */
635 public function get_assets_key(): ?string {
636 try {
637 $config = $this->get_widget_settings();
638 return $config['assetsKey'] ?? null;
639 } catch ( Throwable $e ) {
640 return null;
641 }
642 }
643
644 /**
645 * Get merchant ref
646 */
647 public function get_merchant_ref( $country ): ?string {
648 try {
649 $countries_conf = AdminAPI::get()
650 ->countryConfiguration( $this->get_store_id() )
651 ->getCountryConfigurations()
652 ->toArray();
653
654 foreach ( $countries_conf as $country_conf ) {
655 if ( $country_conf['countryCode'] === $country ) {
656 return $country_conf['merchantId'] ?? null;
657 }
658 }
659 return null;
660 } catch ( Throwable $e ) {
661 return null;
662 }
663 }
664
665 /**
666 * Get connection settings as array
667 *
668 * @throws Throwable
669 */
670 private function get_connection_settings(): array {
671 return AdminAPI::get()
672 ->connection( $this->get_store_id() )
673 ->getConnectionSettings()
674 ->toArray();
675 }
676
677 /**
678 * Get the environment
679 */
680 public function get_env(): ?string {
681 $conn = null;
682 try {
683 $conn = $this->get_connection_settings();
684 } catch ( Throwable $e ) {
685 return null;
686 }
687 return $conn['environment'] ?? null;
688 }
689
690 /**
691 * Get platform payload
692 */
693 public function get_platform(): Platform {
694 /**
695 * WooCommerce data
696 *
697 * @var array<string, string>
698 */
699 $woo = ServiceRegister::getService( 'woocommerce.data' );
700
701 /**
702 * Environment data
703 *
704 * @var array<string, string>
705 */
706 $env = ServiceRegister::getService( 'environment.data' );
707
708 /**
709 * Plugin data
710 *
711 * @var array<string, string>
712 */
713 $sq = ServiceRegister::getService( 'plugin.data' );
714
715 /**
716 * Filter the module version to be used in the platform options.
717 * TODO: document this hook
718 *
719 * @since 3.0.0
720 */
721 $version = apply_filters(
722 'sequra_platform_options_version',
723 $sq['Version'] ?? ''
724 );
725
726 /**
727 * Filter the platform options.
728 * TODO: document this hook
729 *
730 * @since 3.0.0
731 */
732 return apply_filters(
733 'sequra_platform_options',
734 new Platform(
735 $this->getIntegrationName(),
736 $woo['Version'] ?? '',
737 $env['uname'],
738 $env['db_name'],
739 $env['db_version'],
740 $version,
741 $env['php_version']
742 )
743 );
744 }
745 }
746