function it_resolves_eligible_values_for_a_set_of_attributes($localeRepository, $channelRepository, AttributeInterface $sku, AttributeInterface $name, AttributeInterface $desc, AttributeInterface $tax, LocaleInterface $fr, LocaleInterface $en, ChannelInterface $ecom, ChannelInterface $print) { $sku->getCode()->willReturn('sku'); $sku->getAttributeType()->willReturn('pim_catalog_identifier'); $sku->isLocalizable()->willReturn(false); $sku->isScopable()->willReturn(false); $sku->isLocaleSpecific()->willReturn(false); $name->getCode()->willReturn('name'); $name->getAttributeType()->willReturn('pim_catalog_text'); $name->isLocalizable()->willReturn(true); $name->isScopable()->willReturn(false); $name->isLocaleSpecific()->willReturn(false); $desc->getCode()->willReturn('description'); $desc->getAttributeType()->willReturn('pim_catalog_text'); $desc->isLocalizable()->willReturn(true); $desc->isScopable()->willReturn(true); $desc->isLocaleSpecific()->willReturn(false); $tax->getCode()->willReturn('tax'); $tax->getAttributeType()->willReturn('pim_catalog_text'); $tax->isLocalizable()->willReturn(true); $tax->isScopable()->willReturn(false); $tax->isLocaleSpecific()->willReturn(true); $tax->getLocaleSpecificCodes()->willReturn(['fr_FR']); $fr->getCode()->willReturn('fr_FR'); $en->getCode()->willReturn('en_US'); $localeRepository->getActivatedLocales()->willReturn([$fr, $en]); $ecom->getCode()->willReturn('ecommerce'); $ecom->getLocales()->willReturn([$en, $fr]); $print->getCode()->willReturn('print'); $print->getLocales()->willReturn([$en, $fr]); $channelRepository->findAll()->willReturn([$ecom, $print]); $this->resolveEligibleValues([$sku, $name, $desc, $tax])->shouldReturn([['attribute' => 'sku', 'type' => 'pim_catalog_identifier', 'locale' => null, 'scope' => null], ['attribute' => 'name', 'type' => 'pim_catalog_text', 'locale' => 'fr_FR', 'scope' => null], ['attribute' => 'name', 'type' => 'pim_catalog_text', 'locale' => 'en_US', 'scope' => null], ['attribute' => 'description', 'type' => 'pim_catalog_text', 'locale' => 'en_US', 'scope' => 'ecommerce'], ['attribute' => 'description', 'type' => 'pim_catalog_text', 'locale' => 'fr_FR', 'scope' => 'ecommerce'], ['attribute' => 'description', 'type' => 'pim_catalog_text', 'locale' => 'en_US', 'scope' => 'print'], ['attribute' => 'description', 'type' => 'pim_catalog_text', 'locale' => 'fr_FR', 'scope' => 'print'], ['attribute' => 'tax', 'type' => 'pim_catalog_text', 'locale' => 'fr_FR', 'scope' => null]]); }
function it_initializes_itself($productBuilder, $catalogContext, $attributeRepository, $massActionManager, LocaleInterface $deLocale, AttributeInterface $attr1, AttributeInterface $attr2, ProductValueInterface $prodVal1, ProductValueInterface $prodVal2, ChannelInterface $channel, AttributeGroupInterface $attrGroup) { $deLocale->getCode()->willReturn('de_DE'); $this->setLocale($deLocale); $catalogContext->setLocaleCode('de_DE')->shouldBeCalled(); $attributeRepository->findWithGroups([], ['conditions' => ['unique' => 0]])->shouldBeCalled()->willReturn([$attr1, $attr2]); $attr1->setLocale('de_DE')->shouldBeCalled(); $attr2->setLocale('de_DE')->shouldBeCalled(); $attr1->getGroup()->willReturn($attrGroup); $attr2->getGroup()->willReturn($attrGroup); $attrGroup->setLocale('de_DE')->shouldBeCalledTimes(2); $massActionManager->filterLocaleSpecificAttributes([$attr1, $attr2], 'de_DE')->willReturn([$attr1, $attr2]); // First attribute $deLocale->getChannels()->willReturn([$channel]); $attr1->isScopable()->willReturn(true); $attr1->getCode()->willReturn('color'); $channel->getCode()->willReturn('mobile'); $productBuilder->createProductValue($attr1, 'de_DE', 'mobile')->shouldBeCalled()->willReturn($prodVal1); $productBuilder->addMissingPrices($prodVal1)->shouldBeCalled(); // Second attribute $attr2->isScopable()->willReturn(false); $attr2->getCode()->willReturn('price'); $productBuilder->createProductValue($attr2, 'de_DE')->shouldBeCalled()->willReturn($prodVal2); $productBuilder->addMissingPrices($prodVal2)->shouldBeCalled(); $this->initialize(); $this->getValues()->shouldHaveCount(2); }
function let(DocumentManager $manager, ChannelInterface $ecommerce, ChannelInterface $mobile, LocaleInterface $enUs, LocaleInterface $frFr, CategoryInterface $category, ChannelManager $channelManager, CategoryRepositoryInterface $categoryRepository, ProductRepository $productRepository, QueryBuilder $ormQb, Builder $odmQb, Query $odmQuery, Cursor $cursor) { $enUs->getCode()->willReturn('en_US'); $frFr->getCode()->willReturn('fr_FR'); $ecommerce->getCode()->willReturn('ecommerce'); $ecommerce->getLabel()->willReturn('ECommerce'); $ecommerce->getLocales()->willReturn(array($enUs, $frFr)); $ecommerce->getCategory()->willReturn($category); $mobile->getCode()->willReturn('mobile'); $mobile->getLabel()->willReturn('Mobile'); $mobile->getLocales()->willReturn(array($enUs)); $mobile->getCategory()->willReturn($category); $odmQuery->execute()->willReturn($cursor); $productRepository->createQueryBuilder()->willReturn($odmQb); $odmQb->hydrate(Argument::any())->willReturn($odmQb); $odmQb->field(Argument::any())->willReturn($odmQb); $odmQb->in(Argument::any())->willReturn($odmQb); $odmQb->equals(Argument::any())->willReturn($odmQb); $odmQb->select('_id')->willReturn($odmQb); $odmQb->getQuery()->willReturn($odmQuery); $categoryRepository->getAllChildrenQueryBuilder($category, true)->willReturn($ormQb); $categoryRepository->getCategoryIds($category, $ormQb)->willReturn(array(1, 2, 3)); $channelManager->getFullChannels()->willReturn(array($ecommerce, $mobile)); $manager->getRepository('pim_product_class')->willReturn($productRepository); $this->beConstructedWith($manager, $channelManager, $categoryRepository, 'pim_product_class'); }
function it_returns_well_formatted_actions_for_batch_job(AttributeInterface $attrColor, AttributeInterface $attrSize, ChannelInterface $channelMobile, ChannelInterface $channelEcommerce, AttributeRequirementInterface $colorMobileRequirement, AttributeRequirementInterface $colorEcommerceRequirement, AttributeRequirementInterface $sizeEcommerceRequirement) { $attrColor->getCode()->willReturn('color'); $attrSize->getCode()->willReturn('size'); $channelMobile->getCode()->willReturn('mobile'); $channelEcommerce->getCode()->willReturn('ecommerce'); $colorMobileRequirement->getAttribute()->willReturn($attrColor); $colorEcommerceRequirement->getAttribute()->willReturn($attrColor); $sizeEcommerceRequirement->getAttribute()->willReturn($attrSize); $colorMobileRequirement->getChannel()->willReturn($channelMobile); $colorEcommerceRequirement->getChannel()->willReturn($channelEcommerce); $sizeEcommerceRequirement->getChannel()->willReturn($channelEcommerce); $colorMobileRequirement->isRequired()->willReturn(false); $colorEcommerceRequirement->isRequired()->willReturn(true); $sizeEcommerceRequirement->isRequired()->willReturn(true); $colorMobileRequirement->getAttributeCode()->willReturn('color'); $colorEcommerceRequirement->getAttributeCode()->willReturn('color'); $sizeEcommerceRequirement->getAttributeCode()->willReturn('size'); $colorMobileRequirement->getChannelCode()->willReturn('mobile'); $colorEcommerceRequirement->getChannelCode()->willReturn('ecommerce'); $sizeEcommerceRequirement->getChannelCode()->willReturn('ecommerce'); $this->addAttributeRequirement($colorMobileRequirement); $this->addAttributeRequirement($colorEcommerceRequirement); $this->addAttributeRequirement($sizeEcommerceRequirement); $this->getActions()->shouldReturn([['attribute_code' => 'color', 'channel_code' => 'mobile', 'is_required' => false], ['attribute_code' => 'color', 'channel_code' => 'ecommerce', 'is_required' => true], ['attribute_code' => 'size', 'channel_code' => 'ecommerce', 'is_required' => true]]); }
function it_provide_product_completeness_if_family_is_not_defined(ProductInterface $product, ChannelInterface $mobile, LocaleInterface $en) { $product->getFamily()->willReturn(null); $en->getCode()->willReturn('en_US'); $mobile->getCode()->willReturn('mobile'); $this->getProductCompleteness($product, [$mobile], [$en], 'en_US')->shouldReturn([['channels' => [['completeness' => null, 'missing' => []]], 'stats' => ['total' => 0, 'complete' => 0], 'locale' => '']]); }
function it_provides_default_values($decoratedProvider, ChannelRepositoryInterface $channelRepository, LocaleRepositoryInterface $localeRepository, LocaleInterface $locale, ChannelInterface $channel) { $channel->getCode()->willReturn('channel_code'); $channelRepository->getFullChannels()->willReturn([$channel]); $locale->getCode()->willReturn('locale_code'); $localeRepository->getActivatedLocaleCodes()->willReturn([$locale]); $decoratedProvider->getDefaultValues()->willReturn(['decoratedParam' => true]); $this->getDefaultValues()->shouldReturnWellFormedDefaultValues(); }
function it_normalizes_completeness(Completeness $completeness, ChannelInterface $channel, LocaleInterface $locale) { $channel->getCode()->willReturn('ecommerce'); $locale->getCode()->willReturn('en_US'); $completeness->getChannel()->willReturn($channel); $completeness->getLocale()->willReturn($locale); $completeness->getRatio()->willReturn(42); $this->normalize($completeness, 'mongodb_json', [])->shouldReturn(["ecommerce-en_US" => 42]); }
function it_provides_channel_choices(ObjectManager $objectManager, ChannelRepositoryInterface $repository, ChannelInterface $mobile, ChannelInterface $ecommerce) { $repository->findBy(array())->willReturn(array($mobile, $ecommerce)); $mobile->getCode()->willReturn('mobile'); $mobile->getLabel()->willReturn('Mobile'); $ecommerce->getCode()->willReturn('ecommerce'); $ecommerce->getLabel()->willReturn('Ecommerce'); $this->getChannelChoices()->shouldReturn(['mobile' => 'Mobile', 'ecommerce' => 'Ecommerce']); }
function it_generates_a_query_to_update_product_scopable_attributes($namingUtility, AttributeInterface $label, ChannelInterface $mobile) { $namingUtility->getScopableAttributes(false)->willReturn([$label]); $label->getCode()->willReturn('label'); $namingUtility->getLocaleCodes()->willReturn(['fr_FR', 'en_US']); $namingUtility->appendSuffixes(['normalizedData.label'], ['fr_FR', 'en_US'])->willReturn(['normalizedData.label-fr_FR', 'normalizedData.label-en_US']); $namingUtility->appendSuffixes(['normalizedData.label-fr_FR', 'normalizedData.label-en_US'], ['mobile'])->willReturn(['normalizedData.label-fr_FR-mobile', 'normalizedData.label-en_US-mobile']); $mobile->getCode()->willReturn('mobile'); $this->generateQuery($mobile, '', '', '')->shouldReturn([[['normalizedData.label-fr_FR-mobile' => ['$exists' => true]], ['$unset' => ['normalizedData.label-fr_FR-mobile' => '']], ['multiple' => true]], [['normalizedData.label-en_US-mobile' => ['$exists' => true]], ['$unset' => ['normalizedData.label-en_US-mobile' => '']], ['multiple' => true]]]); }
function it_normalizes_channel(ChannelInterface $channel, CategoryInterface $category, CurrencyInterface $currencyUSD, CurrencyInterface $currencyEUR) { $units = ['weight_attribute' => WeightFamilyInterface::GRAM, 'length_attribute' => LengthFamilyInterface::CENTIMETER]; $channel->getCode()->willReturn('my_code'); $channel->getLabel()->willReturn('my_label'); $channel->getCurrencies()->willReturn([$currencyEUR, $currencyUSD]); $channel->getLocaleCodes()->willReturn(['fr_FR', 'en_US', 'de_DE', 'es_ES']); $channel->getCategory()->willReturn($category); $channel->getConversionUnits()->willReturn($units); $category->getCode()->willReturn('winter'); $currencyEUR->getCode()->willReturn('EUR'); $currencyUSD->getCode()->willReturn('USD'); $this->normalize($channel, 'standard', [])->shouldReturn(['code' => 'my_code', 'label' => 'my_label', 'currencies' => ['EUR', 'USD'], 'locales' => ['fr_FR', 'en_US', 'de_DE', 'es_ES'], 'category_tree' => 'winter', 'conversion_units' => $units]); }
function it_normalizes_channel(ChannelInterface $channel, CurrencyInterface $eur, CurrencyInterface $usd, LocaleInterface $en, LocaleInterface $fr, CategoryInterface $category) { $channel->getCode()->willReturn('ecommerce'); $channel->getLabel()->willReturn('Ecommerce'); $channel->getCurrencies()->willReturn([$eur, $usd]); $eur->getCode()->willReturn('EUR'); $usd->getCode()->willReturn('USD'); $channel->getLocales()->willReturn([$en, $fr]); $en->getCode()->willReturn('en_US'); $fr->getCode()->willReturn('fr_FR'); $channel->getCategory()->willReturn($category); $category->getCode()->willReturn('Master catalog'); $channel->getConversionUnits()->willReturn(['Weight' => 'Kilogram', 'Size' => 'Centimeter']); $this->normalize($channel)->shouldReturn(['code' => 'ecommerce', 'label' => 'Ecommerce', 'currencies' => 'EUR,USD', 'locales' => 'en_US,fr_FR', 'category' => 'Master catalog', 'conversion_units' => 'Weight: Kilogram, Size: Centimeter']); }
function it_builds_user_product_context_for_normalization($tokenStorage, $localeRepository, $channelRepository, $choicesBuilder, ChannelInterface $userChannel, ChannelInterface $ecommerce, LocaleInterface $fr, LocaleInterface $en, TokenInterface $token, UserInterface $user) { $userChannel->getCode()->willReturn('mobile'); $channelRepository->findOneByIdentifier([])->willReturn($userChannel); $tokenStorage->getToken()->willReturn($token); $token->getUser()->willReturn($user); $channelRepository->findAll()->willReturn([$ecommerce]); $choicesBuilder->buildChoices([$ecommerce])->willReturn(['mobile' => $userChannel, 'ecommerce' => $ecommerce]); $fr->getCode()->willReturn('fr_FR'); $en->getCode()->willReturn('en_US'); $localeRepository->getActivatedLocales()->willReturn([$en, $fr]); $user->getUiLocale()->willReturn($fr); $user->getCatalogScope()->willReturn($userChannel); $this->toArray()->shouldReturn(['locales' => ['en_US', 'fr_FR'], 'channels' => ['mobile', 'ecommerce'], 'locale' => 'fr_FR']); }
function it_normalizes_channel(ChannelInterface $channel, CurrencyInterface $eur, CurrencyInterface $usd, LocaleInterface $en, LocaleInterface $fr, CategoryInterface $category, CategoryTranslationInterface $translation) { $channel->getCode()->willReturn('ecommerce'); $channel->getLabel()->willReturn('Ecommerce'); $channel->getCurrencies()->willReturn([$eur, $usd]); $eur->getCode()->willReturn('EUR'); $usd->getCode()->willReturn('USD'); $channel->getLocales()->willReturn([$en, $fr]); $en->getCode()->willReturn('en_US'); $fr->getCode()->willReturn('fr_FR'); $channel->getCategory()->willReturn($category); $category->getCode()->willReturn('master'); $category->getId()->willReturn(42); $translation->getLabel()->willReturn('label'); $translation->getLocale()->willReturn('en_US'); $category->getTranslations()->willReturn([$translation]); $channel->getConversionUnits()->willReturn(['Weight' => 'Kilogram', 'Size' => 'Centimeter']); $this->normalize($channel)->shouldReturn(['code' => 'ecommerce', 'label' => 'Ecommerce', 'currencies' => ['EUR', 'USD'], 'locales' => ['en_US', 'fr_FR'], 'category' => ['id' => 42, 'code' => 'master', 'labels' => ['en_US' => 'label']], 'conversion_units' => 'Weight: Kilogram, Size: Centimeter']); }
function it_removes_obsolete_scopable_indexes_when_channel_removed($collection, ChannelInterface $ecommerce) { $ecommerce->getCode()->willReturn('ecommerce'); $collection->getIndexInfo()->willReturn([["key" => ["_id" => 1]], ["key" => ["normalizedData.title-ecommerce-en_US" => 1]], ["key" => ["normalizedData.title-ecommerce-de_DE" => 1]], ["key" => ["normalizedData.title-mobile-de_DE" => 1]], ["key" => ["normalizedData.manufacturer_title" => 1]], ["key" => ["normalizedData.title_left-en_US" => 1]], ["key" => ["normalizedData.title_left-de_DE" => 1]], ["key" => ["normalizedData.price-ecommerce.EUR.data" => 1]], ["key" => ["normalizedData.price-mobile.USD.data" => 1]], ["key" => ["normalizedData.name-mobile" => 1]], ["key" => ["normalizedData.name-ecommerce" => 1]], ["key" => ["normalizedData.mobile_support.id" => 1]], ["key" => ["normalizedData.color-ecommerce.id" => 1]], ["key" => ["normalizedData.completenesses-ecommerce-en_US" => 1]], ["key" => ["normalizedData.completenesses-ecommerce-de_DE" => 1]]]); $collection->deleteIndex('normalizedData.title-ecommerce-en_US')->shouldBeCalled(); $collection->deleteIndex('normalizedData.title-ecommerce-de_DE')->shouldBeCalled(); $collection->deleteIndex('normalizedData.price-ecommerce.EUR.data')->shouldBeCalled(); $collection->deleteIndex('normalizedData.name-ecommerce')->shouldBeCalled(); $collection->deleteIndex('normalizedData.color-ecommerce.id')->shouldBeCalled(); $collection->deleteIndex('normalizedData.completenesses-ecommerce-en_US')->shouldBeCalled(); $collection->deleteIndex('normalizedData.completenesses-ecommerce-de_DE')->shouldBeCalled(); $this->purgeIndexesFromChannel($ecommerce); }
/** * {@inheritdoc} */ public function getChannelCode() { return $this->channel->getCode(); }
/** * {@inheritdoc} */ public function buildByChannelAndCompleteness(ChannelInterface $channel) { $qb = $this->createQueryBuilder('p'); foreach ($channel->getLocales() as $locale) { $qb->addOr($qb->expr()->field(sprintf('normalizedData.completenesses.%s-%s', $channel->getCode(), $locale->getCode()))->equals(100)); } $categoryIds = $this->categoryRepository->getAllChildrenIds($channel->getCategory()); $qb->addAnd($qb->expr()->field('categoryIds')->in($categoryIds)); return $qb; }
/** * Remove indexes associated with the provided channel * * @param ChannelInterface $channel */ public function purgeIndexesFromChannel(ChannelInterface $channel) { $channelPattern = sprintf('/^%s\\..+-%s/', ProductQueryUtility::NORMALIZED_FIELD, $channel->getCode()); $indexesToRemove = $this->getIndexesMatching($channelPattern); $this->removeIndexes($indexesToRemove); }
/** * {@inheritdoc} */ public function buildByChannelAndCompleteness(ChannelInterface $channel) { $scope = $channel->getCode(); $qb = $this->buildByScope($scope); $rootAlias = current($qb->getRootAliases()); $expression = 'pCompleteness.product = ' . $rootAlias . ' AND ' . $qb->expr()->eq('pCompleteness.ratio', '100') . ' AND ' . $qb->expr()->eq('pCompleteness.channel', $channel->getId()); $rootEntity = current($qb->getRootEntities()); $completenessMapping = $this->_em->getClassMetadata($rootEntity)->getAssociationMapping('completenesses'); $completenessClass = $completenessMapping['targetEntity']; $qb->innerJoin($completenessClass, 'pCompleteness', 'WITH', $expression); $treeId = $channel->getCategory()->getId(); $expression = $qb->expr()->eq('pCategory.root', $treeId); $qb->innerJoin($rootAlias . '.categories', 'pCategory', 'WITH', $expression); return $qb; }
/** * Update catalog scope of users using a channel that will be removed * * @param ChannelInterface $channel */ protected function onChannelRemoved(ChannelInterface $channel) { $users = $this->findUsersBy(['catalogScope' => $channel]); $scopes = $this->container->get('pim_catalog.manager.channel')->getChannels(); $defaultScope = current(array_filter($scopes, function ($scope) use($channel) { return $scope->getCode() !== $channel->getCode(); })); foreach ($users as $user) { $user->setCatalogScope($defaultScope); $this->computeChangeset($user); } }
/** * {@inheritdoc} */ public function scheduleForChannelAndLocale(ChannelInterface $channel, LocaleInterface $locale) { $productQb = $this->documentManager->createQueryBuilder($this->productClass); $pullExpr = $productQb->expr()->addAnd($productQb->expr()->field('channel')->equals($channel->getId()))->addAnd($productQb->expr()->field('locale')->equals($locale->getId())); $productQb->update()->multiple(true)->field(sprintf('normalizedData.completenesses.%s-%s', $channel->getCode(), $locale->getCode()))->unsetField()->field('completenesses')->pull($pullExpr)->getQuery()->execute(); }
function it_generates_completeness_indexes($namingUtility, $collection, ChannelInterface $channelWeb, ChannelInterface $channelPrint, LocaleInterface $localeFr, LocaleInterface $localeEn) { $indexes = array_fill(0, 10, 'fake_index'); $collection->getIndexInfo()->willReturn($indexes); $namingUtility->getChannels()->willReturn([$channelWeb, $channelPrint]); $channelWeb->getLocales()->willReturn([$localeEn]); $channelPrint->getLocales()->willReturn([$localeFr, $localeEn]); $channelPrint->getCode()->willReturn('PRINT'); $channelWeb->getCode()->willReturn('WEB'); $localeEn->getCode()->willReturn('en_US'); $localeFr->getCode()->willReturn('fr_FR'); $indexOptions = ['background' => true, 'w' => 0]; $collection->ensureIndex(['normalizedData.completenesses.PRINT-en_US' => 1], $indexOptions)->shouldBeCalled(); $collection->ensureIndex(['normalizedData.completenesses.PRINT-fr_FR' => 1], $indexOptions)->shouldBeCalled(); $collection->ensureIndex(['normalizedData.completenesses.WEB-en_US' => 1], $indexOptions)->shouldBeCalled(); $this->ensureCompletenessesIndexes(); }
/** * @param array $filters * @param ChannelInterface $channel * * @return CursorInterface */ protected function getProductsCursor(array $filters, ChannelInterface $channel = null) { $options = ['filters' => $filters]; if (null !== $channel) { $options['default_scope'] = $channel->getCode(); } $productQueryBuilder = $this->pqbFactory->create($options); return $productQueryBuilder->execute(); }
/** * Get the completeness fields for the channel * * @param ChannelInterface $channel * * @return array */ protected function getCompletenessNormFields(ChannelInterface $channel = null) { $normFields = []; $channels = []; if (null === $channel) { $channels = $this->namingUtility->getChannels(); } else { $channels[] = $channel; } foreach ($channels as $channel) { foreach ($channel->getLocales() as $locale) { $normFields[] = sprintf('%s.completenesses.%s-%s', ProductQueryUtility::NORMALIZED_FIELD, $channel->getCode(), $locale->getCode()); } } return $normFields; }