diff --git a/public/store/controller/product/product.php b/public/store/controller/product/product.php index 223ab4b..019f8cb 100644 --- a/public/store/controller/product/product.php +++ b/public/store/controller/product/product.php @@ -375,11 +375,23 @@ $data['price_n'] = $product_info['price']; $results = $this->model_catalog_product->getProductRelated($this->request->get['product_id']); + if (!$results) { + $results = $this->model_catalog_product->getRandomProductsFromSameCategories($this->request->get['product_id'], 4); + } + foreach ($results as $result) { if ($result['image']) { - $image = $this->model_tool_image->resize($result['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_related_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_related_height')); + $image = $this->model_tool_image->resize($result['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height')); } else { - $image = $this->model_tool_image->resize('placeholder.png', $this->config->get('theme_' . $this->config->get('config_theme') . '_image_related_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_related_height')); + $image = $this->model_tool_image->resize('placeholder.png', $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height')); + } + + $product_images = $this->model_catalog_product->getProductImages($result['product_id']); + + if ($product_images) { + $additional_image = $this->model_tool_image->resize($product_images[0]['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height')); + } else { + $additional_image = false; } if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) { @@ -408,17 +420,57 @@ $data['price_n'] = $product_info['price']; $rating = false; } + $rent_prices = array_filter([$result['price'], $result['price_2']], function($price) { + return (float)$price > 0; + }); + + $min_price = $rent_prices ? min($rent_prices) : 0; + $data['products'][] = array( - 'product_id' => $result['product_id'], + 'product_id' => $result['product_id'], + 'thumb' => $image, + 'additional_thumb' => $additional_image, + 'name' => $result['name'], + 'description' => utf8_substr(trim(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8'))), 0, $this->config->get('theme_' . $this->config->get('config_theme') . '_product_description_length')) . '..', + 'price' => $price, + 'price_n' => $result['price'], + 'price_2' => $this->currency->format($this->tax->calculate($result['price_2'], $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']), + 'price_2_n' => $result['price_2'], + 'price_3' => $this->currency->format($this->tax->calculate($result['price_3'], $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']), + 'price_3_n' => $result['price_3'], + 'min_price' => $this->currency->format($this->tax->calculate($min_price, $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']), + 'special' => $special, + 'tax' => $tax, + 'minimum' => $result['minimum'] > 0 ? $result['minimum'] : 1, + 'rating' => $rating, + 'href' => $this->url->link('product/product', 'product_id=' . $result['product_id']) + ); + } + + $this->load->model('blog/article'); + + $data['articles'] = array(); + + $results = $this->model_blog_article->getArticleRelatedByProduct(array( + 'product_id' => $this->request->get['product_id'], + 'limit' => 3 + )); + + foreach ($results as $result) { + if ($result['image']) { + $image = $this->model_tool_image->resize($result['image'], $this->config->get('configblog_image_article_width'), $this->config->get('configblog_image_article_height')); + } else { + $image = $this->model_tool_image->resize('placeholder.png', $this->config->get('configblog_image_article_width'), $this->config->get('configblog_image_article_height')); + } + + $data['articles'][] = array( + 'article_id' => $result['article_id'], 'thumb' => $image, 'name' => $result['name'], - 'description' => utf8_substr(trim(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8'))), 0, $this->config->get('theme_' . $this->config->get('config_theme') . '_product_description_length')) . '..', - 'price' => $price, - 'special' => $special, - 'tax' => $tax, - 'minimum' => $result['minimum'] > 0 ? $result['minimum'] : 1, - 'rating' => $rating, - 'href' => $this->url->link('product/product', 'product_id=' . $result['product_id']) + 'description' => utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, $this->config->get('configblog_article_description_length')) . '..', + 'date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])), + 'viewed' => $result['viewed'], + 'href' => $this->url->link('blog/article', 'article_id=' . $result['article_id']) ); } diff --git a/public/store/controller/tool/callback.php b/public/store/controller/tool/callback.php index 5872429..4c2a0e5 100644 --- a/public/store/controller/tool/callback.php +++ b/public/store/controller/tool/callback.php @@ -6,15 +6,47 @@ class ControllerToolCallback extends Controller { $json = array(); $json['error'] = []; - - - - if($this->request->post['product_id']){ + + $telephone = isset($this->request->post['telephone']) && is_scalar($this->request->post['telephone']) ? trim((string)$this->request->post['telephone']) : ''; + + if (utf8_strlen($telephone) < 3 || utf8_strlen($telephone) > 32) { + $json['error'][] = 'Укажите номер телефона.'; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($json)); + + return; + } + + $data['request_type'] = isset($this->request->post['request_type']) ? $this->request->post['request_type'] : ''; + $data['fitting_room_products'] = array(); + + if ($data['request_type'] == 'fitting_room') { + $data['fitting_room_products'] = $this->getFittingRoomProducts(); + + if (!$data['fitting_room_products']) { + $json['error'][] = 'Ваша примерочная пуста. Добавьте хотя бы одно платье и попробуйте снова.'; + + $this->response->addHeader('Content-Type: application/json'); + $this->response->setOutput(json_encode($json)); + + return; + } + } + + if (isset($this->request->post['product_id']) && $this->request->post['product_id']) { $this->load->model('catalog/product'); $data['product_info'] = $this->model_catalog_product->getProduct($this->request->post['product_id']); } + + $this->load->model('localisation/zone'); + + $zone_id = isset($this->session->data['city_id']) ? (int)$this->session->data['city_id'] : (int)$this->config->get('config_zone_id'); + $zone = $this->model_localisation_zone->getZone($zone_id); + + $data['city'] = $zone ? $zone['name'] : ''; $data['config_name'] = $this->config->get('config_name'); $data['post'] = $this->request->post; @@ -53,6 +85,38 @@ class ControllerToolCallback extends Controller { $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } + + private function getFittingRoomProducts() { + $product_ids = array(); + + if ($this->customer->isLogged()) { + $this->load->model('account/wishlist'); + + foreach ($this->model_account_wishlist->getWishlist() as $result) { + $product_ids[] = (int)$result['product_id']; + } + } elseif (isset($this->session->data['wishlist']) && is_array($this->session->data['wishlist'])) { + $product_ids = array_map('intval', $this->session->data['wishlist']); + } + + $this->load->model('catalog/product'); + + $products = array(); + + foreach (array_unique($product_ids) as $product_id) { + $product_info = $this->model_catalog_product->getProduct($product_id); + + if ($product_info) { + $products[] = array( + 'name' => $product_info['name'], + 'model' => $product_info['model'], + 'href' => $this->url->link('product/product', 'product_id=' . (int)$product_id) + ); + } + } + + return $products; + } private function sendTG($message){ @@ -91,4 +155,4 @@ class ControllerToolCallback extends Controller { return $response; } -} \ No newline at end of file +} diff --git a/public/store/language/ru-ru/account/account.php b/public/store/language/ru-ru/account/account.php index 78449d7..0401993 100644 --- a/public/store/language/ru-ru/account/account.php +++ b/public/store/language/ru-ru/account/account.php @@ -15,7 +15,7 @@ $_['text_edit'] = 'Изменить контактную информа $_['text_password'] = 'Изменить свой пароль'; $_['text_address'] = 'Изменить мои адреса'; $_['text_credit_card'] = 'Управление сохраненными кредитными картами'; -$_['text_wishlist'] = 'Изменить закладки'; +$_['text_wishlist'] = 'Виртуальная примерочная'; $_['text_order'] = 'История заказов'; $_['text_download'] = 'Файлы для скачивания'; $_['text_reward'] = 'Бонусные баллы'; @@ -26,4 +26,4 @@ $_['text_recurring'] = 'Регулярные платежи'; $_['text_transactions'] = 'Операции'; $_['text_affiliate_add'] = 'Зарегистрировать партнерский аккаунт'; $_['text_affiliate_edit'] = 'Изменить партнерскую информацию'; -$_['text_tracking'] = 'Код отслеживания партнеров'; \ No newline at end of file +$_['text_tracking'] = 'Код отслеживания партнеров'; diff --git a/public/store/language/ru-ru/account/login.php b/public/store/language/ru-ru/account/login.php index 9090bfc..009bf78 100644 --- a/public/store/language/ru-ru/account/login.php +++ b/public/store/language/ru-ru/account/login.php @@ -10,7 +10,7 @@ $_['text_account'] = 'Аккаунт'; $_['text_login'] = 'Авторизация'; $_['text_new_customer'] = 'Новый покупатель'; $_['text_register'] = 'Регистрация'; -$_['text_register_account'] = 'Создание учётной записи поможет делать покупки быстрее и удобнее. Вы также сможете отслеживать статус своего заказа, пользоваться закладками, видеть свои предыдущие заказы или получить скидку как наш постоянный покупатель.'; +$_['text_register_account'] = 'Создание учётной записи поможет делать покупки быстрее и удобнее. Вы также сможете отслеживать статус своего заказа, пользоваться виртуальной примерочной, видеть свои предыдущие заказы или получить скидку как наш постоянный покупатель.'; $_['text_returning_customer'] = 'Постоянный покупатель'; $_['text_i_am_returning_customer'] = 'Я совершал здесь покупки ранее и регистрировался'; $_['text_forgotten'] = 'Забыли пароль?'; @@ -22,4 +22,4 @@ $_['entry_password'] = 'Пароль'; // Error $_['error_login'] = 'Не найден введённый адрес E-Mail и/или пароль указан неправильно.'; $_['error_attempts'] = 'Ваша учетная запись превысила допустимое количество попыток входа в систему. Пожалуйста, попробуйте еще через 1 час.'; -$_['error_approved'] = 'Вы сможете войти после проверки учётной записи администрацией магазина.'; \ No newline at end of file +$_['error_approved'] = 'Вы сможете войти после проверки учётной записи администрацией магазина.'; diff --git a/public/store/language/ru-ru/common/footer.php b/public/store/language/ru-ru/common/footer.php index 4d6b551..cf27f60 100644 --- a/public/store/language/ru-ru/common/footer.php +++ b/public/store/language/ru-ru/common/footer.php @@ -19,6 +19,6 @@ $_['text_bestseller'] = 'Хиты Продаж'; $_['text_mostviewed'] = 'Популярные Товары'; $_['text_account'] = 'Личный кабинет'; $_['text_order'] = 'История заказов'; -$_['text_wishlist'] = 'Закладки'; +$_['text_wishlist'] = 'Виртуальная примерочная'; $_['text_newsletter'] = 'Рассылка'; $_['text_powered'] = 'Работает на ocStore
%s © %s'; diff --git a/public/store/language/ru-ru/common/header.php b/public/store/language/ru-ru/common/header.php index 9ad9f7d..ccf5364 100644 --- a/public/store/language/ru-ru/common/header.php +++ b/public/store/language/ru-ru/common/header.php @@ -4,7 +4,7 @@ // Text $_['text_home'] = 'Главная'; -$_['text_wishlist'] = 'Закладки (%s)'; +$_['text_wishlist'] = 'Примерочная (%s)'; $_['text_shopping_cart'] = 'Корзина'; $_['text_category'] = 'Категории'; $_['text_account'] = 'Личный кабинет'; @@ -15,4 +15,4 @@ $_['text_transaction'] = 'Операции'; $_['text_download'] = 'Файлы для скачивания'; $_['text_logout'] = 'Выход'; $_['text_checkout'] = 'Оформление заказа'; -$_['text_search'] = 'Поиск'; \ No newline at end of file +$_['text_search'] = 'Поиск'; diff --git a/public/store/language/ru-ru/extension/module/account.php b/public/store/language/ru-ru/extension/module/account.php index 4949b05..5ae4729 100644 --- a/public/store/language/ru-ru/extension/module/account.php +++ b/public/store/language/ru-ru/extension/module/account.php @@ -14,11 +14,11 @@ $_['text_account'] = 'Моя информация'; $_['text_edit'] = 'Изменить контактную информацию'; $_['text_password'] = 'Пароль'; $_['text_address'] = 'Список контактов'; -$_['text_wishlist'] = 'Закладки'; +$_['text_wishlist'] = 'Виртуальная примерочная'; $_['text_order'] = 'История заказов'; $_['text_download'] = 'Файлы для скачивания'; $_['text_reward'] = 'Бонусные баллы'; $_['text_return'] = 'Возвраты'; $_['text_transaction'] = 'Платежи'; $_['text_newsletter'] = 'E-Mail рассылка'; -$_['text_recurring'] = 'Регулярные платежи'; \ No newline at end of file +$_['text_recurring'] = 'Регулярные платежи'; diff --git a/public/store/language/ru-ru/product/product.php b/public/store/language/ru-ru/product/product.php index 9b61f32..ca629c2 100644 --- a/public/store/language/ru-ru/product/product.php +++ b/public/store/language/ru-ru/product/product.php @@ -21,7 +21,8 @@ $_['text_login'] = 'Пожалуйста автори $_['text_no_reviews'] = 'Нет отзывов об этом товаре.'; $_['text_note'] = 'Примечание: HTML разметка не поддерживается! Используйте обычный текст.'; $_['text_success'] = 'Спасибо за ваш отзыв. Он поступил администратору для проверки на спам и вскоре будет опубликован.'; -$_['text_related'] = 'Рекомендуемые товары'; +$_['text_related'] = 'Посмотрите другие предложения'; +$_['text_related_article'] = 'Статьи по теме'; $_['text_tags'] = 'Теги:'; $_['text_error'] = 'Товар не найден!'; $_['text_payment_recurring'] = 'Платежный профиль'; @@ -34,6 +35,7 @@ $_['text_semi_month'] = 'Полмесяца'; $_['text_month'] = 'Месяц'; $_['text_year'] = 'Год'; $_['text_benefits'] = 'Преимущества:'; +$_['button_more'] = 'Подробнее'; // Entry $_['entry_qty'] = 'Кол-во'; @@ -51,4 +53,4 @@ $_['tab_review'] = 'Отзывов (%s)'; // Error $_['error_name'] = 'Имя должно содержать от 3 до 25 символов!'; $_['error_text'] = 'Текст отзыва должен содержать от 25 до 1000 символов!'; -$_['error_rating'] = 'Пожалуйста, выберите оценку!'; \ No newline at end of file +$_['error_rating'] = 'Пожалуйста, выберите оценку!'; diff --git a/public/store/language/ru-ru/ru-ru.php b/public/store/language/ru-ru/ru-ru.php index b2d5bc4..0124c7e 100644 --- a/public/store/language/ru-ru/ru-ru.php +++ b/public/store/language/ru-ru/ru-ru.php @@ -29,7 +29,7 @@ $_['button_continue'] = 'Продолжить'; $_['button_cart'] = 'Купить'; $_['button_cancel'] = 'Отмена'; $_['button_compare'] = 'В сравнение'; -$_['button_wishlist'] = 'В закладки'; +$_['button_wishlist'] = 'В примерочную'; $_['button_checkout'] = 'Оформление заказа'; $_['button_confirm'] = 'Подтверждение заказа'; $_['button_coupon'] = 'Применение купона'; diff --git a/public/store/model/blog/article.php b/public/store/model/blog/article.php index 3a3b5b2..31b6844 100644 --- a/public/store/model/blog/article.php +++ b/public/store/model/blog/article.php @@ -245,12 +245,16 @@ class ModelBlogArticle extends Model { $this->load->model('blog/article'); - $sql = "SELECT * FROM " . DB_PREFIX . "product_related_article np LEFT JOIN " . DB_PREFIX . "article p ON (np.article_id = p.article_id) LEFT JOIN " . DB_PREFIX . "article_to_store p2s ON (p.article_id = p2s.article_id) WHERE np.product_id = '" . (int)$data['product_id'] . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' LIMIT " . (int)$data['limit']; + $sql = "SELECT DISTINCT p.article_id FROM ((SELECT article_id FROM " . DB_PREFIX . "product_related_article WHERE product_id = '" . (int)$data['product_id'] . "') UNION (SELECT article_id FROM " . DB_PREFIX . "article_related_product WHERE product_id = '" . (int)$data['product_id'] . "')) related LEFT JOIN " . DB_PREFIX . "article p ON (related.article_id = p.article_id) LEFT JOIN " . DB_PREFIX . "article_to_store p2s ON (p.article_id = p2s.article_id) WHERE p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' LIMIT " . (int)$data['limit']; $query = $this->db->query($sql); foreach ($query->rows as $result) { - $article_data[$result['article_id']] = $this->model_blog_article->getArticle($result['article_id']); + $article = $this->model_blog_article->getArticle($result['article_id']); + + if ($article) { + $article_data[$result['article_id']] = $article; + } } return $article_data; diff --git a/public/store/model/catalog/product.php b/public/store/model/catalog/product.php index 61664fe..a32595b 100644 --- a/public/store/model/catalog/product.php +++ b/public/store/model/catalog/product.php @@ -398,6 +398,35 @@ class ModelCatalogProduct extends Model return $product_data; } + public function getRandomProductsFromSameCategories($product_id, $limit = 4) + { + $product_data = array(); + $cache = 'product.related.random.' . (int) $this->config->get('config_store_id') . '.' . (int) $product_id . '.' . (int) $limit; + $product_ids = $this->cache->get($cache); + + if (!$product_ids) { + $product_ids = array(); + + $query = $this->db->query('SELECT DISTINCT p.product_id FROM ' . DB_PREFIX . 'product_to_category source_p2c INNER JOIN ' . DB_PREFIX . 'product_to_category related_p2c ON (source_p2c.category_id = related_p2c.category_id) INNER JOIN ' . DB_PREFIX . 'product p ON (related_p2c.product_id = p.product_id) INNER JOIN ' . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) WHERE source_p2c.product_id = '" . (int) $product_id . "' AND p.product_id != '" . (int) $product_id . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int) $this->config->get('config_store_id') . "' ORDER BY RAND() LIMIT " . (int) $limit); + + foreach ($query->rows as $result) { + $product_ids[] = $result['product_id']; + } + + $this->cache->set($cache, $product_ids); + } + + foreach ($product_ids as $related_id) { + $product = $this->getProduct($related_id); + + if ($product) { + $product_data[$related_id] = $product; + } + } + + return $product_data; + } + public function getProductLayoutId($product_id) { $query = $this->db->query('SELECT * FROM ' . DB_PREFIX . "product_to_layout WHERE product_id = '" . (int) $product_id . "' AND store_id = '" . (int) $this->config->get('config_store_id') . "'"); diff --git a/public/store/view/theme/dominik/assets/js/script.js b/public/store/view/theme/dominik/assets/js/script.js index 42d766d..0627b2e 100644 --- a/public/store/view/theme/dominik/assets/js/script.js +++ b/public/store/view/theme/dominik/assets/js/script.js @@ -516,23 +516,27 @@ function citySelect(el){ }); } -function SendRequest(product_id = 0){ - - var params = {}; - params['title'] = product_id ? 'Оставьте заявку' : 'Отправить сообщение'; - params['width'] = 420; - var form = $("
"); - form.append($(product_id ? '

И мы свяжемся с вами, чтобы назначить время примерки платья

' : '

Оставьте своё сообщение и мы свяжемся с Вами для консультации

').addClass('text-center')); - if(product_id){ - form.append($("
").text($(".product-title").text()).addClass('text-center heading mb-4')) - +function SendRequest(product_id = 0, request_type = ''){ + + var params = {}; + var isFittingRoom = request_type == 'fitting_room'; + params['title'] = isFittingRoom ? 'Записаться на примерку' : (product_id ? 'Оставьте заявку' : 'Отправить сообщение'); + params['width'] = 420; + var form = $(""); + form.append($(isFittingRoom ? '

Оставьте номер телефона. Мы получим список выбранных платьев и свяжемся с вами, чтобы назначить время примерки.

' : (product_id ? '

И мы свяжемся с вами, чтобы назначить время примерки платья

' : '

Оставьте своё сообщение и мы свяжемся с Вами для консультации

')).addClass('text-center')); + if(isFittingRoom){ + form.append(''); + } + if(product_id){ + form.append($("
").text($(".product-title").text()).addClass('text-center heading mb-4')) + form.append(''); } form.append('
'); form.append('
'); form.append('
'); - form.append('') + form.append('') params['modal'] = form; diff --git a/public/store/view/theme/dominik/template/mail/request.twig b/public/store/view/theme/dominik/template/mail/request.twig index 2e866c9..6232555 100644 --- a/public/store/view/theme/dominik/template/mail/request.twig +++ b/public/store/view/theme/dominik/template/mail/request.twig @@ -1,12 +1,22 @@ -

{{ config_name }}

-
-{% if product_info %} -
Платье: {{ product_info.name }}
-
Код товара: {{ product_info.model }}
-{% endif %} -{% if post.name %} -
Имя: {{ post.name }}
-{% endif %} +

{{ config_name }}

+
+{% if request_type == 'fitting_room' %} +
Заявка: запись из виртуальной примерочной
+
Платья в примерочной на момент заявки:
+{% for product in fitting_room_products %} +
{{ loop.index }}. {{ product.name }} (код: {{ product.model }})
+{% endfor %} +{% endif %} +{% if product_info %} +
Платье: {{ product_info.name }}
+
Код товара: {{ product_info.model }}
+{% endif %} +{% if city %} +
Город: {{ city }}
+{% endif %} +{% if post.name %} +
Имя: {{ post.name }}
+{% endif %} {% if post.telephone %}
Телефон: {{ post.telephone }}
{% endif %} @@ -14,4 +24,4 @@
Комментарий:
{{ post.comment|nl2br }}
{% endif %}
-
{{ ''|date('d.m.Y H:i:s') }}
\ No newline at end of file +
{{ ''|date('d.m.Y H:i:s') }}
diff --git a/public/store/view/theme/dominik/template/product/product.twig b/public/store/view/theme/dominik/template/product/product.twig index 84dcc0e..2c1beff 100644 --- a/public/store/view/theme/dominik/template/product/product.twig +++ b/public/store/view/theme/dominik/template/product/product.twig @@ -188,6 +188,66 @@
+{% if products %} +
+
+
+ Вам может понравиться +

{{ text_related }}

+
+
+ {% for product in products %} +
+ {% include 'dominik/template/common/product.twig' %} +
+ {% endfor %} +
+
+
+{% endif %} + +{% if articles %} +
+
+
+ Полезно знать +

{{ text_related_article }}

+
+
+ {% for article in articles %} + + {% endfor %} +
+
+
+{% endif %} {{ content_bottom }} {{ footer }} {#