public function execute()
 {
     if (!$this->getUser()->getRights('shop', 'settings')) {
         throw new waRightsException(_w('Access denied'));
     }
     if ($features = waRequest::post('feature')) {
         $model = new shopFeatureModel();
         $type_features_model = new shopTypeFeaturesModel();
         foreach ($features as $feature_id => &$feature) {
             $feature['id'] = $model->save($feature, $feature_id);
             if ($feature['selectable']) {
                 $feature['values'] = $model->setValues($feature, $feature['values']);
             }
             $feature['types'] = $type_features_model->updateByFeature($feature['id'], $feature['types']);
             if ($feature_id < $feature['id']) {
                 $feature['sort'] = array();
                 foreach ($feature['types'] as $type) {
                     $feature['sort'][$type] = $type_features_model->move(array('feature_id' => $feature['id'], 'type_id' => $type), null, $type);
                 }
             }
         }
         unset($feature);
         shopFeatureModel::appendTypeNames($features);
     }
     $this->response = $features;
 }
 private function initImport()
 {
     $name = basename(waRequest::post('file'));
     if (empty($name)) {
         throw new waException('Empty import filename');
     }
     $config = wa('shop')->getConfig();
     /**
      * @var shopConfig $config ;
      */
     //TODO detect emulate & type of control
     $file = wa()->getTempPath('csv/upload/' . $name);
     $this->data['emulate'] = waRequest::post('emulate') ? array() : null;
     $this->data['rights'] = $this->getUser()->getRights('shop', 'settings');
     $this->data['new_features'] = array();
     $this->data['currencies'] = $config->getCurrencies();
     $this->data['type_id'] = waRequest::post('type_id', null, waRequest::TYPE_INT);
     if ($this->data['type_id'] && !in_array($this->data['type_id'], $this->data['types'])) {
         $this->data['type_id'] = reset($this->data['types']);
     }
     $map = waRequest::post('csv_map');
     if ($this->emulate()) {
         $this->reader = shopCsvReader::snapshot($file);
         if (!$this->reader) {
             throw new waException('CSV file not found');
         }
         $this->reader->rewind();
     } else {
         /*, waRequest::post('encoding', 'utf-8')*/
         //after upload encoding converted into utf-8
         $this->reader = new shopCsvReader($file, waRequest::post('delimiter', ';'));
         $header = $this->reader->header();
         foreach ($map as $id => &$target) {
             if (preg_match('@^f\\+:(.+)$@', $target, $matches)) {
                 if ($this->data['rights']) {
                     $id = preg_replace('@\\D.*$@', '', $id);
                     $feature = array('name' => ifset($header[$id], 'csv feature'), 'type' => shopFeatureModel::TYPE_VARCHAR, 'multiple' => 0, 'selectable' => 0);
                     list($feature['type'], $feature['multiple'], $feature['selectable']) = explode(':', $matches[1]);
                     $feature['type'] = preg_replace('@([^\\.]+\\.)\\1@', '$1', $feature['type']);
                     if (empty($feature_model)) {
                         $feature_model = new shopFeatureModel();
                     }
                     if (empty($type_features_model)) {
                         $type_features_model = new shopTypeFeaturesModel();
                     }
                     $feature['id'] = $feature_model->save($feature);
                     if ($this->data['type_id']) {
                         $type_features_model->updateByFeature($feature['id'], array($this->data['type_id']), false);
                     }
                     $target = 'features:' . $feature['code'];
                     $this->data['new_features'][$feature['code']] = array('id' => $feature['id'], 'types' => (array) $this->data['type_id']);
                 } else {
                     unset($map[$id]);
                 }
             }
         }
         unset($target);
     }
     $map = array_flip($map);
     $this->reader->setMap($map);
     $this->data['file'] = serialize($this->reader);
     $this->data['primary'] = waRequest::post('primary', 'name');
     $this->data['secondary'] = waRequest::post('secondary', 'skus:-1:sku');
     $this->data['extra_secondary'] = false;
     switch ($this->data['secondary']) {
         case 'skus:-1:sku':
             if (isset($map['skus:-1:name']) && intval($map['skus:-1:name']) >= 0) {
                 $this->data['extra_secondary'] = 'skus:-1:name';
             }
             break;
         case 'skus:-1:name':
             if (isset($map['skus:-1:sku']) && intval($map['skus:-1:sku']) >= 0) {
                 $this->data['extra_secondary'] = 'skus:-1:sku';
             }
             break;
     }
     $upload_app = waRequest::post('upload_app', 'shop', waRequest::TYPE_STRING_TRIM);
     if ($upload_app != 'site') {
         $upload_app = 'shop';
     }
     $this->data['upload_path'] = preg_replace('@[\\\\/]+$@', '/', waRequest::post('upload_path', 'upload/images/') . '/');
     $this->data['upload_path'] = preg_replace('@(^|/)(\\.\\.)/@', '$1/', $this->data['upload_path']);
     if (waSystem::getSetting('csv.upload_path') != $this->data['upload_path']) {
         $app_settings = new waAppSettingsModel();
         $app_settings->set('shop', 'csv.upload_path', $this->data['upload_path']);
     }
     $this->data['virtual_sku_stock'] = waRequest::post('virtual_sku_stock', '', waRequest::TYPE_STRING_TRIM);
     if ($upload_app == 'site') {
         $this->data['upload_path'] = wa()->getDataPath($this->data['upload_path'], true, 'site');
     } else {
         $this->data['upload_path'] = wa()->getDataPath($this->data['upload_path'], false, 'shop');
     }
     if (waSystem::getSetting('csv.upload_app') != $upload_app) {
         if (empty($app_settings)) {
             $app_settings = new waAppSettingsModel();
         }
         $app_settings->set('shop', 'csv.upload_app', $upload_app);
     }
     $this->data['ignore_category'] = !!waRequest::post('ignore_category', 0, waRequest::TYPE_INT);
     if (!in_array($this->data['primary'], array('name', 'url', 'null'))) {
         throw new waException(_w('Invalid primary field'));
     }
     if ($this->data['primary'] == 'null') {
         $this->data['primary'] = null;
     }
     if (!in_array($this->data['secondary'], array('skus:-1:sku', 'skus:-1:name'))) {
         throw new waException(_w('Invalid secondary field'));
     }
     $current = $this->reader->current();
     if (!empty($this->data['primary']) && self::getData($current, $this->data['primary']) === null) {
         throw new waException(_w('Empty primary CSV column'));
     }
     if (empty($this->data['primary']) && self::getData($current, $this->data['secondary']) === null) {
         throw new waException(_w('Empty secondary CSV column'));
     }
     $this->data['count'] = array(self::STAGE_FILE => $this->reader ? $this->reader->size() : null, self::STAGE_CATEGORY => null, self::STAGE_PRODUCT => null, self::STAGE_SKU => null, self::STAGE_IMAGE => null);
 }
Esempio n. 3
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;
 }
 /**
  * @see shopProductStorageInterface::setData()
  * @param shopProduct $product current product object
  * @param array [string] mixed $data new product feature values
  */
 public function setData(shopProduct $product, $data)
 {
     $product_id = $product->getId();
     $feature_model = new shopFeatureModel();
     $codes = array_keys($data);
     $features = $feature_model->getByCode($codes);
     /**
      * composite fields workaround
      */
     $composite_codes = array();
     foreach ($data as $code => $value) {
         if (!preg_match('/\\.[0-3]$/', $code) && isset($features[$code]) && preg_match('/^([23])d\\./', $features[$code]['type'], $matches)) {
             $n = $matches[1];
             $pattern = '/^' . implode('\\s*[×xX\\*]?\\s*', array_fill(0, $n, '([^\\s]+)')) . '(\\s+.+)?$/u';
             if (preg_match($pattern, trim($value), $matches)) {
                 $unit = ifset($matches[$n + 1]);
                 for ($i = 0; $i < $n; $i++) {
                     $c_code = $code . '.' . $i;
                     $data[$c_code] = $matches[$i + 1] . $unit;
                     $composite_codes[] = $c_code;
                 }
                 unset($features[$code]);
             } else {
                 /**
                  * invalid complex feature format
                  */
             }
             unset($data[$code]);
         }
     }
     if ($composite_codes) {
         $features += $feature_model->getByCode($composite_codes);
     }
     $features_map = array();
     foreach ($features as $code => $f) {
         $features_map[$f['id']] =& $features[$code];
     }
     $current = array();
     $rows = $this->getByField(array('product_id' => $product_id, 'sku_id' => null), true);
     foreach ($rows as $row) {
         $id = $row['feature_id'];
         if (isset($features_map[$id])) {
             $f = $features_map[$id];
             $code = $f['code'];
             if (empty($f['multiple'])) {
                 $current[$code] = intval($row['feature_value_id']);
             } else {
                 if (!isset($current[$code])) {
                     $current[$code] = array();
                 }
                 $current[$code][] = intval($row['feature_value_id']);
             }
         } else {
             //obsolete data
         }
     }
     $add = $delete = array();
     foreach ($data as $code => $value) {
         if (isset($features[$code])) {
             $f =& $features[$code];
             if (is_array($value)) {
                 $empty = isset($value['value']) && $value['value'] === '';
                 if (!$empty && isset($value['value']) && is_array($value['value'])) {
                     foreach ($value['value'] as $key => $v) {
                         if ($v === '') {
                             unset($value['value'][$key]);
                         }
                     }
                     $empty = count($value['value']) == 0;
                 }
                 if (!$empty && !isset($value['value'])) {
                     foreach ($value as $key => $v) {
                         if ($v === '') {
                             unset($value[$key]);
                         }
                     }
                     $empty = count($value) == 0;
                 }
             } else {
                 $empty = $value === '';
             }
             if ($empty) {
                 //delete it
                 if (isset($current[$code])) {
                     $delete[$f['id']] = $current[$code];
                 }
             } else {
                 if (is_array($value) && preg_match('/^(.+\\.)[12]$/', $code, $matches) && isset($data[$matches[1] . '0'])) {
                     $value = array_merge($data[$matches[1] . '0'], $value);
                 }
                 $id = $feature_model->getValueId($f, $value, true);
                 if (isset($current[$code])) {
                     if (empty($f['multiple'])) {
                         if ($current[$code] != $id) {
                             $delete[$f['id']] = $current[$code];
                             $add[$f['id']] = $id;
                         }
                     } else {
                         $delete[$f['id']] = array_diff($current[$code], (array) $id);
                         if (empty($delete[$f['id']])) {
                             unset($delete[$f['id']]);
                         }
                         $add[$f['id']] = array_diff((array) $id, $current[$code]);
                         if (empty($add[$f['id']])) {
                             unset($add[$f['id']]);
                         }
                     }
                 } else {
                     $add[$f['id']] = $id;
                 }
             }
         } elseif (!empty($value) && is_array($value)) {
             //it's a new feature
             if (!empty($value) && (ifset($value['type']) == shopFeatureModel::TYPE_BOOLEAN || !empty($value['value']))) {
                 $f = array('name' => $value['name'], 'type' => $value['type'], 'types' => $value['types']);
                 $f['id'] = $feature_model->save($f);
                 $type_features_model = new shopTypeFeaturesModel();
                 $type_features_model->updateByFeature($f['id'], $f['types']);
                 if ($value['value'] !== '') {
                     $add[$f['id']] = $feature_model->getValueId($f, $value['value'], true);
                 }
             }
         }
     }
     foreach ($features as $code => $f) {
         if (empty($data[$code]) && !empty($current[$code])) {
             $delete[$f['id']] = $current[$code];
         }
     }
     foreach ($delete as $feature_id => $value_id) {
         $this->deleteByField(array('product_id' => $product_id, 'sku_id' => null, 'feature_id' => $feature_id, 'feature_value_id' => $value_id));
     }
     foreach ($add as $feature_id => $value_id) {
         $this->multipleInsert(array('product_id' => $product_id, 'feature_id' => $feature_id, 'feature_value_id' => $value_id));
     }
 }