950 lines
31 KiB
PHP
950 lines
31 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Optimized version of product options managment
|
|
*/
|
|
class stNewProductOptions
|
|
{
|
|
protected static $cachePool = array();
|
|
|
|
protected static $filtersPool = null;
|
|
|
|
protected static $post_product_criteria = null;
|
|
|
|
protected static $pre_product_criteria = null;
|
|
|
|
protected static $hide_no_stock = true;
|
|
|
|
public static function updateProduct(Product $product, $selected_ids = array(), $selected_values = array(), $hide_no_stock = true)
|
|
{
|
|
$debug = sfConfig::get('sf_logging_enabled') && sfConfig::get('sf_debug');
|
|
|
|
if ($debug)
|
|
{
|
|
$timer = sfTimerManager::getTimer('__SOTE stNewProductOptions::updateProduct()');
|
|
}
|
|
|
|
if (!isset(self::$cachePool[$product->getId()]))
|
|
{
|
|
$options = ProductOptionsValuePeer::doSelectByProduct($product, $hide_no_stock);
|
|
|
|
$price_type = ProductOptionsValuePeer::getPriceType($product);
|
|
|
|
self::$hide_no_stock = $hide_no_stock;
|
|
|
|
self::updateProductRecursive($product, $options, $price_type, $selected_ids, $asset_image_id, $selected_values);
|
|
|
|
self::updateProductImage($product, $asset_image_id);
|
|
|
|
stEventDispatcher::getInstance()->notify(new sfEvent($product, 'stNewProductOptions.updateProduct'));
|
|
|
|
self::$cachePool[$product->getId()] = array(
|
|
'price_modifiers' => $product->getPriceModifiers(),
|
|
'stock' => $product->getStock(),
|
|
'weight' => $product->getWeight(),
|
|
'selected_options' => $selected_ids,
|
|
'asset_image' => $product->getDefaultAssetImage(),
|
|
'image' => $product->getOptImage(),
|
|
'currency_old_price' => $product->getCurrencyOldPrice(),
|
|
'old_price' => $product->getOldPriceBrutto(),
|
|
'code' => $product->getCode(),
|
|
'man_code' => $product->getManCode(),
|
|
'pum' => $product->getBpumDefaultValue(),
|
|
);
|
|
|
|
self::$hide_no_stock = true;
|
|
}
|
|
else
|
|
{
|
|
$cache = self::$cachePool[$product->getId()];
|
|
|
|
$product->setPriceModifiers($cache['price_modifiers']);
|
|
|
|
$product->setStock($cache['stock']);
|
|
|
|
$product->setWeight($cache['weight']);
|
|
|
|
$product->setBpumDefaultValue($cache['pum']);
|
|
|
|
$product->setDefaultAssetImage($cache['asset_image']);
|
|
|
|
$product->setOptImage($cache['image']);
|
|
|
|
$product->setOldPriceBrutto($cache['old_price']);
|
|
|
|
$product->setCurrencyOldPrice($cache['currency_old_price']);
|
|
|
|
$product->setCode($cache['code']);
|
|
|
|
$product->setManCode($cache['man_code']);
|
|
|
|
$selected_ids = $cache['selected_options'];
|
|
|
|
$product->resetModified();
|
|
}
|
|
|
|
if ($debug)
|
|
{
|
|
$timer->addTime();
|
|
}
|
|
|
|
return $selected_ids;
|
|
}
|
|
|
|
public static function getSelectedOptions($product)
|
|
{
|
|
return isset(self::$cachePool[$product->getId()]) ? self::$cachePool[$product->getId()]['selected_options'] : array();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param Product $product
|
|
* @param ProductOptionsValue[] $options
|
|
* @param array $allowedParentIds
|
|
* @param array $reserverFieldIds
|
|
* @return bool Zwraca false w przypadku niedozwolonej kombinacji opcji produktu
|
|
* @throws PropelException
|
|
* @throws SQLException
|
|
*/
|
|
public static function updateProductBySelectedOptions(Product $product, array $options, array &$allowedParentIds = [], array &$reserverFieldIds = [])
|
|
{
|
|
if ($options)
|
|
{
|
|
ProductOptionsValue::setProductPool($product);
|
|
|
|
$price_type = ProductOptionsValuePeer::getPriceType($product);
|
|
|
|
$image = null;
|
|
|
|
$product->setPriceModifiers(array());
|
|
|
|
foreach ($options as $option)
|
|
{
|
|
if (!empty($allowedParentIds) && !isset($allowedParentIds[$option->getProductOptionsValueId()]) || isset($reserverFieldIds[$option->getProductOptionsFieldId()]))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (isset($allowedParentIds[$option->getId()]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
self::addProductPriceModifier($product, $option->getPrice($price_type), $option->getDepth(), $price_type, array('id' => $option->getId(), 'label' => $option->getValue(), 'color' => $option->getUseImageAsColor() ? $option->getColorImagePath() : $option->getColor(), 'field' => $option->getProductOptionsField()->getName(), 'type' => 'product_options'));
|
|
|
|
if ($option->getsfAssetId())
|
|
{
|
|
$image = $option->getsfAssetId();
|
|
}
|
|
|
|
if ($option->isLeaf())
|
|
{
|
|
self::updateProductStock($product, $option->getStock());
|
|
}
|
|
self::updateProductOldPrice($product, $option);
|
|
self::updateProductWeight($product, $option->getWeight());
|
|
|
|
if ($option->getUseProduct())
|
|
{
|
|
$product->setCode($option->getUseProduct());
|
|
}
|
|
|
|
if ($option->getManCode())
|
|
{
|
|
$product->setManCode($option->getManCode());
|
|
}
|
|
|
|
if ($option->getPum())
|
|
{
|
|
$product->setBpumDefaultValue($option->getPum());
|
|
}
|
|
|
|
$allowedParentIds[$option->getId()] = $option->getId();
|
|
$allowedParentIds[$option->getProductOptionsValueId()] = $option->getProductOptionsValueId();
|
|
$reserverFieldIds[$option->getProductOptionsFieldId()] = $option->getProductOptionsFieldId();
|
|
}
|
|
|
|
self::updateProductImage($product, $image);
|
|
|
|
$product->resetModified();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param Product $product
|
|
* @param ProductOptionsValue[] $options
|
|
* @param string $price_type
|
|
* @param int[] $selected_ids
|
|
* @param int $asset_image_id
|
|
* @param array $selected_values
|
|
* @param int $index
|
|
* @return void
|
|
* @throws PropelException
|
|
* @throws SQLException
|
|
*/
|
|
public static function updateProductRecursive($product, $options, $price_type, &$selected_ids, &$asset_image_id, &$selected_values = array(), &$index = 0)
|
|
{
|
|
if (empty($options))
|
|
{
|
|
if ($product->hasOptions())
|
|
{
|
|
self::updateProductStock($product, 0);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
$selectDefaultOptions = !$product->getConfiguration()->get('disable_default_option_select', false);
|
|
|
|
$selected = null;
|
|
|
|
$field_id = $options[0]->getProductOptionsFieldId();
|
|
|
|
$first_option = $options[0];
|
|
|
|
foreach ($options as $option)
|
|
{
|
|
$field = $option->getProductOptionsField();
|
|
|
|
if ($selectDefaultOptions && null === $selected && $option->getOptValue() == $field->getOptDefaultValue() && $field->getId() == $field_id)
|
|
{
|
|
$selected = $option;
|
|
}
|
|
|
|
if (isset($selected_values[$index]) && isset($selected_values[$index][trim($option->getOptValue())]))
|
|
{
|
|
$selected = $option;
|
|
unset($selected_values[$index][trim($option->getOptValue())]);
|
|
}
|
|
|
|
if ($field->getId() != $field_id && ($selectDefaultOptions || null !== $selected))
|
|
{
|
|
self::updateProductRecursiveHelper($product, $price_type, $selected_ids, $asset_image_id, $selected_values, $index, $option, $selected, $field_id, $first_option);
|
|
}
|
|
}
|
|
|
|
if ($selectDefaultOptions || null !== $selected)
|
|
{
|
|
self::updateProductRecursiveHelper($product, $price_type, $selected_ids, $asset_image_id, $selected_values, $index, $option, $selected, $field_id, $first_option);
|
|
}
|
|
|
|
$product->resetModified();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param Product $product
|
|
* @param mixed $price_type
|
|
* @param mixed $selected_ids
|
|
* @param mixed $asset_image_id
|
|
* @param array $selected_values
|
|
* @param int $index
|
|
* @param mixed $option
|
|
* @param mixed $selected
|
|
* @param mixed $field_id
|
|
* @param mixed $first_option
|
|
* @return void
|
|
* @throws PropelException
|
|
* @throws SQLException
|
|
*/
|
|
public static function updateProductRecursiveHelper($product, $price_type, &$selected_ids, &$asset_image_id, &$selected_values = array(), &$index = 0, $option, &$selected, &$field_id, &$first_option)
|
|
{
|
|
$index++;
|
|
|
|
$field = $option->getProductOptionsField();
|
|
|
|
if (null === $selected)
|
|
{
|
|
$selected = $first_option;
|
|
}
|
|
|
|
$selected_ids[$field_id] = $selected->getId();
|
|
|
|
if ($selected->getsfAssetId())
|
|
{
|
|
$asset_image_id = $selected->getsfAssetId();
|
|
}
|
|
|
|
self::addProductPriceModifier($product, $selected->getPrice($price_type), $selected->getDepth(), $price_type, array('id' => $selected->getId(), 'label' => $selected->getValue(), 'color' => $selected->getUseImageAsColor() ? $selected->getColorImagePath() : $selected->getColor(), 'field' => $selected->getProductOptionsField()->getName(), 'type' => 'product_options'));
|
|
self::updateProductWeight($product, $selected->getWeight());
|
|
|
|
if ($selected->getUseProduct())
|
|
{
|
|
$product->setCode($selected->getUseProduct());
|
|
}
|
|
|
|
if ($selected->getManCode())
|
|
{
|
|
$product->setManCode($selected->getManCode());
|
|
}
|
|
|
|
if ($selected->hasChildren())
|
|
{
|
|
self::updateProductOldPrice($product, $selected);
|
|
self::updateProductRecursive($product, $selected->getChildOptions($product->getConfiguration()->get('hide_options_with_empty_stock') && self::$hide_no_stock), $price_type, $selected_ids, $asset_image_id, $selected_values, $index);
|
|
}
|
|
else
|
|
{
|
|
self::updateProductStock($product, $selected->getStock());
|
|
self::updateProductOldPrice($product, $selected);
|
|
if ($selected->getPum())
|
|
{
|
|
$product->setBpumDefaultValue($selected->getPum());
|
|
}
|
|
}
|
|
|
|
$selected = null;
|
|
|
|
$first_option = $option;
|
|
|
|
if (isset($selected_values[$index]) && isset($selected_values[$index][trim($option->getOptValue())]))
|
|
{
|
|
$selected = $option;
|
|
unset($selected_values[$index][trim($option->getOptValue())]);
|
|
}
|
|
|
|
$field_id = $field->getId();
|
|
}
|
|
|
|
/**
|
|
* Zwraca wybrane opcje w postaci nazwa i przypisanymi ich ID
|
|
*
|
|
* @param ProductOptionsValue $option
|
|
* @param array $selected Wybrane opcje
|
|
* @param array $values Wybrane nazwy wartości opcji i odpowiadające im ID
|
|
* @param array $parents Zmienna pomocnicza
|
|
* @param mixed $index Zmienna pomocnicza
|
|
* @return void
|
|
*/
|
|
public static function buildSelectOptionsValues(ProductOptionsValue $option, array $selected, array &$values, array &$parents = [], &$index = 0)
|
|
{
|
|
if ($index > 0 && $option->getDepth() > 1 && !isset($parents[$option->getParentId()]))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$selectDefaultOptions = stConfig::getInstance('stProduct')->get('disable_default_option_select', false);
|
|
|
|
$values[$index][trim($option->getOptValue())] = $option->getId();
|
|
$parents[$option->getId()] = $option->getId();
|
|
|
|
$index++;
|
|
|
|
if ($option->hasChildren())
|
|
{
|
|
|
|
foreach ($option->getChildren() as $child)
|
|
{
|
|
$field = $child->getProductOptionsField();
|
|
|
|
$isSelected = isset($selected[$field->getId()]) ? $selected[$field->getId()] : null;
|
|
|
|
if (!in_array($child->getId(), $selected) && (null === $isSelected && $selectDefaultOptions && $field->getOptDefaultValue() == $child->getOptValue() || null !== $isSelected && $isSelected == $child->getId()))
|
|
{
|
|
self::buildSelectOptionsValues($child, $selected, $values, $parents, $index);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function updateProductWeight($product, $weight)
|
|
{
|
|
list($prefix, $type, $value) = self::parseValue($weight);
|
|
|
|
$base_weight = $product->getWeight();
|
|
|
|
if ($type == 'percent')
|
|
{
|
|
$value = stPrice::percentValue($base_weight, $value);
|
|
}
|
|
|
|
if ($prefix)
|
|
{
|
|
$base_weight += $prefix . $value;
|
|
}
|
|
elseif ($value != 0)
|
|
{
|
|
$base_weight = $value;
|
|
}
|
|
|
|
if ($base_weight < 0)
|
|
{
|
|
$base_weight = 0;
|
|
}
|
|
|
|
$product->setWeight(stPrice::round($base_weight));
|
|
}
|
|
|
|
public static function parseValue($value)
|
|
{
|
|
if (!$value)
|
|
{
|
|
return array(null, 'numeric', null);
|
|
}
|
|
|
|
$prefix = $value{
|
|
0} == '+' || $value{
|
|
0} == '-' ? $value{
|
|
0} : null;
|
|
$type = substr($value, -1) == '%' ? 'percent' : 'numeric';
|
|
|
|
return array($prefix, $type, floatval(trim($value, '+-%')));
|
|
}
|
|
|
|
/**
|
|
* Dodaje modyfikator ceny do produktu
|
|
*
|
|
* @param Product $product
|
|
* @param string $price Modyfikator ceny
|
|
* @param int $depth Poziom
|
|
* @param string $price_type Typ ceny
|
|
* @param array $custom Własne parametry
|
|
* @return void
|
|
*/
|
|
public static function addProductPriceModifier($product, $price, $depth, $price_type, $custom = array())
|
|
{
|
|
if (!$price)
|
|
{
|
|
$value = null;
|
|
|
|
$type = null;
|
|
|
|
$prefix = null;
|
|
}
|
|
else
|
|
{
|
|
list($prefix, $type, $price_value) = self::parseValue($price);
|
|
|
|
if ($type == 'numeric')
|
|
{
|
|
$price = $price_value;
|
|
|
|
$tax = $product->getTax();
|
|
|
|
$taxRate = $product->getVat();
|
|
|
|
$type = 'numeric';
|
|
|
|
if ($product->getCurrencyExchange() != 1)
|
|
{
|
|
$value = array('currency_brutto' => $price, 'tax' => $taxRate);
|
|
|
|
$value['brutto'] = stCurrency::calculateCurrencyPrice($price, $product->getCurrencyExchange(), true);
|
|
|
|
$value['netto'] = stPrice::extract($value['brutto'], $taxRate);
|
|
|
|
$value['currency_netto'] = stCurrency::calculateCurrencyPrice($value['netto'], $product->getCurrencyExchange());
|
|
}
|
|
else
|
|
{
|
|
$value = array($price_type => $price, 'tax' => $taxRate);
|
|
|
|
if ($price_type == 'netto')
|
|
{
|
|
$value['brutto'] = stPrice::calculate($price, $taxRate);
|
|
}
|
|
else
|
|
{
|
|
if ($tax && null !== $tax->getTaxRateByCountry())
|
|
{
|
|
$value['netto'] = stPrice::extract($price, $tax->getDefaultTaxRate());
|
|
$value['brutto'] = stPrice::calculate($value['netto'], $tax->getTaxRateByCountry());
|
|
}
|
|
else
|
|
{
|
|
$value['netto'] = stPrice::extract($price, $taxRate);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$value = $price_value;
|
|
}
|
|
}
|
|
|
|
$product->addPriceModifier($value, $type, $prefix, $depth, $custom);
|
|
}
|
|
|
|
public static function updateProductStock($product, $stock)
|
|
{
|
|
if ($product->getStockManagment() == ProductPeer::STOCK_PRODUCT_OPTIONS && $product->getStock() !== null && null !== $stock)
|
|
{
|
|
$product->setStock($stock);
|
|
}
|
|
}
|
|
|
|
public static function updateProductOldPrice($product, $selected)
|
|
{
|
|
$oldPrice = $selected->getOldPrice();
|
|
|
|
if ($oldPrice > 0)
|
|
{
|
|
if ($product->getCurrencyExchange() != 1)
|
|
{
|
|
$product->setCurrencyOldPrice($oldPrice);
|
|
$product->setOldPriceBrutto($product->getGlobalCurrency()->exchange($oldPrice, true, $product->getCurrencyExchange()));
|
|
}
|
|
else
|
|
{
|
|
if (ProductOptionsValuePeer::getPriceType($product) == 'netto')
|
|
{
|
|
$product->setOldPriceBrutto(stPrice::calculate($oldPrice, $product->getOptVat()));
|
|
}
|
|
else
|
|
{
|
|
$product->setOldPriceBrutto($oldPrice);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function updateProductImage($product, $asset)
|
|
{
|
|
if ($asset)
|
|
{
|
|
$product->setDefaultAssetImage($asset);
|
|
|
|
$default = $product->getDefaultAssetImage();
|
|
|
|
if ($default)
|
|
{
|
|
$product->setOptImage($default->getRelativePath());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Kopiowanie opcji produktu
|
|
* @param object $source element zrodlowy
|
|
* @param object $dest element docelowy
|
|
*/
|
|
static public function copyDescendands($source, $dest)
|
|
{
|
|
if (count($source->getChildren()) != 0)
|
|
{
|
|
$transform_fields = array();
|
|
foreach ($source->getChildren() as $srcValue)
|
|
{
|
|
$dest = $dest->reload();
|
|
|
|
$newChild = new ProductOptionsValue();
|
|
$newChild->setProductId($dest->getProductId());
|
|
$newChild->setProductOptionsTemplateId(0);
|
|
|
|
$newChild->setCulture($srcValue->getCulture());
|
|
$newChild->setValue($srcValue->getValue());
|
|
$newChild->setStock($srcValue->getStock());
|
|
$newChild->setPrice($srcValue->getPrice());
|
|
$newChild->setPriceType($srcValue->getPriceType());
|
|
$newChild->setSfAsset(self::getDuplicatedImageId($dest->getProductId(), $srcValue));
|
|
$newChild->insertAsLastChildOf($dest);
|
|
$newChild->save();
|
|
|
|
if (empty($transform_fields[$srcValue->getProductOptionsFieldId()]))
|
|
{
|
|
$newField = new ProductOptionsField();
|
|
$oldField = $srcValue->getProductOptionsField();
|
|
|
|
$newField->setRequired($oldField->getRequired());
|
|
$newField->setProductOptionsTemplateId(0);
|
|
$newField->setCulture($oldField->getCulture());
|
|
$newField->setName($oldField->getName());
|
|
$newField->setDefaultValue($newField->getDefaultValue());
|
|
$newField->setOptValueId($newChild->getParentId());
|
|
$newField->save();
|
|
|
|
foreach ($oldField->getProductOptionsFieldI18ns() as $i18n)
|
|
{
|
|
$newField->setCulture($i18n->getCulture());
|
|
$newField->setName($i18n->getName());
|
|
$newField->setDefaultValue($i18n->getDefaultValue());
|
|
$newField->save();
|
|
}
|
|
|
|
$transform_fields[$srcValue->getProductOptionsFieldId()] = $newField->getId();
|
|
}
|
|
$newChild->setProductOptionsFieldId($transform_fields[$srcValue->getProductOptionsFieldId()]);
|
|
$newChild->save();
|
|
|
|
foreach ($srcValue->getProductOptionsValueI18ns() as $sourceI18n)
|
|
{
|
|
$newChild->setCulture($sourceI18n->getCulture());
|
|
$newChild->setValue($sourceI18n->getValue());
|
|
$newChild->setId($newChild->getId());
|
|
$newChild->save();
|
|
}
|
|
|
|
self::copyDescendands($srcValue, $newChild);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function getDuplicatedImageId($dest_product_id, $src_option)
|
|
{
|
|
$src_asset = $src_option->getSfAsset();
|
|
if (is_object($src_asset))
|
|
{
|
|
$src_filename = $src_asset->getFilename();
|
|
$c = new Criteria();
|
|
$c->add(ProductHasSfAssetPeer::PRODUCT_ID, $dest_product_id);
|
|
$c->add(SfAssetPeer::FILENAME, $src_filename);
|
|
$c->addJoin(SfAssetPeer::ID, ProductHasSfAssetPeer::SF_ASSET_ID);
|
|
return SfAssetPeer::doSelectOne($c);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static function clearCache($product = null)
|
|
{
|
|
$product->setPriceModifiers(array());
|
|
|
|
if (isset(self::$cachePool[$product->getId()]))
|
|
{
|
|
unset(self::$cachePool[$product->getId()]);
|
|
}
|
|
}
|
|
|
|
public static function clearStaticPool()
|
|
{
|
|
ProductOptionsValuePeer::clearStatic();
|
|
self::$cachePool = array();
|
|
}
|
|
|
|
public static function getOptionsFilters()
|
|
{
|
|
|
|
$pConfig = stConfig::getInstance(null, 'stProduct');
|
|
|
|
$c = new Criteria();
|
|
|
|
$c->add(ProductOptionsFilterPeer::FILTER_TYPE, ProductOptionsFilterPeer::PRICE_FILTER, Criteria::NOT_EQUAL);
|
|
$c->add(ProductOptionsFilterPeer::IS_VISIBLE, true);
|
|
|
|
$filters = ProductOptionsFilterPeer::doSelectWithI18n($c);
|
|
|
|
if (!$filters)
|
|
{
|
|
return array();
|
|
}
|
|
|
|
$ids = array();
|
|
|
|
foreach ($filters as $filter)
|
|
{
|
|
$ids[] = $filter->getId();
|
|
}
|
|
|
|
/**
|
|
* @var Criteria
|
|
*/
|
|
$c = !stConfig::getInstance('stProduct')->get('filter_narrow') ? clone self::$post_product_criteria : clone self::$pre_product_criteria;
|
|
$c->clearOrderByColumns();
|
|
$c->clearGroupByColumns();
|
|
$c->clearSelectColumns();
|
|
|
|
if ($pConfig->get('hide_options_with_empty_stock'))
|
|
{
|
|
$c->add(ProductOptionsValuePeer::STOCK, sprintf('(%1$s IS NULL OR %1$s > 0)', ProductOptionsValuePeer::STOCK), Criteria::CUSTOM);
|
|
}
|
|
|
|
$c->addSelectColumn(ProductOptionsValuePeer::OPT_FILTER_ID);
|
|
$c->add(ProductOptionsValuePeer::IS_ACTIVE, true);
|
|
|
|
$c->add(ProductOptionsValuePeer::OPT_FILTER_ID, $ids, Criteria::IN);
|
|
|
|
$c->addJoin(ProductPeer::ID, ProductOptionsValuePeer::PRODUCT_ID);
|
|
|
|
$c->addGroupByColumn(ProductOptionsValuePeer::OPT_FILTER_ID);
|
|
$c->addGroupByColumn(ProductPeer::ID);
|
|
|
|
$c->setDistinct();
|
|
|
|
$rs = ProductOptionsValuePeer::doSelectRS($c);
|
|
|
|
$available_ids = array();
|
|
|
|
while ($rs->next())
|
|
{
|
|
$row = $rs->getRow();
|
|
|
|
$available_ids[$row[0]] = $row[0];
|
|
}
|
|
|
|
$results = array();
|
|
|
|
if ($available_ids)
|
|
{
|
|
foreach ($filters as $index => $filter)
|
|
{
|
|
if (isset($available_ids[$filter->getId()]))
|
|
{
|
|
$results[] = $filter;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
public static function getOptionsForFilter($filter)
|
|
{
|
|
$config = stConfig::getInstance(null, 'stProduct');
|
|
|
|
/**
|
|
* @var Criteria
|
|
*/
|
|
$c = !stConfig::getInstance('stProduct')->get('filter_narrow') ? clone self::$post_product_criteria : clone self::$pre_product_criteria;
|
|
$c->clearOrderByColumns();
|
|
$c->clearGroupByColumns();
|
|
$c->clearSelectColumns();
|
|
$c->setLimit(null);
|
|
$c->setOffset(null);
|
|
|
|
if ($filter->getFilterType() == 2)
|
|
{
|
|
$c->addSelectColumn(ProductOptionsValuePeer::COLOR);
|
|
}
|
|
else
|
|
{
|
|
$c->addSelectColumn(ProductOptionsValuePeer::OPT_VALUE);
|
|
}
|
|
|
|
$c->add(ProductOptionsValuePeer::OPT_FILTER_ID, $filter->getId());
|
|
$c->addJoin(ProductPeer::ID, ProductOptionsValuePeer::PRODUCT_ID);
|
|
|
|
if ($filter->getFilterType() == 2)
|
|
{
|
|
$c->addGroupByColumn(ProductOptionsValuePeer::COLOR);
|
|
}
|
|
else
|
|
{
|
|
$c->addGroupByColumn(ProductOptionsValuePeer::OPT_VALUE);
|
|
}
|
|
|
|
$c->addGroupByColumn(ProductPeer::ID);
|
|
|
|
$c->add(ProductOptionsValuePeer::IS_ACTIVE, true);
|
|
|
|
if ($config->get('hide_options_with_empty_stock'))
|
|
{
|
|
$c->add(ProductOptionsValuePeer::STOCK, sprintf('(%1$s IS NULL OR %1$s > 0)', ProductOptionsValuePeer::STOCK), Criteria::CUSTOM);
|
|
}
|
|
|
|
$c->setDistinct();
|
|
|
|
$rs = ProductOptionsValuePeer::doSelectRS($c);
|
|
|
|
$rs->setFetchmode(ResultSet::FETCHMODE_NUM);
|
|
|
|
$values = array();
|
|
|
|
while ($rs->next())
|
|
{
|
|
$values[] = $rs->getString(1);
|
|
}
|
|
|
|
$oc = new Criteria();
|
|
$oc->add(ProductOptionsValuePeer::OPT_FILTER_ID, $filter->getId());
|
|
|
|
if ($filter->getFilterType() == 2)
|
|
{
|
|
$oc->add(ProductOptionsValuePeer::COLOR, $values, Criteria::IN);
|
|
$oc->addGroupByColumn(ProductOptionsValuePeer::COLOR);
|
|
}
|
|
else
|
|
{
|
|
$oc->add(ProductOptionsValuePeer::OPT_VALUE, $values, Criteria::IN);
|
|
$oc->addGroupByColumn(ProductOptionsValuePeer::OPT_VALUE);
|
|
}
|
|
|
|
|
|
|
|
$options = ProductOptionsValuePeer::doSelectWithI18n($oc);
|
|
|
|
uasort($options, array('stNewProductOptions', 'sortHelper'));
|
|
|
|
return $options;
|
|
}
|
|
|
|
public static function sortHelper($o1, $o2)
|
|
{
|
|
return strnatcasecmp($o1->getValue(), $o2->getValue());
|
|
}
|
|
|
|
public static function sortHelperArray($o1, $o2)
|
|
{
|
|
return strnatcasecmp($o1['value'], $o2['value']);
|
|
}
|
|
|
|
/**
|
|
* Returns Filter criteria
|
|
*
|
|
* @return Criteria
|
|
*/
|
|
protected static function getCriteriaForFilter()
|
|
{
|
|
$c = !stConfig::getInstance('stProduct')->get('filter_narrow') ? clone self::$post_product_criteria : clone self::$pre_product_criteria;
|
|
$c->clearSelectColumns()->clearOrderByColumns();
|
|
$c->addSelectColumn(ProductPeer::ID);
|
|
$c->add('custom_option_join', sprintf("%s = %s", ProductOptionsValuePeer::PRODUCT_ID, ProductPeer::ID), Criteria::CUSTOM | Criteria::IGNORE_TABLE);
|
|
$c->setLimit(null);
|
|
$c->setOffset(null);
|
|
|
|
return $c;
|
|
}
|
|
|
|
protected static function getFilterById($id)
|
|
{
|
|
if (null === self::$filtersPool)
|
|
{
|
|
$filters = array();
|
|
foreach (ProductOptionsFilterPeer::doSelect(new Criteria()) as $filter)
|
|
{
|
|
$filters[$filter->getId()] = $filter;
|
|
}
|
|
self::$filtersPool = $filters;
|
|
}
|
|
|
|
return isset(self::$filtersPool[$id]) ? self::$filtersPool[$id] : null;
|
|
}
|
|
|
|
public static function listFilter($event)
|
|
{
|
|
$action = $event->getSubject();
|
|
|
|
if (isset($action->product_pager))
|
|
{
|
|
$request = $action->getRequest();
|
|
|
|
if (!$request->hasParameter('filter') && $request->getHttpHeader('X-Moz') != 'prefetch')
|
|
{
|
|
self::clearFilters($action->getContext());
|
|
}
|
|
|
|
$c = $action->product_pager->getCriteria();
|
|
self::addOptionsFilterCriteria($action->getContext(), $c);
|
|
}
|
|
}
|
|
|
|
public static function addOptionsFilterCriteria(sfContext $context, Criteria $c)
|
|
{
|
|
self::$pre_product_criteria = clone $c;
|
|
|
|
$config = stConfig::getInstance('stProduct');
|
|
|
|
if (stNewProductOptions::hasFilters($context))
|
|
{
|
|
$pConfig = stConfig::getInstance('stProduct');
|
|
$filters = stNewProductOptions::getFilters($context);
|
|
|
|
if ($filters)
|
|
{
|
|
foreach ($filters as $id => $selected)
|
|
{
|
|
$filter = self::getFilterById($id);
|
|
$oc = new Criteria();
|
|
$oc->addSelectColumn(ProductOptionsValuePeer::ID);
|
|
$oc->add(ProductOptionsValuePeer::PRODUCT_ID, sprintf("%s = %s", ProductOptionsValuePeer::PRODUCT_ID, ProductPeer::ID), Criteria::CUSTOM);
|
|
$oc->add(ProductOptionsValuePeer::IS_ACTIVE, true);
|
|
if ($pConfig->get('hide_options_with_empty_stock'))
|
|
{
|
|
$oc->add(ProductOptionsValuePeer::STOCK, sprintf('(%1$s IS NULL OR %1$s > 0)', ProductOptionsValuePeer::STOCK), Criteria::CUSTOM);
|
|
}
|
|
$oc->add($filter->getFilterType() == 2 ? ProductOptionsValuePeer::COLOR : ProductOptionsValuePeer::OPT_VALUE, array_values($selected), Criteria::IN);
|
|
$oc->add(ProductOptionsValuePeer::OPT_FILTER_ID, $id);
|
|
$query = BasePeer::createSqlQuery($oc);
|
|
$cnew = $c->getNewCriterion(ProductPeer::ID, sprintf("EXISTS (%s)", $query), Criteria::CUSTOM);
|
|
$c->addAnd($cnew);
|
|
}
|
|
}
|
|
}
|
|
|
|
self::$post_product_criteria = clone $c;
|
|
}
|
|
|
|
|
|
public static function getFilters(sfContext $context)
|
|
{
|
|
return $context->getUser()->getAttribute('filters', array(), stProductFilter::getNamespace($context, 'soteshop/stProductOptions'));
|
|
}
|
|
|
|
public static function hasFilters(sfContext $context)
|
|
{
|
|
return (bool)self::getFilters($context);
|
|
}
|
|
|
|
public static function setFilters(sfContext $context, $filters)
|
|
{
|
|
$context->getUser()->setAttribute('filters', $filters, stProductFilter::getNamespace($context, 'soteshop/stProductOptions'));
|
|
}
|
|
|
|
public static function clearFilters(sfContext $context, $filter = null)
|
|
{
|
|
$filters = self::getFilters($context);
|
|
|
|
if ($filter && isset($filters[$filter]))
|
|
{
|
|
unset($filters[$filter]);
|
|
}
|
|
elseif (null === $filter)
|
|
{
|
|
$filters = array();
|
|
}
|
|
|
|
self::setFilters($context, $filters);
|
|
}
|
|
|
|
public static function saveProductColors($event)
|
|
{
|
|
$product = $event->getSubject();
|
|
$product_id = $product->getId();
|
|
|
|
if (!$product->isNew())
|
|
{
|
|
$c = new Criteria();
|
|
$c->addSelectColumn(ProductOptionsFilterPeer::ID);
|
|
$c->add(ProductOptionsFilterPeer::FILTER_TYPE, 2);
|
|
$rs = ProductOptionsFilterPeer::doSelectRs($c);
|
|
$filters = array();
|
|
|
|
while ($rs->next())
|
|
{
|
|
$filters[] = $rs->getInt(1);
|
|
}
|
|
|
|
if ($filters)
|
|
{
|
|
$c = new Criteria();
|
|
$c->addSelectColumn(ProductOptionsValuePeer::ID);
|
|
$c->addSelectColumn(ProductOptionsValuePeer::COLOR);
|
|
$c->addSelectColumn(ProductOptionsValuePeer::STOCK);
|
|
$c->addSelectColumn(ProductOptionsValuePeer::USE_IMAGE_AS_COLOR);
|
|
$c->add(ProductOptionsValuePeer::LFT, ProductOptionsValuePeer::RGT . " - " . ProductOptionsValuePeer::LFT . " > 0", Criteria::CUSTOM);
|
|
$c->add(ProductOptionsValuePeer::PRODUCT_ID, $product_id);
|
|
$c->add(ProductOptionsValuePeer::OPT_FILTER_ID, $filters, Criteria::IN);
|
|
$c->addDescendingOrderByColumn(ProductOptionsValuePeer::STOCK);
|
|
$c->addGroupByColumn(ProductOptionsValuePeer::COLOR);
|
|
$rs = ProductOptionsValuePeer::doSelectRs($c);
|
|
|
|
$colors = array();
|
|
|
|
while ($rs->next())
|
|
{
|
|
$row = $rs->getRow();
|
|
$colors[] = array(
|
|
'color' => $row[3] ? ProductOptionsValuePeer::getColorImagePath($product_id, $row[0], $row[1]) : $row[1],
|
|
'stock' => $row[2],
|
|
'image_as_color' => $row[3]
|
|
);
|
|
}
|
|
|
|
$product->setOptionsColor($colors);
|
|
}
|
|
}
|
|
}
|
|
}
|