Делаем корзину покупок с помощью Codeigniter и JQuery. Часть 4.

С Codeigniter поставляется готовый модуль для работы с корзиной покупок - Cart (документация). Он позволяет решить основные задачи, положеные на корзину в интернет магазине. Давайте разберём как с ним работать и реализуем уже полноценную работу с корзиной, но пока без AJAX.

В начале разработки корзины мы добавили в автозагрузку библиотеку cart. Это и есть корзина, методы которой будут доступны во всех контроллерах. Добавим возможность добавлять товары в корзину. Как это будет происходить:

  • Пользователь нажимает на кнопку "Купить".
  • Отправляется POST запрос на сервер с product_id товара.
  • Сервер проверяет, есть ли такой товар (потому что можно отправить что угодно, а мы делаем качественную корзину).
  • Если такой товар есть, то получаем его название, цену.
  • Добавляем товар в корзину.

Важно не доверять тем данным, которые приходят от клиента, ведь их можно легко подделать!

Давайте напишем метод в контроллере cart для добавления товара в корзину. Для этого в файле application/controllers/cart.php добавьте новый метод add_to_cart(). Если посмотреть на шаблон вывода сетки товаров, который мы создавали в третьей части, то можно увидеть, что action формы добавленая товара в корзину как раз и ведёт к контроллеру cart и методу add_to_cart().

<?php print form_open('cart/add_to_cart'); ?>
<input type="hidden" name="product_id" value="<?php print $item['id']; ?>"/>
<input type="submit" name="add-to-cart" value="Купить"/>
<?php print form_close(); ?>

Метод принимает через массив $_POST id товара, который необходимо добавить в корзину.

application/controllers/cart.php

/**
 * Добавление товара в корзину
 */
public function add_to_cart()
{
    // Получаем id добавляемого продукта
    $product_id = $this->input->post('product_id', true);

    // Проверяем тип запроса. Если true, то запрос передан с помощью
    // AJAX, если false то обычный POST запрос
    $is_ajax = $this->input->is_ajax_request();

    // Массив с результатами работы скрипта
    $result = array(
        'status' => 'error',
        'message' => 'Переданы неверные данные',
    );

    // Если $product_id не пустой
    if ($product_id)
    {
        // Получает данные товара
        $product_data = $this->cart_model->get_product($product_id);

        // Если товар существует
        if ($product_data) {
            $this->cart->insert(array(
                'id' => $product_id,
                'qty' => 1,
                'price' => $product_data['price'],
                'name' => $product_data['name'],
            ));

            $result = array(
                'status' => 'success',
                'message' => 'Товар добавлен в корзину',
            );
        } else {
            $result = array(
                'status' => 'error',
                'message' => 'Такого товара не существует',
            );
        }
    }

    if ($is_ajax) {
        // Если был AJAX запрос, возвращаем JSON ответ
        $this->output->set_content_type('application/json');
        $this->output->set_output(json_encode($result));
    } else {
        // Выводим сообщение
        $this->session->set_flashdata('message', $result);

        // Редирект на страницу с товарами
        redirect(base_url());
    }
}

С помощью $this->input->is_ajax_request() проверяем, как был вызван этот метод: простой отправкой формы или с помощью ajax. В зависимости от этого мы по-разному будет возвращать результат: редирект на страницу с выводом сообщения или возвращать JSON ответ, который с помощью javascript выводится пользователю.

В методе добавления товара используется проверка на существование добавляемого товара.

$this->cart_model->get_product($product_id);

Для этого мы делаем запрос к БД и возвращаем данные товара, который необходимо добавить. Если данных нет, значит и такого товара нет, т.е. произошла какая то ошибка или пользователь специально подделал данные и отправил, ну или товар был удалён smiley. Давайте напишем метод получения товара из БД в модели cart_model.

/**
 * Получает товар магазина
 * @param $product_id
 * @return mixed
 */
public function get_product($product_id)
{
    return $this->db->where('id', $product_id)
        ->get('products')
        // Результат в виде ассоциативного массива
        ->row_array();
}

С помощью библиотеки session (которую мы добавили в автозагрузку в первой статье) мы можем выводить сообщения для пользователя. Для этого используем метод set_flashdata().

$this->session->set_flashdata('message', $result);

Он позволяет кратковременно добавить данные в сессию. При следующей загрузке страницы этих данных уже не будет.

Теперь немного изменим метод index() контроллера cart, который выводит главную страницк нашего приложения. Добавим туда вывод сообщений пользователю.

application/controllers/cart.php

/**
 * Выводит товары и корзину
 */
public function index()
{
    ...
    ...

    // Сообщения пользователю
    $data['messages'] = '';

    // Получаем сообщения из сессии и выводим их пользователю
    if ($message = $this->session->flashdata('message'))
    {
        $data['messages'] = '<div class="message-' . $message['status'] . '">' . $message['message'] . '</div>';
    }

    // Выводим основной шаблон
    $this->load->view('template', $data);
}

Здесь всё просто. Если есть сообщения в сессии, то получаем их и передаёт основному шаблону, в котором мы их и показываем.

application/views/template.php

...
<div class="content">
        <?php // Выводим сообщения пользователю ?>
        <?php print $messages; ?>
        ...
</div>
...

При следующей загрузке страницы сообщение не покажется, т.к. данные добавлены кратковременно с помощью метода set_flashdata().

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

Теперь добавление в корзину работает. При нажатии на кнопку "Купить" страница перезагружается и выводится сообщение о том, что товар добавлен в корзину.

ci_add_to_cart.jpg

Вы можете заметить, что хоть мы и добавили товар в корзину, всё равно написано, что "В корзине нет товаров". Здесь ошибки нет, потому что мы еще не дописали функционал вывода корзины пользователю.

Следующим шагом будет вывод всех товаров в корзине покупок пользователя. Это будем делать в методе index() контроллера cart. Но так как статья получилась и так большой, сделаем это в следующей части.