public function execute()
 {
     if (!$this->getUser()->getRights('shop', 'settings')) {
         throw new waRightsException(_w('Access denied'));
     }
     $model = new shopFeatureModel();
     $values = array(waRequest::post('value'));
     $code = waRequest::post('code');
     if ($values && $code && ($feature = $model->getByField('code', $code))) {
         $this->response = $model->setValues($feature, $values);
     } else {
         $this->setError(_w('Product feature not found'));
     }
 }
 /**
  * Filters collection products by specified conditions. 
  * 
  * @param array $data Product filtering conditions:
  *     'in_stock_only'     => whether only products with positive or unlimited stock count must be returned
  *     'price_min'         => minimum price limit
  *     'price_max'         => maximum price limit
  *     '%feature_code%'    => feature value
  */
 public function filters($data)
 {
     if ($this->filtered) {
         return;
     }
     $delete = array('page', 'sort', 'order');
     foreach ($delete as $k) {
         if (isset($data[$k])) {
             unset($data[$k]);
         }
     }
     $config = wa('shop')->getConfig();
     if (isset($data['in_stock_only'])) {
         $this->where[] = '(p.count > 0 OR p.count IS NULL)';
     }
     if (isset($data['price_min']) && $data['price_min'] !== '') {
         $this->where[] = 'p.max_price >= ' . $this->toFloat(shop_currency($data['price_min'], true, $config->getCurrency(true), false));
         unset($data['price_min']);
     }
     if (isset($data['price_max']) && $data['price_max'] !== '') {
         $this->where[] = 'p.min_price <= ' . $this->toFloat(shop_currency($data['price_max'], true, $config->getCurrency(true), false));
         unset($data['price_max']);
     }
     $feature_model = new shopFeatureModel();
     $features = $feature_model->getByField('code', array_keys($data), 'code');
     foreach ($data as $feature_code => $values) {
         if (!is_array($values)) {
             if ($values === '') {
                 continue;
             }
             $values = array($values);
         }
         if (isset($features[$feature_code])) {
             if (isset($values['min']) || isset($values['max']) || isset($values['unit'])) {
                 if (ifset($values['min'], '') === '' && ifset($values['max'], '') === '') {
                     continue;
                 } else {
                     $unit = ifset($values['unit']);
                     $min = $max = null;
                     if (isset($values['min'])) {
                         $min = $values['min'];
                         if ($unit) {
                             $min = shopDimension::getInstance()->convert($min, $features[$feature_code]['type'], null, $unit);
                         }
                     }
                     if (isset($values['max'])) {
                         $max = $values['max'];
                         if ($unit) {
                             $max = shopDimension::getInstance()->convert($max, $features[$feature_code]['type'], null, $unit);
                         }
                     }
                     $fm = $feature_model->getValuesModel($features[$feature_code]['type']);
                     $values = $fm->getValueIdsByRange($features[$feature_code]['id'], $min, $max);
                 }
             } else {
                 foreach ($values as &$v) {
                     $v = (int) $v;
                 }
             }
             if ($values) {
                 $this->addJoin('shop_product_features', 'p.id = :table.product_id AND :table.feature_id = ' . (int) $features[$feature_code]['id'], ':table.feature_value_id IN (' . implode(',', $values) . ')');
                 $this->group_by = 'p.id';
             } else {
                 $this->where[] = '0';
             }
         }
     }
     $this->filtered = true;
 }
Пример #3
0
 /**
  * @param int $id
  * @param array $data
  * @param bool $correct
  * @param shopProduct $product
  * @return array
  */
 protected function updateSku($id = 0, $data, $correct = true, shopProduct $product = null)
 {
     /**
      * @var shopProductStocksModel $stocks_model
      */
     static $stocks_model;
     /**
      * @var bool $multi_stock
      */
     static $multi_stock = null;
     /**
      * @var shopFeatureModel $feature_model
      */
     static $feature_model;
     /**
      * @var shopProductFeaturesModel $product_features_model
      */
     static $product_features_model;
     if (isset($data['price'])) {
         $data['price'] = $this->castValue('double', $data['price']);
     }
     if (isset($data['purchase_price'])) {
         $data['purchase_price'] = $this->castValue('double', $data['purchase_price']);
     }
     if (isset($data['compare_price'])) {
         $data['compare_price'] = $this->castValue('double', $data['compare_price']);
     }
     if ($id > 0) {
         if ($product && (!isset($data['virtual']) || !empty($data['virtual']))) {
             #check changes for virtual SKU
             $virtual_sku_defaults = array('price' => $product->base_price_selectable, 'purchase_price' => $product->purchase_price_selectable, 'compare_price' => $product->compare_price_selectable, 'count' => 0);
             $virtual = null;
             foreach ($virtual_sku_defaults as $field => $default) {
                 if (isset($data[$field])) {
                     $value = $data[$field];
                     if (is_array($value)) {
                         $value = max($value);
                     }
                     if ($value != $default) {
                         if ($virtual === null) {
                             $virtual = isset($product->skus[$id]) && !empty($product->skus[$id]['virtual']);
                         }
                         if ($virtual) {
                             $data['virtual'] = 0;
                             $virtual = false;
                         }
                         if (!$virtual) {
                             break;
                         }
                     }
                 }
             }
         }
         if (empty($data['eproduct']) && !empty($data['file_name'])) {
             $file_path = shopProduct::getPath($data['product_id'], "sku_file/{$id}." . pathinfo($data['file_name'], PATHINFO_EXTENSION));
             waFiles::delete($file_path);
             $data['file_name'] = '';
             $data['file_description'] = '';
         } elseif (isset($data['file_name'])) {
             unset($data['file_name']);
         }
         $this->updateById($id, $data);
     } else {
         if (!isset($data['sku'])) {
             $data['sku'] = '';
         }
         $id = $this->insert($data);
     }
     $data['id'] = $id;
     $sku_count = false;
     // if stocking for this sku
     if (isset($data['stock']) && count($data['stock'])) {
         if ($multi_stock === null) {
             $stock_model = new shopStockModel();
             $stocks = $stock_model->getAll($stock_model->getTableId());
             $multi_stock = $stocks ? array_keys($stocks) : false;
         }
         // not multistocking
         if (!$multi_stock || isset($data['stock'][0])) {
             $sku_count = self::castStock($data['stock'][0]);
             unset($data['stock']);
             $this->logCount($data['product_id'], $id, $sku_count);
             // multistocking
         } else {
             $sku_count = 0;
             $missed = array_combine($multi_stock, $multi_stock);
             if (!$stocks_model) {
                 $stocks_model = new shopProductStocksModel();
             }
             // need for track transition from aggregating mode to multistocking mode
             $has_any_stocks = $stocks_model->hasAnyStocks($id);
             if (!$has_any_stocks) {
                 $this->writeOffCount($data['product_id'], $id);
             }
             foreach ($data['stock'] as $stock_id => $count) {
                 if ($stock_id > 0 && isset($missed[$stock_id])) {
                     unset($missed[$stock_id]);
                     $field = array('sku_id' => $id, 'stock_id' => $stock_id, 'product_id' => $data['product_id']);
                     $count = self::castStock($count);
                     $stock = array('count' => $count);
                     if ($count === null) {
                         $sku_count = null;
                     } else {
                         // Once turned into NULL value is not changed
                         if ($sku_count !== null) {
                             $sku_count += $count;
                         }
                     }
                     // there is taking into account stocks log inside this method
                     $stocks_model->set(array_merge($field, $stock));
                     $data['stock'][$stock_id] = $count;
                 }
             }
             //get stock_count for missed stocks
             if ($sku_count !== null && !empty($missed)) {
                 $search = array('stock_id' => $missed, 'sku_id' => $id, 'product_id' => $data['product_id']);
                 foreach ($stocks_model->getByField($search, 'stock_id') as $stock_id => $row) {
                     $count = $row['count'];
                     $data['stock'][$stock_id] = $count;
                     if ($count === null) {
                         $sku_count = null;
                     } else {
                         // Once turned into NULL value is not changed
                         if ($sku_count !== null) {
                             $sku_count += $count;
                         }
                     }
                 }
             }
         }
     }
     if ($sku_count !== false) {
         $data['count'] = $sku_count;
         $this->updateById($id, array('count' => $sku_count));
     }
     if (isset($data['features'])) {
         if (!$feature_model) {
             $feature_model = new shopFeatureModel();
         }
         if (!$product_features_model) {
             $product_features_model = new shopProductFeaturesModel();
         }
         $features = $data['features'];
         $data['features'] = array();
         $skip_values = array('', false, null);
         foreach ($features as $code => $value) {
             if ($feature = $feature_model->getByField('code', $code)) {
                 $model = shopFeatureModel::getValuesModel($feature['type']);
                 $field = array('product_id' => $data['product_id'], 'sku_id' => $id, 'feature_id' => $feature['id']);
                 $product_features_model->deleteByField($field);
                 if (is_array($value)) {
                     if (!empty($value['id'])) {
                         $field['feature_value_id'] = $value['id'];
                     } elseif (isset($value['value']) && !in_array($value['value'], $skip_values, true)) {
                         $field['feature_value_id'] = $model->getId($feature['id'], $code == 'weight' ? $value : $value['value'], $feature['type']);
                     }
                 } elseif (!in_array($value, $skip_values, true)) {
                     $field['feature_value_id'] = $model->getId($feature['id'], $value, $feature['type']);
                     $value = array('value' => $value, 'id' => $field['feature_value_id']);
                 }
                 if (!empty($field['feature_value_id'])) {
                     $product_features_model->insert($field);
                     $data['features'][$code] = $value;
                 }
             } elseif (is_numeric($code) && is_numeric($value)) {
                 if ($feature = $feature_model->getById($code)) {
                     $field = array('product_id' => $data['product_id'], 'sku_id' => $id, 'feature_id' => $code);
                     $product_features_model->deleteByField($field);
                     if (empty($value)) {
                         continue;
                     }
                     $field['feature_value_id'] = $value;
                     $product_features_model->insert($field);
                     $data['features'][$feature['code']] = $feature_model->getValuesModel($feature['type'])->getFeatureValue($value);
                 }
             }
         }
     }
     if ($correct) {
         $product_model = new shopProductModel();
         $product_model->correct($data['product_id']);
     }
     return $data;
 }
Пример #4
0
 /**
  * @param $template_id
  * @param bool $extend
  * @return array|null
  * @throws waException
  */
 public function insertTemplate($template_id, $extend = false)
 {
     $types = self::getTemplates();
     $feature_model = new shopFeatureModel();
     $type_features_model = new shopTypeFeaturesModel();
     $type = null;
     if (!empty($types[$template_id])) {
         $type = $types[$template_id];
         $type['sort'] = $this->select('MAX(sort)+1 as max_sort')->fetchField('max_sort');
         $type['id'] = $this->insert($type);
         if ($type['id'] && !empty($type['features'])) {
             foreach ($type['features'] as $code => &$feature) {
                 $feature += array('type' => 'varchar', 'selectable' => false, 'multiple' => false);
                 $feature['types'] = array($type['id']);
                 $feature['name'] = ifempty(self::$translate[$feature['name']], $feature['name']);
                 $feature['code'] = $code;
                 $id = null;
                 if ($data = $feature_model->getByField('code', $code)) {
                     if ($feature['type'] == $data['type'] && $feature['selectable'] == $data['selectable'] && $feature['multiple'] == $data['multiple']) {
                         $id = $data['id'];
                     }
                 }
                 $feature['id'] = $feature_model->save($feature, $id);
                 if ($feature['id']) {
                     if (!empty($feature['selectable']) && !empty($feature['values'])) {
                         foreach ($feature['values'] as &$value) {
                             if (is_string($value)) {
                                 $value = ifempty(self::$translate[$value], $value);
                             } elseif (isset($value['value'])) {
                                 $value['value'] = ifempty(self::$translate[$value['value']], $value['value']);
                             }
                         }
                         unset($value);
                         $feature['values'] = $feature_model->setValues($feature, $feature['values'], false, true);
                     }
                     $feature['types'] = $type_features_model->updateByFeature($feature['id'], $feature['types'], false);
                     if ($id && $extend) {
                         //TODO get exists feature values
                         //$feature_model->getFeatureValues($feature);
                         $feature['types'] = array_keys($type_features_model->getByField('feature_id', $feature['id'], 'type_id'));
                     }
                 }
                 unset($feature);
             }
             if ($extend) {
                 shopFeatureModel::appendTypeNames($type['features']);
             }
         }
     }
     return $type;
 }
 public function execute()
 {
     if ($id = waRequest::get('id', 0, waRequest::TYPE_INT)) {
         #load product
         $this->view->assign('product', $product = new shopProduct($id));
         #load product types
         $type_model = new shopTypeModel();
         $this->view->assign('product_types', $product_types = $type_model->getAll($type_model->getTableId(), true));
         if ($param = waRequest::request('param', array(), waRequest::TYPE_ARRAY_INT)) {
             $type_id = reset($param);
             if (!isset($product_types[$type_id])) {
                 $type_id = $product->type_id;
             }
         } else {
             $type_id = $product->type_id;
         }
         $this->view->assign('type_id', $type_id);
         #load feature's values
         $model = new shopFeatureModel();
         $changed_features = array();
         if ($data = waRequest::post('product')) {
             $changed_features = empty($data['features']) || !is_array($data['features']) ? array() : $data['features'];
             foreach ($changed_features as $code => $value) {
                 if (isset($product->features[$code])) {
                     if (is_array($value)) {
                         $intersect = array_unique(array_merge($value, (array) $product->features[$code]));
                         if (count($value) == count($intersect)) {
                             unset($changed_features[$code]);
                         }
                     } elseif ($value === $product->features[$code]) {
                         unset($changed_features[$code]);
                     }
                 }
             }
         }
         #load changed feature's values
         $this->view->assign('changed_features', $changed_features);
         $codes = array_keys($product->features);
         foreach ($changed_features as $code => $value) {
             if ($value !== '') {
                 $codes[] = $code;
             }
         }
         $codes = array_unique($codes);
         $features = $model->getByType($type_id, 'code');
         foreach ($features as $code => &$feature) {
             $feature['internal'] = true;
             $key = array_search($code, $codes);
             if ($key !== false) {
                 unset($codes[$key]);
             }
         }
         unset($feature);
         if ($codes) {
             $features += $model->getByField('code', $codes, 'code');
         }
         foreach ($features as $code => &$feature) {
             $feature['feature_id'] = intval($feature['id']);
         }
         unset($feature);
         $features = $model->getValues($features);
         $this->view->assign('features', $features);
     }
 }
 private function getChildren($feature)
 {
     return $this->feature_model->getByField('parent_id', $feature['id'], 'id');
 }