Skip to content

Commit

Permalink
Product entity is no longer dependent on ProductCategoryDomainFactory
Browse files Browse the repository at this point in the history
- entities must not use external dependencies in their logic
- the creation of ProductCategoryDomain entities is moved to ProductCategoryDomainFactory and used in ProductFacade
- Product::$productCategoryDomains now must be set from outside (public
setter)
- when setting $productCategoryDomains array for main variant, the items are
copied for all its variants (ProductCategoryDomain::$product must be
changed accordingly using public setter)
- when adding a new variant, the $productCategoryDomains are copied from
the main variant the same way as well
  • Loading branch information
vitek-rostislav committed Jun 13, 2019
1 parent 8c11a04 commit c662e65
Show file tree
Hide file tree
Showing 19 changed files with 176 additions and 198 deletions.
109 changes: 40 additions & 69 deletions packages/framework/src/Model/Product/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,9 @@ class Product extends AbstractTranslatableEntity

/**
* @param \Shopsys\FrameworkBundle\Model\Product\ProductData $productData
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
* @param \Shopsys\FrameworkBundle\Model\Product\Product[]|null $variants
*/
protected function __construct(ProductData $productData, ProductCategoryDomainFactoryInterface $productCategoryDomainFactory, ?array $variants = null)
protected function __construct(ProductData $productData, ?array $variants = null)
{
$this->translations = new ArrayCollection();
$this->domains = new ArrayCollection();
Expand Down Expand Up @@ -318,38 +317,36 @@ protected function __construct(ProductData $productData, ProductCategoryDomainFa
$this->variantType = self::VARIANT_TYPE_NONE;
} else {
$this->variantType = self::VARIANT_TYPE_MAIN;
$this->addVariants($variants, $productCategoryDomainFactory);
$this->addVariants($variants);
}
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\ProductData $productData
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
* @return \Shopsys\FrameworkBundle\Model\Product\Product
*/
public static function create(ProductData $productData, ProductCategoryDomainFactoryInterface $productCategoryDomainFactory)
public static function create(ProductData $productData)
{
return new static($productData, $productCategoryDomainFactory, null);
return new static($productData, null);
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\ProductData $productData
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
* @param \Shopsys\FrameworkBundle\Model\Product\Product[] $variants
* @return \Shopsys\FrameworkBundle\Model\Product\Product
*/
public static function createMainVariant(ProductData $productData, ProductCategoryDomainFactoryInterface $productCategoryDomainFactory, array $variants)
public static function createMainVariant(ProductData $productData, array $variants)
{
return new static($productData, $productCategoryDomainFactory, $variants);
return new static($productData, $variants);
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomain[] $productCategoryDomains
* @param \Shopsys\FrameworkBundle\Model\Product\ProductData $productData
* @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceRecalculationScheduler $productPriceRecalculationScheduler
*/
public function edit(
ProductCategoryDomainFactoryInterface $productCategoryDomainFactory,
array $productCategoryDomains,
ProductData $productData,
ProductPriceRecalculationScheduler $productPriceRecalculationScheduler
) {
Expand All @@ -366,7 +363,7 @@ public function edit(
$this->setDomains($productData);

if (!$this->isVariant()) {
$this->setCategories($productCategoryDomainFactory, $productData->categoriesByDomainId);
$this->setProductCategoryDomains($productCategoryDomains);
}
if (!$this->isMainVariant()) {
$this->usingStock = $productData->usingStock;
Expand Down Expand Up @@ -617,56 +614,19 @@ public function setCalculatedAvailability(Availability $calculatedAvailability)
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
* @param \Shopsys\FrameworkBundle\Model\Category\Category[] $categoriesByDomainId
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomain[] $productCategoryDomains
*/
public function setCategories(
ProductCategoryDomainFactoryInterface $productCategoryDomainFactory,
array $categoriesByDomainId
) {
foreach ($categoriesByDomainId as $domainId => $categories) {
$this->removeOldProductCategoryDomains($categories, $domainId);
$this->createNewProductCategoryDomains($productCategoryDomainFactory, $categories, $domainId);
public function setProductCategoryDomains(array $productCategoryDomains)
{
$this->productCategoryDomains->clear();

foreach ($productCategoryDomains as $productCategoryDomain) {
$this->productCategoryDomains->add($productCategoryDomain);
}

if ($this->isMainVariant()) {
foreach ($this->getVariants() as $variant) {
$variant->setCategories($productCategoryDomainFactory, $categoriesByDomainId);
}
}
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
* @param \Shopsys\FrameworkBundle\Model\Category\Category[] $newCategories
* @param int $domainId
*/
protected function createNewProductCategoryDomains(
ProductCategoryDomainFactoryInterface $productCategoryDomainFactory,
array $newCategories,
$domainId
) {
$currentProductCategoryDomainsOnDomainByCategoryId = $this->getProductCategoryDomainsByDomainIdIndexedByCategoryId($domainId);

foreach ($newCategories as $newCategory) {
if (!array_key_exists($newCategory->getId(), $currentProductCategoryDomainsOnDomainByCategoryId)) {
$productCategoryDomain = $productCategoryDomainFactory->create($this, $newCategory, $domainId);
$this->productCategoryDomains->add($productCategoryDomain);
}
}
}

/**
* @param \Shopsys\FrameworkBundle\Model\Category\Category[] $newCategories
* @param int $domainId
*/
protected function removeOldProductCategoryDomains(array $newCategories, $domainId)
{
$currentProductCategoryDomains = $this->getProductCategoryDomainsByDomainIdIndexedByCategoryId($domainId);

foreach ($currentProductCategoryDomains as $currentProductCategoryDomain) {
if (!in_array($currentProductCategoryDomain->getCategory(), $newCategories, true)) {
$this->productCategoryDomains->removeElement($currentProductCategoryDomain);
$variant->copyProductCategoryDomains($productCategoryDomains);
}
}
}
Expand Down Expand Up @@ -807,9 +767,8 @@ public function getMainVariant()

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product $variant
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
*/
public function addVariant(self $variant, ProductCategoryDomainFactoryInterface $productCategoryDomainFactory)
public function addVariant(self $variant)
{
if (!$this->isMainVariant()) {
throw new \Shopsys\FrameworkBundle\Model\Product\Exception\VariantCanBeAddedOnlyToMainVariantException(
Expand All @@ -827,18 +786,32 @@ public function addVariant(self $variant, ProductCategoryDomainFactoryInterface
if (!$this->variants->contains($variant)) {
$this->variants->add($variant);
$variant->setMainVariant($this);
$variant->setCategories($productCategoryDomainFactory, $this->getCategoriesIndexedByDomainId());
$variant->copyProductCategoryDomains($this->productCategoryDomains->toArray());
}
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomain[] $productCategoryDomains
*/
protected function copyProductCategoryDomains(array $productCategoryDomains)
{
$newProductCategoryDomains = [];

foreach ($productCategoryDomains as $productCategoryDomain) {
$copiedProductCategoryDomain = clone $productCategoryDomain;
$copiedProductCategoryDomain->setProduct($this);
$newProductCategoryDomains[] = $copiedProductCategoryDomain;
}
$this->setProductCategoryDomains($newProductCategoryDomains);
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product[] $variants
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
*/
protected function addVariants(array $variants, ProductCategoryDomainFactoryInterface $productCategoryDomainFactory)
protected function addVariants(array $variants)
{
foreach ($variants as $variant) {
$this->addVariant($variant, $productCategoryDomainFactory);
$this->addVariant($variant);
}
}

Expand Down Expand Up @@ -1030,23 +1003,21 @@ public function checkIsNotMainVariant(): void

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product[] $currentVariants
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
*/
public function refreshVariants(array $currentVariants, ProductCategoryDomainFactoryInterface $productCategoryDomainFactory): void
public function refreshVariants(array $currentVariants): void
{
$this->unsetRemovedVariants($currentVariants);
$this->addNewVariants($currentVariants, $productCategoryDomainFactory);
$this->addNewVariants($currentVariants);
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product[] $currentVariants
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
*/
protected function addNewVariants(array $currentVariants, ProductCategoryDomainFactoryInterface $productCategoryDomainFactory): void
protected function addNewVariants(array $currentVariants): void
{
foreach ($currentVariants as $currentVariant) {
if (!in_array($currentVariant, $this->getVariants(), true)) {
$this->addVariant($currentVariant, $productCategoryDomainFactory);
$this->addVariant($currentVariant);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,12 @@ public function getDomainId()
{
return $this->domainId;
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product $product
*/
public function setProduct(Product $product): void
{
$this->product = $product;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,27 @@ public function create(

return new $classData($product, $category, $domainId);
}

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product $product
* @param \Shopsys\FrameworkBundle\Model\Category\Category[][] $categoriesIndexedByDomainId
* @return \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomain[]
*/
public function createMultiple(
Product $product,
array $categoriesIndexedByDomainId
): array {
$productCategoryDomains = [];
foreach ($categoriesIndexedByDomainId as $domainId => $categoriesOnDomain) {
foreach ($categoriesOnDomain as $category) {
$productCategoryDomains[] = $this->create(
$product,
$category,
$domainId
);
}
}

return $productCategoryDomains;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,14 @@ public function create(
Category $category,
int $domainId
): ProductCategoryDomain;

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Product $product
* @param \Shopsys\FrameworkBundle\Model\Category\Category[][] $categoriesIndexedByDomainId
* @return \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomain[]
*/
public function createMultiple(
Product $product,
array $categoriesIndexedByDomainId
): array;
}
8 changes: 5 additions & 3 deletions packages/framework/src/Model/Product/ProductFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ public function setAdditionalDataAfterCreate(Product $product, ProductData $prod
{
// Persist of ProductCategoryDomain requires known primary key of Product
// @see https://github.com/doctrine/doctrine2/issues/4869
$product->setCategories($this->productCategoryDomainFactory, $productData->categoriesByDomainId);
$productCategoryDomains = $this->productCategoryDomainFactory->createMultiple($product, $productData->categoriesByDomainId);
$product->setProductCategoryDomains($productCategoryDomains);
$this->em->flush($product);

$this->saveParameters($product, $productData->parameters);
Expand All @@ -264,13 +265,14 @@ public function edit($productId, ProductData $productData)
{
$product = $this->productRepository->getById($productId);

$product->edit($this->productCategoryDomainFactory, $productData, $this->productPriceRecalculationScheduler);
$productCategoryDomains = $this->productCategoryDomainFactory->createMultiple($product, $productData->categoriesByDomainId);
$product->edit($productCategoryDomains, $productData, $this->productPriceRecalculationScheduler);

$this->saveParameters($product, $productData->parameters);
if (!$product->isMainVariant()) {
$this->refreshProductManualInputPrices($product, $productData->manualInputPricesByPricingGroupId);
} else {
$product->refreshVariants($productData->variants, $this->productCategoryDomainFactory);
$product->refreshVariants($productData->variants);
}
$this->refreshProductAccessories($product, $productData->accessories);
$this->em->flush();
Expand Down
14 changes: 3 additions & 11 deletions packages/framework/src/Model/Product/ProductFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,16 @@ class ProductFactory implements ProductFactoryInterface
*/
protected $productAvailabilityCalculation;

/**
* @var \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface
*/
protected $productCategoryDomainFactory;

/**
* @param \Shopsys\FrameworkBundle\Component\EntityExtension\EntityNameResolver $entityNameResolver
* @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityCalculation $productAvailabilityCalculation
* @param \Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
*/
public function __construct(
EntityNameResolver $entityNameResolver,
ProductAvailabilityCalculation $productAvailabilityCalculation,
ProductCategoryDomainFactoryInterface $productCategoryDomainFactory
ProductAvailabilityCalculation $productAvailabilityCalculation
) {
$this->entityNameResolver = $entityNameResolver;
$this->productAvailabilityCalculation = $productAvailabilityCalculation;
$this->productCategoryDomainFactory = $productCategoryDomainFactory;
}

/**
Expand All @@ -45,7 +37,7 @@ public function create(ProductData $data): Product
{
$classData = $this->entityNameResolver->resolve(Product::class);

$product = $classData::create($data, $this->productCategoryDomainFactory);
$product = $classData::create($data);
$this->setCalculatedAvailabilityIfMissing($product);

return $product;
Expand All @@ -63,7 +55,7 @@ public function createMainVariant(ProductData $data, Product $mainProduct, array

$classData = $this->entityNameResolver->resolve(Product::class);

$mainVariant = $classData::createMainVariant($data, $this->productCategoryDomainFactory, $variants);
$mainVariant = $classData::createMainVariant($data, $variants);
$this->setCalculatedAvailabilityIfMissing($mainVariant);

return $mainVariant;
Expand Down
12 changes: 5 additions & 7 deletions packages/framework/tests/Unit/Model/Cart/CartTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
namespace Tests\FrameworkBundle\Unit\Model\Cart;

use PHPUnit\Framework\TestCase;
use Shopsys\FrameworkBundle\Component\EntityExtension\EntityNameResolver;
use Shopsys\FrameworkBundle\Component\Money\Money;
use Shopsys\FrameworkBundle\Model\Cart\Cart;
use Shopsys\FrameworkBundle\Model\Cart\Item\CartItem;
use Shopsys\FrameworkBundle\Model\Customer\CustomerIdentifier;
use Shopsys\FrameworkBundle\Model\Pricing\Vat\Vat;
use Shopsys\FrameworkBundle\Model\Pricing\Vat\VatData;
use Shopsys\FrameworkBundle\Model\Product\Product;
use Shopsys\FrameworkBundle\Model\Product\ProductCategoryDomainFactory;
use Shopsys\FrameworkBundle\Model\Product\ProductData;

class CartTest extends TestCase
Expand All @@ -35,12 +33,12 @@ public function testGetItemsCount()
$productData1 = new ProductData();
$productData1->name = ['cs' => 'Product 1'];
$productData1->vat = $vat;
$product1 = Product::create($productData1, new ProductCategoryDomainFactory(new EntityNameResolver([])));
$product1 = Product::create($productData1);

$productData2 = new ProductData();
$productData2->name = ['cs' => 'Product 2'];
$productData2->vat = $vat;
$product2 = Product::create($productData2, new ProductCategoryDomainFactory(new EntityNameResolver([])));
$product2 = Product::create($productData2);

$cart = new Cart($customerIdentifier->getCartIdentifier());

Expand Down Expand Up @@ -73,7 +71,7 @@ public function testIsNotEmpty()
$productData = new ProductData();
$productData->name = ['cs' => 'Product 1'];
$productData->vat = $vat;
$product = Product::create($productData, new ProductCategoryDomainFactory(new EntityNameResolver([])));
$product = Product::create($productData);

$cart = new Cart($customerIdentifier->getCartIdentifier());

Expand All @@ -94,12 +92,12 @@ public function testClean()
$productData1 = new ProductData();
$productData1->name = ['cs' => 'Product 1'];
$productData1->vat = $vat;
$product1 = Product::create($productData1, new ProductCategoryDomainFactory(new EntityNameResolver([])));
$product1 = Product::create($productData1);

$productData2 = new ProductData();
$productData2->name = ['cs' => 'Product 2'];
$productData2->vat = $vat;
$product2 = Product::create($productData2, new ProductCategoryDomainFactory(new EntityNameResolver([])));
$product2 = Product::create($productData2);

$cart = new Cart($customerIdentifier->getCartIdentifier());

Expand Down
Loading

0 comments on commit c662e65

Please sign in to comment.