• Как вывести опции товара в корзине?

    dv1zhok
    @dv1zhok Автор вопроса
    Freelancer
    Антон Р. Pashok Doom Спасибо за советы!
    Получилось реализовать сделав следующее:
    1. Вносим изменения в контроллер /checkout/cart.php:
    Перед строкой:
    if ($this->cart->hasProducts() || !empty($this->session->data['vouchers'])) {

    Добавляем:
    $this->load->model('catalog/product');

    Далее после строки:
    $option_data = array();
    Добавляем код:
    $product_options = array();
                    $product_info = $this->model_catalog_product->getProduct($product['product_id']);
    
                    foreach ($this->model_catalog_product->getProductOptions($product['product_id']) as $option) {
                        $product_option_value_data = array();
    
                        foreach ($option['product_option_value'] as $option_value) {
                            if (!$option_value['subtract'] || ($option_value['quantity'] > 0)) {
                                if ((($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) && (float)$option_value['price']) {
                                    $price = $this->currency->format($this->tax->calculate($option_value['price'], $product_info['tax_class_id'], $this->config->get('config_tax') ? 'P' : false), $this->session->data['currency']);
                                } else {
                                    $price = false;
                                }
    
                                $product_option_value_data[] = array(
                                    'product_option_value_id' => $option_value['product_option_value_id'],
                                    'option_value_id' => $option_value['option_value_id'],
                                    'name' => $option_value['name'],
                                    'image' => $option_value['image'] ? $this->model_tool_image->resize($option_value['image'], 16, 16) : '',
                                    'price' => $price,
                                    'price_raw' => round($option_value['price']),
                                    'price_prefix' => $option_value['price_prefix']
                                );
                            }
                        }
    
                        $product_options[] = array(
                            'product_option_id' => $option['product_option_id'],
                            'product_option_value' => $product_option_value_data,
                            'option_id' => $option['option_id'],
                            'name' => $option['name'],
                            'type' => $option['type'],
                            'value' => $option['value'],
                            'required' => $option['required']
                        );
                    }


    В массив:
    $data['products'][] = array(

    Добавляем:
    'options' => $product_options,

    Находим строки:
    foreach ($this->request->post['quantity'] as $key => $value) {
      $this->cart->update($key, $value);
    }


    Заменяем на:
    $this->cart->update($this->request->post['key'], $this->request->post['quantity'], $this->request->post['option']);


    Во вьюхе /checkout/cart.tpl выводим опции так же, как они выводятся на странице товара.

    Далее нужно отредактировать JS файл, отвечающий за обновление данных корзины, а конкретно функцию update, что бы выглядела следующим образом:
    'update': function(key, quantity, option) {
            $.ajax({
                url: 'index.php?route=checkout/cart/edit',
                type: 'post',
                data: 'key=' + key + '&quantity=' + (typeof(quantity) != 'undefined' ? quantity : 1) + '&option=' + option,
                dataType: 'json',
                beforeSend: function() {
                    $('#cart > button').button('loading');
                },
                complete: function() {
                    $('#cart > button').button('reset');
                },
                success: function(json) {
                    // Need to set timeout otherwise it wont update the total
                    setTimeout(function () {
                        $('#cart > button').html('<span id="cart-total"><i class="fa fa-shopping-cart"></i> ' + json['total'] + '</span>');
                    }, 100);
    
                    if (getURLVar('route') == 'checkout/cart' || getURLVar('route') == 'checkout/checkout') {
                        location = 'index.php?route=checkout/cart';
                    } else {
                        $('#cart > ul').load('index.php?route=common/cart/info ul li');
                    }
                },
                error: function(xhr, ajaxOptions, thrownError) {
                    alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
                }
            });
        },

    Отредактировать JS код, передающий параметры функции cart.update, что бы так же передавались опции.

    И отредактировать запрос в базу, (файл system/library/cart/cart.php) отвечающий за обновление данных в корзине. Изначально он выглядит так:
    public function update($cart_id, $quantity) {
    		$this->db->query("UPDATE " . DB_PREFIX . "cart SET quantity = '" . (int)$quantity . "' WHERE cart_id = '" . (int)$cart_id . "' AND api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "'");
    	}

    Меняем на:
    public function update($cart_id, $quantity, $option) {
    		$this->db->query("UPDATE " . DB_PREFIX . "cart SET quantity = '" . (int)$quantity . "', `option` = '" . $this->db->escape(json_encode($option)) . "' WHERE cart_id = '" . (int)$cart_id . "' AND api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "'");
    	}


    Этого достаточно для вывода и обновлений опций товара в таблице корзины вашей базы данных.

    Для обновления корзины нужно писать еще код, но т.к. у меня все кастомное, то он не подойдет к стандартным файлам opencart/ocstore.
    Ответ написан
    Комментировать
  • Как развить навык разбиения сущностей на абстракции?

    Zoominger
    @Zoominger Куратор тега IT-образование
    System Integrator
    Знакомое состояние, сталкивался с ним на заре погромиста.
    Ответ: практика. Больше практики. Ещё больше практики.
    Любое обучение и прокачка мозгов - это механическое повторение тех или иных кейсов, никакой новой техники не существует.
    Ответ написан
    Комментировать
  • Почему программисту нужен английский?

    kshnkvn
    @kshnkvn
    yay ✌️ t.me/kshnkvn
    Как минимум для того, что-бы при сообщении вроде:
    Running as root without --no-sandbox is not supported.

    не бежать на форум за помощью.
    действительно ли американские туториалы и спецификации лучше русскоязычных ?

    Да, потому что английский язык в сфере IT - это "оригинальный" язык. Даже если отбросить фактор перевода, который очень часто может сильно ухудшить качество материала, то остается фактор актуальности, так как перевод занимает не 1 день, а с учетом того, как быстро технологии умеют развиваться, то некоторые книги, или документация к моменту перевода уже могут быть не актуальными.
    Ответ написан
    5 комментариев
  • Куда уйти из системных администраторов?

    Robur
    @Robur
    Знаю больше чем это необходимо
    куда-нибудь туда, где вам привьют психологическую самостоятельность.

    Вам серьезно требуется чтобы кто-то вам дал добро на то чтобы "попробовать себя в управлении проектами"?
    Хотите - встаньте и попробуйте.

    Если у вас разные страхи, неуверенность, неспособность что-то поменять, которые не дают встать и попробовать, то это к психотерапевту.
    Если вам не дают встать и попробовать обязательства, ипотека, жена, трое детей и собака, то создавайте финансовую подушку и пробуйте новое "в свободное от работы время".
    Ответ написан
    5 комментариев
  • Что означают такие языковые конструкции как Post::class, PostType::class и так далее?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Начиная с PHP версии 5.5 ключевое слово ::class используется для разрешения имени класса. Это означает, что оно возвращает полное имя класса, что особенно полезно, при работе с длинными именами классов. Это тоже самое, что self::class self означает текущий, а Post::class используется для получение имени класса поста.
    Ответ написан
    5 комментариев
  • Архитектура приложения. Как сделать независимые модули (сервисы)?

    myks92
    @myks92 Куратор тега Yii
    Нашёл решение — пометь вопрос ответом!
    По этому вопросу очень долго искал ответа))
    Вам уже скинули статью по независимым модулям, но этого мало. Что вам нужно:

    1. Независимый слой MODEL.
    В этой папке находятся Use Case (Service), Сама сущность Entity (AR), Желательно иметь репозитории для изоляции от базы данных ну и другой доменный слой логики, который не зависит ни от чего. Ни от фреймворка, ни от других модулей и пакетов. Ваша задача написать код в этой части так, чтобы его можно было скопировать в любую папку, настроить зависимости и чтобы этот код заработал хоть на чистом PHP. Если не планируете менять фреймворк, то можно зависить от фреймворка.

    2. Зависимости
    Все зависимости модуля реализовать либо через Interface либо через события, но события лучше. А дальше уже синхронизируйте через приложение или отдельный модуль. Можно и по api.

    3. UI (пользовательский интерфейс)
    Он может быть зависимым от других модулей. В него входят: контроллеры, view, формы, vue.js и так далее. В общем то, с чем взаимодействует пользователь.

    Тем самым получается такая система если опираться на MVC:
    VC - могут быть зависимы от других модулей
    M - не может быть зависима ни от чего, кроме PHP. Желательно и отделять слой базы данных с помощью Repository. Тогда ваш пакет будет очень сильно независим даже от базы. И вам вообще будет без разницы куда вы это храните в user или employee.

    Если будет такой слой, то можно спокойно переносить хоть на будущий Yii3. Однако На Yii1 и Yii2 такое сделать сложно. Надо изворачиваться и займет это больше времени. Так как сам Фреймворк вставляет нам палки и приходится делать костыли из-за его монолитности. К такому подходу не привыкли Yii1 и Yii2 разработчики. Обычно на Yii такое понимание «фигак, фигак и в продакшн».

    Такую архитектуру удобно будет строить на Symfony ну и будущем Yii3.

    Рекомендую к прочтению:
    Ответ написан
    7 комментариев
  • Нужен ли красный диплом?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Важны только знания. Корочка нужна только для галочки, да и то далеко не всегда. В неё никто никогда не заглянет.

    Главное - не слушать тех, кто потратил пять лет жизни, но так и не нашёл способа применить полученные знания, а теперь обижается, что ПТУшники способы делать ту же работу и получать те же деньги.
    Ответ написан
    3 комментария
  • Как решить проблему с URL в пагинации?

    SeaInside
    @SeaInside
    15 лет пилю все эти штуки
    У вас вся ошибка в том, что вопросительным знаком обозначается только начало GET-параметров, а не каждый из них. Параметры разделяются амперсандом.
    // categorie.php?id=2&page=25
    echo $_GET['id'] // 2
    echo $_GET['page'] // 25

    И category всё-таки, а не categorie.
    Ответ написан
    3 комментария
  • Как вывести PHP переменную?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Как вывести PHP переменную?

    Ждем вопросов как включить компьютер
    Ответ написан
    Комментировать
  • Можно ли использовать шрифт Futura для интернет-магазина?

    @n1ksON
    мидл
    Тут бесплатная библиотека шрифтов - https://fonts.google.com/.
    Тут можете почитать как правильно их выбирать и сочетать.
    Ответ написан
    5 комментариев
  • Какую платформу изучить для вебсайтов?

    bersus
    @bersus
    https://bersus.design
    Если 80% заявок по WP - вот и ответ на вопрос, что же нужно изучать.

    WordPress медленный. Toyota надёжная. Land Rover ломается.
    Стереотипы. Это не всегда так, все зависит от конкретных условий.
    Ответ написан
    1 комментарий
  • Как узнать, что в данный момент хранит поле формы входа?

    coderisimo
    @coderisimo Куратор тега JavaScript
    Вот простейший пример. ОНО
    Это песочница с кодом. Можно разбираться, как это работает, менять код и смотреть, что будет происходить Вникайте.

    вот весь материал. JavaScript Form Validation
    Ответ написан
    6 комментариев
  • Не работает php в html?

    Nolis
    @Nolis
    it-гопник
    php и не должен работать в html
    Ответ написан
    Комментировать
  • Что такое инверсия зависимостей в python?

    Ranc58
    @Ranc58
    Backend python developer
    По сути - как и везде. Пример- У бизнесс логики не должно быть зависимостей от конкретных реализаций. Сегодня у вас все хранится в постгрес а завтра в монге. Инверсия зависимостей позволяет более менее безболезненно совершить такой переезд, так как слой бизнесс логики понятия не имеет где вы храните данные. Ниже накидал грубый но вроде понятный кусок кода. Есть некая сущность блог, к которой можно добавлять пользователей и смотреть их. Блог должен откуда то тянуть данные и где то хранить их. Мы создаем некий интерфейс DBInterface ,который имеет стандартные методы добавить/удалить данные. Далее создаем класс SQLdb который реализует этот интерфейс.

    В самом классе блога мы реализуем функции получения/добавления пользователей без привязки к конкретной системе хранения: просто создаем экземпляр класса SQLdb и экземпляр класса Blog , передавая туда sqldb. Когда мы захотим переехать на монгу - нам не надо будет трогать класс блога. Мы всего лишь реализуем класс Mongodb для новой базы и будем опрокидывать его в блог вместо sqldb. Итог - блог не зависит от системы хранения вообще.
    Пример сильно упрощен и утрирован, но для понимания как оно работает думаю сойдет)

    from abc import ABC, abstractmethod
    import random
    
    
    class DBInterface(ABC):
    
        @abstractmethod
        def insert(self, data):
            pass
    
        @abstractmethod
        def get(self, id):
            pass
    
    
    class SQLdb(DBInterface):
    
        def insert(self, data):
            print(f"inserted {data} from mysql")
            return random.randint(0, 100)
    
        def get(self, id):
            print(f"get user {id} data from mysql")
            return {'id': id, "data": "some_data"}
    
    
    class Mongodb(DBInterface):
    
        def insert(self, data):
            print(f"inserted {data} from mongo")
            return random.randint(0, 100)
    
        def get(self, id):
            print(f"get user {id} data from mongo")
            return {'id': id, "data": "some_data"}
    
    
    class Blog:
    
        def __init__(self, db, blog_id):
            self.db = db
            self.blog_id = blog_id
    
        def add_user(self, name):
            self.db.insert(name)
    
        def get_users(self):
            return self.db.get(self.blog_id)
    
    
    if __name__ == '__main__':
        sql_db = SQLdb()
        mongo_db = Mongodb()
    
        blog_with_sql = Blog(db=sql_db, blog_id=1)
        blog_with_sql.add_user("test") # Выведет inserted test from mysql
    
        blog_with_mongo = Blog(db=mongo_db, blog_id=1)
        blog_with_mongo.add_user("test") # Выведет inserted test from mongo
    Ответ написан
    2 комментария
  • Как добавить несколько имён файлов в БД?

    Reexel
    @Reexel
    public function uploadImages(){
            if($this->images) {
                $filesName = [];
                foreach ($this->images as $file) {
                    $filename=Yii::$app->getSecurity()->generateRandomString(15);
                    if ($file->saveAs('uploads/images/products/source/' . $filename . '.' . $file->extension)){
                        $filesName[] = $filename;
                    }
                }
                return $filesName;
            }else {
                return false;
            }
        }


    if ($model->load(Yii::$app->request->post()) && $model->save()) {
                $model->images = UploadedFile::getInstances($model, 'images');
    
                if ($filenames= $model->uploadImages()) {
                    $model->product_id = $id;
                    if($filenames && $model->save()) {
                         foreach($filenames as $filename) {
                               $modelImage = new Image();
                               $modelImage->name = $filename;
                               $modelImage->item_id = $model->id;
    
                               ... записываем еще свойства объекта картинки
    
                               if($modelImage->save()) {
                                        Yii::$app->session->setFlash('success', "Товар {$model->name} обновлён");
                               }
                          }
                    }
                }
            }


    По коду не совсем понятно, какие модели и как сформированы (поэтому в код может быть не совсем корректен). В общем идея такая: собираем в массив названия картинок и передаем его. Затем в модели картинок записываем эти файлы после сохранения модели товара (необходимо для наличия id товара.
    Ответ написан
    Комментировать
  • Как тренироваться кодить на Python?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Просто берите учебник, читайте полностью, попутно экспериментируя с примерами из книги. Обязательно примеры набирать самостоятельно, а не копировать. Обязательно пытаться их изменять, чтобы убедиться, что вы действительно понимаете, как они работают. После прочтения попытайтесь набомбить пет-проект с использованием изученных технологий.

    Если где-то застрянете, перечитывайте соответствующие главы, читайте официальную документацию, ищите ответы в гугле. Ни в коем случае не несите свою проблему другим людям до тех пор, пока не потратили хотя бы пару-тройку дней на поиск решения. Если ответы вам будет давать кто-то другой, программировать вы не научитесь.

    И не используйте IDE на этапе обучения. Применяйте обычный текстовый редактор и консоль. Во-первых, IDE избавляет вас от рутинных операций, но именно рутинные операции позволяют набить руку . Во-вторых, IDE скрывает многие процессы, выполняя их за программиста, но именно они позволяют понять базовые принципы.
    Ответ написан
    Комментировать
  • Паттерны проектирования в популярных Open Source проектах?

    @NinjaNickName
    Web разработчик
    Вот такая клевая ссылка есть https://refactoring.guru/ru/design-patterns
    Ответ написан
    Комментировать
  • Как в Yii2 после добавления данных очистить форму и вывести flash сообщение на той же странице без повторной отправки?

    @Nc_Soft
    Нужно сделать редирект после записи формы, чтобы скинуть post. А в сессии останется flash сообщение.
    Ответ написан
    Комментировать