/** * Set up */ public function setUp() { parent::setUp(); $this->cart = $this->get('elcodi.factory.cart')->create(); $this->purchasable = $this->createPurchasable(); $this->cartLine = $this->get('elcodi.factory.cart_line')->create()->setPurchasable($this->purchasable)->setProductAmount($this->purchasable->getPrice())->setAmount($this->purchasable->getPrice())->setQuantity(1); $this->get('elcodi.event_dispatcher.cart')->dispatchCartLoadEvents($this->cart); }
/** * Overrides the product categories assigning the one saved as principal * category. * * @param ProductInterface $product The product being saved */ protected function fixProductCategory(ProductInterface $product) { $principalCategory = $product->getPrincipalCategory(); if ($principalCategory instanceof CategoryInterface) { $categories = new ArrayCollection(); $categories->add($principalCategory); $product->setCategories($categories); } }
/** * Given a specific Product, return a simple collection of related products * * @param ProductInterface $product Product * @param int $limit Limit * * @return ArrayCollection */ public function getRelatedProducts(ProductInterface $product, $limit) { $relatedProducts = new ArrayCollection(); $principalCategory = $product->getPrincipalCategory(); if ($principalCategory instanceof CategoryInterface) { $relatedProducts = $this->productRepository->createQueryBuilder('p')->select('p', 'v', 'o')->leftJoin('p.variants', 'v')->leftJoin('v.options', 'o')->where('p.principalCategory = :principalCategory')->andWhere('p.enabled = :enabled')->setParameters(['principalCategory' => $principalCategory, 'enabled' => true])->getQuery()->getResult(); $relatedProducts = new ArrayCollection($relatedProducts); $relatedProducts->removeElement($product); $relatedProducts = $relatedProducts->slice(0, $limit); } return $relatedProducts; }
/** * Product view * * @param ProductInterface $product Product * @param string $slug Product slug * * @return array * * @Route( * path = "/{slug}/{id}", * name = "store_product_view", * requirements = { * "slug": "[\w-]+", * "id": "\d+", * }, * methods = {"GET"} * ) * * @AnnotationEntity( * class = "elcodi.entity.product.class", * name = "product", * mapping = { * "id" = "~id~", * "enabled" = true, * } * ) */ public function viewAction(ProductInterface $product, $slug) { /** * We must check that the product slug is right. Otherwise we must * return a Redirection 301 to the right url */ if ($slug !== $product->getSlug()) { return $this->redirectToRoute('store_product_view', ['id' => $product->getId(), 'slug' => $product->getSlug()], 301); } $useStock = $this->get('elcodi.store')->getUseStock(); $relatedProducts = $this->get('elcodi_store.provider.product_collection')->getRelatedProducts($product, 3); $template = $product->hasVariants() ? 'Pages:product-view-variant.html.twig' : 'Pages:product-view-item.html.twig'; return $this->renderTemplate($template, ['product' => $product, 'related_products' => $relatedProducts, 'useStock' => $useStock]); }
/** * Adds an option to this variant. * * Passed option Attribute is also added to the attribute collection * of the parent Product. * * If Variant::product is not set or does not implement ProductInterface * a LogicException is thrown: presence of the parent product is mandatory * since adding an Option to a Variant also updates the Parent product * Attribute collection. This way Variant::options and Product::attributes * are synchronized * * @param ValueInterface $option * * @throws \LogicException * * @return $this Self object */ public function addOption(ValueInterface $option) { if (!$this->product instanceof ProductInterface) { throw new \LogicException('Cannot add options to a Variant before setting a parent Product'); } $this->options->add($option); $this->product->addAttribute($option->getAttribute()); return $this; }
/** * Fixes the product categories. * * @param ProductInterface $product The product to fix. */ public function fixProduct(ProductInterface $product) { $principalCategory = $product->getPrincipalCategory(); $categories = $product->getCategories(); if (!empty($principalCategory) && !$categories->contains($principalCategory)) { /** * The product has a principal category but this one is not assigned * as product category so this one is added. */ $categories->add($principalCategory); $product->setCategories($categories); } elseif (empty($principalCategory) && 0 < $categories->count()) { /** * The product does not have principal category but has categories * assigned so the first category is assigned as principal category. */ $product->setPrincipalCategory($categories->first()); } }
/** * Returns an array of unique available options for a Product. * * Returned Options belong to Variants available for purchase * * @param ProductInterface $product Product * @param AttributeInterface $attribute Attribute * * @return ArrayCollection */ public function getAvailableOptions(ProductInterface $product, AttributeInterface $attribute) { $availableOptions = new ArrayCollection(); foreach ($product->getVariants() as $variant) { /** * @var VariantInterface $variant */ if (!$variant->isEnabled() || $variant->getStock() <= 0) { continue; } foreach ($variant->getOptions() as $option) { /** * @var ValueInterface $option */ if ($option->getAttribute() == $attribute && !$availableOptions->contains($option)) { $availableOptions->add($option); } } } return $availableOptions; }
/** * Given a Product and an array of integer representing the IDs of a Value Entity, * returns the Variant that is associated with the options matching the IDs, if any * * @param ProductInterface $product to compare Variants from * @param array $optionsSearchedIds array containing IDs of the options to match * * @return VariantInterface|null Variant if found, or null if not */ public function findByOptionIds(ProductInterface $product, array $optionsSearchedIds = []) { sort($optionsSearchedIds); foreach ($product->getVariants() as $variant) { /** * @var VariantInterface $variant */ $optionsConfiguredIds = array_map(function (ValueInterface $option) { return $option->getId(); }, $variant->getOptions()->toArray()); sort($optionsConfiguredIds); if ($optionsSearchedIds == $optionsConfiguredIds) { /** * Options match, we found the product Variant */ return $variant; } } /** * No match, probable option misconfiguration in Variants */ return null; }
/** * Steps necessary to store an image * * @param ObjectManager $imageObjectManager Image ObjectManager * @param ImageManager $imageManager ImageManager * @param Filesystem $filesystem Filesystem * @param fileIdentifierTransformer $fileIdentifierTransformer fileIdentifierTransformer * @param ProductInterface $product Product * @param string $imageName Image name * * @return $this Self object */ protected function storeImage(ObjectManager $imageObjectManager, ImageManager $imageManager, Filesystem $filesystem, FileIdentifierTransformerInterface $fileIdentifierTransformer, ProductInterface $product, $imageName) { $imagePath = realpath(dirname(__FILE__) . '/images/' . $imageName); $image = $imageManager->createImage(new File($imagePath)); $image->setPath('products'); $imageObjectManager->persist($image); $imageObjectManager->flush($image); $filesystem->write($fileIdentifierTransformer->transform($image), file_get_contents($imagePath), true); $product->addImage($image); $product->setPrincipalImage($image); return $this; }
/** * Resolve name for product. * * @param ProductInterface $product Product * * @return string Resolve product name */ private function resolveProductName(ProductInterface $product) { return $product->getName(); }
/** * Edit and Saves product * * @param FormInterface $form Form * @param ProductInterface $product Product * @param boolean $isValid Is valid * * @return RedirectResponse Redirect response * * @Route( * path = "/{id}", * name = "admin_product_view", * requirements = { * "id" = "\d+", * }, * methods = {"GET"} * ) * @Route( * path = "/{id}/edit", * name = "admin_product_edit", * requirements = { * "id" = "\d+", * }, * methods = {"GET"} * ) * @Route( * path = "/{id}/update", * name = "admin_product_update", * requirements = { * "id" = "\d+", * }, * methods = {"POST"} * ) * * @Route( * path = "/new", * name = "admin_product_new", * methods = {"GET"} * ) * @Route( * path = "/new/update", * name = "admin_product_save", * methods = {"POST"} * ) * * @EntityAnnotation( * class = { * "factory" = "elcodi.factory.product", * "method" = "create", * "static" = false * }, * mapping = { * "id" = "~id~" * }, * mappingFallback = true, * name = "product", * persist = true * ) * @FormAnnotation( * class = "elcodi_admin_product_form_type_product", * name = "form", * entity = "product", * handleRequest = true, * validate = "isValid" * ) * * @Template */ public function editAction(FormInterface $form, ProductInterface $product, $isValid) { if ($isValid) { $firstImage = $product->getSortedImages()->first(); if ($firstImage instanceof ImageInterface) { $product->setPrincipalImage($firstImage); } $this->flush($product); $this->addFlash('success', $this->get('translator')->trans('admin.product.saved')); return $this->redirectToRoute('admin_product_list'); } return ['product' => $product, 'form' => $form->createView()]; }
/** * Steps necessary to store an image * * @param ProductInterface $product Product * @param string $imageName Image name * * @return $this Self object */ protected function storeProductImage(ProductInterface $product, $imageName) { $imagePath = realpath(dirname(__FILE__) . '/images/' . $imageName); $image = $this->storeImage($imagePath); $product->addImage($image); $product->setPrincipalImage($image); return $this; }
/** * Product manufacturer. * * @return ManufacturerInterface Manufacturer */ public function getManufacturer() { return $this->product->getManufacturer(); }