Skip to content
This repository has been archived by the owner on Aug 3, 2018. It is now read-only.

Commit

Permalink
Merge pull request #26 from Sylius/taxon-bubbling
Browse files Browse the repository at this point in the history
[ElasticSearch] Tag products with all taxon ancestors
  • Loading branch information
lchrusciel authored Jun 29, 2017
2 parents be71258 + 2c08c98 commit bdf1dcc
Show file tree
Hide file tree
Showing 5 changed files with 354 additions and 21 deletions.
79 changes: 58 additions & 21 deletions src/Factory/ProductDocumentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductTranslationInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Model\TranslationInterface;
use Sylius\Component\Taxonomy\Model\TaxonTranslation;
use Sylius\Component\Taxonomy\Model\TaxonTranslationInterface;
use Sylius\ElasticSearchPlugin\Document\AttributeDocument;
use Sylius\ElasticSearchPlugin\Document\AttributeValueDocument;
use Sylius\ElasticSearchPlugin\Document\ImageDocument;
Expand Down Expand Up @@ -126,7 +127,7 @@ public function createFromSyliusSimpleProductModel(ProductInterface $syliusProdu
if (null !== $syliusProduct->getMainTaxon()) {
/** @var TaxonDocument $mainTaxonDocument */
$mainTaxonDocument = new $this->taxonDocumentClass();
/** @var TaxonTranslation $mainTaxonTranslation */
/** @var TaxonTranslationInterface $mainTaxonTranslation */
$mainTaxonTranslation = $syliusProduct->getMainTaxon()->getTranslation($locale->getCode());

$mainTaxonDocument->setCode($syliusProduct->getMainTaxon()->getCode());
Expand Down Expand Up @@ -154,26 +155,13 @@ public function createFromSyliusSimpleProductModel(ProductInterface $syliusProdu

$productTaxons = [];
foreach ($syliusProductTaxons as $syliusProductTaxon) {
/** @var TaxonDocument $productTaxon */
$productTaxon = new $this->taxonDocumentClass();
$productTaxonTranslation = $syliusProductTaxon->getTaxon()->getTranslation($locale->getCode());
$productTaxon->setCode($syliusProductTaxon->getTaxon()->getCode());
$productTaxon->setSlug($productTaxonTranslation->getSlug());
$productTaxon->setPosition($syliusProductTaxon->getTaxon()->getPosition());
$productTaxon->setDescription($productTaxonTranslation->getDescription());

$productTaxonImages = [];
$syliusTaxonImages = $syliusProductTaxon->getTaxon()->getImages();
foreach ($syliusTaxonImages as $syliusTaxonImage) {
/** @var ImageDocument $productTaxonImage */
$productTaxonImage = new $this->imageDocumentClass();
$productTaxonImage->setPath($syliusTaxonImage->getPath());
$productTaxonImage->setCode($syliusTaxonImage->getType());
$productTaxonImages[] = $productTaxonImage;
}
$productTaxon->setImages(new Collection($productTaxonImages));
$syliusProductTaxonAncestors = $this->getAncestorsFromTaxon($syliusProductTaxon->getTaxon());

$productTaxons[] = $this->createTaxonDocumentFromSyliusTaxon($syliusProductTaxon->getTaxon(), $locale->getCode());

$productTaxons[] = $productTaxon;
foreach ($syliusProductTaxonAncestors as $syliusProductTaxonAncestor) {
$productTaxons[] = $this->createTaxonDocumentFromSyliusTaxon($syliusProductTaxonAncestor, $locale->getCode());
}
}
$product->setTaxons(new Collection($productTaxons));
$productAttributeValues = [];
Expand All @@ -198,6 +186,55 @@ public function createFromSyliusSimpleProductModel(ProductInterface $syliusProdu
return $product;
}

/**
* @param TaxonInterface $taxon
* @param string $localeCode
*
* @return TaxonDocument
*/
private function createTaxonDocumentFromSyliusTaxon(TaxonInterface $taxon, $localeCode = null)
{
/** @var TaxonTranslationInterface $taxonTranslation */
$taxonTranslation = $taxon->getTranslation($localeCode);

/** @var TaxonDocument $taxonDocument */
$taxonDocument = new $this->taxonDocumentClass();
$taxonDocument->setCode($taxon->getCode());
$taxonDocument->setSlug($taxonTranslation->getSlug());
$taxonDocument->setPosition($taxon->getPosition());
$taxonDocument->setDescription($taxonTranslation->getDescription());

$taxonDocumentImages = [];
$syliusTaxonImages = $taxon->getImages();
foreach ($syliusTaxonImages as $syliusTaxonImage) {
/** @var ImageDocument $taxonDocumentImage */
$taxonDocumentImage = new $this->imageDocumentClass();
$taxonDocumentImage->setPath($syliusTaxonImage->getPath());
$taxonDocumentImage->setCode($syliusTaxonImage->getType());
$taxonDocumentImages[] = $taxonDocumentImage;
}
$taxonDocument->setImages(new Collection($taxonDocumentImages));

return $taxonDocument;
}

/**
* @param TaxonInterface $taxon
*
* @return array
*/
private function getAncestorsFromTaxon(TaxonInterface $taxon)
{
$ancestors = [];
while (null !== $taxon->getParent()) {
$taxon = $taxon->getParent();

$ancestors[] = $taxon;
}

return $ancestors;
}

/**
* @param ProductVariantInterface $productVariant
* @param ChannelInterface $channel
Expand Down
149 changes: 149 additions & 0 deletions tests/Factory/ProductDocumentFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,4 +302,153 @@ public function it_creates_product_document_only_with_whitelisted_attributes()
$this->assertEquals(new Collection([$productTaxon]), $product->getTaxons());
$this->assertEquals(0.0, $product->getAverageReviewRating());
}

/**
* @test
*/
public function it_creates_product_document_with_all_taxon_parents()
{
$createdAt = \DateTime::createFromFormat(\DateTime::W3C, '2017-04-18T16:12:55+02:00');
$firstSyliusProductAttributeValue = new ProductAttributeValue();
$firstSyliusProductAttribute = new ProductAttribute();
$firstSyliusProductAttribute->setCurrentLocale('en_US');
$firstSyliusProductAttribute->setCode('material');
$firstSyliusProductAttribute->setName('Material');
$firstSyliusProductAttributeValue->setLocaleCode('en_US');
$firstSyliusProductAttribute->setType(TextAttributeType::TYPE);
$firstSyliusProductAttribute->setStorageType(TextAttributeType::TYPE);
$firstSyliusProductAttributeValue->setAttribute($firstSyliusProductAttribute);
$firstSyliusProductAttributeValue->setValue('wood');

$secondSyliusProductAttributeValue = new ProductAttributeValue();
$secondSyliusProductAttribute = new ProductAttribute();
$secondSyliusProductAttribute->setCurrentLocale('en_US');
$secondSyliusProductAttribute->setCode('size');
$secondSyliusProductAttribute->setName('Size');
$secondSyliusProductAttributeValue->setLocaleCode('en_US');
$secondSyliusProductAttribute->setType(TextAttributeType::TYPE);
$secondSyliusProductAttribute->setStorageType(TextAttributeType::TYPE);
$secondSyliusProductAttributeValue->setAttribute($secondSyliusProductAttribute);
$secondSyliusProductAttributeValue->setValue('M');

$syliusParentTaxon = new SyliusTaxon();
$syliusParentTaxon->setCurrentLocale('en_US');
$syliusParentTaxon->setCode('root');
$syliusParentTaxon->setSlug('/root');
$syliusParentTaxon->setDescription('Lorem ipsum');

$syliusTaxon = new SyliusTaxon();
$syliusTaxon->setCurrentLocale('en_US');
$syliusTaxon->setCode('tree');
$syliusTaxon->setSlug('/tree');
$syliusTaxon->setDescription('Lorem ipsum');
$syliusTaxon->setParent($syliusParentTaxon);
$syliusProductTaxon = new ProductTaxon();

$syliusLocale = new Locale();
$syliusLocale->setCode('en_US');

$syliusProduct = new SyliusProduct();
$syliusProductVariant = new ProductVariant();
$channelPrice = new ChannelPricing();
$syliusChannel = new Channel();
$currency = new Currency();
$currency->setCode('USD');

$syliusProductTaxon->setProduct($syliusProduct);
$syliusProductTaxon->setTaxon($syliusTaxon);
$channelPrice->setPrice(1000);
$channelPrice->setChannelCode('mobile');

$syliusChannel->setCode('mobile');
$syliusChannel->setDefaultLocale($syliusLocale);
$syliusChannel->addLocale($syliusLocale);
$syliusChannel->addCurrency($currency);
$syliusChannel->setBaseCurrency($currency);

$syliusProductVariant->addChannelPricing($channelPrice);
$syliusProduct->addVariant($syliusProductVariant);
$syliusProduct->addChannel($syliusChannel);
$syliusProduct->setMainTaxon($syliusTaxon);
$syliusProduct->addProductTaxon($syliusProductTaxon);
$syliusProduct->setCreatedAt($createdAt);
$syliusProduct->setCurrentLocale('en_US');
$syliusProduct->setName('Banana');
$syliusProduct->setSlug('/banana');
$syliusProduct->setDescription('Lorem ipsum');
$syliusProduct->setCode('banana');
$syliusProduct->addAttribute($firstSyliusProductAttributeValue);
$syliusProduct->addAttribute($secondSyliusProductAttributeValue);

$factory = new ProductDocumentFactory(
ProductDocument::class,
AttributeDocument::class,
AttributeValueDocument::class,
ImageDocument::class,
PriceDocument::class,
TaxonDocument::class,
['material']
);
/** @var ProductDocument $product */
$product = $factory->createFromSyliusSimpleProductModel(
$syliusProduct,
$syliusLocale,
$syliusChannel
);

$taxon = new TaxonDocument();
$taxon->setCode('tree');
$taxon->setPosition(0);
$taxon->setSlug('/tree');
$taxon->setDescription('Lorem ipsum');

$rootTaxon = new TaxonDocument();
$rootTaxon->setCode('root');
$rootTaxon->setPosition(0);
$rootTaxon->setSlug('/root');
$rootTaxon->setDescription('Lorem ipsum');

$productTaxon = new TaxonDocument();
$productTaxon->setCode('tree');
$productTaxon->setSlug('/tree');
$productTaxon->setPosition(0);
$productTaxon->setDescription('Lorem ipsum');

$firstProductAttribute = new AttributeDocument();
$firstProductAttribute->setCode('material');
$firstProductAttribute->setName('Material');

$firstProductAttributeValue = new AttributeValueDocument();
$firstProductAttributeValue->setValue('wood');
$firstProductAttributeValue->setAttribute($firstProductAttribute);

$secondProductAttribute = new AttributeDocument();
$secondProductAttribute->setCode('size');
$secondProductAttribute->setName('Size');

$secondProductAttributeValue = new AttributeValueDocument();
$secondProductAttributeValue->setValue('M');
$secondProductAttributeValue->setAttribute($secondProductAttribute);

$this->assertEquals('banana', $product->getCode());
$this->assertEquals('Banana', $product->getName());
$this->assertEquals('en_US', $product->getLocaleCode());
$this->assertEquals(
new Collection([
$firstProductAttributeValue,
]),
$product->getAttributeValues()
);

$this->assertEquals(1000, $product->getPrice()->getAmount());
$this->assertEquals('USD', $product->getPrice()->getCurrency());
$this->assertEquals('en_US', $product->getLocaleCode());
$this->assertEquals('mobile', $product->getChannelCode());
$this->assertEquals('/banana', $product->getSlug());
$this->assertEquals('Banana', $product->getName());
$this->assertEquals($createdAt, $product->getCreatedAt());
$this->assertEquals('Lorem ipsum', $product->getDescription());
$this->assertEquals($taxon, $product->getMainTaxon());
$this->assertEquals(new Collection([$productTaxon, $rootTaxon]), $product->getTaxons());
}
}
25 changes: 25 additions & 0 deletions tests/Responses/Expected/mugs_list_page.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
"images": [],
"description": "@string@"
},
{
"code": "CATEGORY",
"slug": "categories",
"position": 0,
"images": [],
"description": "@string@"
},
{
"code": "BRAND",
"slug": "brands",
Expand Down Expand Up @@ -161,6 +168,24 @@
"label": "brands",
"count": 3
},
{
"active": false,
"default": false,
"urlParameters": {
"taxon_slug": "categories"
},
"label": "categories",
"count": 3
},
{
"active": false,
"default": false,
"urlParameters": {
"taxon_slug": "kategorien"
},
"label": "kategorien",
"count": 3
},
{
"active": false,
"default": false,
Expand Down
Loading

0 comments on commit bdf1dcc

Please sign in to comment.