Php сессия корзины не обновляет атрибуты, только количество - PullRequest
0 голосов
/ 04 апреля 2020

Я пытаюсь обновить атрибуты корзины, но я не знаю, почему не работает, количество обновляется просто отлично, но вложенные атрибуты не будут. Я не понимаю, как заставить это работать должным образом при обновлении корзины сессий. Некоторая помощь приветствуется. Спасибо!

Php Полный код класса корзины:

class Cart
{
    /**
     * An unique ID for the cart.
     *
     * @var string
     */
    protected $cartId;

    /**
     * Maximum item allowed in the cart.
     *
     * @var int
     */
    protected $cartMaxItem = 0;

    /**
     * Maximum quantity of a item allowed in the cart.
     *
     * @var int
     */
    protected $itemMaxQuantity = 0;

    /**
     * Enable or disable cookie.
     *
     * @var bool
     */
    protected $useCookie = false;

    /**
     * A collection of cart items.
     *
     * @var array
     */
    private $items = [];

    /**
     * Initialize cart.
     *
     * @param array $options
     */
    public function __construct($options = [])
    {
        if (!session_id()) {
            session_start();
        }

        if (isset($options['cartMaxItem']) && preg_match('/^\d+$/', $options['cartMaxItem'])) {
            $this->cartMaxItem = $options['cartMaxItem'];
        }

        if (isset($options['itemMaxQuantity']) && preg_match('/^\d+$/', $options['itemMaxQuantity'])) {
            $this->itemMaxQuantity = $options['itemMaxQuantity'];
        }

        if (isset($options['useCookie']) && $options['useCookie']) {
            $this->useCookie = true;
        }

        $this->cartId = md5((isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : 'SimpleCart') . '_cart';

        $this->read();
    }

    /**
     * Get items in  cart.
     *
     * @return array
     */
    public function getItems()
    {
        return $this->items;
    }

    /**
     * Check if the cart is empty.
     *
     * @return bool
     */
    public function isEmpty()
    {
        return empty(array_filter($this->items));
    }

    /**
     * Get the total of item in cart.
     *
     * @return int
     */
    public function getTotalItem()
    {
        $total = 0;

        foreach ($this->items as $items) {
            foreach ($items as $item) {
                ++$total;
            }
        }

        return $total;
    }

    /**
     * Get the total of item quantity in cart.
     *
     * @return int
     */
    public function getTotalQuantity()
    {
        $quantity = 0;

        foreach ($this->items as $items) {
            foreach ($items as $item) {
                $quantity += $item['quantity'];
            }
        }

        return $quantity;
    }

    /**
     * Get the sum of a attribute from cart.
     *
     * @param string $attribute
     *
     * @return int
     */
    public function getAttributeTotal($attribute = 'price')
    {
        $total = 0;

        foreach ($this->items as $items) {
            foreach ($items as $item) {
                if (isset($item['attributes'][$attribute])) {
                    $total += $item['attributes'][$attribute] * $item['quantity'];
                }
            }
        }

        return $total;
    }

    /**
     * Remove all items from cart.
     */
    public function clear()
    {
        $this->items = [];
        $this->write();
    }

    /**
     * Check if a item exist in cart.
     *
     * @param string $id
     * @param array  $attributes
     *
     * @return bool
     */
    public function isItemExists($id, $attributes = [])
    {
        $attributes = (is_array($attributes)) ? array_filter($attributes) : [$attributes];

        if (isset($this->items[$id])) {
            $hash = md5(json_encode($attributes));
            foreach ($this->items[$id] as $item) {
                if ($item['hash'] == $hash) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Add item to cart.
     *
     * @param string $id
     * @param int    $quantity
     * @param array  $attributes
     *
     * @return bool
     */
    public function add($id, $quantity = 1, $attributes = [])
    {
        $quantity = (preg_match('/^\d+$/', $quantity)) ? $quantity : 1;
        $attributes = (is_array($attributes)) ? array_filter($attributes) : [$attributes];
        $hash = md5(json_encode($attributes));

        if (count($this->items) >= $this->cartMaxItem && $this->cartMaxItem != 0) {
            return false;
        }

        if (isset($this->items[$id])) {
            foreach ($this->items[$id] as $index => $item) {
                if ($item['hash'] == $hash) {
                    $this->items[$id][$index]['quantity'] += $quantity;
                    $this->items[$id][$index]['quantity'] = ($this->itemMaxQuantity < $this->items[$id][$index]['quantity'] && $this->itemMaxQuantity != 0) ? $this->itemMaxQuantity : $this->items[$id][$index]['quantity'];

                    $this->write();

                    return true;
                }
            }
        }

        $this->items[$id][] = [
            'id'         => $id,
            'quantity'   => ($quantity > $this->itemMaxQuantity && $this->itemMaxQuantity != 0) ? $this->itemMaxQuantity : $quantity,
            'hash'       => $hash,
            'attributes' => $attributes,
        ];

        $this->write();

        return true;
    }

    /**
     * Update item quantity.
     *
     * @param string $id
     * @param int    $quantity
     * @param array  $attributes
     *
     * @return bool
     */
    public function update($id, $quantity = 1, $attributes = [])
    {
        $quantity = (preg_match('/^\d+$/', $quantity)) ? $quantity : 1;

        if ($quantity == 0) {
            $this->remove($id, $attributes);

            return true;
        }

        if (isset($this->items[$id])) {
            $hash = md5(json_encode(array_filter($attributes)));

            foreach ($this->items[$id] as $index => $item) {
                if ($item['hash'] == $hash) {
                    $this->items[$id][$index]['quantity'] = $quantity;
                    $this->items[$id][$index]['quantity'] = ($this->itemMaxQuantity < $this->items[$id][$index]['quantity'] && $this->itemMaxQuantity != 0) ? $this->itemMaxQuantity : $this->items[$id][$index]['quantity'];

                    $this->write();

                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Remove item from cart.
     *
     * @param string $id
     * @param array  $attributes
     *
     * @return bool
     */
    public function remove($id, $attributes = [])
    {
        if (!isset($this->items[$id])) {
            return false;
        }

        if (empty($attributes)) {
            unset($this->items[$id]);

            $this->write();

            return true;
        }
        $hash = md5(json_encode(array_filter($attributes)));

        foreach ($this->items[$id] as $index => $item) {
            if ($item['hash'] == $hash) {
                unset($this->items[$id][$index]);

                $this->write();

                return true;
            }
        }

        return false;
    }

    /**
     * Destroy cart session.
     */
    public function destroy()
    {
        $this->items = [];

        if ($this->useCookie) {
            setcookie($this->cartId, '', -1);
        } else {
            unset($_SESSION[$this->cartId]);
        }
    }

    /**
     * Read items from cart session.
     */
    private function read()
    {
        $this->items = ($this->useCookie) ? json_decode((isset($_COOKIE[$this->cartId])) ? $_COOKIE[$this->cartId] : '[]', true) : json_decode((isset($_SESSION[$this->cartId])) ? $_SESSION[$this->cartId] : '[]', true);
    }

    /**
     * Write changes into cart session.
     */
    private function write()
    {
        if ($this->useCookie) {
            setcookie($this->cartId, json_encode(array_filter($this->items)), time() + 604800);
        } else {
            $_SESSION[$this->cartId] = json_encode(array_filter($this->items));
        }
    }
}

Использование:

  // Include core Cart library
require_once 'class.Cart.php';

// Initialize Cart object
$cart = new Cart([
  // Can add unlimited number of item to cart
  'cartMaxItem'      => 0,

  // Set maximum quantity allowed per item to 99
  'itemMaxQuantity'  => 99,

  // Do not use cookie, cart data will lost when browser is closed
  'useCookie'        => false,
]);

     // Add item with ID #1003 with price, color, and size
        $cart->add('1003', 1, [
         'price'  => '5.99',
         'color'  => 'White',
         'size'   => 'XS',
        ]);

       // Set quantity for item #1003 to 2
         $cart->update('1003', 2, [
          'price'  => '5.99',
          'color'  => 'Red',
          'size'   => 'M',
        ]);

Вложенный вывод:

Array
(
    [1003] => Array
        (
            [0] => Array
                (
                    [id] => 1003
                    [quantity] => 1
                    [hash] => 9f6bf828c80134b8d3e07b058045fba6acd4e9ac
                    [attributes] => Array
                        (
                            [price] => 5.99
                            [color] => White
                            [size] => XS
                        )

                )

        )

)

1 Ответ

0 голосов
/ 04 апреля 2020

Я проверил код.

При вызове метода обновления происходит сравнение между $ атрибутами, уже сохраненными в элементе, и новыми $ атрибутами, которые вы пытаетесь обновить. Сравнение выполняется путем хеширования двух массивов ...

Как вы можете обнаружить ... оно не будет совпадать (хэши будут различаться). Чтобы обновить $ атрибуты, вы должны удалить сравнение if:

if ($item['hash'] == $hash)

и добавить эти две строки, которые обновляют ha sh и атрибуты:

$this->items[$id][$index]['hash'] = $hash;
$this->items[$id][$index]['attributes'] = $attributes;

Окончательный метод обновления должно быть так:

public function update($id, $quantity = 1, $attributes = [])
    {
        $quantity = (preg_match('/^\d+$/', $quantity)) ? $quantity : 1;
        $attributes = (is_array($attributes)) ? array_filter($attributes) : [$attributes];

        if ($quantity == 0) {
            $this->remove($id, $attributes);

            return true;
        }

        if (isset($this->items[$id])) {

            $hash = md5(json_encode(array_filter($attributes)));

            foreach ($this->items[$id] as $index => $item) {

                    $this->items[$id][$index]['quantity'] = $quantity;
                    $this->items[$id][$index]['quantity'] = ($this->itemMaxQuantity < $this->items[$id][$index]['quantity'] && $this->itemMaxQuantity != 0) ? $this->itemMaxQuantity : $this->items[$id][$index]['quantity'];

                    $this->items[$id][$index]['hash'] = $hash;
                    $this->items[$id][$index]['attributes'] = $attributes;

                    $this->write();

                    return true;
            }
        }

        return false;
    }

Затем, когда вы позвоните:

$cart->getItems()

Вы увидите, что элемент обновлен ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...