Skip to content

Instantly share code, notes, and snippets.

@mininaim
Created February 13, 2024 09:39
Show Gist options
  • Save mininaim/5f16f351c9ad7215fd3f5bb21fe4ce4b to your computer and use it in GitHub Desktop.
Save mininaim/5f16f351c9ad7215fd3f5bb21fe4ce4b to your computer and use it in GitHub Desktop.
View.php
<?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