Created
February 13, 2024 09:39
-
-
Save mininaim/5f16f351c9ad7215fd3f5bb21fe4ce4b to your computer and use it in GitHub Desktop.
View.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Foundation\Services\StorefrontTheme; | |
| use Twig\Environment; | |
| use Twig\Loader\ArrayLoader; | |
| use Twig\Extension\SandboxExtension; | |
| use Twig\Sandbox\SecurityPolicy; | |
| use App\Foundation\ZidPlatformAPI\Stores\GetCustomThemeFiles; | |
| use App\Foundation\TwigTags\SchemaTokenParser; | |
| use App\Foundation\TwigTags\TwigFunctions; | |
| use App\Exceptions\TwigRenderException; | |
| use App\Foundation\Facades\Products; | |
| use Illuminate\Support\Facades\File; | |
| use App\Foundation\ZidPlatformAPI\Category\GetCategories; | |
| class View | |
| { | |
| const templateActionChange = 'template_change'; | |
| const templateActionUpdateFile = 'template_update_file'; | |
| private $request; | |
| private $store; | |
| private $cartSessionId; | |
| private $requestUri; | |
| private $baseUrl; | |
| private $customer; | |
| private $session; | |
| private $editingMode; | |
| private $csrfToken; | |
| private $appLang; | |
| private $previewMode; | |
| private $fileExt; | |
| private $themeId; | |
| private $product; | |
| private $cart; | |
| private $templateDataHelper; | |
| private $sessionKeySuffix; | |
| public function __construct() | |
| { | |
| $this->fileExt = '.twig'; | |
| $this->previewMode = false; | |
| $this->templateDataHelper = new TemplateData(); | |
| } | |
| private function initialize($renderViewData) | |
| { | |
| $this->request = $renderViewData['request']; | |
| $this->store = $renderViewData['data']['store']; | |
| $this->requestUri = $renderViewData['requestUri']; | |
| $this->baseUrl = $renderViewData['baseUrl']; | |
| $this->customer = $renderViewData['data']['customer']; | |
| $this->session = $renderViewData['data']['session']; | |
| $this->themeId = $renderViewData['data']['store']['storefront_theme']['id']; | |
| $this->editingMode = [ | |
| 'enable' => $renderViewData['data']['editingMode'], | |
| 'template' => $this->request->get('template', NULL), | |
| 'action' => $this->request->get('action', NULL), | |
| 'fileId' => $this->request->get('section-id', NULL), | |
| 'connectionId' => $this->request->get('connection-id', NULL), | |
| 'settings' => $this->request->get('settings', NULL) | |
| ]; | |
| $this->csrfToken = $renderViewData['data']['csrfToken']; | |
| $this->appLang = $this->session['lang']['code'] ?? 'ar'; | |
| $this->sessionKeySuffix = $this->store['id'] . $this->themeId; | |
| if(!empty($renderViewData['data']['serverMessage']['status'])) | |
| { | |
| $this->session['serverMessage'] = $renderViewData['data']['serverMessage']; | |
| } | |
| unset($renderViewData['data']); | |
| $this->templateDataHelper->initialize($this->fileExt, $this->themeId); | |
| if ((isset($this->store['storefront_theme']['status_code']) | |
| && $this->store['storefront_theme']['status_code'] == 'theme_preview')) { | |
| $this->previewMode = true; | |
| } | |
| } | |
| public function renderView($renderViewData) | |
| { | |
| $this->initialize($renderViewData); | |
| //check if customer try to navigate to routes need auth | |
| //false = redirect to login page | |
| // if (!$this->checkCustomerAuthRoutes($this->requestUri)) { | |
| // return redirect('/auth/login'); | |
| // } | |
| $themeFiles = []; | |
| $themeModules = []; | |
| $themeLocales = []; | |
| $templateData = [ | |
| 'page' => NULL, | |
| 'data' => NULL | |
| ]; | |
| $homeTemplateModules = NULL; | |
| $templateData['page'] = $this->templateDataHelper->getTemplatePageName($this->requestUri); | |
| logger('page'); | |
| logger($templateData['page']); | |
| $themeTemplateLayout = $this->getTemplateLayout($templateData['page']); | |
| foreach ($themeTemplateLayout['payload']['files'] as $i => &$file) { | |
| if ($file['name'] == 'ar.json' || $file['name'] == 'en.json') { | |
| if ($this->appLang == substr($file['name'], 0, -5)) { | |
| $themeLocales = json_decode($file['content'], true); | |
| } | |
| } | |
| if (!isset($file['folder']) || $file['folder'] != 'modules') { | |
| $this->setThemeFileContent($themeFiles, $file); | |
| } else { | |
| array_push($themeModules, $file); | |
| } | |
| if ($this->editingMode['enable'] && $file['name'] == 'layout' . $this->fileExt) { | |
| $pos = strrpos($themeFiles[$file['name']], '</body>'); | |
| $themeFiles[$file['name']] = substr_replace($themeFiles[$file['name']], '{{ editing_mode_script|raw }}', $pos, 0); | |
| } | |
| } | |
| if ($templateData['page'] == 'home' . $this->fileExt) { | |
| if (count($themeModules) > 0) { | |
| $themeModules = $this->mapModulesToFiles($themeModules, $this->appLang); | |
| foreach ($themeModules['files'] as $file) { | |
| $this->setThemeFileContent($themeFiles, $file); | |
| } | |
| $homeTemplateModules = $themeModules['includes_str']; | |
| $themeFiles['home' . $this->fileExt] = preg_replace('/{{ home_template_modules }}/', $homeTemplateModules, $themeFiles['home' . $this->fileExt], 1); | |
| } | |
| } | |
| $templateData['data'] = $this->getTemplateData(false); | |
| if (isset($templateData['data'])) { | |
| $this->addToStoreObject($themeTemplateLayout); | |
| $templateData['data'] = $this->templateGlobalDataInject($templateData['data']); | |
| } | |
| if ($templateData['page'] == 'home' . $this->fileExt) { | |
| $templateData['data']['storeCategories'] = (new GetCategories($this->store['id'], $this->cartSessionId))->perform()['payload']; | |
| $storeProducts = Products::getStoreProducts( | |
| $this->store['id'], | |
| [ | |
| 'page' => 1, | |
| 'perPage' => 14, | |
| ], | |
| $this->cartSessionId | |
| )['results']; | |
| foreach ($storeProducts as &$product) { | |
| $product = Products::setProductEnhancedVariables($this->store, $product); | |
| } | |
| $templateData['data']['storeProducts'] = $storeProducts; | |
| //dd($templateData['data']['storeCategories']); | |
| } | |
| if ($templateData['page'] == 'product' . $this->fileExt) { | |
| $patterns = array(); | |
| $patterns[0] = '/{{ template_for_product_variants_dropdown }}/'; | |
| $patterns[1] = '/{{ template_for_product_input_fields }}/'; | |
| $patterns[2] = '/{{ template_for_product_option_fields }}/'; | |
| $patterns[3] = '/{{ template_for_product_variants_list }}/'; | |
| $patterns[4] = '/{{ template_for_product_custom_input_fields }}/'; | |
| $patterns[5] = '/{{ template_for_product_tamara_widget }}/'; | |
| $patterns[6] = '/{{ template_for_product_payments_widget }}/'; | |
| $replacements = array(); | |
| $replacements[6] = \File::get(resource_path('views') . '/twig/product/template_for_product_variants_dropdown.twig'); | |
| $replacements[5] = \File::get(resource_path('views') . '/twig/product/template_for_product_input_fields.twig'); | |
| $replacements[4] = \File::get(resource_path('views') . '/twig/product/template_for_product_option_fields.twig'); | |
| $replacements[3] = \File::get(resource_path('views') . '/twig/product/template_for_product_variants_list.twig'); | |
| $replacements[2] = \File::get(resource_path('views') . '/twig/product/template_for_product_custom_input_fields.twig'); | |
| $replacements[1] = \File::get(resource_path('views') . '/twig/product/template_for_product_tamara_widget.twig'); | |
| $replacements[0] = \File::get(resource_path('views') . '/twig/product/template_for_product_payments_widget.twig'); | |
| $themeFiles['product' . $this->fileExt] = preg_replace( | |
| $patterns, | |
| $replacements, | |
| $themeFiles['product' . $this->fileExt], | |
| 1 | |
| ); | |
| $this->product = $templateData['data']['product'] ?? NULL; | |
| $templateData['data']['product_view_scripts'] = $this->getProductViewScripts(); | |
| } | |
| $themeGiftPopoverLocales = trans('strings.cart_send_as_gift_popover'); | |
| $themeLocales = array_merge($themeLocales, $themeGiftPopoverLocales); | |
| if($templateData['page'] == 'cart'.$this->fileExt) | |
| { | |
| $themeLocales['cart_product_per_item'] = | |
| $themeLocales['cart_product_per_item'] ?? trans('strings.cart_product_per_item'); | |
| $themeLocales['cart_product_not_taxable'] = | |
| $themeLocales['cart_product_not_taxable'] ?? trans('strings.cart_product_not_taxable'); | |
| $themeLocales['cart_product_file_download'] = | |
| $themeLocales['cart_product_file_download'] ?? trans('strings.cart_product_file_download'); | |
| $themeGiftLocales = trans('strings.cart_send_as_gift'); | |
| $themeLocales = array_merge($themeLocales, $themeGiftLocales); | |
| $this->cart = $templateData['data']['cart'] ?? NULL; | |
| $patterns = array(); | |
| $patterns[0] = '/{{ template_for_cart_products_list }}/'; | |
| $patterns[1] = '/{{ template_for_cart_products_card }}/'; | |
| $patterns[2] = '/{{ template_for_cart_loyalty_points }}/'; | |
| $patterns[3] = '/{{ template_for_cart_payments_widget }}/'; | |
| $patterns[4] = '/{{ template_for_cart_gifts_widget }}/'; | |
| $replacements = array(); | |
| $replacements[4] = \File::get(resource_path('views') . '/twig/cart/template_for_cart_products_list.twig'); | |
| $replacements[3] = \File::get(resource_path('views') . '/twig/cart/template_for_cart_products_card.twig'); | |
| $replacements[2] = \File::get(resource_path('views') . '/twig/cart/template_for_cart_loyalty_points_widget.twig'); | |
| $replacements[1] = \File::get(resource_path('views') . '/twig/cart/template_for_cart_payments_widget.twig'); | |
| $replacements[0] = \File::get(resource_path('views') . '/twig/cart/template_for_cart_gifts_widget.twig'); | |
| $themeFiles['cart'.$this->fileExt] = preg_replace($patterns, $replacements, | |
| $themeFiles['cart'.$this->fileExt] , 1); | |
| $templateData['data']['cart_view_scripts'] = $this->getCartViewScripts(); | |
| } | |
| if ($templateData['page'] == 'products'.$this->fileExt || $templateData['page'] == 'category'.$this->fileExt) | |
| { | |
| $themeFiles['template_for_products_attributes'] = \File::get(resource_path('views') .'/twig/products/template_for_products_attributes.twig'); | |
| } | |
| if ($templateData['page'] == 'shipping-and-payments' . $this->fileExt) { | |
| $templateData['data']['store_payment_methods'] = $themeTemplateLayout['payload']['payment_methods'] ?? NULL; | |
| } | |
| if ($templateData['page'] == 'account-profile' . $this->fileExt) { | |
| $themeLocales['mazeed_description'] = $themeLocales['mazeed_description'] ?? trans('strings.mazeed_description'); | |
| $themeLocales['mazeed_download_now'] = $themeLocales['mazeed_download_now'] ?? trans('strings.mazeed_download_now'); | |
| $themeFiles['template_for_mazeed_badge'] = \File::get(resource_path('views') . '/twig/profile/template_for_mazeed_badge.twig'); | |
| } | |
| $themeFiles['template_for_store_messages'] = \File::get(resource_path('views') . '/twig/layout/template_for_store_messages.twig'); | |
| $themeLocales['active_payment_session_notification'] = | |
| $themeLocales['active_payment_session_notification'] ?? trans('strings.active_payment_session_notification'); | |
| $themeLocales['active_payment_session_cancel'] = | |
| $themeLocales['active_payment_session_cancel'] ?? trans('strings.active_payment_session_cancel'); | |
| $themeLocales['notify_apple_pay_available_in_app'] = | |
| $themeLocales['notify_apple_pay_available_in_app'] ?? trans('strings.notify_apple_pay_available_in_app'); | |
| $themeLocales['notify_apple_pay_available'] = | |
| $themeLocales['notify_apple_pay_available'] ?? trans('strings.notify_apple_pay_available'); | |
| $themeFiles['template_for_shipping_destination_currency_lang'] = \File::get(resource_path('views') .'/twig/layout/template_for_shipping_destination_currency_lang.twig'); | |
| $themeLocales['sys_lbl_cart_includes_vat'] = | |
| $themeLocales['sys_lbl_cart_includes_vat'] ?? trans('strings.sys_lbl_cart_includes_vat', ['percentage' => $this->store['cart_total_tax_percentage']]); | |
| $themeLocales['sys_lbl_destination_country'] = | |
| $themeLocales['sys_lbl_destination_country'] ?? trans('strings.sys_lbl_destination_country'); | |
| $themeLocales['sys_lbl_destination_city'] = | |
| $themeLocales['sys_lbl_destination_city'] ?? trans('strings.sys_lbl_destination_city'); | |
| $themeLocales['sys_lbl_store_currency'] = | |
| $themeLocales['sys_lbl_store_currency'] ?? trans('strings.sys_lbl_store_currency'); | |
| $themeLocales['sys_lbl_store_lang'] = | |
| $themeLocales['sys_lbl_store_lang'] ?? trans('strings.sys_lbl_store_lang'); | |
| $loader = new ArrayLoader($themeFiles); | |
| $twig = new Environment($loader, ['debug' => true]); | |
| $twig->addTokenParser(new SchemaTokenParser()); | |
| $tags = ['extends', 'block', 'if', 'set', 'include', 'for', 'schema', 'embed']; | |
| $filters = ['escape','length', 'raw', 'striptags', 'slice', 'json_encode', 'format', 'round', 'trim', 'lower', 'upper', 'filter', 'split', 'first', 'last', 'url_encode']; | |
| $methods = []; | |
| $properties = []; | |
| $functions = ['include', 'dump', 'requestAdd', 'rangeN', 'rangeNWithStep', 'requestGet', 'requestUri', 'requestInputs', 'assetUrl', 'imageUrl', 'datetimeFormat', 'timeFormat', 'tDate', 'strReplace']; | |
| $policy = new SecurityPolicy($tags, $filters, $methods, $properties, $functions); | |
| $sandbox = new SandboxExtension($policy, true); | |
| $twig->addExtension($sandbox); | |
| $twig->addExtension(new \Twig\Extension\DebugExtension()); | |
| new TwigFunctions( | |
| $twig, | |
| $this->request, | |
| $themeTemplateLayout['payload']['assets_url'] ?? NULL, | |
| $this->store['storefront_theme']['updated_at'] ?? NULL, | |
| app()->getLocale() | |
| ); | |
| $renderedData = array_merge([ | |
| 'request' => [ | |
| 'path' => $this->request->path(), | |
| 'query' => $this->request->query() | |
| ], | |
| 'main_menu' => $themeTemplateLayout['payload']['menu'] ?? NULL, | |
| 'main_navigation_menu' => $this->getNavigationMenu($themeTemplateLayout['payload']['menu_v2'] ?? NULL), | |
| 'asset_url' => $themeTemplateLayout['payload']['assets_url'], | |
| 'locals' => $themeLocales, | |
| 'zidapi_script' => $this->getZidApiScript(), | |
| 'editing_mode_script' => $this->getStoreEditScript($templateData['data']['template'], $this->csrfToken), | |
| 'csrf_token' => $this->csrfToken, | |
| 'home_template_modules' => $homeTemplateModules, | |
| 'user_custom_css' => $themeTemplateLayout['payload']['custom_css_url'] ?? NULL, | |
| 'customer_cart_is_reserved' => $this->store['customer_cart_is_reserved'], | |
| 'theme_code' => $this->store['storefront_theme']['code'] ?? NULL, | |
| 'template_value_store_country_name' => $this->store['is_filter_products_based_on_city'] ? 'store_country_name' : ($this->session['currency']['country']['name'] ?? NULL), | |
| 'template_value_store_city_name' => $this->store['is_filter_products_based_on_city'] ? 'store_city_name' : '', | |
| ], $templateData['data']); | |
| try { | |
| return $this->injectSystemScripts($templateData['page'], $twig->render($templateData['page'], $renderedData)); | |
| }catch (\Twig\Error\Error $exception){ | |
| //dd($exception->getMessage()); | |
| throw new TwigRenderException($exception->getMessage()); | |
| } | |
| } | |
| private function getZidApiScript() | |
| { | |
| $permalink = $this->store['permalink']; | |
| $baseURL = $permalink.'api/v1'; | |
| $storeId = $this->store['id']; | |
| $ip = NULL; | |
| $cartSessionId = $this->session['cartSessionId']; | |
| $customerToken = $this->session['customerToken'] ?? NULL; | |
| $script = " | |
| <script type='text/javascript' src='/js/zidapi/zidapi.min.js?v=1.0.6.".env('VERSION','0')."'></script> | |
| <script> | |
| zid.store.initApp('" | |
| .base64_encode("{ | |
| \"baseURL\":\"$baseURL\", | |
| \"headers\":null, | |
| \"storeId\":$storeId, | |
| \"permalink\":\"$permalink\", | |
| \"ip\":\"$ip\", | |
| \"cartSessionId\":\"$cartSessionId\", | |
| \"apiAuthorization\":\"".api_authorization($this->csrfToken)."\", | |
| \"customerToken\":".( ($customerToken) ? ("\"".$customerToken."\"") : "null" ) | |
| ."}") | |
| ."')</script> | |
| "; | |
| return $script; | |
| } | |
| private function getStoreEditScript($template, $csrfToken) | |
| { | |
| if(!$this->editingMode['enable']) | |
| { | |
| return NULL; | |
| } | |
| $script = " | |
| <script type='text/javascript' src='/js/smoothscroll.js?v=1.0.0'></script> | |
| <script type='text/javascript' src='/js/editing-mode-store-front-end.js?v=1.0.7'></script> | |
| <script type='text/javascript'> | |
| notifyLandingPageLoaded(\"".session()->getId()."\",\"".$template."\",\"".$csrfToken."\"); | |
| </script> | |
| "; | |
| return $script; | |
| } | |
| private function getProductViewScripts() | |
| { | |
| $script = " | |
| <script type='text/javascript' src='/js/product_variants_change_listener.js?v=1.25'></script> | |
| <script type='text/javascript' src='/js/product_date_time_picker.js?v=1.0.61'></script> | |
| "; | |
| return $script; | |
| } | |
| private function getCartViewScripts() | |
| { | |
| $script = " | |
| <script type='text/javascript' src='/js/cart_products_update_listener.js?v=1.0.6.".env('VERSION','0')."'></script> | |
| "; | |
| return $script; | |
| } | |
| private function templateGlobalDataInject($arr) | |
| { | |
| $commonData = [ | |
| 'store' => $this->store, | |
| 'session' => $this->session, | |
| 'customer' => $this->customer | |
| ]; | |
| if(!isset($arr)) | |
| { | |
| return $commonData; | |
| } | |
| return array_merge($arr, $commonData); | |
| } | |
| private function cleanStoreObject($store) | |
| { | |
| unset($store['theme']); | |
| unset($store['one_signal_keys']); | |
| unset($store['storefront_theme']['pivot']); | |
| unset($store['storefront_theme']['price']); | |
| unset($store['storefront_theme']['desc']); | |
| unset($store['storefront_theme']['author']); | |
| unset($store['storefront_theme']['file_path']); | |
| unset($store['storefront_theme']['created_at']); | |
| unset($store['is_custom_theme']); | |
| return $store; | |
| } | |
| private function addToStoreObject(&$themeTemplateLayout) | |
| { | |
| $this->store['business_location'] = isset($themeTemplateLayout['payload']['business_location']['country']) ? | |
| $themeTemplateLayout['payload']['business_location'] : NULL; | |
| $this->store['social_media'] = $themeTemplateLayout['payload']['social_media'] ?? NULL; | |
| $this->store['payment_methods'] = $themeTemplateLayout['payload']['payment_methods'] ?? NULL; | |
| $this->store['shipping_methods'] = $themeTemplateLayout['payload']['shipping_methods'] ?? NULL; | |
| $this->store['colors']['primary'] = $themeTemplateLayout['payload']['colors']['btn_default_background_color'] ?? '#8D5DA7'; | |
| $this->store['colors']['text_of_primary_bg'] = $themeTemplateLayout['payload']['colors']['btn_default_text_color'] ?? '#FFFFFF'; | |
| $this->store['apps']['android_package_name'] = $this->store['one_signal_keys']['android_package_name'] ?? NULL; | |
| $this->store['apps']['ios_app_id'] = $this->store['one_signal_keys']['ios_app_id'] ?? NULL; | |
| $this->store['editing_mode'] = $this->editingMode['enable'] ?? false; | |
| $this->store['copyrights'] = $this->getStoreCopyRightText($themeTemplateLayout); | |
| if(isset($this->store['availability'])) | |
| { | |
| if(isset($this->store['availability']['message'][$this->appLang])) | |
| { | |
| $this->store['availability']['message'] = $this->store['availability']['message'][$this->appLang].', '.trans('strings.store_availability_orders_hold'); | |
| } | |
| $this->store['availability']['closed_now'] = ($this->store['availability']['closed_now'] && $this->store['availability']['is_store_closed']); | |
| } | |
| if(empty($this->store['commercial_registration_number_activation']) | |
| || $this->store['commercial_registration_number_activation'] == '0'){ | |
| $this->store['commercial_registration_number'] = NULL; | |
| } | |
| $this->store['is_cart_total_vat_included'] = | |
| !empty($themeTemplateLayout['payload']['vat_settings']['vat_activate']) && | |
| !empty($themeTemplateLayout['payload']['vat_settings']['is_vat_included_in_product_price']); | |
| $this->store['cart_total_tax_percentage'] = ($themeTemplateLayout['payload']['vat_settings']['tax_percentage'] ?? 0) * 100; | |
| $this->store['countries'] = []; | |
| $destinationsCountries = $themeTemplateLayout['payload']['destinations']['countries'] ?? []; | |
| if(count($destinationsCountries) <= 0){ | |
| $this->store['is_filter_products_based_on_city'] = false; | |
| } | |
| if($this->store['is_filter_products_based_on_city']) | |
| { | |
| $this->session['country'] = $this->getDestinationCountry($destinationsCountries, $this->session['cityId']); | |
| $this->store['countries'] = $destinationsCountries; | |
| }else { | |
| $this->session['country'] = $this->session['currency']['country'] ?? NULL; | |
| $this->store['countries'] = array_map(function($currency){ | |
| return $currency['country']; | |
| }, $this->store['currencies']); | |
| } | |
| $this->store['customer_cart_is_reserved'] = $themeTemplateLayout['payload']['cart']['is_reserved'] ?? false; | |
| $this->store = $this->cleanStoreObject($this->store); | |
| } | |
| private function checkCustomerAuthRoutes($requestUri) | |
| { | |
| $pageRouteName = getPageRouteName($requestUri); | |
| switch ($pageRouteName) | |
| { | |
| case "account-orders": | |
| case "account-order": | |
| case "account-profile": | |
| case "account-addresses": | |
| case "account-address": | |
| if(isset($this->customer['id'])) | |
| { | |
| return true; | |
| }else{ | |
| return false; | |
| } | |
| default: | |
| return true; | |
| } | |
| } | |
| private function injectSystemScripts($template, $html) | |
| { | |
| if($this->editingMode['enable']) { | |
| return $html; | |
| } | |
| $systemHeadScripts = view('layouts.includes.headScripts', [ | |
| 'storeSettings' => $this->store, | |
| 'testingStores' => [], | |
| 'customer' => $this->customer, | |
| 'customTheme' => true, | |
| 'template' => strtok($template, '.') | |
| ])->render(); | |
| $systemBodyScripts = view('layouts.includes.bodyScripts', [ | |
| 'storeSettings' => $this->store, | |
| 'testingStores' => [], | |
| 'customer' => $this->customer, | |
| 'template' => strtok($template, '.'), | |
| 'product' => $this->product, | |
| 'cart' => $this->cart, | |
| 'customTheme' => true, | |
| 'session' => $this->session, | |
| 'csrfToken' => $this-> csrfToken | |
| ])->render(); | |
| $systemMessage = view('layouts.includes.systemMessage', [ | |
| 'session' => $this->session, | |
| 'customTheme' => true | |
| ])->render(); | |
| $patterns = array(); | |
| $patterns[0] = '/<(\s*)\/(\s*)head(\s*)>/i'; | |
| $patterns[1] = '/<(\s*)\/(\s*)body(\s*)>/i'; | |
| $replacements = array(); | |
| $replacements[1] = $systemHeadScripts.'</head>'; | |
| $replacements[0] = $systemBodyScripts.$systemMessage.'</body>'; | |
| return preg_replace($patterns,$replacements,$html); | |
| } | |
| private function mapModulesToFiles($files, $lang = 'ar'){ | |
| if(!isset($files) || count($files) <= 0) | |
| return []; | |
| $cFiles = []; | |
| $includeStr = ''; | |
| foreach ($files as $i => $file) { | |
| if (isset($file['modules']) && count($file['modules']) > 0) { | |
| foreach ($file['modules'] as $j => $module) { | |
| array_push($cFiles, [ | |
| 'id' => $module['id'], | |
| 'name' => $file['name'] . '-' . $i . $j, | |
| 'folder' => $file['folder'], | |
| 'theme_id' => $file['theme_id'], | |
| 'content' => $file['content'], | |
| 'path' => $file['path'], | |
| 'config' => $file['config'], | |
| 'created_at' => $file['created_at'], | |
| 'updated_at' => $file['updated_at'], | |
| 'modules' => [ | |
| 0 => $module | |
| ] | |
| ]); | |
| } | |
| } | |
| } | |
| usort($cFiles, function ($fileA, $fileB) use ($lang) { | |
| $orderA = $fileA['modules'][0]['settings']['order'] ?? -1; | |
| $orderB = $fileB['modules'][0]['settings']['order'] ?? -1; | |
| if ($orderA == $orderB) { | |
| return 0; | |
| } | |
| return ($orderA < $orderB) ? -1 : 1; | |
| }); | |
| foreach ($cFiles as $file) { | |
| $includeStr = $includeStr . '{% include \'' . $file['name'] . '\' %}'; | |
| } | |
| return [ | |
| 'files' => $cFiles, | |
| 'includes_str' => $includeStr | |
| ]; | |
| } | |
| private function setThemeFileContent(&$themeFiles, &$file) | |
| { | |
| $sectionId = '{% set sectionId = \'' . $file['id'] . '\' %} '; | |
| $settings = '{% set settings = {} %}'; | |
| if (!empty($file['modules'][0]['settings'])) { | |
| $this->setEnhancedSetting($file['modules'][0]['settings']); | |
| $settings = '{% set settings = ' . json_encode($file['modules'][0]['settings'], JSON_UNESCAPED_UNICODE) . ' %}'; | |
| } | |
| if ($this->editingMode['enable'] && !empty($this->editingMode['settings'])) { | |
| if ($file['id'] == $this->editingMode['fileId']) { | |
| $fileSettings = $file['modules'][0]['settings'] ?? []; | |
| $fileSettings = array_filter($fileSettings, function ($fileSetting) { | |
| return is_array($fileSetting); | |
| }); | |
| $settings = json_decode($this->editingMode['settings'], true); | |
| $fileSettings = array_merge($fileSettings, $settings); | |
| $settings = '{% set settings = ' . json_encode($fileSettings, JSON_UNESCAPED_UNICODE) . ' %}'; | |
| } | |
| } | |
| $themeFiles[$file['name']] = $sectionId . $settings . $file['content']; | |
| } | |
| private function getTemplateData($withHomePageQuery) | |
| { | |
| if ($this->editingMode['enable'] && $this->editingMode['action'] == self::templateActionUpdateFile) { | |
| $templateDataSession = session('templateData_' . $this->sessionKeySuffix); | |
| if (isset($templateDataSession)) { | |
| return $templateDataSession; | |
| } | |
| } | |
| $templateData = $this->templateDataHelper->generate($this->store, $this->session, $this->customer, $this->requestUri, $this->request, $withHomePageQuery); | |
| if ($this->editingMode['enable'] && empty($this->editingMode['action'])) { | |
| session()->put('templateData_' . $this->sessionKeySuffix, $templateData); | |
| } | |
| return $templateData; | |
| } | |
| private function getTemplateLayout($page) | |
| { | |
| if ($this->editingMode['enable'] && $this->editingMode['action'] == self::templateActionUpdateFile) { | |
| $themeFilesAPISession = session('themeFilesAPI_' . $this->sessionKeySuffix); | |
| if (isset($themeFilesAPISession)) { | |
| return $themeFilesAPISession; | |
| } | |
| } | |
| $themeFiles = (new GetCustomThemeFiles($this->store['id'], $this->store['storefront_theme']['id'], $page, $this->previewMode, $this->editingMode['enable'], $this->session['cartSessionId']))->perform(); | |
| $OriginalThemeFiles = json_decode(json_encode($themeFiles), true); | |
| if (env('STOREFRONT_LOCAL_THEMES')) { | |
| $this->getCustomThemeLocalFiles($page, $themeFiles); | |
| foreach ($OriginalThemeFiles['payload']['files'] as $OriginalThemeFile) { | |
| foreach ($themeFiles['payload']['files'] as &$themeFile) { | |
| if ($OriginalThemeFile['name'] == $themeFile['name']) { | |
| $themeFile['modules'] = json_decode(json_encode($OriginalThemeFile['modules']), true); | |
| } | |
| } | |
| } | |
| } | |
| if ($this->editingMode['enable'] && empty($this->editingMode['action'])) { | |
| session()->put('themeFilesAPI_' . $this->sessionKeySuffix, $themeFiles); | |
| } | |
| return $themeFiles; | |
| } | |
| public function getCartView($request, $cart, $fileName) | |
| { | |
| $fileContent = NULL; | |
| if ($fileName == 'template_for_cart_products_card') { | |
| $fileContent = \File::get(resource_path('views') . '/twig/cart/template_for_cart_products_card.twig'); | |
| } else { | |
| $fileContent = \File::get(resource_path('views') . '/twig/cart/template_for_cart_products_list.twig'); | |
| } | |
| if (!isset($fileContent)) { | |
| return ''; | |
| } | |
| $loader = new ArrayLoader([ | |
| 'cart_view.html' => $fileContent, | |
| ]); | |
| $twig = new \Twig\Environment($loader); | |
| new TwigFunctions($twig, | |
| $request, | |
| NULL, | |
| NULL, | |
| app()->getLocale() | |
| ); | |
| return $twig->render('cart_view.html', ['cart' => $cart]); | |
| } | |
| private function getStoreCopyRightText($themeTemplateLayout) | |
| { | |
| $copyrightsLink = '#'; | |
| if (empty($themeTemplateLayout['payload']['copyright_meta']['is_custom'])) { | |
| $copyrightsLink = 'https://grow.zid.sa/join-zid?utm_source=referral&utm_medium=store_footer&utm_campaign=zid_rewards' | |
| . '&store_link=' . urlencode($this->store['permalink']) | |
| . (!empty($this->store['vloops_ref_code']) ? '&referralCode=' . $this->store['vloops_ref_code'] : ''); | |
| } | |
| $tag = ($copyrightsLink == '#') ? 'span' : 'a'; | |
| return '<' . $tag . ' href="' . $copyrightsLink . '" target="_blank" class="footer-marketing-link">' . $themeTemplateLayout['payload']['copyright_meta']['text'] . '</' . $tag . '>'; | |
| } | |
| private function setEnhancedSetting(&$settings) | |
| { | |
| foreach ($settings as &$settingObj) { | |
| if (is_array($settingObj)) { | |
| if (!empty($settingObj['module_type'])) { | |
| $settingObj = $this->setEnhancedSettingOfModuleType($settingObj, $settingObj['module_type']); | |
| } else { | |
| $this->setEnhancedSetting($settingObj); | |
| } | |
| } | |
| } | |
| } | |
| private function setEnhancedSettingOfModuleType($settings, $moduleType) | |
| { | |
| switch ($moduleType) { | |
| case 'category_products': | |
| return $this->setEnhancedCategoryProducts($settings); | |
| case 'sale_products': | |
| case 'recent_products': | |
| case 'products_category': | |
| return $this->setEnhancedProducts($settings, $moduleType); | |
| case 'product': | |
| return $this->setEnhancedProduct($settings); | |
| case 'demo_product': | |
| return $this->getDemoProduct(); | |
| case 'demo_category': | |
| return $this->getDemoCategory(); | |
| case 'demo_category_products': | |
| return $this->getDemoCategoryProducts(); | |
| case 'demo_products': | |
| return $this->getDemoProducts(); | |
| default: | |
| return $settings; | |
| } | |
| } | |
| private function setEnhancedCategoryProducts($categoryProducts) | |
| { | |
| if (isset($categoryProducts['products']) && count($categoryProducts['products']) > 0) { | |
| foreach ($categoryProducts['products'] as &$product) { | |
| $product = Products::setProductEnhancedVariables($this->store, $product); | |
| } | |
| } | |
| return $categoryProducts; | |
| } | |
| private function setEnhancedProduct($product) | |
| { | |
| if (isset($product)) { | |
| $product = Products::setProductEnhancedVariables($this->store, $product); | |
| } | |
| return $product; | |
| } | |
| private function setEnhancedProducts($products, $moduleType) | |
| { | |
| if (isset($products['products']) && count($products['products']) > 0) { | |
| foreach ($products['products'] as &$product) { | |
| $product = Products::setProductEnhancedVariables($this->store, $product); | |
| } | |
| if ($moduleType == 'recent_products') { | |
| $products['url'] = '/products'; | |
| } else if ($moduleType == 'sale_products') { | |
| $products['url'] = '/products/sales'; | |
| } | |
| } | |
| return $products; | |
| } | |
| private function getDemoProduct() | |
| { | |
| $contentStr = \File::get(resource_path('views') . '/twig/demo/product.json'); | |
| $product = json_decode($contentStr, true); | |
| if ($this->appLang == 'en') { | |
| $contentEnStr = \File::get(resource_path('views') . '/twig/demo/product_en.json'); | |
| $productEn = json_decode($contentEnStr, true); | |
| $product = array_merge($product, $productEn); | |
| } | |
| return $product; | |
| } | |
| private function getDemoCategory() | |
| { | |
| $contentStr = \File::get(resource_path('views') . '/twig/demo/category.json'); | |
| $category = json_decode($contentStr, true); | |
| if ($this->appLang == 'en') { | |
| $contentEnStr = \File::get(resource_path('views') . '/twig/demo/category_en.json'); | |
| $categoryEn = json_decode($contentEnStr, true); | |
| $category = array_merge($category, $categoryEn); | |
| } | |
| return $category; | |
| } | |
| private function getDemoCategoryProducts() | |
| { | |
| $category = $this->getDemoCategory(); | |
| $product = $this->getDemoProduct(); | |
| $category['products'] = array(); | |
| for ($x = 0; $x < 14; $x++) { | |
| array_push($category['products'], $product); | |
| } | |
| return $category; | |
| } | |
| private function getDemoProducts() | |
| { | |
| $product = $this->getDemoProduct(); | |
| $products['products'] = array(); | |
| for ($x = 0; $x < 14; $x++) { | |
| array_push($products['products'], $product); | |
| } | |
| return $products; | |
| } | |
| private function getNavigationMenu($menu){ | |
| $navigationMenu['items'] = []; | |
| if(empty($menu['items'])) | |
| { | |
| return $navigationMenu ; | |
| } | |
| $homeMenuItem = current(array_filter($menu['items'], function ($menuItem) { | |
| //this should be fixed from backend | |
| //and should used a fixed name for slug | |
| return ($menuItem['name'] == 'الصفحة الرئيسية' || $menuItem['name'] == 'homepage'); | |
| })); | |
| if($homeMenuItem) | |
| { | |
| //this should be fixed from backend | |
| $homeMenuItem['url'] = '/'; | |
| $homeMenuItem['slug'] = 'home'; | |
| array_push($navigationMenu['items'], $homeMenuItem); | |
| } | |
| $allProductsMenuItem = current(array_filter($menu['items'], function ($menuItem) { | |
| //this should be fixed from backend | |
| //and should used a fixed name for slug | |
| return ($menuItem['name'] == 'جميع المنتجات' || $menuItem['name'] == 'all products'); | |
| })); | |
| if($allProductsMenuItem) | |
| { | |
| //this should be fixed from backend | |
| $allProductsMenuItem['url'] = '/products'; | |
| $allProductsMenuItem['slug'] = 'all_products'; | |
| array_push($navigationMenu['items'], $allProductsMenuItem); | |
| } | |
| foreach($menu['items'] as $menuItem){ | |
| //this should be fixed from backend | |
| //and should used a fixed name for slug | |
| if($menuItem['name'] != 'الصفحة الرئيسية' | |
| && $menuItem['name'] != 'homepage' | |
| && $menuItem['name'] != 'جميع المنتجات' | |
| && $menuItem['name'] != 'all products' | |
| && $menuItem['name'] != 'جميع التصنيفات' | |
| && $menuItem['name'] != 'all categories'){ | |
| array_push($navigationMenu['items'], $menuItem); | |
| } | |
| } | |
| $allCategoiresMenuItem = current(array_filter($menu['items'], function ($menuItem) { | |
| //this should be fixed from backend | |
| //and should used a fixed name for slug | |
| return ($menuItem['name'] == 'جميع التصنيفات' || $menuItem['name'] == 'all categories'); | |
| })); | |
| if($allCategoiresMenuItem) | |
| { | |
| $allCategoiresMenuItem['url'] = '/categories'; | |
| $allCategoiresMenuItem['slug'] = 'all_categories'; | |
| array_push($navigationMenu['items'], $allCategoiresMenuItem); | |
| } | |
| return $navigationMenu; | |
| } | |
| private function getDestinationCountry($countries, $cityId){ | |
| if(empty($countries)) | |
| { | |
| return NULL; | |
| } | |
| if(empty($cityId)) | |
| { | |
| $country = $countries[0]; | |
| $country['city'] = $country['cities'][0] ?? NULL; | |
| return $country; | |
| } | |
| foreach ($countries as $country) | |
| { | |
| $city = current(array_filter($country['cities'], function ($cCity) use($cityId) | |
| { | |
| return ($cCity['id'] == $cityId); | |
| })); | |
| if(!empty($city) && count($city) > 0) | |
| { | |
| $country['city'] = $city; | |
| return $country; | |
| } | |
| } | |
| return NULL; | |
| } | |
| private function getCustomThemeLocalFiles($template, &$themeFiles) | |
| { | |
| $localThemePath = 'storefrontThemes/' . env('STOREFRONT_LOCAL_THEME_NAME') . '/'; | |
| $files = []; | |
| $this->addLocalFileToFiles($files, 'layout.twig', File::get(public_path($localThemePath . 'layout.twig')), 'root'); | |
| $this->addLocalFileToFiles($files, 'header.twig', File::get(public_path($localThemePath . 'header.twig')), 'root'); | |
| $this->addLocalFileToFiles($files, 'footer.twig', File::get(public_path($localThemePath . 'footer.twig')), 'root'); | |
| $this->addLocalFileToFiles($files, 'ar.json', File::get(public_path($localThemePath . 'locals/ar.json')), 'locals'); | |
| $this->addLocalFileToFiles($files, 'en.json', File::get(public_path($localThemePath . 'locals/en.json')), 'locals'); | |
| $commonFiles = File::allFiles(public_path($localThemePath . 'common')); | |
| foreach ($commonFiles as $commonFile) { | |
| $fileName = $commonFile->getFilename(); | |
| $this->addLocalFileToFiles($files, $fileName, File::get(public_path($localThemePath . 'common/' . $fileName)), 'common'); | |
| } | |
| if ($template == 'home.twig') { | |
| $modulesFiles = File::allFiles(public_path($localThemePath . 'modules')); | |
| foreach ($modulesFiles as $modulesFile) { | |
| $fileName = $modulesFile->getFilename(); | |
| $this->addLocalFileToFiles($files, $fileName, File::get(public_path($localThemePath . 'modules/' . $fileName)), 'modules'); | |
| } | |
| } | |
| $this->addLocalFileToFiles($files, $template, File::get(public_path($localThemePath . 'templates/' . $template)), 'templates'); | |
| $themeFiles['payload']['files'] = $files; | |
| $themeFiles['payload']['assets_url'] = '/' . $localThemePath . 'assets/'; | |
| if (!empty($themeFiles['payload']['menu']['items'])) { | |
| $this->replaceMenuUrlWithLocalhost($themeFiles['payload']['menu']['items']); | |
| } | |
| } | |
| private function addLocalFileToFiles(&$files, $name, $content, $folder) | |
| { | |
| array_push($files, [ | |
| 'id' => str_replace('.twig', '', '' . $folder . '-' . $name), | |
| 'theme_id' => $this->themeId, | |
| 'path' => $folder . '/' . $name, | |
| 'config' => NULL, | |
| 'name' => $name, | |
| 'content' => $content, | |
| 'created_at' => 'created_at', | |
| 'updated_at' => 'updated_at', | |
| 'folder' => $folder, | |
| 'modules' => ($folder == 'modules') ? [ | |
| 0 => [ | |
| 'id' => str_replace('.twig', '', 'module-' . $folder . '-' . $name), | |
| 'settings' => [ | |
| 'order' => intval($this->get_string_between($content, "{% schema %}", "{% endschema %}")) | |
| ] | |
| ] | |
| ] : [] | |
| ]); | |
| } | |
| private function get_string_between($string, $start, $end) | |
| { | |
| $string = ' ' . $string; | |
| $ini = strpos($string, $start); | |
| if ($ini == 0) return ''; | |
| $ini += strlen($start); | |
| $len = strpos($string, $end, $ini) - $ini; | |
| return substr($string, $ini, $len); | |
| } | |
| private function replaceMenuUrlWithLocalhost(&$menu) | |
| { | |
| if (!empty($menu)) { | |
| foreach ($menu as &$menuItem) { | |
| $menuItem['url'] = str_replace( | |
| env('APP_TEST_STORE'), | |
| substr(env('APP_URL'), 0, -1) . (($_SERVER['SERVER_PORT'] != '80') ? $_SERVER['SERVER_PORT'] : '') . '/', | |
| $menuItem['url'] | |
| ); | |
| if (!empty($menuItem['sub_categories'])) { | |
| $this->replaceMenuUrlWithLocalhost($menuItem['sub_categories']); | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment