/** * Correct product amount to add to cart. * * @param \XLite\Model\Product $product Product to add * @param integer|null $amount Amount of product * * @return integer */ protected function correctAmountAsProduct(\XLite\Model\Product $product, $amount) { if (is_null($amount) && $product->mustHaveVariants()) { $amount = 1; } else { $amount = parent::correctAmountAsProduct($product, $amount); } return $amount; }
/** * Check attribute is variable or not * * @param \XLite\Model\Product $product Product * * @return boolean */ public function isVariable(\XLite\Model\Product $product) { $result = false; foreach ($product->getVariantsAttributes() as $a) { if ($a->getId() == $this->getId()) { $result = true; break; } } return $result; }
/** * Import 'attachmentsPrivate' value * * @param \XLite\Model\Product $model Product * @param array $value Value * @param array $column Column info * * @return void */ protected function importAttachmentsPrivateColumn(\XLite\Model\Product $model, array $value, array $column) { if ($value) { foreach ($value as $index => $val) { $attachment = $model->getAttachments()->get($index); if ($attachment) { $attachment->setPrivate($this->normalizeValueAsBoolean($val)); } } } }
/** * Return product options that are requested to add to cart with a provided product. * * @param \XLite\Model\Product $product Product class that is requested to add to cart * * @return array */ protected function getCurrentProductOptions(\XLite\Model\Product $product) { if (isset(\XLite\Core\Request::getInstance()->product_options)) { $options = $product->prepareOptions(\XLite\Core\Request::getInstance()->product_options); if (!$product->checkOptionsException($options)) { $options = null; } } else { $options = $product->getDefaultProductOptions(); } return $options; }
/** * Clone * * @return \XLite\Model\AEntity */ public function cloneEntity() { $newProduct = parent::cloneEntity(); foreach ($this->getAttachments() as $attachment) { $attachment->cloneEntityForProduct($newProduct); } $newProduct->update(true); return $newProduct; }
/** * Import 'sale' value * * @param \XLite\Model\Product $model Product * @param string $value Value * @param array $column Column info * * @return void */ protected function importSaleColumn(\XLite\Model\Product $model, $value, array $column) { if ($value) { $model->setParticipateSale(true); $model->setSalePriceValue(floatval($value)); $model->setDiscountType(strpos($value, '%') > 0 ? \XLite\Model\Product::SALE_DISCOUNT_TYPE_PERCENT : \XLite\Model\Product::SALE_DISCOUNT_TYPE_PRICE); } else { $model->setParticipateSale(false); } }
/** * Clone * * @return \XLite\Model\AEntity */ public function cloneEntity() { $newProduct = parent::cloneEntity(); if ($this->getUpsellingProducts()) { $this->cloneUpsellingLinks($newProduct, false); } if ($this->getUpsellingParentProducts()) { $this->cloneUpsellingLinks($newProduct, true); } return $newProduct; }
/** * Define query builder for getMinQuantities() * * @param \XLite\Model\Product $product Product entity * @param \XLite\Model\Membership $membership Membership entity (or null) OPTIONAL * * @return \Doctrine\ORM\QueryBuilder */ protected function defineMinQuantitiesQuery($product, $membership = null) { $qb = $this->createQueryBuilder('m'); $qb->innerJoin('m.product', 'product')->andWhere('product.product_id = :productId')->setParameter('productId', $product->getProductId()); if (!is_null($membership)) { $qb->innerJoin('m.membership', 'membership')->andWhere('membership.membership_id = :membershipId')->addOrderBy('membership.membership_id')->setParameter('membershipId', $membership->getMembershipId()); } else { $qb->andWhere('m.membership is null'); } return $qb; }
/** * Update product categories * * @param \XLite\Model\Product $model Product model * @param array $categoryIds List of IDs of new categories * * @return void */ protected function updateProductCategories($model, $categoryIds) { $categoriesToRemoveCache = array(); // List of old category IDs $oldCategoryIds = array(); // Get old category IDs list $oldCategoryProducts = $model->getCategoryProducts()->toArray(); if (!empty($oldCategoryProducts)) { foreach ($oldCategoryProducts as $cp) { $oldCategoryIds[] = $cp->getCategory()->getCategoryId(); if (!in_array($cp->getCategory()->getCategoryId(), $categoryIds)) { $categoriesToRemoveCache[] = $cp->getCategory()->getCategoryId(); } } } $categoriesToRemoveCache = array_merge($categoriesToRemoveCache, array_diff($categoryIds, $oldCategoryIds)); if ($categoriesToRemoveCache) { \XLite\Core\Database::getRepo('XLite\\Model\\Category')->removeProductFilterCache($categoriesToRemoveCache); } parent::updateProductCategories($model, $categoryIds); }
/** * Get registered label for product * * @param \XLite\Model\Product $product Product object * * @return array */ public static function getLabel(\XLite\Model\Product $product) { if (!isset(static::$labels[$product->getProductId()])) { static::$labels[$product->getProductId()] = $product->getFreeShip() ? static::getLabelContent() : ''; } return !empty(static::$labels[$product->getProductId()]) ? static::$labels[$product->getProductId()] : array(); }
/** * Clone product * * @return \XLite\Model\AEntity */ public function cloneEntity() { $newProduct = parent::cloneEntity(); if ($this->getTabs()) { foreach ($this->getTabs() as $tab) { $newTab = $tab->cloneEntity(); $newTab->setProduct($newProduct); $newProduct->addTabs($newTab); \XLite\Core\Database::getEM()->persist($newTab); } } return $newProduct; }
protected function checkProductOnList(\XLite\Model\Product $product, $modes, $sale, $type) { $listPrice = $this->formatPrice($product->getListPrice()); foreach ($modes as $mode) { $this->click('css=a.' . $mode); //$this->waitForAjaxProgress(); sleep(1); $this->assertElementPresent("css=.content .items-list .product.productid-" . $product->getProductId(), "Sale product missing, {$mode} mode, {$sale} {$type}"); $this->assertElementPresent("css=.content .items-list .productid-" . $product->getProductId() . " .label-orange.sale-price", "Sale label missing, {$mode} mode, {$sale} {$type}"); $this->assertNotEquals($product->getPrice(), $product->getListPrice(), "Price and list price equals, {$mode} mode, {$sale} {$type}"); $this->assertElementContainsText("css=.content .items-list .product.productid-" . $product->getProductId() . " .product-price", $listPrice, "Price shown without sale, {$mode} mode, {$sale} {$type}"); } }
/** * Reverse product price * * @param \XLite\Model\Product $product Product * @param float $amount Currenct product price OPTIONAL * * @return float */ public function reverseProductPrice(\XLite\Model\Product $product, $amount = null) { return $amount ?: $product->getPrice(); }
/** * Clone * * @return \XLite\Model\AEntity */ public function cloneEntity() { $newProduct = parent::cloneEntity(); $newProduct->setSales(0); return $newProduct; }
/** * Show message about wrong product amount * * @param \XLite\Model\Product $product Product to process * @param integer $amount Available amount * * @return void */ protected function processInvalidAmountError(\XLite\Model\Product $product, $amount) { \XLite\Core\TopMessage::addWarning('Only ' . $amount . ' items are available for the "' . $product->getName() . '" product'); }
/** * Register the change amount inventory * * @param integer $orderId Order identificator * @param \XLite\Model\Product $product Product object * @param integer $delta Inventory delta changes * * @return void */ public function registerChangeAmount($orderId, $product, $delta) { $inventory = $product->getInventory(); if ($inventory->getEnabled()) { $this->registerEvent($orderId, static::CODE_CHANGE_AMOUNT, $this->getOrderChangeAmountDescription($orderId, $delta, $inventory), $this->getOrderChangeAmountData($orderId, $product->getName(), $inventory->getPublicAmount(), $delta)); } }
/** * Returns product class variant attribute by name and group * * @param \XLite\Model\Product $model Product * @param string $name Attribute name * @param string $group Attribute group * * @return \XLite\Model\Attribute */ protected function findProductClassAttribute($model, $name, $group) { $attributes = $model->getProductClass() ? $model->getProductClass()->getAttributes()->toArray() : array(); /** @var \XLite\Model\Attribute $item */ return array_reduce($attributes, function ($carry, $item) use($name, $group) { return null === $carry && $name === $item->getName() && $group === ($item->getAttributeGroup() ? $item->getAttributeGroup()->getName() : '') ? $item : $carry; }, null); }
/** * Preprocess change product class * * @return void */ protected function preprocessChangeProductClass() { parent::preprocessChangeProductClass(); $changed = false; foreach ($this->getVariantsAttributes() as $va) { if ($va->getProductClass() && $va->getProductClass() == $this->productClass->getId()) { $this->getVariantsAttributes()->removeElement($va); $va->getVariantsProducts()->removeElement($this); $changed = true; } } if ($changed) { $this->checkVariants(); } }
/** * Import classes * * @param \XLite\Model\Product $product Product * @param string $data Data * * @return void */ protected function importClasses(\XLite\Model\Product $product, $data) { // Remove old classes foreach ($product->getClasses() as $class) { $class->getProducts()->removeElement($product); } $product->getClasses()->clear(); if ($data) { // Add classes links foreach (explode(';', $data) as $name) { $name = trim($name); $translation = \XLite\Core\Database::getRepo('XLite\\Model\\ProductClassTranslation')->findOneBy(array('name' => $name)); if ($translation) { $class = $translation->getOwner(); } else { $class = new \XLite\Model\ProductClass(); $class->setName($name); \XLite\Core\Database::getEM()->persist($class); } $class->addProducts($product); $product->addClasses($class); } } }
/** * Constructor * * @param array $data Entity properties OPTIONAL * * @return void */ public function __construct(array $data = array()) { $this->optionGroups = new \Doctrine\Common\Collections\ArrayCollection(); parent::__construct($data); }
/** * Import 'free shipping' value * * @param \XLite\Model\Product $model Product * @param string $value Value * @param array $column Column info * * @return void */ protected function importFreeShippingColumn(\XLite\Model\Product $model, $value, array $column) { $model->setFreeShip($this->normalizeValueAsBoolean($value)); }
/** * Get deleted product * * @return \XLite\Model\Product|void */ protected function getDeletedProduct() { if (!isset($this->dumpProduct)) { $this->dumpProduct = new \XLite\Model\Product(); $this->dumpProduct->setPrice($this->getItemPrice()); $this->dumpProduct->setName($this->getName()); $this->dumpProduct->setSku($this->getSku()); } return $this->dumpProduct; }
/** * Generate clean URL * * @param \XLite\Model\Product $model Product * @param string $value Value OPTIONAL * * @return void */ protected function generateCleanURL(\XLite\Model\Product $model, $value = '') { if (\XLite\Core\Converter::isEmptyString($value)) { if (!\XLite\Core\Converter::isEmptyString($this->currentRowData['name'])) { // Input cleanURL value is empty, trying to get product name from current row data $lngCodes = array_unique(array('en', $this->importer->getLanguageCode())); foreach ($lngCodes as $code) { if (!empty($this->currentRowData['name'][$code])) { $value = $this->currentRowData['name'][$code]; break; } } } if (\XLite\Core\Converter::isEmptyString($value)) { // Try to get value from current product name $value = $model->getName(); } } else { $value = preg_replace('/\\.html$/', '', $value); } /** @var \XLite\Model\Repo\CleanURL $repo */ $repo = \XLite\Core\Database::getRepo('XLite\\Model\\CleanURL'); $value = $repo->generateCleanURL($model, $value); if (!\XLite\Core\Converter::isEmptyString($value)) { $this->updateCleanURL($model, $value); } }
/** * Clone entity (inventory) * * @param \XLite\Model\Product $newProduct New product * * @return void */ protected function cloneEntityInventory(\XLite\Model\Product $newProduct) { $inventory = $this->getInventory()->cloneEntity(); $newProduct->setInventory($inventory); $inventory->setProduct($newProduct); }
/** * Return sale participation flag * * @param \XLite\Model\Product $product Product model * * @return boolean */ protected function participateSale(\XLite\Model\Product $product) { return $product->getParticipateSale() && $product->getSalePrice() < $product->getPrice(); }
/** * Generate SKU * * @param \XLite\Model\Product $product Product * * @return string */ public function generateSKU(\XLite\Model\Product $product) { $id = $product->getProductId(); if (11 > strlen((string) $id)) { $id = str_repeat('0', 11 - strlen((string) $id)) . $id; } $sku = (string) $id; $i = 0; $qb = $this->defineGenerateSKUQuery(); while ($i < static::SKU_GENERATION_LIMIT && 0 < intval($qb->setParameter('sku', $sku)->getSingleScalarResult())) { $i++; $sku = $id . '-' . $i; } if ($i >= static::SKU_GENERATION_LIMIT) { $sku = md5($sku . microtime(true)); } return $sku; }
/** * Calculate product net price * * @param \XLite\Model\Product $product Product * @param float $price Price * * @return float */ public function deductTaxFromPrice(\XLite\Model\Product $product, $price) { foreach ($this->getTaxes() as $tax) { $includedZones = $tax->getVATZone() ? array($tax->getVATZone()->getZoneId()) : array(); $included = $tax->getFilteredRate($includedZones, $tax->getVATMembership(), $product->getClasses()); if ($included) { $price -= $included->calculateProductPriceExcludingTax($product, $price); } } return $price; }
/** * Get product URL * * @param \XLite\Model\Product $product Product object * @param integer $categoryId Category ID * * @return string */ protected function getProductURL(\XLite\Model\Product $product, $categoryId = null) { $params = array(); $params['product_id'] = $product->getProductId(); if ($categoryId) { $found = false; $firstId = null; $productCategories = $product->getCategories(); if ($productCategories && (1 < count($productCategories) || LC_USE_CLEAN_URLS && !(bool) \Includes\Utils\ConfigParser::getOptions(array('clean_urls', 'use_canonical_urls_only')))) { foreach ($productCategories as $category) { if (!isset($firstId)) { $firstId = $category->getCategoryId(); } if ($category->getCategoryId() == $categoryId) { $found = true; break; } } if (!$found) { $categoryId = $firstId; } } else { $categoryId = null; } if ($categoryId) { $params['category_id'] = $categoryId; } } return \XLite\Core\Converter::buildURL('product', '', $params); }
/** * Import 'relatedProducts' value * * @param \XLite\Model\Product $model Product * @param array $value Value (array of related products SKUs) * @param array $column Column info * * @return void */ protected function importRelatedProductsColumn(\XLite\Model\Product $model, array $value, array $column) { $currentRelations = \XLite\Core\Database::getRepo('XLite\\Module\\XC\\Upselling\\Model\\UpsellingProduct')->getUpsellingProducts($model->getProductId()); $relSku = array(); if ($currentRelations) { // Get SKU cache of currently assigned related products // and remove related products which are not in new values list $toDelete = array(); foreach ($currentRelations as $rel) { $relSku[] = $rel->getProduct()->getSku(); if ($rel->getProduct() && !in_array($rel->getProduct()->getSku(), $value)) { $toDelete[] = $rel; } } if ($toDelete) { \XLite\Core\Database::getRepo('XLite\\Module\\XC\\Upselling\\Model\\UpsellingProduct')->deleteInBatch($toDelete); } } if ($value) { // Add current product SKU to avoid creations of the related product with the same SKU $relSku[] = $model->getSku(); foreach ($value as $relProductSku) { if (!in_array($relProductSku, $relSku)) { // Create new relation $relProduct = \XLite\Core\Database::getRepo('XLite\\Model\\Product')->findOneBySku($relProductSku); if ($relProduct) { $up = new \XLite\Module\XC\Upselling\Model\UpsellingProduct(); $up->setProduct($relProduct); $up->setParentProduct($model); \XLite\Core\Database::getEM()->persist($up); } } } } }
/** * Constructor * * @param array $data Entity properties OPTIONAL * * @return void */ public function __construct(array $data = array()) { $this->featuredProducts = new \Doctrine\Common\Collections\ArrayCollection(); parent::__construct($data); }