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