ElixirVault/www/system-brs-core/app/index/inc/indexController.php

1181 lines
41 KiB
PHP

<?php
namespace BRSystems\Core\App\index\inc;
use BRSystems\Core\Cms\cmsTextManager\inc\cmsTextManagerConst;
use BRSystems\Core\Library\cCore\cCore;
use BRSystems\Core\Library\cDefuseCrypto\cDefuseCrypto;
use BRSystems\Core\Library\cJSON\cJSON;
use BRSystems\Core\Library\cSession\cSession;
use BRSystems\Core\Library\cValidator\cValidator;
use BRSystems\Core\Library\cApc\cCacheHelper;
use Exception;
class indexController extends cCore
{
public $dir;
public $name;
public $module;
private $post;
public $sScrollTo = '';
/** @var cCacheHelper */
private $cache;
const IMG_ASSETS_DEFAULT_SLIDER = '/img/assets/slider-1.jpg';
const IMG_ASSETS_DEFAULT_SLIDER_MOB = '/img/assets/slider-mobile1.jpg';
const IMG_ASSETS_DEFAULT_CAT = '/img/assets/cat-1.jpg';
const IMG_ASSETS_DEFAULT_SERVICE = '/img/assets/service-1.png';
const IMG_ASSETS_DEFAULT_TESTIMONIAL = '/img/assets/testimonial/testi-1.jpg';
const IMG_ASSETS_DEFAULT_TESTIMONIAL_BG = '/img/assets/testimonial-bgimg.png';
const IMG_DEFAULT_BREADCRUMBS_BG = '/img/assets/other/base_cat_bg.png';
const IMG_DEFAULT_COLLECTION_BANNER = '/img/assets/collection/collection-banner.jpg';
const IMG_DEFAULT_POPUP_BG = '/img/assets/newsletter/newsletter-popup.jpg';
public function __construct($uriData, $dir, $name)
{
$this->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 <info@brsystems.lv>
* @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 <mareks.keiss@brsystems.lv>
* @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 <mareks.zukovskis@gmail.com>
* @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 <mareks.zukovskis@gmail.com>
* @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;
}
}