Создание корзины покупок с помощью 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”