PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Hooks / Handlers / ShortCodes / CustomerProfileHandler.php

CustomerProfileHandler.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.5, at app/Hooks/Handlers/ShortCodes/CustomerProfileHandler.php

481 lines 24.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Hooks\Handlers\ShortCodes;
4
5 use FluentCart\Api\ModuleSettings;
6 use FluentCart\Api\PaymentMethods;
7 use FluentCart\Api\Resource\CustomerResource;
8 use FluentCart\Api\StoreSettings;
9 use FluentCart\App\App;
10 use FluentCart\App\Services\CustomerIdentity\EmailClaimPortal;
11 use FluentCart\App\Services\CustomerIdentity\CustomerRecoveryService;
12 use FluentCart\App\Services\CustomerIdentity\EmailClaimService;
13 use FluentCart\App\Services\CustomerIdentity\EmailVerificationService;
14 use FluentCart\App\Helpers\CurrenciesHelper;
15 use FluentCart\App\Helpers\Helper;
16 use FluentCart\App\Models\Subscription;
17 use FluentCart\App\Modules\Templating\AssetLoader;
18 use FluentCart\App\Services\Renderer\CheckoutFieldsSchema;
19 use FluentCart\App\Services\TemplateService;
20 use FluentCart\App\Services\DateTime\DayjsFormatter;
21 use FluentCart\App\Services\Translations\TransStrings;
22 use FluentCart\App\Vite;
23 use FluentCart\Framework\Support\Arr;
24 use FluentCart\Framework\Support\Str;
25
26 class CustomerProfileHandler extends ShortCode
27 {
28 const SHORT_CODE = 'fluent_cart_customer_profile';
29 protected static string $shortCodeName = 'fluent_cart_customer_profile';
30
31 protected static $slug = '';
32 protected string $assetsPath = '';
33
34 public function renderShortcode($block = null)
35 {
36 ob_start(null);
37 $view = $this->render(
38 $this->viewData()
39 );
40 return $view ?? ob_get_clean();
41 }
42
43 public static function register()
44 {
45 parent::register();
46
47 add_action(CustomerRecoveryService::HOOK, [CustomerRecoveryService::class, 'run']);
48
49 add_action('template_redirect', function () {
50 $redirect = EmailClaimPortal::handleSubmission();
51 if ($redirect) {
52 wp_safe_redirect($redirect);
53 exit;
54 }
55 });
56
57 // Add wildcard customer profile pages
58 // add a custom permalink endpoint
59 add_action('init', function () {
60 $pageSlug = (new StoreSettings())->getCustomerDashboardPageSlug();
61 $customerProfilePageId = (new StoreSettings())->getCustomerProfilePageId();
62 static::$slug = $pageSlug;
63
64 if($customerProfilePageId && $pageSlug) {
65 add_rewrite_rule(
66 '^'.$pageSlug.'/(.+)?$',
67 'index.php?page_id='.$customerProfilePageId,
68 'top'
69 );
70 }
71 });
72 }
73
74
75 public function render(?array $viewData = null)
76 {
77 if (!is_user_logged_in()) {
78 ob_start();
79 $redirectUrl = $this->resolveLoginRedirectUrl(
80 (new StoreSettings())->getCustomerProfilePage()
81 );
82
83 $claimToken = Arr::get($_GET, EmailClaimService::QUERY_TOKEN, '');
84 if (is_string($claimToken) && $claimToken !== '') {
85 $redirectUrl = add_query_arg(EmailClaimService::QUERY_TOKEN, sanitize_text_field(wp_unslash($claimToken)), (new StoreSettings())->getCustomerProfilePage());
86 }
87
88 if (defined('FLUENT_AUTH_VERSION') && (new \FluentAuth\App\Hooks\Handlers\CustomAuthHandler())->isEnabled()) {
89 ?>
90 <div style="max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #CBD5E0; border-radius: 8px;" class="fct_auth_wrap">
91 <h4><?php echo esc_html__('Please log in to access your customer portal.', 'fluent-cart'); ?></h4>
92 <?php
93 // The URL travels inside a double-quoted shortcode attribute, where a
94 // bracket or quote would truncate the shortcode. Carry them encoded.
95 $attributeUrl = str_replace(['[', ']', '"'], ['%5B', '%5D', '%22'], $redirectUrl);
96 echo do_shortcode('[fluent_auth redirect_to="' . $attributeUrl . '"]');
97 echo '</div>';
98 } else {
99 ?>
100 <div class="fct_auth_wrap">
101 <div class="fct_auth_message">
102 <h2><?php echo esc_html__('Login', 'fluent-cart'); ?></h2>
103 <p><?php echo esc_html__('Please log in to access your customer portal.', 'fluent-cart'); ?></p>
104 <a href="<?php echo esc_url(wp_login_url($redirectUrl ?? '')); ?>" class="button">
105 <?php echo esc_html__('Login', 'fluent-cart'); ?>
106 </a>
107 </div>
108 </div>
109 <?php
110 }
111 return ob_get_clean();
112 }
113
114 $this->renderCustomerAppContainer();
115 }
116
117 /**
118 * Resolve where a logged-out visitor should land once they have logged in.
119 *
120 * `redirect_to` is attacker-supplied, so it is only honoured when
121 * wp_validate_redirect() accepts it. That compares the parsed host against the
122 * site host. A string-prefix comparison must not be used here: a hostile host
123 * can be built by suffixing the site host, or by placing the site host in the
124 * userinfo position ahead of an `@`, and both keep the site URL as a prefix
125 * while resolving somewhere else entirely.
126 *
127 * @param string $fallbackUrl Where to send the visitor when no usable target was supplied.
128 * @return string
129 */
130 public function resolveLoginRedirectUrl($fallbackUrl)
131 {
132 if (empty($_GET['redirect_to']) || !is_string($_GET['redirect_to'])) {
133 return $fallbackUrl;
134 }
135
136 $intendedRedirectUrl = sanitize_url(wp_unslash($_GET['redirect_to']));
137
138 $validatedUrl = wp_validate_redirect($intendedRedirectUrl, '');
139
140 return $validatedUrl ? $validatedUrl : $fallbackUrl;
141 }
142
143 public function renderCustomerAppContainer()
144 {
145
146 // Enqueue global styles
147 Vite::enqueueStyle( 'fluent-cart-customer-profile-global',
148 'public/customer-profile/style/customer-profile-global.scss',
149 );
150
151 // Gate before custom endpoint callbacks or the dashboard load customer data.
152 $verificationNotice = EmailClaimPortal::render();
153 if (EmailVerificationService::isRequired(get_current_user_id())) {
154 echo $verificationNotice; // @phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped in the view
155 return;
156 }
157
158 $customEndpointContent = $this->maybeCustomEndpointContent();
159
160 if(!$customEndpointContent) {
161 (new static())->enqueueStyles();
162 }
163
164 $colors = self::generateCssColorVariables(Arr::get($this->shortCodeAttributes, 'colors', ''));
165 add_action('fluent_cart/customer_menu', array($this, 'renderCustomerMenu'));
166 add_action('fluent_cart/customer_app', function () use ($customEndpointContent, $verificationNotice) {
167 echo $verificationNotice; // @phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped in the view
168 if($customEndpointContent) {
169 echo $customEndpointContent; // @phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
170 } else {
171 AssetLoader::loadCustomerDashboardAssets();
172 $this->renderCustomerApp();
173 }
174 });
175
176 App::make('view')->render('frontend.customer_app', [
177 'wp_page_title' => get_the_title(),
178 'colors' => $colors,
179 'active_tab' => apply_filters('fluent_cart/customer_portal/active_tab', ''),
180 ]);
181 }
182
183 public function maybeCustomEndpointContent() {
184 global $wp;
185 $requestedPath = $wp->request;
186 // remove static::$slug from the requested path
187 if (static::$slug && Str::startsWith($requestedPath, static::$slug)) {
188 $requestedPath = Str::replaceFirst(static::$slug, '', $requestedPath);
189 $requestedPath = trim($requestedPath, '/');
190 }
191
192 if($requestedPath) {
193 $paths = explode('/', $requestedPath);
194 $requestedPath = array_shift($paths);
195 }
196
197 $reserved = ['dashboard', 'purchase-history', 'subscriptions', 'licenses', 'downloads', 'profile'];
198 if(!$requestedPath || in_array($requestedPath, $reserved)) {
199 return ''; // No specific path requested, return early
200 }
201
202 // Maybe it's a custom endpoint path
203 $customEndpoints = apply_filters('fluent_cart/customer_portal/custom_endpoints', []);
204
205 if(empty($customEndpoints) || !isset($customEndpoints[$requestedPath])) {
206 return ''; // No custom endpoints defined, return early
207 }
208
209 ob_start();
210 $endpoint = $customEndpoints[$requestedPath];
211
212 add_filter('fluent_cart/customer_portal/active_tab', function ($activeTab) use ($requestedPath) {
213 return $requestedPath;
214 });
215
216 if (isset($endpoint['render_callback']) && is_callable($endpoint['render_callback'])) {
217 call_user_func($endpoint['render_callback']);
218 return ob_get_clean();
219 }
220
221 if(isset($endpoint['page_id'])) {
222 $pageId = (int) $endpoint['page_id'];
223 // Create a custom query to fetch the two pages
224 $args = array(
225 'post_type' => 'page',
226 'post__in' => [$pageId],
227 'posts_per_page' => 1,
228 'orderby' => 'post__in', // Preserve the order of the IDs
229 );
230
231 $page_query = new \WP_Query($args);
232
233 // Check if the query has posts
234 if ($page_query->have_posts()) :
235 while ($page_query->have_posts()) : $page_query->the_post();
236 ?>
237 <div class="fluent-cart-custom-page-content">
238 <div><?php the_content(); ?></div>
239 </div>
240 <?php
241 endwhile;
242 // Reset post data to avoid conflicts with other queries
243 wp_reset_postdata();
244 else :
245 echo '<p>' . esc_html__('No content found!', 'fluent-cart') . '</p>';
246 endif;
247 }
248
249 return ob_get_clean();
250 }
251
252 public function renderCustomerApp()
253 {
254 echo '<div data-fluent-cart-customer-profile-app><app/></div>';
255 }
256
257 public function renderCustomerMenu()
258 {
259 $baseUrl = TemplateService::getCustomerProfileUrl('/');
260
261 $menuItems = [
262 'dashboard' => [
263 'label' => __('Dashboard', 'fluent-cart'),
264 'css_class' => 'fct_route',
265 'link' => $baseUrl,
266 'icon_svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
267 <path d="M5.875 9.625C5.43179 9.625 4.99292 9.5377 4.58344 9.36809C4.17397 9.19848 3.80191 8.94988 3.48851 8.63649C3.17512 8.32309 2.92652 7.95103 2.75691 7.54156C2.5873 7.13208 2.5 6.69321 2.5 6.25C2.5 5.80679 2.5873 5.36792 2.75691 4.95844C2.92652 4.54897 3.17512 4.17691 3.48851 3.86351C3.80191 3.55012 4.17397 3.30152 4.58344 3.13191C4.99292 2.9623 5.43179 2.875 5.875 2.875C6.77011 2.875 7.62855 3.23058 8.26148 3.86351C8.89442 4.49645 9.25 5.35489 9.25 6.25C9.25 7.14511 8.89442 8.00355 8.26148 8.63649C7.62855 9.26942 6.77011 9.625 5.875 9.625V9.625ZM6.25 17.125C5.35489 17.125 4.49645 16.7694 3.86351 16.1365C3.23058 15.5035 2.875 14.6451 2.875 13.75C2.875 12.8549 3.23058 11.9965 3.86351 11.3635C4.49645 10.7306 5.35489 10.375 6.25 10.375C7.14511 10.375 8.00355 10.7306 8.63648 11.3635C9.26942 11.9965 9.625 12.8549 9.625 13.75C9.625 14.6451 9.26942 15.5035 8.63648 16.1365C8.00355 16.7694 7.14511 17.125 6.25 17.125V17.125ZM13.75 9.625C13.3068 9.625 12.8679 9.5377 12.4584 9.36809C12.049 9.19848 11.6769 8.94988 11.3635 8.63649C11.0501 8.32309 10.8015 7.95103 10.6319 7.54156C10.4623 7.13208 10.375 6.69321 10.375 6.25C10.375 5.80679 10.4623 5.36792 10.6319 4.95844C10.8015 4.54897 11.0501 4.17691 11.3635 3.86351C11.6769 3.55012 12.049 3.30152 12.4584 3.13191C12.8679 2.9623 13.3068 2.875 13.75 2.875C14.6451 2.875 15.5035 3.23058 16.1365 3.86351C16.7694 4.49645 17.125 5.35489 17.125 6.25C17.125 7.14511 16.7694 8.00355 16.1365 8.63649C15.5035 9.26942 14.6451 9.625 13.75 9.625V9.625ZM13.75 17.125C12.8549 17.125 11.9964 16.7694 11.3635 16.1365C10.7306 15.5035 10.375 14.6451 10.375 13.75C10.375 12.8549 10.7306 11.9965 11.3635 11.3635C11.9964 10.7306 12.8549 10.375 13.75 10.375C14.6451 10.375 15.5035 10.7306 16.1365 11.3635C16.7694 11.9965 17.125 12.8549 17.125 13.75C17.125 14.6451 16.7694 15.5035 16.1365 16.1365C15.5035 16.7694 14.6451 17.125 13.75 17.125ZM5.875 8.125C6.37228 8.125 6.84919 7.92746 7.20082 7.57583C7.55246 7.22419 7.75 6.74728 7.75 6.25C7.75 5.75272 7.55246 5.27581 7.20082 4.92417C6.84919 4.57254 6.37228 4.375 5.875 4.375C5.37772 4.375 4.90081 4.57254 4.54917 4.92417C4.19754 5.27581 4 5.75272 4 6.25C4 6.74728 4.19754 7.22419 4.54917 7.57583C4.90081 7.92746 5.37772 8.125 5.875 8.125V8.125ZM6.25 15.625C6.74728 15.625 7.22419 15.4275 7.57582 15.0758C7.92746 14.7242 8.125 14.2473 8.125 13.75C8.125 13.2527 7.92746 12.7758 7.57582 12.4242C7.22419 12.0725 6.74728 11.875 6.25 11.875C5.75272 11.875 5.27581 12.0725 4.92417 12.4242C4.57254 12.7758 4.375 13.2527 4.375 13.75C4.375 14.2473 4.57254 14.7242 4.92417 15.0758C5.27581 15.4275 5.75272 15.625 6.25 15.625ZM13.75 8.125C14.2473 8.125 14.7242 7.92746 15.0758 7.57583C15.4275 7.22419 15.625 6.74728 15.625 6.25C15.625 5.75272 15.4275 5.27581 15.0758 4.92417C14.7242 4.57254 14.2473 4.375 13.75 4.375C13.2527 4.375 12.7758 4.57254 12.4242 4.92417C12.0725 5.27581 11.875 5.75272 11.875 6.25C11.875 6.74728 12.0725 7.22419 12.4242 7.57583C12.7758 7.92746 13.2527 8.125 13.75 8.125ZM13.75 15.625C14.2473 15.625 14.7242 15.4275 15.0758 15.0758C15.4275 14.7242 15.625 14.2473 15.625 13.75C15.625 13.2527 15.4275 12.7758 15.0758 12.4242C14.7242 12.0725 14.2473 11.875 13.75 11.875C13.2527 11.875 12.7758 12.0725 12.4242 12.4242C12.0725 12.7758 11.875 13.2527 11.875 13.75C11.875 14.2473 12.0725 14.7242 12.4242 15.0758C12.7758 15.4275 13.2527 15.625 13.75 15.625Z" fill="currentColor"/>
268 </svg>',
269 ],
270 'purchase-history' => [
271 'label' => __('Purchase History', 'fluent-cart'),
272 'css_class' => 'fct_route',
273 'link' => $baseUrl . 'purchase-history',
274 'icon_svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
275 <path d="M10 2.5C14.1422 2.5 17.5 5.85775 17.5 10C17.5 14.1422 14.1422 17.5 10 17.5C5.85775 17.5 2.5 14.1422 2.5 10H4C4 13.3135 6.6865 16 10 16C13.3135 16 16 13.3135 16 10C16 6.6865 13.3135 4 10 4C7.9375 4 6.118 5.04025 5.03875 6.625H7V8.125H2.5V3.625H4V5.5C5.368 3.6775 7.54675 2.5 10 2.5ZM10.75 6.25V9.68875L13.1823 12.121L12.121 13.1823L9.25 10.3098V6.25H10.75Z" fill="currentColor"/>
276 </svg>'
277 ],
278 'subscriptions' => [
279 'label' => __('Subscription Plans', 'fluent-cart'),
280 'css_class' => 'fct_route',
281 'link' => $baseUrl . 'subscriptions',
282 'icon_svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
283 <path d="M10 5C11.7179 5 13.2343 5.86641 14.1348 7.1875H12.5V8.4375H16.25V4.6875H15V6.2496C13.8601 4.73229 12.0452 3.75 10 3.75C6.54822 3.75 3.75 6.54822 3.75 10H5C5 7.23857 7.23857 5 10 5ZM15 10C15 12.7614 12.7614 15 10 15C8.28215 15 6.76567 14.1336 5.86527 12.8125H7.5V11.5625H3.75V15.3125H5V13.7504C6.13988 15.2677 7.95477 16.25 10 16.25C13.4517 16.25 16.25 13.4517 16.25 10H15Z" fill="currentColor"/>
284 </svg>'
285 ],
286 'licenses' => [
287 'label' => __('Licenses', 'fluent-cart'),
288 'css_class' => 'fct_route',
289 'link' => $baseUrl . 'licenses',
290 'icon_svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
291 <path d="M16 17.5H4C3.80109 17.5 3.61032 17.421 3.46967 17.2803C3.32902 17.1397 3.25 16.9489 3.25 16.75V3.25C3.25 3.05109 3.32902 2.86032 3.46967 2.71967C3.61032 2.57902 3.80109 2.5 4 2.5H16C16.1989 2.5 16.3897 2.57902 16.5303 2.71967C16.671 2.86032 16.75 3.05109 16.75 3.25V16.75C16.75 16.9489 16.671 17.1397 16.5303 17.2803C16.3897 17.421 16.1989 17.5 16 17.5ZM15.25 16V4H4.75V16H15.25ZM7 6.25H13V7.75H7V6.25ZM7 9.25H13V10.75H7V9.25ZM7 12.25H10.75V13.75H7V12.25Z" fill="currentColor"/>
292 </svg>'
293 ],
294 'downloads' => [
295 'label' => __('Downloads', 'fluent-cart'),
296 'css_class' => 'fct_route',
297 'link' => $baseUrl . 'downloads',
298 'icon_svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
299 <path d="M10.75 8.5H14.5L10 13L5.5 8.5H9.25V3.25H10.75V8.5ZM4 15.25H16V10H17.5V16C17.5 16.1989 17.421 16.3897 17.2803 16.5303C17.1397 16.671 16.9489 16.75 16.75 16.75H3.25C3.05109 16.75 2.86032 16.671 2.71967 16.5303C2.57902 16.3897 2.5 16.1989 2.5 16V10H4V15.25Z" fill="currentColor"/>
300 </svg>'
301 ],
302 'profile' => [
303 'label' => __('Profile', 'fluent-cart'),
304 'css_class' => 'fct_route',
305 'link' => $baseUrl . 'profile',
306 'icon_svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
307 <path d="M4 17.5C4 15.9087 4.63214 14.3826 5.75736 13.2574C6.88258 12.1321 8.4087 11.5 10 11.5C11.5913 11.5 13.1174 12.1321 14.2426 13.2574C15.3679 14.3826 16 15.9087 16 17.5H14.5C14.5 16.3065 14.0259 15.1619 13.182 14.318C12.3381 13.4741 11.1935 13 10 13C8.80653 13 7.66193 13.4741 6.81802 14.318C5.97411 15.1619 5.5 16.3065 5.5 17.5H4ZM10 10.75C7.51375 10.75 5.5 8.73625 5.5 6.25C5.5 3.76375 7.51375 1.75 10 1.75C12.4863 1.75 14.5 3.76375 14.5 6.25C14.5 8.73625 12.4863 10.75 10 10.75ZM10 9.25C11.6575 9.25 13 7.9075 13 6.25C13 4.5925 11.6575 3.25 10 3.25C8.3425 3.25 7 4.5925 7 6.25C7 7.9075 8.3425 9.25 10 9.25Z" fill="currentColor"/>
308 </svg>'
309 ]
310 ];
311
312 $currentCustomer = CustomerResource::getCurrentCustomer();
313
314 if (!ModuleSettings::isActive('license') || !App::isProActive()) {
315 unset($menuItems['licenses']);
316 }
317
318
319 if($currentCustomer) {
320 $hasSubscriptions = Subscription::query()->where('customer_id', $currentCustomer->id)->exists();
321 if(!$hasSubscriptions) {
322 unset($menuItems['subscriptions']);
323 }
324 } else {
325 unset($menuItems['subscriptions']);
326 }
327
328 $menuItems = apply_filters('fluent_cart/global_customer_menu_items', $menuItems, [
329 'base_url' => $baseUrl
330 ]);
331
332 $profileData = null;
333 if($currentCustomer) {
334 $profileData = [
335 'email' => $currentCustomer->email,
336 'full_name' => $currentCustomer->full_name,
337 'photo' => $currentCustomer->photo
338 ];
339 } else if(is_user_logged_in()) {
340 $user = wp_get_current_user();
341 $profileData = [
342 'email' => $user->user_email,
343 'full_name' => $user->display_name,
344 'photo' => get_avatar_url($user->ID)
345 ];
346 }
347
348 add_filter('fct_allowed_svg_tags', function ($tags) {
349 return [
350 'svg' => [
351 'xmlns' => true,
352 'width' => true,
353 'height' => true,
354 'viewBox' => true,
355 'fill' => true,
356 'stroke' => true,
357 'stroke-width' => true,
358 'class' => true
359 ],
360 'path' => [
361 'd' => true,
362 'fill' => true,
363 'stroke' => true,
364 'stroke-width' => true
365 ],
366 'g' => [
367 'fill' => true,
368 'stroke' => true
369 ]
370 ];
371 });
372
373
374 App::make('view')->render('frontend.customer_menu', [
375 'menuItems' => $menuItems,
376 'profileData' => $profileData,
377 ]);
378 }
379
380 public static function getLocalizationData($attributes = []):array
381 {
382
383 $currentCustomer = CustomerResource::getCurrentCustomer();
384 $customerEmail = $currentCustomer ? $currentCustomer->email : '';
385
386
387 $pageUrl = TemplateService::getCustomerProfileUrl();
388
389 $pageSlug = trim(str_replace(home_url('/'), '', $pageUrl), '/');
390 $dashboardSlug = (new StoreSettings())->getCustomerDashboardPageSlug();
391
392 if($pageSlug !== $dashboardSlug) {
393 // we should resave the page slug from settings
394 $prevSettings = (new StoreSettings())->get();
395 (new StoreSettings())->save($prevSettings);
396 }
397
398 $shopLocalizationData = Helper::shopConfig();
399 $shopLocalizationData['shop_url'] = (new StoreSettings())->getShopPage();
400
401
402 // For supporting subdirectory installations
403 $domainParts = parse_url(home_url('/'));
404 // if we have path in domain url, we need to set it as base path
405 $basePath = trim(Arr::get($domainParts, 'path', ''), '/');
406 if($basePath && $basePath !== '/') {
407 $pageSlug = $basePath.'/'.$pageSlug;
408 }
409
410 return [
411 'fluentcart_customer_profile_vars' => [
412 'app_slug' => $pageSlug,
413 'app_url' => TemplateService::getCustomerProfileUrl(),
414 'shop' => $shopLocalizationData,
415 'currency_signs' => array_map(function ($sign) {
416 return html_entity_decode($sign, ENT_QUOTES, 'UTF-8');
417 }, CurrenciesHelper::getCurrencySigns()),
418 'trans' => TransStrings::getCustomerProfileString(),
419 'download_url_base' => site_url('fluent-cart/download-file/?fluent_cart_download=true'),
420 'placeholder_image' => Vite::getAssetUrl('images/placeholder.svg'),
421 'stripe_pub_key' => apply_filters('fluent_cart/payment_methods/stripe_pub_key', ''),
422 'paypal_client_id' => apply_filters('fluent_cart/payment_methods/paypal_client_id', '', []),
423 'assets_path' => Vite::getAssetUrl(),
424 'rest' => Helper::getRestInfo(),
425 'customer_email' => $customerEmail,
426 'wp_page_title' => get_the_title(),
427 'payment_methods' => PaymentMethods::getActiveMeta(),
428 'site_url' => site_url(),
429 'me' => [
430 'email' => $currentCustomer ? $currentCustomer->email : '',
431 'first_name' => $currentCustomer ? $currentCustomer->first_name : '',
432 'last_name' => $currentCustomer ? $currentCustomer->last_name : '',
433 ],
434 'logout_url' => wp_logout_url(home_url()),
435 'datei18' => DayjsFormatter::localizedStrings(),
436 'el_strings' => TransStrings::elStrings(),
437 'wp_locale' => get_locale(),
438 'is_company_name_enabled' => CheckoutFieldsSchema::isCompanyNameEnabled(),
439 'is_company_name_required' => CheckoutFieldsSchema::isCompanyNameRequired(),
440 'is_vat_number_enabled' => CheckoutFieldsSchema::isVatNumberEnabled(),
441 'is_vat_number_required' => CheckoutFieldsSchema::isVatNumberRequired(),
442 'is_legal_registration_id_enabled' => CheckoutFieldsSchema::isLegalRegistrationIdEnabled(),
443 'is_legal_registration_id_required' => CheckoutFieldsSchema::isLegalRegistrationIdRequired()
444 ],
445 'fluentCartRestVars' => [
446 'rest' => Helper::getRestInfo(),
447 ],
448 ];
449 }
450
451 public function localizeData(): array
452 {
453 return static::getLocalizationData($this->shortCodeAttributes);
454 }
455
456 private static function generateCssColorVariables($colors): string
457 {
458 $cssVariables = '';
459
460 if (!empty($colors)) {
461 // Split the colors string by commas to separate each key-value pair
462 $pairs = explode(',', $colors);
463 $colorVariables = [];
464
465 foreach ($pairs as $pair) {
466 list($key, $value) = explode('=', trim($pair));
467
468 // Only add to the array if the value is not empty or just a semicolon
469 if (!empty($value) && $value !== ';') {
470 $colorVariables[] = "$key: $value;";
471 }
472 }
473
474 $cssVariables = implode("\n", $colorVariables);
475 }
476
477 return $cssVariables;
478 }
479
480 }
481