Рубрики
Uncategorized

Создание объектов корзины | Создание корзины покупок с помощью Symfony

Генерация сущностей Генерация сущности элемента заказа Генерация сущности заказа Настройка каскада O… С тегами php, symfony, учебник, доктрина.

Создание корзины покупок с помощью Symfony (Серия из 11 частей)

  • Генерирующие организации
    • Создание сущности элемента заказа
    • Создание сущности заказа
    • Настройка Каскадных Операций
  • Перенос базы данных
  • Установка статуса заказа по умолчанию
  • Избегание добавления повторяющегося элемента
  • Удаление всех товаров из заказа
  • Расчет общей суммы заказа
  • Создание фабрики

На протяжении всего урока мы будем говорить о корзине как о заказе. Это Заказ, который находится в процессе выполнения, но еще не размещен.

На самом деле корзина – это Заказ в статусе корзина .

Генерирующие организации

Сущность Заказа содержит:

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

Создание сущности элемента заказа

Используйте пакет Maker для создания объекта OrderItem :

$ symfony console make:entity OrderItem

Добавьте поля, которые нам нужны:

  • продукт, отношение, относящийся к сущности продукта, ManyToOne, нет, нет
  • количество, целое число, нет
id;
    }

    public function getProduct(): ?Product
    {
        return $this->product;
    }

    public function setProduct(?Product $product): self
    {
        $this->product = $product;

        return $this;
    }

    public function getQuantity(): ?int
    {
        return $this->quantity;
    }

    public function setQuantity(int $quantity): self
    {
        $this->quantity = $quantity;

        return $this;
    }
}

Создание сущности заказа

Еще раз используйте пакет Maker для создания объекта Заказ :

$ symfony console make:entity Order

Добавьте поля, которые нам нужны:

  • элементы, отношение, связанные с сущностью OrderItem , OneToMany, ссылка на заказ (заказ – зарезервированное слово в Mysql), нет, да
  • статус, строка, 255, нет
  • создан_ат, дата и время, нет
  • обновленный_ат, дата и время, нет
items = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return Collection|OrderItem[]
     */
    public function getItems(): Collection
    {
        return $this->items;
    }

    public function addItem(OrderItem $item): self
    {
        if (!$this->items->contains($item)) {
            $this->items[] = $item;
            $item->setOrderRef($this);
        }

        return $this;
    }

    public function removeItem(OrderItem $item): self
    {
        if ($this->items->removeElement($item)) {
            // set the owning side to null (unless already changed)
            if ($item->getOrderRef() === $this) {
                $item->setOrderRef(null);
            }
        }

        return $this;
    }

    public function getStatus(): ?string
    {
        return $this->status;
    }

    public function setStatus(string $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    public function getUpdatedAt(): ?\DateTimeInterface
    {
        return $this->updatedAt;
    }

    public function setUpdatedAt(\DateTimeInterface $updatedAt): self
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

}

Элемент заказа был обновлен со следующими изменениями:

orderRef;
    }

    public function setOrderRef(?Order $orderRef): self
    {
        $this->orderRef = $orderRef;

        return $this;
    }
}

Настройка Каскадных Операций

Когда мы добавляем новую сущность OrderItem в сущность Order , мы должны сохранить ее, прежде чем сохранять сущность Order . Кроме того, когда мы захотим удалить объект Заказа , мы должны удалить весь элемент заказа сущности перед удалением сущности Порядка .

Это может быть действительно скучно, поэтому мы позволим Доктрине позаботиться об этом внутренне, используя каскадные операции. Для этого добавьте новую опцию каскада в свойство товары объекта Заказ :

/**
 * @ORM\OneToMany(targetEntity=OrderItem::class, mappedBy="orderRef", cascade={"persist", "remove"}, orphanRemoval=true)
 */
private $items;

Поэтому, когда мы будем сохранять/удалять объект Order , Doctrine автоматически вызовет persist/remove для каждого из объектов OrderItem , связанных с объектом Order .

Перенос базы данных

Создайте файл миграции с помощью пакета Maker:

$ symfony console make:migration

Файл миграции сохранен в каталоге миграции/ :

addSql('CREATE TABLE `order` (id INT AUTO_INCREMENT NOT NULL, status VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
        $this->addSql('CREATE TABLE order_item (id INT AUTO_INCREMENT NOT NULL, product_id INT NOT NULL, order_ref_id INT NOT NULL, quantity INT NOT NULL, INDEX IDX_52EA1F094584665A (product_id), INDEX IDX_52EA1F09E238517C (order_ref_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
        $this->addSql('ALTER TABLE order_item ADD CONSTRAINT FK_52EA1F094584665A FOREIGN KEY (product_id) REFERENCES product (id)');
        $this->addSql('ALTER TABLE order_item ADD CONSTRAINT FK_52EA1F09E238517C FOREIGN KEY (order_ref_id) REFERENCES `order` (id)');
    }

    public function down(Schema $schema) : void
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->addSql('ALTER TABLE order_item DROP FOREIGN KEY FK_52EA1F09E238517C');
        $this->addSql('DROP TABLE `order`');
        $this->addSql('DROP TABLE order_item');
    }
}

Теперь мы можем обновить схему локальной базы данных:

$ symfony console doctrine:migrations:migrate

Установка статуса заказа по умолчанию

Все новые заказы должны быть в состоянии по умолчанию корзина . В сгенерированном объекте Порядок инициализируйте статус с помощью константы STATUS_CART :

Избежание добавления повторяющегося элемента Заказа

В настоящее время можно добавлять повторяющиеся объекты OrderItem (с одним и тем же продуктом) в объект Заказ . Давайте это исправим.

Добавьте метод equals() в класс OrderItem , чтобы узнать, соответствует ли элемент элементу, указанному в качестве аргумента.

/**
 * Tests if the given item given corresponds to the same order item.
 *
 * @param OrderItem $item
 *
 * @return bool
 */
public function equals(OrderItem $item): bool
{
    return $this->getProduct()->getId() === $item->getProduct()->getId();
}

Обновите метод addItem() объекта Заказ для суммирования количества, если товар уже существует:

public function addItem(OrderItem $item): self
{
    foreach ($this->getItems() as $existingItem) {
        // The item already exists, update the quantity
        if ($existingItem->equals($item)) {
            $existingItem->setQuantity(
                $existingItem->getQuantity() + $item->getQuantity()
            );
            return $this;
        }
    }

    $this->items[] = $item;
    $item->setOrderRef($this);

    return $this;
}

Удаление всех товаров из заказа

Добавьте метод removeItems() в класс Order , чтобы удалить все товары из заказа:

/**
 * Removes all items from the order.
 *
 * @return $this
 */
public function removeItems(): self
{
    foreach ($this->getItems() as $item) {
        $this->removeItem($item);
    }

    return $this;
}

Расчет общей суммы заказа

Нам нужно будет показать сводку корзины. Обратите внимание, что мы игнорируем изменения, которые могут быть внесены в заказ, такие как стоимость доставки, промо-код и т.д.

Во-первых, добавьте метод getTotal() в объект OrderItem для расчета общего количества товаров:

/**
 * Calculates the item total.
 *
 * @return float|int
 */
public function getTotal(): float
{
    return $this->getProduct()->getPrice() * $this->getQuantity();
}

Наконец, добавьте метод getTotal() в объект Заказ для расчета общей суммы заказа:

/**
 * Calculates the order total.
 *
 * @return float
 */
public function getTotal(): float
{
    $total = 0;

    foreach ($this->getItems() as $item) {
        $total += $item->getTotal();
    }

    return $total;
}

Создание фабрики

Фабрика заказов фабрика поможет нам создать Заказ и Элемент заказа сущности с данными по умолчанию. Это также позволяет вам легко изменять сущность Порядок .

setStatus(Order::STATUS_CART)
            ->setCreatedAt(new \DateTime())
            ->setUpdatedAt(new \DateTime());

        return $order;
    }

    /**
     * Creates an item for a product.
     *
     * @param Product $product
     *
     * @return OrderItem
     */
    public function createItem(Product $product): OrderItem
    {
        $item = new OrderItem();
        $item->setProduct($product);
        $item->setQuantity(1);

        return $item;
    }
}

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

Создание корзины покупок с помощью Symfony (Серия из 11 частей)

Оригинал: “https://dev.to/qferrer/creating-cart-entities-building-a-shopping-cart-with-symfony-h90”