public function execute()
 {
     $product_features_model = new shopProductFeaturesModel();
     $this->view->assign('sku_id', $sku_id = waRequest::get('sku_id', 0, waRequest::TYPE_INT));
     $this->view->assign('product_id', $product_id = waRequest::get('product_id', 0, waRequest::TYPE_INT));
     $this->view->assign('product', $product = new shopProduct($product_id));
     if ($sku_id < 0) {
         $sku = array('image_id' => '', 'available' => 1, 'purchase_price' => null, 'compare_price' => null);
     } elseif (isset($product->skus[$sku_id])) {
         $sku = $product->skus[$sku_id];
     } else {
         throw new waException("SKU not found", 404);
     }
     $this->view->assign('sku', $sku);
     //$this->view->assign('features', $features_model->getByType($product->type_id, 'code', true));
     $this->view->assign('features', $this->getFeatures($product));
     $this->view->assign('sku_features', $product_features_model->getValues($product_id, -$sku_id));
 }
 private function bindToProducts($feature, $values)
 {
     if (is_array($feature)) {
         $feature_id = $feature['id'];
     } else {
         $feature_id = (int) $feature;
         $feature = $this->feature_model->getById($feature_id);
     }
     $is_multidimensional = $this->isMultidimensional($feature);
     // bind products with values of new feature
     foreach ($values as $v) {
         if ($feature['type'] !== 'boolean') {
             if (isset($v['original_id'])) {
                 $new_id = $v['original_id'];
             } else {
                 $new_id = $v['id'];
             }
             if (isset($v['original_id'])) {
                 $old_id = -$v['id'];
             } else {
                 $old_id = -$v['insert_id'];
             }
         } else {
             $old_id = -$v['id'];
             $new_id = $v['value'];
         }
         if (!$is_multidimensional) {
             $key = array('feature_id' => $feature_id, 'feature_value_id' => $old_id);
             $value = array('feature_value_id' => $new_id);
         } else {
             $key = array('feature_id' => $v['feature_id'], 'feature_value_id' => $old_id);
             $value = array('feature_value_id' => $new_id);
         }
         $this->product_features_model->updateByField($key, $value);
         $key['value_id'] = $key['feature_value_id'];
         unset($key['feature_value_id']);
         $value['value_id'] = $value['feature_value_id'];
         unset($value['feature_value_id']);
         $this->product_features_selectable_model->updateByField($key, $value);
     }
 }
 protected function upsellingPrepare($product_id, $auto_title = false)
 {
     $model = $this->getModel();
     if (isset($this->options['product'])) {
         $product = $this->options['product'];
         $conditions = $this->options['conditions'];
     } else {
         $product = new shopProduct($product_id);
         $type_upselling_model = new shopTypeUpsellingModel();
         $conditions = $type_upselling_model->getByField('type_id', $product['type'], true);
     }
     $this->where[] = 'p.id != ' . (int) $product_id;
     $sum = array();
     foreach ($conditions as $row) {
         if ($row['feature'] == 'tag') {
             $tag_model = new shopTagModel();
             $tag = $tag_model->getByName($row['value']);
             if ($tag) {
                 $this->where[] = 'pt.tag_id = ' . (int) $tag['id'];
                 $this->joins[] = array('table' => 'shop_product_tags', 'alias' => 'pt');
             }
             continue;
         } elseif ($row['feature'] == 'type_id') {
             if ($row['cond'] == 'same') {
                 $this->where[] = 'p.type_id = ' . (int) $product['type_id'];
             } elseif ($row['cond'] == 'notsame') {
                 $this->where[] = 'p.type_id != ' . (int) $product['type_id'];
             } elseif ($row['cond'] == 'is') {
                 $this->where[] = 'p.type_id = ' . (int) $row['value'];
             }
             continue;
         }
         switch ($row['cond']) {
             case 'between':
                 list($min, $max) = explode(',', $row['value']);
                 if ($model->fieldExists($row['feature'])) {
                     $v = $product[$row['feature']];
                 } else {
                     $v = isset($product['features'][$row['feature']]) ? $product['features'][$row['feature']] : null;
                 }
                 if (!$v) {
                     continue;
                 }
                 $min = $v * (double) (100 + $min) / 100;
                 $max = $v * (double) (100 + $max) / 100;
                 $v = str_replace(',', '.', $v);
                 if ($model->fieldExists($row['feature'])) {
                     $this->where[] = 'p.' . $row['feature'] . ' > ' . str_replace(',', '.', $min);
                     $this->where[] = 'p.' . $row['feature'] . ' < ' . str_replace(',', '.', $max);
                     $sum[] = 'ABS(p.' . $row['feature'] . ' - ' . $v . ')/' . $v;
                 }
                 break;
             case 'is':
                 if ($model->fieldExists($row['feature'])) {
                     $this->where[] = 'p.' . $row['feature'] . " = '" . $model->escape($row['value']) . "'";
                 } else {
                     $this->addJoin('shop_product_features', null, ":table.feature_id = " . (int) $row['feature_id'] . " AND :table.feature_value_id = " . (int) $row['value']);
                     $this->group_by = 'p.id';
                 }
                 break;
             case 'any':
             case 'all':
                 if ($model->fieldExists($row['feature'])) {
                     //$this->where[] = 'p.'.$row['feture']." = '".$model->escape($row['value'])."'";
                 } else {
                     if ($row['value']) {
                         $this->addJoin('shop_product_features', null, ":table.feature_id = " . (int) $row['feature_id'] . " AND :table.feature_value_id IN (" . $row['value'] . ")");
                         $this->group_by = 'p.id';
                     } else {
                         $this->where[] = '0';
                     }
                 }
                 break;
             case 'notsame':
             case 'same':
                 if ($model->fieldExists($row['feature'])) {
                     $this->where[] = 'p.' . $row['feature'] . " " . ($row['cond'] == 'notsame' ? '!' : '') . "= '" . $model->escape($product->features[$row['feature']]) . "'";
                 } else {
                     $product_features_model = new shopProductFeaturesModel();
                     $rows = $product_features_model->getByField(array('product_id' => $product['id'], 'sku_id' => null, 'feature_id' => $row['feature_id']), true);
                     $values = array();
                     foreach ($rows as $r) {
                         $values[] = $r['feature_value_id'];
                     }
                     if ($values) {
                         $alias = $this->addJoin('shop_product_features');
                         $this->where[] = $alias . ".feature_id = " . $row['feature_id'];
                         $this->where[] = $alias . ".feature_value_id " . (count($values) == 1 ? ($row['cond'] == 'notsame' ? '!' : '') . "= " . $values[0] : ($row['cond'] == 'notsame' ? 'NOT ' : '') . "IN (" . implode(',', $values) . ")");
                         $this->group_by = 'p.id';
                     }
                 }
                 break;
         }
     }
     if ($sum) {
         $this->fields[] = '(' . implode(' + ', $sum) . ') AS upselling_deviation';
         $this->order_by = 'upselling_deviation';
     }
 }
Beispiel #4
0
 /**
  * @param array $options
  * @return shopProduct
  * @throws waException
  */
 public function duplicate($options = array())
 {
     if (!$this->checkRights()) {
         throw new waRightsException('Access denied');
     }
     $data = $this->data;
     $skip = array('id', 'create_datetime', 'id_1c', 'rating', 'rating_count', 'total_sales', 'image_id', 'contact_id', 'ext', 'count', 'sku_count');
     foreach ($skip as $field) {
         if (isset($data[$field])) {
             unset($data[$field]);
         }
     }
     $duplicate = new shopProduct();
     $this->getStorage(null);
     $sku_files = array();
     $sku_images = array();
     $ignore_select = true;
     foreach (self::$data_storages as $key => $i) {
         $raw = $this->getStorage($key)->getData($this);
         switch ($key) {
             case 'features_selectable':
                 $storage_data = array();
                 if (!$ignore_select) {
                     if ($this->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
                         if (!is_array($raw)) {
                             $raw = array();
                         }
                         foreach ($raw as $id => $f) {
                             if (!empty($f['selected'])) {
                                 foreach ($f['values'] as $value_id => &$value) {
                                     if (!empty($value['selected'])) {
                                         $value = array('id' => $value_id);
                                     } else {
                                         unset($f['values'][$value_id]);
                                     }
                                 }
                                 $storage_data[$id] = $f;
                             }
                         }
                     }
                 }
                 break;
             case 'skus':
                 $storage_data = array();
                 $i = 0;
                 foreach ($raw as $sku_id => $sku) {
                     if (!empty($sku['virtual']) || $ignore_select) {
                         if ($file_path = shopProductSkusModel::getPath($sku)) {
                             $sku_files[$sku['id']] = array('file_name' => $sku['file_name'], 'file_description' => $sku['file_description'], 'file_size' => $sku['file_size'], 'file_path' => $file_path);
                         }
                         if (!empty($sku['image_id'])) {
                             $sku_images[$sku['id']] = $sku['image_id'];
                         }
                         foreach (array('id', 'id_1c', 'product_id', 'image_id', 'file_name', 'file_size', 'file_description') as $field) {
                             if (isset($sku[$field])) {
                                 unset($sku[$field]);
                             }
                         }
                         $storage_data[--$i] = $sku;
                     }
                 }
                 break;
             case 'tags':
                 $storage_data = array_values($raw);
                 break;
             case 'categories':
                 $storage_data = array_keys($raw);
                 break;
             default:
                 $storage_data = $raw;
                 break;
         }
         $duplicate->{$key} = $storage_data;
     }
     $counter = 0;
     $data['url'] = shopHelper::genUniqueUrl($this->url, $this->model, $counter);
     $data['name'] = $this->name . sprintf('(%d)', $counter ? $counter : 1);
     $duplicate->save($data);
     $product_id = $duplicate->getId();
     $sku_map = array_combine(array_keys($this->skus), array_keys($duplicate->skus));
     $config = wa('shop')->getConfig();
     $image_thumbs_on_demand = $config->getOption('image_thumbs_on_demand');
     /**
      * @var shopConfig $config
      */
     if ($this->pages) {
         $product_pages_model = new shopProductPagesModel();
         foreach ($this->pages as $page) {
             unset($page['id']);
             unset($page['create_time']);
             unset($page['update_datetime']);
             unset($page['create_contact_id']);
             $page['product_id'] = $duplicate->getId();
             $product_pages_model->add($page);
         }
     }
     #duplicate images
     $product_skus_model = new shopProductSkusModel();
     $images_model = new shopProductImagesModel();
     $images = $images_model->getByField('product_id', $this->getId(), $images_model->getTableId());
     $callback = create_function('$a, $b', 'return (max(-1, min(1, $a["sort"] - $b["sort"])));');
     usort($images, $callback);
     foreach ($images as $id => $image) {
         $source_path = shopImage::getPath($image);
         $original_file = shopImage::getOriginalPath($image);
         $image['product_id'] = $duplicate->getId();
         if ($sku_id = array_search($image['id'], $sku_images)) {
             $sku_id = $sku_map[$sku_id];
         }
         unset($image['id']);
         try {
             if ($image['id'] = $images_model->add($image, $id == $this->image_id)) {
                 waFiles::copy($source_path, shopImage::getPath($image));
                 if (file_exists($original_file)) {
                     waFiles::copy($original_file, shopImage::getOriginalPath($image));
                 }
                 if ($sku_id) {
                     $product_skus_model->updateById($sku_id, array('image_id' => $image['id']));
                 }
                 if (!$image_thumbs_on_demand) {
                     shopImage::generateThumbs($image, $config->getImageSizes());
                     //TODO use dummy copy  with rename files
                 }
             }
         } catch (waDbException $ex) {
             //just ignore it
             waLog::log('Error during copy product: ' . $ex->getMessage(), 'shop.log');
         } catch (waException $ex) {
             if (!empty($image['id'])) {
                 $images_model->deleteById($image['id']);
             }
             waLog::log('Error during copy product: ' . $ex->getMessage(), 'shop.log');
         }
     }
     foreach ($sku_files as $sku_id => $data) {
         $source_path = $data['file_path'];
         unset($data['file_path']);
         $sku_id = $sku_map[$sku_id];
         $sku = array_merge($duplicate->skus[$sku_id], $data);
         $product_skus_model->updateById($sku_id, $data);
         $target_path = shopProductSkusModel::getPath($sku);
         try {
             waFiles::copy($source_path, $target_path);
         } catch (waException $ex) {
             $data = array('file_name' => '', 'file_description' => '', 'file_size' => 0);
             $product_skus_model->updateById($sku_id, $data);
             print $ex->getMessage();
         }
     }
     $product_features_model = new shopProductFeaturesModel();
     $skus_features = $product_features_model->getSkuFeatures($this->id);
     $skus_features_data = array();
     foreach ($skus_features as $sku_id => $features) {
         $sku_id = $sku_map[$sku_id];
         foreach ($features as $feature_id => $feature_value_id) {
             $skus_features_data[] = compact('product_id', 'sku_id', 'feature_id', 'feature_value_id');
         }
     }
     if ($skus_features_data) {
         $product_features_model->multipleInsert($skus_features_data);
     }
     if ($this->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
         $product_features_selectable_model = new shopProductFeaturesSelectableModel();
         if ($features_selectable = $product_features_selectable_model->getByField('product_id', $this->id, true)) {
             foreach ($features_selectable as &$feature_selectable) {
                 $feature_selectable['product_id'] = $product_id;
             }
             unset($feature_selectable);
             $product_features_selectable_model->multipleInsert($features_selectable);
         }
     }
     $product_services_model = new shopProductServicesModel();
     if ($services = $product_services_model->getByField('product_id', $this->id, true)) {
         foreach ($services as &$service) {
             unset($service['id']);
             $service['product_id'] = $product_id;
             $service['sku_id'] = ifset($sku_map[$service['sku_id']]);
             unset($service);
         }
         $product_services_model->multipleInsert($services);
     }
     $product_related_model = new shopProductRelatedModel();
     if ($related = $product_related_model->getByField('product_id', $this->id, true)) {
         foreach ($related as &$row) {
             $row['product_id'] = $product_id;
         }
         unset($row);
         $product_related_model->multipleInsert($related);
     }
     $params = array('product' => &$this, 'duplicate' => &$duplicate);
     /**
      * @wa-event product_duplicate
      */
     wa()->event('product_duplicate', $params);
     return $duplicate;
 }
 private function stepExportProduct(&$current_stage, &$count, &$processed)
 {
     static $products;
     static $product_feature_model;
     static $feature_model;
     static $tags_model;
     static $size;
     if (!$products) {
         $offset = $current_stage[self::STAGE_PRODUCT] - ifset($this->data['map'][self::STAGE_PRODUCT], 0);
         $fields = '*';
         if (!empty($this->data['options']['images'])) {
             $fields .= ', images';
         }
         $products = $this->getCollection()->getProducts($fields, $offset, 50, false);
     }
     $chunk = 5;
     $non_sku_fields = array('summary', 'meta_title', 'meta_keywords', 'meta_description', 'description', 'sort', 'tags', 'images');
     while ($chunk-- > 0 && ($product = reset($products))) {
         $exported = false;
         /* check rights per product type && settlement options */
         $rights = empty($product['type_id']) || in_array($product['type_id'], $this->data['types']);
         $category_id = isset($product['category_id']) ? intval($product['category_id']) : null;
         /* check category match*/
         $category_match = !$this->data['export_category'] || $category_id === $this->data['map'][self::STAGE_CATEGORY];
         if ($rights && $category_match) {
             $shop_product = new shopProduct($product);
             if (!empty($this->data['options']['features'])) {
                 if (!isset($product['features'])) {
                     if (!$product_feature_model) {
                         $product_feature_model = new shopProductFeaturesModel();
                     }
                     $product['features'] = $product_feature_model->getValues($product['id']);
                 }
                 foreach ($product['features'] as $code => &$feature) {
                     if (!empty($this->data['composite_features'][$code])) {
                         $feature = str_replace('×', 'x', $feature);
                     }
                     unset($feature);
                 }
             }
             if (!isset($product['tags'])) {
                 if (!$tags_model) {
                     $tags_model = new shopProductTagsModel();
                 }
                 $product['tags'] = implode(',', $tags_model->getTags($product['id']));
             }
             if (!empty($this->data['options']['images'])) {
                 if (isset($product['images'])) {
                     if (!$size) {
                         /**
                          * @var shopConfig $config
                          */
                         $config = $this->getConfig();
                         $size = $config->getImageSize('big');
                     }
                     foreach ($product['images'] as &$image) {
                         $image = 'http://' . ifempty($this->data['base_url'], 'localhost') . shopImage::getUrl($image, $size);
                     }
                     $product['images'] = array_values($product['images']);
                 }
             }
             $product['type_name'] = $shop_product->type['name'];
             $skus = $shop_product->skus;
             if (false && $product['sku_id']) {
                 #default SKU reorder
                 if (isset($skus[$product['sku_id']])) {
                     $sku = $skus[$product['sku_id']];
                     $sku['stock'][0] = $sku['count'];
                     $product['skus'] = array(-1 => $sku);
                     unset($skus[$product['sku_id']]);
                 }
                 $this->writer->write($product);
                 if (!empty($this->data['options']['images'])) {
                     if (isset($product['images'])) {
                         $processed[self::STAGE_IMAGE] += count($product['images']);
                     }
                 }
                 $exported = true;
                 if (!empty($this->data['options']['features'])) {
                     unset($product['features']);
                 }
             }
             if (!empty($product['tax_id'])) {
                 $product['tax_name'] = ifset($this->data['taxes'][$product['tax_id']]);
             }
             if (!isset($product['features'])) {
                 $product['features'] = array();
             }
             foreach ($skus as $sku_id => $sku) {
                 if ($exported) {
                     foreach ($non_sku_fields as $field) {
                         if (isset($product[$field])) {
                             unset($product[$field]);
                         }
                     }
                 }
                 $sku['stock'][0] = $sku['count'];
                 if (!empty($this->data['options']['features'])) {
                     $sku['features'] = $product_feature_model->getValues($product['id'], -$sku_id);
                     if ($product['sku_type'] == shopProductModel::SKU_TYPE_SELECTABLE) {
                         if (!$exported) {
                             $features_selectable_model = new shopProductFeaturesSelectableModel();
                             if ($selected = $features_selectable_model->getByProduct($product['id'])) {
                                 if (!$feature_model) {
                                     $feature_model = new shopFeatureModel();
                                 }
                                 $features = $feature_model->getById(array_keys($selected));
                                 $enclosure = $this->writer->enclosure;
                                 $pattern = sprintf("/(?:%s|%s|%s)/", preg_quote(',', '/'), preg_quote($enclosure, '/'), preg_quote($enclosure, '/'));
                                 foreach ($features as $feature_id => $feature) {
                                     $values = shopFeatureModel::getValuesModel($feature['type'])->getValues(array('feature_id' => $feature_id, 'id' => $selected[$feature_id]));
                                     if (!empty($values[$feature['id']])) {
                                         $f_values = $values[$feature['id']];
                                         if (!isset($product['features'])) {
                                             $product['features'] = array();
                                         }
                                         if (isset($sku['features'][$feature['code']])) {
                                             array_unshift($f_values, (string) $sku['features'][$feature['code']]);
                                         }
                                         foreach ($f_values as &$value) {
                                             if (preg_match($pattern, $value)) {
                                                 $value = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $value) . $enclosure;
                                             }
                                             unset($value);
                                         }
                                         $f_values = array_unique($f_values);
                                         $product['features'][$feature['code']] = '<{' . implode(',', $f_values) . '}>';
                                     }
                                 }
                             }
                             $virtual_product = $product;
                             if (isset($skus[$product['sku_id']])) {
                                 $virtual_product['skus'] = array(-1 => $skus[$product['sku_id']]);
                             } else {
                                 $virtual_product['skus'] = array(-1 => $sku);
                             }
                             $virtual_product['skus'][-1]['stock'] = array(0 => $product['count']);
                             $this->writer->write($virtual_product);
                         }
                         $product['features'] = $sku['features'];
                     } else {
                         if (!$exported) {
                             foreach ($product['features'] as $code => &$values) {
                                 if (isset($sku['features'][$code])) {
                                     $values = array_unique(array_merge($values, $sku['features'][$code]));
                                 }
                                 unset($values);
                             }
                         } else {
                             $product['features'] = $sku['features'];
                         }
                     }
                 }
                 $product['skus'] = array(-1 => $sku);
                 $this->writer->write($product);
                 if (isset($product['images'])) {
                     $processed[self::STAGE_IMAGE] += count($product['images']);
                 }
                 $exported = true;
                 ++$current_stage[self::STAGE_SKU];
                 ++$processed[self::STAGE_SKU];
             }
         } elseif (count($products) > 1) {
             ++$chunk;
         }
         array_shift($products);
         ++$current_stage[self::STAGE_PRODUCT];
         if ($exported) {
             ++$processed[self::STAGE_PRODUCT];
         }
     }
     return $current_stage[self::STAGE_PRODUCT] < $count[self::STAGE_PRODUCT];
 }
 /**
  * @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;
 }
 private function getValue(&$product, $sku, $field, $info)
 {
     static $features_model;
     $value = null;
     list($source, $param) = explode(':', $info['source'], 2);
     switch ($source) {
         case 'field':
             $value = isset($product[$param]) ? $product[$param] : null;
             if (!empty($this->data['export']['sku'])) {
                 switch ($param) {
                     case 'id':
                         if (!empty($sku['id']) && $sku['id'] != $product['sku_id']) {
                             $value .= 's' . $sku['id'];
                         }
                         break;
                     case 'frontend_url':
                         if (!empty($sku['id']) && $sku['id'] != $product['sku_id']) {
                             if (strpos($value, '?')) {
                                 $value .= '&sku=' . $sku['id'];
                             } else {
                                 $value .= '?sku=' . $sku['id'];
                             }
                         }
                         break;
                     case 'file_name':
                         if (!empty($sku)) {
                             $value = empty($sku[$param]) ? null : 'true';
                         } else {
                             $value = empty($value) ? null : 'true';
                         }
                         break;
                     case 'price':
                     case 'count':
                     case 'sku':
                     case 'group_id':
                     case 'compare_price':
                         $value = ifset($sku[$param], $value);
                         break;
                 }
             }
             $value = $this->format($field, $value, $info, $product, $sku);
             break;
         case 'value':
         case 'text':
             $value = $this->format($field, $param, $info);
             break;
         case 'feature':
             if (!isset($product['features'])) {
                 if (!$features_model) {
                     $features_model = new shopProductFeaturesModel();
                 }
                 $product['features'] = $features_model->getValues($product['id'], ifset($sku['id']));
             }
             $value = $this->format($field, ifempty($product['features'][$param]), $info, $product, $sku);
             break;
         case 'function':
             switch ($param) {
                 case 'prepaid':
                     $source = array('source' => 'field:count');
                     if ($this->getValue($product, $sku, 'available', $source) === 'false') {
                         $value = 'Заказ товара по предоплате';
                     }
                     break;
                 case 'group_category':
                     break;
                 case 'group_market_category':
                     break;
             }
             break;
     }
     return $value;
 }
Beispiel #8
0
 public function setValues($feature, $values, $delete_obsolete = true, $force = false)
 {
     $model = self::getValuesModel($feature['type']);
     if ($delete_obsolete) {
         $current_values = $model->getByField('feature_id', $feature['id'], 'id');
         $obsolete_values = array_diff(array_keys($current_values), array_keys($values));
         if ($obsolete_values) {
             $product_features_model = new shopProductFeaturesModel();
             $product_features_model->deleteByFeature($feature['id'], $obsolete_values);
             $field = array('feature_id' => $feature['id'], 'id' => $obsolete_values);
             $model->deleteByField($field);
         }
     }
     $data = array();
     $sort = 0;
     foreach ($values as $id => $value) {
         $value = $model->addValue($feature['id'], $value, $force ? null : $id, $feature['type'], ++$sort);
         if ($force) {
             if (!empty($value['error'])) {
                 if (!empty($value['error']['original_id'])) {
                     $value['id'] = $value['error']['original_id'];
                     $value['value'] = $value['error']['original_value'];
                     unset($value['error']);
                     $data[] = $value;
                 }
             }
         } else {
             $data[] = $value;
         }
     }
     $this->recount($feature);
     return $data;
 }
 public static function checkCart(&$cart = null)
 {
     $error = false;
     $cart = new shopCart();
     $code = $cart->getCode();
     $view = wa()->getView();
     if (!wa()->getSetting('ignore_stock_count')) {
         $cart_model = new shopCartItemsModel();
         $sku_model = new shopProductSkusModel();
         $product_model = new shopProductModel();
         $items = $cart->items(false);
         foreach ($items as &$item) {
             if (!isset($item['product_id'])) {
                 $sku = $sku_model->getById($item['sku_id']);
                 $product = $product_model->getById($sku['product_id']);
             } else {
                 $product = $product_model->getById($item['product_id']);
                 if (isset($item['sku_id'])) {
                     $sku = $sku_model->getById($item['sku_id']);
                 } else {
                     if (isset($item['features'])) {
                         $product_features_model = new shopProductFeaturesModel();
                         $sku_id = $product_features_model->getSkuByFeatures($product['id'], $item['features']);
                         if ($sku_id) {
                             $sku = $sku_model->getById($sku_id);
                         } else {
                             $sku = null;
                         }
                     } else {
                         $sku = $sku_model->getById($product['sku_id']);
                         if (!$sku['available']) {
                             $sku = $sku_model->getByField(array('product_id' => $product['id'], 'available' => 1));
                         }
                         if (!$sku) {
                             $item['error'] = _w('This product is not available for purchase');
                             $error = true;
                         }
                     }
                 }
             }
             $quantity = $item['quantity'];
             $c = $cart_model->countSku($code, $sku['id']);
             if ($sku['count'] !== null && $c + $quantity > $sku['count']) {
                 $quantity = $sku['count'] - $c;
                 $name = $product['name'] . ($sku['name'] ? ' (' . $sku['name'] . ')' : '');
                 if ($quantity < 0) {
                     $item['error'] = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $sku['count'], $name);
                     $error = true;
                 }
             }
         }
         unset($item);
         foreach ($items as $item_id => $item) {
             $price = shop_currency($item['price'] * $item['quantity'], $item['currency'], null, false);
             if (isset($item['services'])) {
                 foreach ($item['services'] as $s) {
                     if (!empty($s['id'])) {
                         if (isset($s['variants'])) {
                             $price += shop_currency($s['variants'][$s['variant_id']]['price'] * $item['quantity'], $s['currency'], null, false);
                         } else {
                             $price += shop_currency($s['price'] * $item['quantity'], $s['currency'], null, false);
                         }
                     }
                 }
             }
             $items[$item_id]['full_price'] = $price;
         }
         $cart = array('items' => $items, 'total' => $cart->total(false), 'count' => $cart->count());
     }
     return $error;
 }
 protected function prepareProduct(shopProduct $product)
 {
     if (waRequest::get('sku')) {
         $url_params = array('product_url' => $product['url']);
         if ($product['category_url']) {
             $url_params['category_url'] = $product['category_url'];
         }
         if (isset($product->skus[waRequest::get('sku')])) {
             $product['sku_id'] = waRequest::get('sku');
             $s = $product->skus[$product['sku_id']];
             if ($s['image_id'] && isset($product->images[$s['image_id']])) {
                 $product['image_id'] = $s['image_id'];
                 $product['ext'] = $product->images[$s['image_id']]['ext'];
             }
         }
     }
     if (!isset($product->skus[$product->sku_id])) {
         $product->sku_id = $product->skus ? key($product->skus) : null;
     }
     if (!$product->skus) {
         $product->skus = array(null => array('name' => '', 'sku' => '', 'id' => null, 'available' => false, 'count' => 0, 'price' => null, 'stock' => array()));
     }
     if ($this->getConfig()->getOption('can_use_smarty') && $product->description) {
         $product->description = wa()->getView()->fetch('string:' . $product->description);
     }
     if ((double) $product->compare_price <= (double) $product->price) {
         $product->compare_price = 0;
     }
     // check categories
     if ($product['categories']) {
         $categories = $product['categories'];
         $route = wa()->getRouting()->getDomain(null, true) . '/' . wa()->getRouting()->getRoute('url');
         $category_routes_model = new shopCategoryRoutesModel();
         $routes = $category_routes_model->getRoutes(array_keys($categories));
         foreach ($categories as $c) {
             if (isset($routes[$c['id']]) && !in_array($route, $routes[$c['id']])) {
                 unset($categories[$c['id']]);
             }
         }
         $product['categories'] = $categories;
     }
     $this->view->assign('product', $product);
     if ($product->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
         $features_selectable = $product->features_selectable;
         $this->view->assign('features_selectable', $features_selectable);
         $product_features_model = new shopProductFeaturesModel();
         $sku_features = $product_features_model->getSkuFeatures($product->id);
         $sku_selectable = array();
         foreach ($sku_features as $sku_id => $sf) {
             if (!isset($product->skus[$sku_id])) {
                 continue;
             }
             $sku_f = "";
             foreach ($features_selectable as $f_id => $f) {
                 if (isset($sf[$f_id])) {
                     $sku_f .= $f_id . ":" . $sf[$f_id] . ";";
                 }
             }
             $sku = $product->skus[$sku_id];
             $sku_selectable[$sku_f] = array('id' => $sku_id, 'price' => (double) shop_currency($sku['price'], $product['currency'], null, false), 'num' => 141, 'available' => $product->status && $sku['available'] && ($this->getConfig()->getGeneralSettings('ignore_stock_count') || $sku['count'] === null || $sku['count'] > 0), 'image_id' => (int) $sku['image_id']);
             if ($sku['compare_price']) {
                 $sku_selectable[$sku_f]['compare_price'] = (double) shop_currency($sku['compare_price'], $product['currency'], null, false);
             }
         }
         $product['sku_features'] = ifset($sku_features[$product->sku_id], array());
         $this->view->assign('sku_features_selectable', $sku_selectable);
     }
 }
 /**
  * @todo use delta/absolute price
  * @param shopProduct $product
  * @param array $selected
  * @param array $data
  * @return array
  */
 private function generateSku(shopProduct $product, $selected, &$data)
 {
     $skus = $product->skus;
     if (empty($skus)) {
         $skus = array();
     }
     #build features map for exists SKUs
     $sku_map = array();
     $product_features_model = new shopProductFeaturesModel();
     foreach ($z = $product_features_model->getSkuFeatures($product->id) as $sku_id => $f) {
         $key = "";
         foreach ($f as $feature_id => $value_id) {
             $key .= $feature_id . ":" . $value_id . ";";
         }
         $sku_map[$key] = $sku_id;
     }
     $map = array();
     foreach ($data as $code => $d) {
         $map[$d['feature_id']] = $code;
     }
     $default_sku = array('sku' => '', 'virtual' => 1, 'available' => 1, 'count' => null);
     $i = 0;
     foreach ($this->arrayCartesian($selected) as $features) {
         $sku = array('name' => array(), 'features' => array(), 'price' => $product->base_price_selectable, 'compare_price' => $product->compare_price_selectable, 'purchase_price' => $product->purchase_price_selectable);
         $sku_key = "";
         $last_value_id = end($features);
         foreach ($features as $feature_id => $value_id) {
             $code = $map[$feature_id];
             $value = $data[$code]['values'][$value_id];
             $sku['features'][$code] = $value;
             $sku['name'][] = ifset($value['value'], $value['id']);
             #correct price
             if (isset($data[$feature_id]['values'][$value_id]['price'])) {
                 self::parseSkuPrice($sku, $data[$feature_id]['values'][$value_id]['price']);
             }
             #set counts per stock
             if (isset($data[$feature_id]['stock'])) {
                 self::parseSkuStock($sku, $data[$feature_id]['stock'], $value_id == $last_value_id ? count($f) : null);
             }
             $sku_key .= $feature_id . ":" . $value_id . ";";
             $sku['key'] = $sku_key;
         }
         #concat name from feature values
         $sku['name'] = implode(', ', $sku['name']);
         if (isset($sku_map[$sku_key])) {
             // already exists
             $sku_id = $sku_map[$sku_key];
             if (!empty($skus[$sku_id]['virtual'])) {
                 //update SKU if still virtual
                 $skus[$sku_id] = array_merge($skus[$sku_id], $sku);
             }
             $sku_map[$sku_key] = false;
         } else {
             # get free sku_id
             do {
                 --$i;
             } while (isset($skus[$i]));
             $skus[$i] = array_merge($default_sku, $sku);
         }
     }
     if ($product->id) {
         // remove old virtual skus
         $sku_map = array_filter($sku_map);
         foreach ($sku_map as $key => $sku_id) {
             if (isset($skus[$sku_id])) {
                 if (empty($skus[$sku_id]['virtual'])) {
                     unset($sku_map[$key]);
                 } else {
                     unset($skus[$sku_id]);
                 }
             }
         }
         if ($sku_map && false) {
             $product_skus_model = new shopProductSkusModel();
             $product_skus_model->deleteJoin('shop_product_features', $product->id, array('virtual' => 1, 'id' => $sku_map));
             $product_skus_model->deleteByField(array('product_id' => $product->id, 'virtual' => 1, 'id' => $sku_map));
         }
     }
     $product->skus = $skus;
     return $sku_map;
 }
 public function execute()
 {
     $code = waRequest::cookie('shop_cart');
     if (!$code) {
         $code = md5(uniqid(time(), true));
         // header for IE
         wa()->getResponse()->addHeader('P3P', 'CP="NOI ADM DEV COM NAV OUR STP"');
         // set cart cookie
         wa()->getResponse()->setCookie('shop_cart', $code, time() + 30 * 86400, null, '', false, true);
     }
     $this->cart = new shopCart($code);
     $this->cart_model = new shopCartItemsModel();
     $data = waRequest::post();
     $this->is_html = waRequest::request('html');
     // add service
     if (isset($data['parent_id'])) {
         $this->addService($data);
         return;
     }
     // add sku
     $sku_model = new shopProductSkusModel();
     $product_model = new shopProductModel();
     if (!isset($data['product_id'])) {
         $sku = $sku_model->getById($data['sku_id']);
         $product = $product_model->getById($sku['product_id']);
     } else {
         $product = $product_model->getById($data['product_id']);
         if (isset($data['sku_id'])) {
             $sku = $sku_model->getById($data['sku_id']);
         } else {
             if (isset($data['features'])) {
                 $product_features_model = new shopProductFeaturesModel();
                 $sku_id = $product_features_model->getSkuByFeatures($product['id'], $data['features']);
                 if ($sku_id) {
                     $sku = $sku_model->getById($sku_id);
                 } else {
                     $sku = null;
                 }
             } else {
                 $sku = $sku_model->getById($product['sku_id']);
                 if (!$sku['available']) {
                     $sku = $sku_model->getByField(array('product_id' => $product['id'], 'available' => 1));
                 }
                 if (!$sku) {
                     $this->errors = _w('This product is not available for purchase');
                     return;
                 }
             }
         }
     }
     $quantity = waRequest::post('quantity', 1);
     if ($product && $sku) {
         // check quantity
         if (!wa()->getSetting('ignore_stock_count')) {
             $c = $this->cart_model->countSku($code, $sku['id']);
             if ($sku['count'] !== null && $c + $quantity > $sku['count']) {
                 $quantity = $sku['count'] - $c;
                 $name = $product['name'] . ($sku['name'] ? ' (' . $sku['name'] . ')' : '');
                 if (!$quantity) {
                     $this->errors = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $sku['count'], $name);
                     return;
                 } else {
                     $this->response['error'] = sprintf(_w('Only %d pcs of %s are available, and you already have all of them in your shopping cart.'), $sku['count'], $name);
                 }
             }
         }
         $services = waRequest::post('services', array());
         if ($services) {
             $variants = waRequest::post('service_variant');
             $temp = array();
             $service_ids = array();
             foreach ($services as $service_id) {
                 if (isset($variants[$service_id])) {
                     $temp[$service_id] = $variants[$service_id];
                 } else {
                     $service_ids[] = $service_id;
                 }
             }
             if ($service_ids) {
                 $service_model = new shopServiceModel();
                 $temp_services = $service_model->getById($service_ids);
                 foreach ($temp_services as $row) {
                     $temp[$row['id']] = $row['variant_id'];
                 }
             }
             $services = $temp;
         }
         $item_id = null;
         $item = $this->cart_model->getItemByProductAndServices($code, $product['id'], $sku['id'], $services);
         if ($item) {
             $item_id = $item['id'];
             $this->cart->setQuantity($item_id, $item['quantity'] + $quantity);
         }
         if (!$item_id) {
             $data = array('create_datetime' => date('Y-m-d H:i:s'), 'product_id' => $product['id'], 'sku_id' => $sku['id'], 'quantity' => $quantity, 'type' => 'product');
             if ($services) {
                 $data_services = array();
                 foreach ($services as $service_id => $variant_id) {
                     $data_services[] = array('service_id' => $service_id, 'service_variant_id' => $variant_id);
                 }
             } else {
                 $data_services = array();
             }
             $item_id = $this->cart->addItem($data, $data_services);
         }
         if (waRequest::isXMLHttpRequest()) {
             $this->response['item_id'] = $item_id;
             $this->response['total'] = $this->currencyFormat($this->cart->total());
             $this->response['discount'] = $this->currencyFormat($this->cart->discount());
             $this->response['count'] = $this->cart->count();
         } else {
             $this->redirect(waRequest::server('HTTP_REFERER'));
         }
     } else {
         throw new waException('product not found');
     }
 }
 public function execute()
 {
     $category = $this->getCategory();
     $this->addCanonical();
     // breadcrumbs
     $root_category_id = $category['id'];
     if ($category['parent_id']) {
         $breadcrumbs = array();
         $path = array_reverse($this->getModel()->getPath($category['id']));
         $root_category = reset($path);
         $root_category_id = $root_category['id'];
         foreach ($path as $row) {
             $breadcrumbs[] = array('url' => wa()->getRouteUrl('/frontend/category', array('category_url' => waRequest::param('url_type') == 1 ? $row['url'] : $row['full_url'])), 'name' => $row['name']);
         }
         if ($breadcrumbs) {
             $this->view->assign('breadcrumbs', $breadcrumbs);
         }
     }
     $this->view->assign('root_category_id', $root_category_id);
     // sort
     if ($category['type'] == shopCategoryModel::TYPE_DYNAMIC && !$category['sort_products']) {
         $category['sort_products'] = 'create_datetime DESC';
     }
     if ($category['sort_products'] && !waRequest::get('sort')) {
         $sort = explode(' ', $category['sort_products']);
         $this->view->assign('active_sort', $sort[0] == 'count' ? 'stock' : $sort[0]);
     } elseif (!$category['sort_products'] && !waRequest::get('sort')) {
         $this->view->assign('active_sort', '');
     }
     $this->view->assign('category', $category);
     // products
     $collection = new shopProductsCollection('category/' . $category['id']);
     // filters
     if ($category['filter']) {
         $filter_ids = explode(',', $category['filter']);
         $feature_model = new shopFeatureModel();
         $features = $feature_model->getById(array_filter($filter_ids, 'is_numeric'));
         if ($features) {
             $features = $feature_model->getValues($features);
         }
         $category_value_ids = $collection->getFeatureValueIds();
         $filters = array();
         foreach ($filter_ids as $fid) {
             if ($fid == 'price') {
                 $range = $collection->getPriceRange();
                 if ($range['min'] != $range['max']) {
                     $filters['price'] = array('min' => shop_currency($range['min'], null, null, false), 'max' => shop_currency($range['max'], null, null, false));
                 }
             } elseif (isset($features[$fid]) && isset($category_value_ids[$fid])) {
                 $filters[$fid] = $features[$fid];
                 $min = $max = $unit = null;
                 foreach ($filters[$fid]['values'] as $v_id => $v) {
                     if (!in_array($v_id, $category_value_ids[$fid])) {
                         unset($filters[$fid]['values'][$v_id]);
                     } else {
                         if ($v instanceof shopRangeValue) {
                             $begin = $this->getFeatureValue($v->begin);
                             if ($min === null || $begin < $min) {
                                 $min = $begin;
                             }
                             $end = $this->getFeatureValue($v->end);
                             if ($max === null || $end > $max) {
                                 $max = $end;
                                 if ($v->end instanceof shopDimensionValue) {
                                     $unit = $v->end->unit;
                                 }
                             }
                         } else {
                             $tmp_v = $this->getFeatureValue($v);
                             if ($min === null || $tmp_v < $min) {
                                 $min = $tmp_v;
                             }
                             if ($max === null || $tmp_v > $max) {
                                 $max = $tmp_v;
                                 if ($v instanceof shopDimensionValue) {
                                     $unit = $v->unit;
                                 }
                             }
                         }
                     }
                 }
                 if (!$filters[$fid]['selectable'] && ($filters[$fid]['type'] == 'double' || substr($filters[$fid]['type'], 0, 6) == 'range.' || substr($filters[$fid]['type'], 0, 10) == 'dimension.')) {
                     if ($min == $max) {
                         unset($filters[$fid]);
                     } else {
                         $type = preg_replace('/^[^\\.]*\\./', '', $filters[$fid]['type']);
                         if ($type != 'double') {
                             $filters[$fid]['base_unit'] = shopDimension::getBaseUnit($type);
                             $filters[$fid]['unit'] = shopDimension::getUnit($type, $unit);
                             if ($filters[$fid]['base_unit']['value'] != $filters[$fid]['unit']['value']) {
                                 $dimension = shopDimension::getInstance();
                                 $min = $dimension->convert($min, $type, $filters[$fid]['unit']['value']);
                                 $max = $dimension->convert($max, $type, $filters[$fid]['unit']['value']);
                             }
                         }
                         $filters[$fid]['min'] = $min;
                         $filters[$fid]['max'] = $max;
                     }
                 }
             }
         }
         $this->view->assign('filters', $filters);
         $this->setCollection($collection);
         // fix prices
         $products = $this->view->getVars('products');
         $product_ids = array();
         foreach ($products as $p_id => $p) {
             if ($p['sku_count'] > 1) {
                 $product_ids[] = $p_id;
             }
         }
         if ($product_ids) {
             $min_price = $max_price = null;
             $tmp = array();
             foreach ($filters as $fid => $f) {
                 if ($fid == 'price') {
                     $min_price = waRequest::get('price_min');
                     if (!empty($min_price)) {
                         $min_price = (double) $min_price;
                     } else {
                         $min_price = null;
                     }
                     $max_price = waRequest::get('price_max');
                     if (!empty($max_price)) {
                         $max_price = (double) $max_price;
                     } else {
                         $max_price = null;
                     }
                 } else {
                     $fvalues = waRequest::get($f['code']);
                     if ($fvalues && !isset($fvalues['min']) && !isset($fvalues['max'])) {
                         $tmp[$fid] = $fvalues;
                     }
                 }
             }
             $product_skus = array();
             if ($tmp) {
                 $pf_model = new shopProductFeaturesModel();
                 $product_skus = $pf_model->getSkusByFeatures($product_ids, $tmp);
             } elseif ($min_price || $max_price) {
                 $ps_model = new shopProductSkusModel();
                 $rows = $ps_model->getByField('product_id', $product_ids, true);
                 foreach ($rows as $row) {
                     $product_skus[$row['product_id']][] = $row;
                 }
             }
             $default_currency = $this->getConfig()->getCurrency(true);
             if ($product_skus) {
                 foreach ($product_skus as $product_id => $skus) {
                     $currency = $products[$product_id]['currency'];
                     usort($skus, array($this, 'sortSkus'));
                     $k = 0;
                     if ($min_price || $max_price) {
                         foreach ($skus as $i => $sku) {
                             if ($min_price) {
                                 $tmp_price = shop_currency($min_price, true, $currency, false);
                                 if ($sku['price'] < $tmp_price) {
                                     continue;
                                 }
                             }
                             if ($max_price) {
                                 $tmp_price = shop_currency($max_price, true, $currency, false);
                                 if ($sku['price'] > $tmp_price) {
                                     continue;
                                 }
                             }
                             $k = $i;
                             break;
                         }
                     }
                     $sku = $skus[$k];
                     if ($products[$product_id]['sku_id'] != $sku['id']) {
                         $products[$product_id]['sku_id'] = $sku['id'];
                         $products[$product_id]['frontend_url'] .= '?sku=' . $sku['id'];
                         $products[$product_id]['price'] = shop_currency($sku['price'], $currency, $default_currency, false);
                         $products[$product_id]['compare_price'] = shop_currency($sku['compare_price'], $currency, $default_currency, false);
                     }
                 }
                 $this->view->assign('products', $products);
             }
         }
     } else {
         $this->setCollection($collection);
     }
     //отображение дополнительных размеров
     $products = $this->view->getVars('products');
     $product_features_model = new shopProductFeaturesSelectableModel();
     foreach ($products as &$p) {
         $sku_features = $product_features_model->getByProduct($p['id']);
         $sizes = $sku_features[3];
         if (!$sizes) {
             $p['sizes'] = array();
             continue;
         }
         $pf_names = $product_features_model->query("SELECT `id`, `value` FROM shop_feature_values_varchar where `id` IN (" . implode(',', $sizes) . ') ORDER BY `sort`;')->fetchAll();
         foreach ($pf_names as $key => $val) {
             $sizes[$val['id']] = $val['value'];
         }
         $p['sizes'] = $pf_names;
     }
     //отображение всех картинок
     foreach ($products as &$p) {
         $images_full = shopViewHelper::images($p['id']);
         if (isset($images_full[$p['id']])) {
             $p['image_ids'] = array_keys($images_full[$p['id']]);
         }
     }
     $this->view->assign('products', $products);
     // set meta
     $title = $category['meta_title'] ? $category['meta_title'] : $category['name'];
     wa()->getResponse()->setTitle($title);
     wa()->getResponse()->setMeta('keywords', $category['meta_keywords']);
     wa()->getResponse()->setMeta('description', $category['meta_description']);
     /**
      * @event frontend_category
      * @return array[string]string $return[%plugin_id%] html output for category
      */
     $this->view->assign('frontend_category', wa()->event('frontend_category', $category));
     $this->setThemeTemplate('category.html');
 }