dir = $dir; $this->name = $name; parent:: __construct($uriData); $this->module = new indexModule(); $this->cache = new cCacheHelper($this->oApc); $this->oView->setTemplateDir($this->dir . "/tmpl/"); $this->oView->bPubIsSys = false; if (!$this->oView->cacheUsed()) { $this->oView->setJs(getCurrentFolder($this->dir) . '/js/' . $this->name . '.js'); $this->oView->setCss(getCurrentFolder($this->dir) . '/css/' . $this->name . '.css'); } /** Show global notification */ // TODO: Get notification from cms text manager (needs a new type) $this->oView->show_notification = true; $this->oView->global_notification = "First order 25%! Only today, don't miss it!"; $this->sScrollTo = new cSession("scrollTo"); // Set JS module init title $this->oView->setAsJSON(cCore::JS_MOD, ucfirst($name)); } public function runIndex() { $this->oView->TITLE = $this->gM("Index page"); $this->oView->INDEX = true; $indexData = $this->loadIndexGlobalData(); $this->oView->HOME_SLIDER = $indexData['HOME_SLIDER']; $this->oView->CATEGORY_SLIDER = $indexData['CATEGORY_SLIDER']; $this->oView->FEATURED_PRODUCTS = $indexData['FEATURED_PRODUCTS']; $this->oView->SERVICE_AREA = $indexData['SERVICE_AREA']; $this->oView->HOME_ABOUT_PRODUCTS = $indexData['HOME_ABOUT_PRODUCTS']; $this->oView->ABOUT_TEXT = $indexData['ABOUT_TEXT']; $this->oView->DEAL_OF_AREA = $indexData['DEAL_OF_AREA']; $this->oView->TESTIMONIAL = $indexData['TESTIMONIAL']; $this->oView->TESTIMONIAL_BG = $indexData['TESTIMONIAL_BG']; // Set variables to view $this->oView->setAsJSON('gM', $this->getJsTranslations()); $this->oView->setAsJSON('sScrollTo', $this->sScrollTo->scrollTo); $this->sScrollTo->destroy(); $this->oView->display('index', 'BODY'); } public function getIndexGlobalData(): array { return $this->loadIndexGlobalData(); } private function loadIndexGlobalData(): array { $cached = self::getCachedIndexGlobalData($this->cache, $this->langId); if (!empty($cached)) { return $cached; } $data = [ 'HOME_SLIDER' => $this->getIndexHeaderData(), 'CATEGORY_SLIDER' => $this->getIndexCategorySliderData(), 'FEATURED_PRODUCTS' => $this->getIndexCategoryProductsData(), 'SERVICE_AREA' => $this->getIndexServiceAreaData(), 'HOME_ABOUT_PRODUCTS' => $this->getIndexAboutProductsData(), 'ABOUT_TEXT' => $this->getIndexAboutTextSectionsData(), 'DEAL_OF_AREA' => $this->getIndexDealOfAreaData(), 'TESTIMONIAL' => $this->getIndexTestimonialData(), 'TESTIMONIAL_BG' => $this->getIndexTestimonialBackgroundImg(), ]; $this->cache->store(cmsTextManagerConst::APC_INDEX_GLOBAL_KEY, $this->langId, $data); return $data; } public static function getCachedIndexGlobalData(cCacheHelper $cache, int $langId): array { $cached = $cache->get(cmsTextManagerConst::APC_INDEX_GLOBAL_KEY, $langId); return (is_array($cached) ? $cached : []); } public function getIndexHeaderData(): array { $data = $this->module->getArticleData(cmsTextManagerConst::INDEX_PAGE_HERO_SLIDER, $this->langId, true); if (empty($data)) { return []; } $result = []; foreach ($data as $k => $v) { // Set image path or default image. $imgPath = self::IMG_ASSETS_DEFAULT_SLIDER; if (!empty($v['i'])) { $imgPath = self::normalizeImagePath($v['i'], 'carousel'); } $result[$k] = [ 'img_desktop' => $imgPath, // For now use the same as img_desktop or default for mobile 'img_mobile' => !empty($v['i']) ? $imgPath : self::IMG_ASSETS_DEFAULT_SLIDER_MOB, 'subtitle' => $v['s'], 'heading' => $v['t'], 'btn_text' => $v['v'], 'btn_url' => $v['l'], ]; } return $result; } public function getIndexCategorySliderData(): array { $data = $this->module->getArticleData(cmsTextManagerConst::BASE_CATEGORIES, $this->langId, true); if (empty($data)) { return []; } $getCategoriesUrls = $this->module->getCategoriesUrls(array_keys($data), $this->langId); $productCountInCategories = $this->module->countProductsInCategories(array_keys($data)); $result = []; foreach ($data as $k => $v) { if ($k === 1) { // 1st id is for base category that we need to ignore continue; } // Set image path or default image. $imgPath = self::IMG_ASSETS_DEFAULT_CAT; if (!empty($v['i'])) { $imgPath = self::normalizeImagePath($v['i'], 'base_cat'); } $result[$k] = [ 'img' => $imgPath, 'name' => $v['t'], 'count' => $productCountInCategories[$k] ?? '0', 'url' => $getCategoriesUrls[$k] ?? '', ]; } return $result; } public function getIndexCategoryProductsData(): array { $featuredProducts = $this->module->getFeaturedProducts($this->langId); if (empty($featuredProducts)) { return []; } $cry = new cDefuseCrypto(); $result = []; foreach ($featuredProducts as $id => $product) { $default = '/img/assets/product/p-1.jpg'; $imgPath = ''; if (!empty($product['img_path'])) { $imgPath = self::normalizeImagePath($product['img_path'], 'prod_card'); } if (!$imgPath) { // Set default image if the product image does not exist $imgPath = $default; } $price = number_format((float)($product['prod_price'] ?? 0), 2, '.', ' '); $oldPrice = ''; $label = ''; $labelType = ''; $isDiscount = ((int)($product['prod_discount'] ?? 0) === 1 && (float)($product['prod_discount_value'] ?? 0) > 0); if ($isDiscount) { $discountValue = (float)$product['prod_discount_value']; $discountPrice = max(0, (float)$product['prod_price'] - ($discountValue / 100 * (float)$product['prod_price'])); $price = number_format($discountPrice, 2, '.', ' '); $oldPrice = number_format((float)$product['prod_price'], 2, '.', ' '); $label = '-' . rtrim(rtrim(number_format($discountValue, 2, '.', ''), '0'), '.') . '%'; $labelType = 'product-label-discount'; } $isNew = $product['prod_created'] >= (time() - (3 * 24 * 60 * 60)); if ($isNew) { $label = 'New'; $labelType = 'product-label-new'; } // TODO: $soldOut = false; if ($soldOut) { $label = 'Sold'; $labelType = 'product-label-sold'; } // TODO: $isOnSale = false; if ($isOnSale) { $label = 'On Sale'; $labelType = 'product-label-sale'; } $result[$id] = [ 'id' => $id, 'cart_id' => $cry->encrypt((string)$id), 'img1' => $imgPath, 'img2' => $imgPath, 'title' => $product['prod_name'] ?? '', 'description'=> $product['prod_sdescription'] ?? ($product['prod_description'] ?? ''), 'url' => !empty($product['prod_url']) ? $this->oUrl->rmSlashesIndex($product['prod_url']) : '', 'price' => $price, 'old_price' => $oldPrice, 'rating' => 0, 'label' => $label, 'label_type' => $labelType, 'sold_out' => $soldOut, ]; } return $result; } public function getIndexServiceAreaData(): array { $data = $this->module->getArticleData(cmsTextManagerConst::INDEX_PAGE_SERVICES, $this->langId, true); if (empty($data)) { return []; } $result = []; foreach ($data as $k => $v) { // Set image path or default image. $imgPath = self::IMG_ASSETS_DEFAULT_SERVICE; if (!empty($v['i'])) { $imgPath = self::normalizeImagePath($v['i'], 'service_card'); } $result[$k] = [ 'img' => $imgPath, 'name' => $v['t'], 'text' => $v['s'] ]; } return $result; } public function getIndexAboutProductsData(): array { $data = $this->module->getArticleData(cmsTextManagerConst::INDEX_PAGE_ABOUT_PRODUCT, $this->langId, true); if (empty($data)) { return []; } $result = [ 'leftItems' => [], 'rightItems' => [] ]; $i = 0; foreach ($data as $v) { // Set image path or default image. $imgPath = self::IMG_ASSETS_DEFAULT_SERVICE; if (!empty($v['i'])) { $imgPath = self::normalizeImagePath($v['i']); } $item = [ 'img' => $imgPath, 'title' => $v['t'], 'text' => $v['s'] ]; if ($i % 2 === 0) { $result['leftItems'][] = $item; } else { $result['rightItems'][] = $item; } $i++; } return $result; } public function getIndexDealOfAreaData(): array { // TODO: Gather product data $data = [ [ 'img1' => '/img/assets/product/p-21.jpg', 'img2' => '/img/assets/product/p-22.jpg', 'title' => 'Radiance LED skin mask', 'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry It is a long established fact that a will be distracted by the readable of at', 'url' => 'veikals/topi/asd', 'price' => '$4.00', 'old_price' => '$9.00', 'rating' => 0, 'label' => '', 'label_type' => '', 'sold_out' => false ], [ 'img1' => '/img/assets/product/p-23.jpg', 'img2' => '/img/assets/product/p-24.jpg', 'title' => 'Luxury glow gift box', 'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry ...', 'url' => 'veikals/topi/asd', 'price' => '$9.00', 'old_price' => '$14.00', 'rating' => 0, 'label' => '', 'label_type' => '', 'sold_out' => false ], [ 'img1' => '/img/assets/product/p-1.jpg', 'img2' => '/img/assets/product/p-2.jpg', 'title' => 'Glow boost face cream', 'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry ...', 'url' => 'veikals/topi/asd', 'price' => '$79.00', 'old_price' => '$89.00', 'rating' => 4, 'label' => '', 'label_type' => '', 'sold_out' => false ], [ 'img1' => '/img/assets/product/p-3.jpg', 'img2' => '/img/assets/product/p-4.jpg', 'title' => 'Velvet kiss lipstick set', 'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry ...', 'url' => 'veikals/topi/asd', 'price' => '$49.00', 'old_price' => '$59.00', 'rating' => 0, 'label' => 'New', 'label_type' => 'product-label-new', 'sold_out' => false ] ]; $cry = new cDefuseCrypto(); foreach ($data as &$item) { $itemId = (isset($item['id']) ? (string)$item['id'] : ''); $item['cart_id'] = ($itemId !== '' ? $cry->encrypt($itemId) : ''); } unset($item); return empty($data) ? [] : $data; } public function getIndexTestimonialData(): array { $data = $this->module->getArticleData(cmsTextManagerConst::INDEX_PAGE_TESTIMONIAL, $this->langId, true); $result = []; foreach ($data as $k => $v) { // Set image path or default image. $imgPath = self::IMG_ASSETS_DEFAULT_TESTIMONIAL; if (!empty($v['i'])) { $imgPath = self::normalizeImagePath($v['i']); } $result[$k] = [ 'img' => $imgPath, 'name' => $v['t'], 'role' => $v['s'], 'quote' => strip_tags($v['d']), ]; } return $result; } public function getIndexTestimonialBackgroundImg(): string { $data = $this->module->getArticleData(cmsTextManagerConst::INDEX_PAGE_TESTIMONIAL_BG, $this->langId, true); $header = firstE($data); if (empty($header)) { return self::IMG_ASSETS_DEFAULT_TESTIMONIAL_BG; } $backgroundImg = self::IMG_ASSETS_DEFAULT_TESTIMONIAL_BG; if (!empty($header['i'])) { $backgroundImg = self::normalizeImagePath($header['i'], 'testimonial'); } return $backgroundImg; } public static function getPopupBackgroundImg(int $langId): string { $data = (new indexModule())->getArticleData(cmsTextManagerConst::POPUP_SUBSCRIBE_BG, $langId, true); $header = firstE($data); if (empty($header)) { return self::IMG_DEFAULT_POPUP_BG; } $backgroundImg = self::IMG_DEFAULT_POPUP_BG; if (!empty($header['i'])) { $backgroundImg = self::normalizeImagePath($header['i'], 'subscribe'); } return $backgroundImg; } public static function getBreadcrumbBackgroundImg(int $langId): string { $data = (new indexModule())->getArticleData(cmsTextManagerConst::GLOBAL_BREADCRUMBS, $langId, true); $header = firstE($data); if (empty($header)) { return self::IMG_DEFAULT_BREADCRUMBS_BG; } if (empty($header['i'])) { return self::IMG_DEFAULT_BREADCRUMBS_BG; } $backgroundImg = self::normalizeImagePath($header['i'], 'category_bg'); return ($backgroundImg ?: self::IMG_DEFAULT_BREADCRUMBS_BG); } public static function getCollectionBannerImg(int $langId): string { $data = (new indexModule())->getArticleData(cmsTextManagerConst::COLLECTION_BANNER, $langId, true); $header = firstE($data); if (empty($header)) { return self::IMG_DEFAULT_COLLECTION_BANNER; } if (empty($header['i'])) { return self::IMG_DEFAULT_COLLECTION_BANNER; } $backgroundImg = self::normalizeImagePath($header['i'], 'collection_banner'); return ($backgroundImg ?: self::IMG_DEFAULT_COLLECTION_BANNER); } public function getIndexAboutTextSectionsData(): array { $data = $this->module->getArticleData(cmsTextManagerConst::INDEX_PAGE_ABOUT_TEXT, $this->langId, true); if (empty($data)) { return []; } foreach ($data as $k => $v) { $data[$k] = [ 'subtitle' => $v['s'], 'title' => $v['t'], 'description' => strip_tags($v['d']), 'button_text' => $v['v'], 'link' => $v['l'], ]; } return $data; } public function runCookies() { $this->oView->HEADER = ['t' => $this->gM("Cookies")]; $this->oView->DATA = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_INDEX_COOKIES_KEY, cmsTextManagerConst::PAGE_TYPE_COOKIES ); $this->oView->display('page', 'BODY'); } public function runTermsOfUsage() { $this->oView->DATA = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_INDEX_AGREE_TO_TERMS_KEY, cmsTextManagerConst::PAGE_TYPE_AGREE_TO_TERMS ); // Return only content for modal/AJAX requests. if ($this->isTermsContentOnlyRequest()) { $this->oView->IFRAME = true; $this->oView->POPUP_CONTENT_ONLY = true; $html = $this->oView->genTemplate('page'); echo $this->stripDataAnimateAttributes($html); return; } $this->oView->HEADER = ['t' => $this->gM("Terms & conditions")]; $this->oView->display('page', 'BODY'); } private function isTermsContentOnlyRequest(): bool { return getG('fload') || getG('p'); } private function stripDataAnimateAttributes(string $html): string { $result = preg_replace('/\sdata-animate=(["\']).*?\1/i', '', $html); return ($result === null ? $html : $result); } public function runContactUs(){ $this->oView->DATA = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_INDEX_CONTACT_US_KEY, cmsTextManagerConst::PAGE_TYPE_CONTACT_US, false, function (array $data) { foreach ($data as $k => $v) { $data[$k] = [ 'title' => $v['t'], 'description' => strip_tags($v['d']), ]; } return $data; } ); $this->oView->HEADER = ['t' => $this->gM("Contact us")]; $this->oView->setAsJSON('valCfg', $this->valCfgForContacts()); $this->oView->display('contact_us', 'BODY'); } public function runAboutUs() { $this->oView->DATA = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_ABOUT_US_KEY, cmsTextManagerConst::PAGE_TYPE_ABOUT_US, ); $this->oView->HEADER = ['breadcrumbs_t' => $this->gM("About us")]; $this->oView->setAsJSON('valCfg', $this->valCfgForContacts()); $this->oView->display('page', 'BODY'); } public function runFaq() { $this->oView->DATA = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_FAQ_KEY, cmsTextManagerConst::PAGE_TYPE_FAQ, ); $this->oView->HEADER = ['t' => $this->gM("Frequently asked questions")]; $this->oView->setAsJSON('valCfg', $this->valCfgForContacts()); $this->oView->display('page', 'BODY'); } public function runCopyRights() { $vData = $this->loadCachedArticleBlock( cmsTextManagerConst::PAGE_TYPE_COPYRIGHT, cmsTextManagerConst::PAGE_TYPE_COPYRIGHT, false, function (array $data) { return findAndReplaceLinksInText($data, $this); } ); $this->oView->DATA = $vData; $this->oView->HEADER = [ 't' => $this->gM("Copyrights"), 'd' => $this->gM("Copyrights short description"), ]; $this->oView->CUSTOM_HEADER = true; $this->oView->display('page', 'BODY'); } public function runDisclaimer() { $vData = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_DISCLAIMER_KEY, cmsTextManagerConst::PAGE_TYPE_DISCLAIMER, ); $this->oView->DATA = $vData; $this->oView->HEADER = ['t' => $this->gM("Disclaimer")]; $this->oView->display('page', 'BODY'); } public function runPrivacyPolicy() { $vData = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_PRIVACY_POLICY_KEY, cmsTextManagerConst::PAGE_TYPE_PRIVACY_POLICY, ); $this->oView->DATA = $vData; // Return only content for modal/AJAX requests. if ($this->isTermsContentOnlyRequest()) { $this->oView->IFRAME = true; $this->oView->POPUP_CONTENT_ONLY = true; $html = $this->oView->genTemplate('page'); echo $this->stripDataAnimateAttributes($html); return; } $this->oView->HEADER = ['t' => $this->gM("Privacy policy")]; $this->oView->display('page', 'BODY'); } public function runPaymentPolicy() { $vData = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_PAYMENT_POLICY_KEY, cmsTextManagerConst::PAGE_TYPE_PAYMENT_POLICY, ); $this->oView->DATA = $vData; $this->oView->HEADER = ['t' => $this->gM("Payment terms")]; $this->oView->display('page', 'BODY'); } public function runReturnPolicy() { $vData = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_RETURN_POLICY_KEY, cmsTextManagerConst::PAGE_TYPE_RETURN_POLICY, ); $this->oView->DATA = $vData; // Return only content for modal/AJAX requests. if ($this->isTermsContentOnlyRequest()) { $this->oView->IFRAME = true; $this->oView->POPUP_CONTENT_ONLY = true; $html = $this->oView->genTemplate('page'); echo $this->stripDataAnimateAttributes($html); return; } $this->oView->HEADER = ['t' => $this->gM("Return policy")]; $this->oView->display('page', 'BODY'); } public function runShippingPolicy() { $vData = $this->loadCachedArticleBlock( cmsTextManagerConst::APC_SHIPPING_POLICY_KEY, cmsTextManagerConst::PAGE_TYPE_SHIPPING_POLICY, ); $this->oView->DATA = $vData; // Return only content for modal/AJAX requests. if ($this->isTermsContentOnlyRequest()) { $this->oView->IFRAME = true; $this->oView->POPUP_CONTENT_ONLY = true; $html = $this->oView->genTemplate('page'); echo $this->stripDataAnimateAttributes($html); return; } $this->oView->HEADER = ['t' => $this->gM("Shipping policy")]; $this->oView->display('page', 'BODY'); } public function runAccessError() { $this->oView->HEADER = ['t' => $this->gM("Access Error")]; $this->oView->display('access_error', 'BODY'); } public function runSubscribe() { // TODO: Need to finish and clean this up. if(!!($POST_DATA = $this->post->DATA) && is_array($POST_DATA)){ $this->post->destroy(); // Validate fields $valid = new cValidator($this); $errors = $valid->checkArray($POST_DATA, $this->valCfgForSubscribe()); if($errors === true){ if($this->addUserToSubscriptionList($POST_DATA)) $this->oView->STATUS_OK = str_replace('%E-MAIL%', $POST_DATA['sub_email'], $this->gM('Your email "%E-MAIL%" has successfully been added to our subscription list!')); else $this->oView->STATUS_ERROR = $this->gM("Something went wrong while saving message!"); }else{ foreach ($errors as $key => $val){ $k = substr($key, 1); $errors[$k] = $val; $POST_DATA[$k] = $POST_DATA[$key]; unset($errors[$key], $POST_DATA[$key]); } $this->oView->setAsJSON('fData', array('err' => $errors, 'val' => $POST_DATA)); } } $this->oView->HEADER = [ 't' => $this->gM("Subscribe"), 'd' => $this->gM("Subscribe to our newsletters"), ]; $this->oView->setAsJSON('gM', $this->getJsTranslations()); $this->oView->display('page_subscribe', 'BODY'); } public function runUnSubscribe() { $this->oView->HEADER = ['t' => $this->gM("UnSubscribe")]; $this->oView->setAsJSON('gM', $this->getJsTranslations()); $this->oView->display('unsubscribe', 'BODY'); } private function loadCachedArticleBlock($cacheKey, $typeId, $withImages = false, $formatter = null) { $cached = $this->cache->get($cacheKey, $this->langId); if ($cached !== false) { return $cached; } $data = $this->module->getArticleData($typeId, $this->langId, $withImages); if (is_callable($formatter)) { $data = call_user_func($formatter, $data ?? []); } $this->cache->store($cacheKey, $this->langId, $data); return $data; } public function addUserToSubscriptionList($vData) { // Validate email field and send error if any found. $errors = (new cValidator($this))->checkArray($vData, $this->valCfgForSubscribe()); if (is_array($errors) && !empty($errors)) { cJSON::sendError(['msg' => $this->gM('Something went wrong'), 'errors' => $errors]); } // Add or enable email in subscription list if ($this->module->chkEmailExists($vData['sub_email'])) { $this->module->enableEmail($vData['sub_email']); } else { $this->module->saveEmail([ 'email' => $vData['sub_email'], 'email_sub' => 1, 'email_sub_ip' => $_SERVER['REMOTE_ADDR'], 'email_sub_language' => $this->langId, 'email_reg_user_agent' => $_SERVER['HTTP_USER_AGENT'], 'email_added' => time(), 'email_modified' => time(), ]); } cJSON::sendOk(); } public function removeUserFromSubscriptionList($vData) { // remove email if one already exists if (!empty($vData['sub_email'])) { // Validate fields $valid = new cValidator($this); $errors = $valid->checkArray($vData, $this->valCfgForSubscribe()); if ($errors === true) { if ($this->module->chkEmailExists($vData['sub_email'])) { $this->module->disableEmail($vData['sub_email']); } } else { foreach ($errors as $key => $val) { $k = substr($key, 1); $errors[$k] = $val; $vData[$k] = $vData[$key]; unset($errors[$key], $vData[$key]); } $this->oView->setAsJSON('fData', ['err' => $errors, 'val' => $vData]); } cJSON::sendOk(); } cJSON::sendError(['msg' => $this->gM('Something went wrong!')]); } public static function valCfgForSubscribe(): array { return [ 'cfg' => ['sBindAttrTitle' => 'name'], 'sub_email' => [ cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_TEST => [cValidator::CHK_EMAIL], ], ]; } public static function acceptCookiePolicy(): bool { if (!isset($_COOKIE['_cookie_policy_accepted'])) { /* expire in 1 month */ setSameSiteCookie('_cookie_policy_accepted', 1, 60 * 60 * 24 * 30); } return true; } public function contactUs($sData) { // Validate fields $vData = cJSON::decode($sData ?? '', true); $errors = (new cValidator($this))->checkArray($vData, $this->valCfgForContacts()); if ($errors === true) { if ($this->addUserComment($vData)) cJSON::sendOk(); cJSON::sendError(['msg' => $this->gM('Something went wrong!')]); } else { cJSON::sendError(['err' => $errors]); } } public static function valCfgForContacts(): array { return [ 'cfg' => [ 'sBindAttrTitle' => 'id', ], 'name' => [ cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_TEST => [cValidator::CHK_STR], ], 'email' => [ cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_TEST => [cValidator::CHK_EMAIL], ], 'phone' => [ cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_TEST => [cValidator::CHK_PHONE], ], 'message' => [ cValidator::P_TYPE => cValidator::TY_STR, cValidator::P_COMP => 1, cValidator::P_TEST => [cValidator::CHK_STR], ], ]; } public function addUserComment($vData) { return $this->module->saveComment( [ 'first_name' => $vData['name'], 'last_name' => '', 'email' => $vData['email'], 'subject' => '', 'phone' => $vData['phone'], 'message' => $vData['message'], 'ip_from' => $_SERVER['REMOTE_ADDR'], 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'created' => time(), 'modified' => time(), ], ); } /** * Function to get javascript translations * * @author Aivars Žukovskis * @category APP Index * @return array */ public function getJsTranslations(): array { return cValidator::getJSTranslations( $this, $this->valCfgForSubscribe(), [ 'no' => $this->gM('No'), 'yes' => $this->gM('Yes'), /*'chkComp' => $this->gM('Please fill in the field!'), 'chkEmail' => $this->gM('Not a valid email address specified!'), 'chkPhone' => $this->gM('Invalid telephone specified!'),*/ ], ); } /** * Function to download file * * @category APP INDEX * @author Aivars Žukovskis * @returns array */ public static function requestFileDownload($fileId, $bFilePath = false) { if ($fileId) { $cry = new cDefuseCrypto(); $fileId = $cry->decrypt($fileId); $sFilePath = ""; $sFileName = ""; if ($bFilePath) { $sFilePath = $fileId; $sFileName = basename($sFilePath); } else { $indexModule = new indexModule(); if (is_numeric($fileId) && $fileData = $indexModule->getFilePath($fileId)) { if ( !!$fileData['file_link'] && $file = preg_replace('/^\/files\/|^\//', '', $fileData['file_link']) ) { $sFilePath = __FILES__ . $file; $sFileName = $fileData['file_name']; } } } if (strlen($sFilePath) && file_exists($sFilePath)) { $mimeTypes = [ 'png' => 'image/png', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'doc' => 'application/msword', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'htm' => 'text/html', 'html' => 'text/html', 'pdf' => 'application/pdf', 'xls' => 'application/excel', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'zip' => 'application/zip', ]; if (isset($GLOBALS['coverage_tests_running'])) { throw new Exception("File Download: $sFilePath"); } header("Content-Disposition: attachment; filename={$sFileName}." . getExtension($sFilePath)); header("Content-Type: " . $mimeTypes[strtolower(getExtension($sFilePath))]); header('Cache-Control: max-age=0'); readfile($sFilePath); die(); } } redirectToUri('/'); return true; } public static function normalizeImagePath(string $path, $sub = 'preview'): string { if (indexController::isSvg($path)) { return $path; } $path = dirname($path) . '/' . $sub . '/' . basename($path); if (!file_exists(__MDIR__ . $path) || !is_file(__MDIR__ . $path)) { $path = false; } return $path; } public static function isSvg(string $fileLink): bool { $file = __MDIR__ . $fileLink; return getFileExtension($fileLink) === 'svg' && is_file($file); } /** * Function to load category button menu data from APC * * @author Aivars Zukovskis * @category APP Index * @param object $oCore - class object * @param int $dLangId - default language id * @return array with data */ public static function loadCategoryButtonMenu($oCore, $dLangId = 0) { $oModule = new indexModule(); if (!empty($_SESSION['showAllCategories'])) { $aTempt = $oModule->getAllCategoryButtons($oCore->langId, $oCore->oUrl->_endSlash, true); $menu = []; if (!!$aTempt && is_array($aTempt)) { foreach ($aTempt as $k => $val) { // chk url slashes $val['l'] = $oCore->oUrl->rmSlashesIndex($val['l']); $menu[$val['ct']][$k] = [ 't' => $val['t'], 'l' => $val['l'], 'a' => $val['alias_id'], 'i' => $val['i'], ]; } } // Split MENU into chunks for better overview if (!!$menu) { foreach ($menu as $k => &$v) { if (count($v) >= 14) { $v = array_chunk($v, 12); $v['split'] = 1; } } unset($v); } } else { $langId = ($dLangId ?: $oCore->langId); $menu = $oCore->oApc->check(cmsTextManagerConst::APC_CATEGORY_MENU_KEY . $langId); // Reload data if (empty($menu)) { // Get buttons & check if file exists - if not add default image $aTempt = $oModule->getCatButtons($langId, $oCore->oUrl->_endSlash); if (!!$aTempt && is_array($aTempt)) { $menu = []; foreach ($aTempt as $k => $val) { $menu[$val['ct']][$k] = [ 't' => $val['t'], 'l' => $oCore->oUrl->rmSlashesIndex($val['l']), 'a' => $val['alias_id'], 'c' => $val['prod_count'], // TODO: When saving products we should drop the APC key as well due to the prod count 'i' => $val['i'] ?? '', ]; } $menu = self::splitMenuIntoChunks($menu); } } } return $menu; } /** * Function to load header menu data from APC * * @author Aivars Zukovskis * @category APP Index * @param object $oCore - class object * @param int $dLangId - default language id * @return array with data */ public static function loadHeaderCategoryMenu($oCore, $dLangId = 0): array { $langId = ($dLangId ?: $oCore->langId); $apcKey = cmsTextManagerConst::APC_HEADER_CATEGORY_MENU_KEY . $langId; $useApc = empty($_SESSION['showAllCategories']); $menu = ($useApc ? $oCore->oApc->check($apcKey) : false); if (!!$menu && is_array($menu)) { return $menu; } $baseCategories = (new indexModule())->getArticleData(cmsTextManagerConst::BASE_CATEGORIES, $langId, true); if (empty($baseCategories)) { return []; } $subCategories = self::loadCategoryButtonMenu($oCore, $langId); $menu = []; foreach ($baseCategories as $catId => $catData) { if ((int)$catId === 1 || empty($catData['t'])) { continue; } $baseCatUrl = $oCore->oUrl->rmSlashesIndex($catData['l'] ?? ''); $menu[] = [ 'title' => $catData['t'], 'url' => $oCore->gL(cmsTextManagerConst::CATEGORY_ALIAS_ID, $baseCatUrl), 'type' => 'product', 'columns' => self::normalizeHeaderCategoryColumns($subCategories[$catData['t']] ?? [], $oCore), ]; } if ($useApc && !!$menu) { $oCore->oApc->store($apcKey, $menu); } return $menu; } private static function normalizeHeaderCategoryColumns($columnsSource, $oCore): array { if (empty($columnsSource) || !is_array($columnsSource)) { return []; } $columns = []; if (isset($columnsSource['split'])) { unset($columnsSource['split']); foreach ($columnsSource as $chunk) { if (!is_array($chunk)) { continue; } $links = self::buildHeaderCategoryLinks($chunk, $oCore); if (!empty($links)) { $columns[] = ['links' => $links]; } } return $columns; } $links = self::buildHeaderCategoryLinks($columnsSource, $oCore); if (!empty($links)) { $columns[] = ['links' => $links]; } return $columns; } private static function buildHeaderCategoryLinks(array $items, $oCore): array { $links = []; foreach ($items as $subCatId => $subCat) { if ($subCatId === 'split' || !is_array($subCat) || empty($subCat['t']) || empty($subCat['l'])) { continue; } $links[] = [ 'url' => $oCore->oUrl->rmSlashesIndex($subCat['l']), 'text' => $subCat['t'], ]; } return $links; } /** * Split MENU into chunks for better overview */ public static function splitMenuIntoChunks(array $menu, int $chunkSize = 5): array { $lCount = 0; $m = 1; foreach ($menu as $k => &$v) { if (count($v) >= $chunkSize) { $v = array_chunk($v, $chunkSize); $v['split'] = 1; } else { if (($m % 2 == 0 || $m % 3 == 0) && $lCount > count($v)) { while ($lCount > count($v)) { $v[] = ['empty' => 1]; } if ($m % 3 == 0) { $m = 1; } } $lCount = count($v); $v = is_array($v) ? $v : [$v]; } $m++; } unset($v); return $menu; } }