Пример #1
0
 /**
  * @param shopProduct $product
  * @param string|array $tags
  * @return array
  */
 public function setData(shopProduct $product, $tags)
 {
     $product_id = $product->getId();
     if (!is_array($tags)) {
         $tags = explode(',', $tags);
     }
     $tag_model = new shopTagModel();
     $tag_ids = $tag_model->getIds($tags);
     $old_tag_ids = $this->query("SELECT tag_id FROM " . $this->table . "\n            WHERE product_id = i:id", array('id' => $product_id))->fetchAll(null, true);
     // find new tags to add
     $add_tag_ids = array_diff($tag_ids, $old_tag_ids);
     if ($add_tag_ids) {
         $this->multipleInsert(array('product_id' => $product_id, 'tag_id' => $add_tag_ids));
         $tag_model->incCounters($add_tag_ids);
     }
     // find tags to remove
     $remove_tag_ids = array_diff($old_tag_ids, $tag_ids);
     if ($remove_tag_ids) {
         $this->deleteByField(array('product_id' => $product_id, 'tag_id' => $remove_tag_ids));
         $tag_model->incCounters($remove_tag_ids, -1);
     }
     if ($add_tag_ids || $remove_tag_ids) {
         if ($cache = wa()->getCache()) {
             $cache->delete('tags');
         }
     }
     // return new tags
     return $this->getData($product);
 }
 public function execute()
 {
     $id = $this->get('id', true);
     $product_model = new shopProductModel();
     $data = $product_model->getById($id);
     if (!$data) {
         throw new waAPIException('invalid_param', 'Product not found', 404);
     }
     $this->response = $data;
     $p = new shopProduct($data);
     if ($p['image_id']) {
         $this->response['image_url'] = shopImage::getUrl(array('product_id' => $id, 'id' => $p['image_id'], 'ext' => $p['ext']), wa('shop')->getConfig()->getImageSize('default'), true);
     }
     $this->response['skus'] = array_values($p->skus);
     foreach ($this->response['skus'] as &$sku) {
         $stocks = array();
         foreach ($sku['stock'] as $stock_id => $count) {
             $stocks[] = array('id' => $stock_id, 'count' => $count);
         }
         unset($sku['stock']);
         $sku['stocks'] = $stocks;
     }
     unset($sku);
     $this->response['categories'] = array_values($p->categories);
     $this->response['images'] = array_values($p->getImages('thumb', true));
     $this->response['features'] = array();
     foreach ($p->features as $f => $v) {
         if (is_array($v)) {
             $this->response['features'][$f] = array_values($v);
         } else {
             $this->response['features'][$f] = (string) $v;
         }
     }
 }
 protected function save($type)
 {
     $value = waRequest::post($type);
     $product = new shopProduct($this->product_id);
     $product->save(array($type => $value));
     if ($value != 2) {
         $related_model = new shopProductRelatedModel();
         $related_model->deleteByField(array('product_id' => $this->product_id, 'type' => $type));
     }
 }
 public function execute()
 {
     $product_id = $this->get('product_id', true);
     $product_model = new shopProductModel();
     $product = $product_model->getById($product_id);
     if (!$product) {
         throw new waAPIException('invalid_param', 'Product not found', 404);
     }
     $p = new shopProduct($product);
     $this->response = array_values($p->getImages('thumb', true));
     $this->response['_element'] = 'image';
 }
 public function execute()
 {
     $id = $this->get('id', true);
     $product = $this->getProduct($id);
     $data = waRequest::post();
     if (isset($data['type_id'])) {
         $this->checkRights($data['type_id']);
     }
     $this->checkSku($data);
     $p = new shopProduct($product);
     if ($p->save($data, true, $errors)) {
         $_GET['id'] = $p->getId();
         $method = new shopProductGetInfoMethod();
         $this->response = $method->getResponse(true);
     } else {
         throw new waAPIException('server_error', implode(",\n", $errors), 500);
     }
 }
Пример #6
0
 public function execute()
 {
     $data = waRequest::post();
     $exclude = array('id', 'sku_type');
     foreach ($exclude as $k) {
         if (isset($data[$k])) {
             unset($data[$k]);
         }
     }
     $this->post("name", true);
     $this->post("skus", true);
     $this->checkSku($data);
     // check access rights
     $this->checkRights($this->post("type_id", true));
     $p = new shopProduct();
     if ($p->save($data, true, $errors)) {
         $_GET['id'] = $p->getId();
         $method = new shopProductGetInfoMethod();
         $this->response = $method->getResponse(true);
     } else {
         throw new waAPIException('server_error', implode(",\n", $errors), 500);
     }
 }
Пример #7
0
 public function execute()
 {
     $id = waRequest::get('id', 0, waRequest::TYPE_INT);
     if (!$id) {
         throw new waException("Unknown product");
     }
     $product = new shopProduct($id);
     $sizes = $this->getConfig()->getImageSizes('system');
     $images = $product->getImages($sizes);
     $param = waRequest::get('param', array(), waRequest::TYPE_ARRAY_INT);
     $image_id = !empty($param[0]) ? $param[0] : 0;
     if (isset($images[$image_id])) {
         $image = $images[$image_id];
         if ($image['size']) {
             $image['size'] = waFiles::formatSize($image['size'], '%0.2f', 'B,KB,MB,GB');
         }
         $this->setTemplate('ProductImage');
         $images = array_values($images);
         array_unshift($images, null);
         array_push($images, null);
         $offset = 0;
         foreach ($images as $k => $img) {
             if ($image['id'] == $img['id']) {
                 $offset = $k;
             }
         }
         $next = $images[$offset + 1];
         $image['dimensions'] = shopImage::getThumbDimensions($image, $sizes['big']);
         $this->view->assign(array('image' => $image, 'next' => $next, 'offset' => $offset, 'original_exists' => file_exists(shopImage::getOriginalPath($image)), 'photostream' => waRequest::get('ps', array())));
     }
     $this->view->assign(array('sizes' => $sizes, 'images' => $images, 'count' => count($images) - 2, 'product_id' => $id, 'product' => $product));
     /**
      * @event backend_product_edit
      * @return array[string][string]string $return[%plugin_id%]['images'] html output
      */
     $this->view->assign('backend_product_edit', wa()->event('backend_product_edit', $product));
 }
 protected function save(waRequestFile $file)
 {
     if (!$this->model) {
         $this->model = new shopProductSkusModel();
     }
     $field = array('id' => waRequest::post('sku_id', null, waRequest::TYPE_INT), 'product_id' => waRequest::post('product_id', null, waRequest::TYPE_INT));
     $data = array('file_size' => $file->size, 'file_name' => $file->name);
     $this->model->updateByField($field, $data);
     $file_path = shopProduct::getPath($field['product_id'], "sku_file/{$field['id']}." . pathinfo($file->name, PATHINFO_EXTENSION));
     if (file_exists($file_path) && !is_writable($file_path) || !file_exists($file_path) && !waFiles::create($file_path)) {
         $data = array('file_size' => 0, 'file_name' => '');
         $this->model->updateByField($field, $data);
         throw new waException(sprintf("The insufficient file write permissions for the %s folder.", substr($file_path, strlen($this->getConfig()->getRootPath()))));
     }
     $file->moveTo($file_path);
     return array('name' => $file->name, 'size' => waFiles::formatSize($file->size));
 }
Пример #9
0
 public function delete(array $product_ids)
 {
     if (wa()->getEnv() !== 'cli') {
         $delete_ids = $this->filterAllowedProductIds($product_ids);
     } else {
         $delete_ids = $product_ids;
     }
     // remove files
     foreach ($delete_ids as $product_id) {
         try {
             waFiles::delete(shopProduct::getPath($product_id, null, false));
             waFiles::delete(shopProduct::getPath($product_id, null, true));
         } catch (waException $e) {
         }
     }
     if (empty($delete_ids)) {
         return false;
     }
     $params = array('ids' => $delete_ids);
     /**
      * @event product_delete
      * @param array [string]mixed $params
      * @param array [string]array $params['ids'] Array of IDs of deleted product entries
      * @return void
      */
     wa()->event('product_delete', $params);
     // remove from related models
     foreach (array(new shopProductFeaturesModel(), new shopProductImagesModel(), new shopProductReviewsModel(), new shopProductServicesModel(), new shopProductSkusModel(), new shopProductStocksModel(), new shopProductStocksLogModel(), new shopProductTagsModel(), new shopCategoryProductsModel(), new shopSetProductsModel(), new shopSearchIndexModel(), new shopProductFeaturesSelectableModel(), new shopProductParamsModel(), new shopCartItemsModel()) as $model) {
         $model->deleteByProducts($delete_ids);
     }
     $type_ids = $this->select('DISTINCT `type_id`')->where($this->getWhereByField($this->id, $delete_ids))->fetchAll('type_id');
     // remove records
     if ($this->deleteById($delete_ids)) {
         $type_model = new shopTypeModel();
         $type_model->recount(array_keys($type_ids));
         if ($cache = wa('shop')->getCache()) {
             $cache->deleteGroup('sets');
         }
         return $delete_ids;
     }
     return false;
 }
Пример #10
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;
 }
 /**
  *
  * @param array $data
  * @return shopProduct
  */
 private function findProduct(&$data)
 {
     static $currencies;
     static $model;
     static $sku_model;
     /**
      * @var shopTypeFeaturesModel $type_features_model
      */
     static $type_features_model;
     if (empty($model)) {
         $model = new shopProductModel();
     }
     if (empty($currencies)) {
         $currencies = array();
         $config = wa()->getConfig();
         /**
          * @var shopConfig $config
          */
         $c = $config->getCurrency();
         $currencies[$c] = $c;
         foreach ($config->getCurrencies() as $row) {
             $currencies[$row['code']] = $row['code'];
         }
     }
     if (!empty($data['skus'][-1]['stock'])) {
         $per_stock = false;
         $stock =& $data['skus'][-1]['stock'];
         foreach ($stock as $id => &$count) {
             if ($count === '') {
                 $count = null;
             } else {
                 $count = intval($count);
                 if ($id) {
                     $per_stock = true;
                 }
             }
         }
         unset($count);
         if ($per_stock) {
             if (isset($stock[0])) {
                 unset($stock[0]);
             }
         } else {
             $count = ifset($stock[0]);
             $stock = array(0 => $count);
         }
         unset($stock);
     }
     $stack = ifset($this->data['map'][self::STAGE_CATEGORY], array());
     $category_id = end($stack);
     if (!$category_id) {
         $category_id = null;
     }
     $primary = $this->data['primary'];
     $fields = false;
     if (empty($primary)) {
         $keys = explode(':', $this->data['secondary']);
         if (empty($sku_model)) {
             $sku_model = new shopProductSkusModel();
         }
         $sku_fields = array(end($keys) => self::getData($data, $keys));
         //hack for empty SKU code ???
         if (false && reset($sku_fields) === '' && $this->data['extra_secondary']) {
             $extra_keys = explode(':', $this->data['extra_secondary']);
             $sku_fields[end($extra_keys)] = self::getData($data, $this->data['extra_secondary']);
         }
         if ($sku = $sku_model->getByField($sku_fields)) {
             $fields = array('category_id' => $category_id, 'id' => $sku['product_id']);
         }
     } elseif (!empty($primary)) {
         $fields = array('category_id' => $category_id, $primary => ifset($data[$primary], ''));
     }
     if ($fields && $this->data['ignore_category']) {
         unset($fields['category_id']);
     }
     $key = 'p';
     if ($fields && ($current_data = $model->getByField($fields))) {
         $product = new shopProduct($current_data['id']);
         $data['type_id'] = ifempty($current_data['type_id'], $this->data['type_id']);
         if (!empty($current_data['tax_id'])) {
             $data['tax_id'] = $current_data['tax_id'];
         }
         if (isset($data['currency']) && !isset($currencies[$data['currency']])) {
             $this->data['processed_count'][self::STAGE_PRODUCT]['currency']++;
             $data['currency'] = reset($currencies);
         }
         if (!empty($data['skus'])) {
             $data['sku_id'] = ifempty($current_data['sku_id'], -1);
         }
         foreach ($product->skus as $sku_id => $current_sku) {
             if (empty($data['skus'][$sku_id])) {
                 if (!count($current_sku['stock']) && $current_sku['count'] !== null) {
                     $current_sku['stock'][0] = $current_sku['count'];
                 }
                 $data['skus'][$sku_id] = $current_sku;
             }
         }
         $key .= ':u:' . $product->getId();
     } else {
         $product = new shopProduct();
         if ($category_id) {
             $data['categories'] = array($category_id);
         }
         $data['currency'] = ifempty($data['currency'], reset($currencies));
         if (!isset($currencies[$data['currency']])) {
             $this->data['processed_count'][self::STAGE_PRODUCT]['currency']++;
             $data['currency'] = reset($currencies);
         }
         if (!empty($data['skus'])) {
             $sku = reset($data['skus']);
             $data['sku_id'] = key($data['skus']);
             if (!isset($sku['available'])) {
                 $sku['available'] = true;
                 $data['skus'][$data['sku_id']] = $sku;
             }
         }
         $key .= ':i:' . $this->getKey($fields);
     }
     if (!empty($data['features'])) {
         foreach ($data['features'] as $feature => &$values) {
             if (is_array($values)) {
             } elseif (preg_match('/^<\\{(.*)\\}>$/', $values, $matches)) {
                 if (!isset($data['features_selectable'])) {
                     $data['features_selectable'] = array();
                 }
                 if ($values = explode(',', $matches[1])) {
                     foreach ($values as &$value) {
                         if (preg_match('@^(.+)=([\\+\\-]?(\\d+|\\.\\d+|\\d\\.\\d))$@', $value, $matches)) {
                             $value = array('value' => trim($matches[1]), 'price' => $matches[2]);
                         } else {
                             $value = array('value' => trim($value));
                         }
                         unset($value);
                     }
                     $data['features_selectable'][$feature] = array('values' => $values);
                     if (!empty($this->data['virtual_sku_stock']) && isset($data['skus'][-1]['stock'])) {
                         $stock = $data['skus'][-1]['stock'];
                         switch ($this->data['virtual_sku_stock']) {
                             case 'distribute':
                                 if (is_array($stock)) {
                                     foreach ($stock as &$stock_item) {
                                         $stock_item = $stock_item / count($values);
                                         unset($stock_item);
                                     }
                                 } else {
                                     $stock = $stock / count($values);
                                 }
                                 $data['features_selectable'][$feature]['stock'] = $stock;
                                 break;
                             case 'set':
                                 $data['features_selectable'][$feature]['stock'] = $stock;
                                 break;
                         }
                     }
                     $product->sku_type = shopProductModel::SKU_TYPE_SELECTABLE;
                     if (isset($data['skus'][-1])) {
                         if (!isset($data['base_price_selectable'])) {
                             $data['base_price_selectable'] = ifset($data['skus'][-1]['price']);
                         }
                         if (!isset($data['purchase_price_selectable'])) {
                             $data['purchase_price_selectable'] = ifset($data['skus'][-1]['purchase_price']);
                         }
                         if (!isset($data['compare_price_selectable'])) {
                             $data['compare_price_selectable'] = ifset($data['skus'][-1]['compare_price']);
                         }
                     }
                     unset($data['skus']);
                 }
                 unset($data['features'][$feature]);
             } elseif (preg_match('/^\\{(.*)\\}$/', $values, $matches)) {
                 $values = explode(',', $matches[1]);
             }
         }
         unset($values);
     }
     $this->findTax($data);
     $access = $this->findType($data);
     if ($access) {
         $access = !$product->type_id || in_array($product->type_id, $this->data['types']);
     }
     if ($access) {
         $product->__hash = $key;
         foreach ($this->data['new_features'] as $code => &$feature) {
             if (isset($data['features'][$code]) || isset($data['features_selectable'][$code])) {
                 if ($data['type_id'] && !in_array($data['type_id'], $feature['types'])) {
                     if (empty($type_features_model)) {
                         $type_features_model = new shopTypeFeaturesModel();
                     }
                     $type_features_model->updateByFeature($feature['id'], array($data['type_id']), false);
                     $feature['types'][] = $data['type_id'];
                 }
             }
             unset($feature);
         }
     }
     return $access ? $product : null;
 }
Пример #12
0
 public static function getPath($sku)
 {
     return empty($sku['file_name']) ? null : shopProduct::getPath($sku['product_id'], "sku_file/{$sku['id']}." . pathinfo($sku['file_name'], PATHINFO_EXTENSION));
 }
Пример #13
0
 /**
  * Returns URL of a product image. 
  * 
  * @param array $image Key-value image data object
  * @param string $size Size value string (e.g., '200x0', '96x96', etc.)
  * @param bool $absolute Whether absolute URL must be returned
  * @return string
  */
 public static function getUrl($image, $size = null, $absolute = false)
 {
     $path = shopProduct::getFolder($image['product_id']) . "/{$image['product_id']}/images/{$image['id']}/{$image['id']}.{$size}.{$image['ext']}";
     if (waSystemConfig::systemOption('mod_rewrite')) {
         return wa()->getDataUrl($path, true, 'shop', $absolute);
     } else {
         if (file_exists(wa()->getDataPath($path, true, 'shop'))) {
             return wa()->getDataUrl($path, true, 'shop', $absolute);
         } else {
             $path = str_replace('products/', 'products/thumb.php/', $path);
             return wa()->getDataUrl($path, true, 'shop', $absolute);
         }
     }
 }
Пример #14
0
 public function deleteByProducts(array $product_ids, $hard = false)
 {
     if ($hard) {
         foreach ($product_ids as $product_id) {
             waFiles::delete(shopProduct::getPath($product_id, 'images', false));
             waFiles::delete(shopProduct::getPath($product_id, 'images', true));
         }
     }
     $this->deleteByField('product_id', $product_ids);
 }
Пример #15
0
 /**
  * @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));
     }
 }
Пример #16
0
 public function execute()
 {
     $update = waRequest::post('update');
     // just update one or any field of product
     if ($update) {
         $this->update($update);
         return;
     }
     $data = waRequest::post('product');
     $id = empty($data['id']) || !intval($data['id']) ? null : $data['id'];
     if (!$id && isset($data['id'])) {
         unset($data['id']);
     }
     # edit product info - check rights
     $product_model = new shopProductModel();
     if ($id) {
         if (!$product_model->checkRights($id)) {
             throw new waRightsException(_w("Access denied"));
         }
     } else {
         if (!$product_model->checkRights($data)) {
             throw new waRightsException(_w("Access denied"));
         }
     }
     $skus = waRequest::post('skus', array());
     if (isset($data['skus'])) {
         foreach ($skus as $s_id => $s) {
             if (isset($data['skus'][$s_id])) {
                 $data['skus'][$s_id] += $s;
             } else {
                 $data['skus'][$s_id] = $s;
             }
         }
     } else {
         $data['skus'] = $skus;
     }
     if (empty($data['categories'])) {
         $data['categories'] = array();
     }
     if (empty($data['tags'])) {
         $data['tags'] = array();
     }
     if (empty($data['features_selectable'])) {
         $data['features_selectable'] = array();
     }
     # verify sku_type before save
     if ($data['type_id']) {
         $features_model = new shopFeatureModel();
         if ($features_model->isTypeMultipleSelectable($data['type_id'])) {
             if ($data['sku_type'] == shopProductModel::SKU_TYPE_SELECTABLE) {
                 if (empty($data['features_selectable'])) {
                     throw new waException(_w("Check at least one feature value"));
                 }
             }
         } else {
             $data['sku_type'] = shopProductModel::SKU_TYPE_FLAT;
         }
     } else {
         $data['sku_type'] = shopProductModel::SKU_TYPE_FLAT;
     }
     if ($data['sku_type'] == shopProductModel::SKU_TYPE_FLAT) {
         $data['features_selectable'] = array();
     }
     try {
         $product = new shopProduct($id);
         // for logging changes in stocks
         shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_PRODUCT);
         if ($product->save($data, true, $this->errors)) {
             $features_counts = null;
             if ($product->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
                 $features_counts = array();
                 foreach ($product->features_selectable as $f) {
                     if (isset($f['selected'])) {
                         $features_counts[] = $f['selected'];
                     } else {
                         $features_counts[] = count($f['values']);
                     }
                 }
                 $features_total_count = array_product($features_counts);
                 $this->response['features_selectable_strings'] = array('options' => implode(' x ', $features_counts) . ' ' . _w('option', 'options', $features_total_count), 'skus' => _w('%d SKU in total', '%d SKUs in total', $features_total_count));
             }
             shopProductStocksLogModel::clearContext();
             if ($id) {
                 $this->logAction('product_edit', $id);
             } else {
                 $this->logAction('product_add', $product->getId());
             }
             $this->response['id'] = $product->getId();
             $this->response['name'] = $product->name;
             $this->response['url'] = $product->url;
             $this->response['frontend_urls'] = $this->getUrl($product);
             $this->response['raw'] = $this->workupData($product->getData());
             $sales_rate = waRequest::post('sales_rate', 0, waRequest::TYPE_STRING_TRIM);
             $sales_rate = (double) str_replace(',', '.', $sales_rate);
             $runout = $product->getRunout($sales_rate);
             if (!empty($runout['product'])) {
                 $runout['product']['date_str'] = wa_date("humandate", $runout['product']['date']);
                 $runout['product']['days_str'] = _w('%d day', '%d days', $runout['product']['days']);
                 if ($runout['product']['days'] < 3 * 365 && $runout['product']['days'] > 0) {
                     $runout['product_str'] = sprintf(_w('Based on last 30 days sales dynamic (%d items of %s sold during last 30 days), you will run out of %s in <strong>%d days</strong> (on %s)'), $sales_rate * 30, $product->name, $product->name, $runout['product']['days'], wa_date("humandate", $runout['product']['date']));
                 }
             } else {
                 $runout['product'] = new stdClass();
                 /* {} */
             }
             if (!empty($runout['sku'])) {
                 foreach ($runout['sku'] as &$sk_r) {
                     if (empty($sk_r['stock'])) {
                         $sk_r['date_str'] = wa_date("humandate", $sk_r['date']);
                         $sk_r['days_str'] = _w('%d day', '%d days', $sk_r['days']);
                     } else {
                         foreach ($sk_r['stock'] as &$st_r) {
                             $st_r['date_str'] = wa_date("humandate", $st_r['date']);
                             $st_r['days_str'] = _w('%d day', '%d days', $st_r['days']);
                         }
                     }
                 }
                 unset($sk_r, $st_r);
             } else {
                 $runout['sku'] = new stdClass();
                 /* {} */
             }
             $this->response['raw']['runout'] = $runout;
             $this->response['storefront_map'] = $product_model->getStorefrontMap($product->id);
         }
     } catch (Exception $ex) {
         $this->setError($ex->getMessage());
     }
 }
Пример #17
0
 public function crossSelling($product_id, $limit = 5, $available_only = false, $key = false)
 {
     if (!is_numeric($limit)) {
         $key = $available_only;
         $available_only = $limit;
         $limit = 5;
     }
     if (is_string($available_only)) {
         $key = $available_only;
         $available_only = false;
     }
     if (!$product_id) {
         return array();
     }
     if (is_array($product_id)) {
         if ($key) {
             foreach ($product_id as &$r) {
                 $r = $r[$key];
             }
             unset($r);
         }
         $product_model = new shopProductModel();
         $sql = "SELECT p.* FROM  shop_product p JOIN shop_type t ON p.type_id = t.id\n            WHERE (p.id IN (i:id)) AND (t.cross_selling !=  '' OR p.cross_selling = 2)\n            ORDER BY RAND() LIMIT 1";
         $p = $product_model->query($sql, array('id' => $product_id))->fetchAssoc();
         $p = new shopProduct($p);
         $result = $p->crossSelling($limit, $available_only);
         foreach ($result as $p_id => $pr) {
             if (in_array($p_id, $product_id)) {
                 unset($result[$p_id]);
             }
         }
         return $result;
     } else {
         $p = new shopProduct($product_id);
         return $p->crossSelling($limit, $available_only);
     }
 }
 /**
  * Daten fuer Produktbereiche aufbereiten
  *
  * @param array $hParams      Parameter für shopProduct::readEntry und Assigns
  * @return array
  */
 protected static function includeProductCompare($hParams = array())
 {
     if (array_key_exists('settings_file', $hParams)) {
         $sSettingsFile = $hParams['settings_file'] ? $hParams['settings_file'] : 'products';
         unset($hParams['settings_file']);
         $hParams['shop_settings'] = Settings::get($sSettingsFile);
     }
     // Einstellungen dem Renderer zuweisen
     $sSettingsAssignName = null;
     if (array_key_exists('assign_settings', $hParams)) {
         $sSettingsAssignName = $hParams['assign_settings'];
         Renderer::assign($sSettingsAssignName, $hParams['shop_settings']);
         unset($hParams['assign_settings']);
     }
     // Produkt-IDs setzen
     if (!array_key_exists('peid', $hParams)) {
         $hParams['peid'] = $hParams['shop_settings']['products']['peid'];
     }
     // Daten für Vergleiche formatieren
     $hParams['return_shopformat'] = 1;
     // Daten auslesen und zurückgeben
     return shopProduct::readEntry($hParams);
 }
 public function addNewProduct($data)
 {
     $product = new shopProduct();
     $product->save($data);
     return $product->getId();
 }
Пример #20
0
 private function getProductInfo($product_id, $sku_id = null, $order_id = null)
 {
     $product = new shopProduct($product_id);
     $data = $product->getData();
     if (!$data) {
         return array();
     }
     $rate = 1;
     $currency_model = $this->getModel('currency');
     if ($order_id) {
         $order = $this->getOrder($order_id);
         $rate = $order['rate'];
     }
     $data['price'] = (double) $currency_model->convertByRate($data['price'], 1, $rate);
     $data['max_price'] = (double) $currency_model->convertByRate($data['max_price'], 1, $rate);
     $data['min_price'] = (double) $currency_model->convertByRate($data['min_price'], 1, $rate);
     $data['skus'] = $product->skus;
     foreach ($data['skus'] as &$sku) {
         $sku['price'] = (double) $currency_model->convertByRate($sku['primary_price'], 1, $rate);
     }
     unset($sku);
     if ($sku_id === null) {
         $sku_id = count($data['skus']) > 1 ? $product->sku_id : null;
     }
     if ($sku_id && isset($data['skus'][$sku_id])) {
         $sku_price = $data['skus'][$sku_id]['price'];
     } else {
         $sku_price = $data['price'];
     }
     $data['services'] = $this->getServices($product_id, $sku_id, $order_id, $sku_price);
     return $data;
 }
Пример #21
0
 protected function assignReportsData(shopProduct $product)
 {
     $order_model = new shopOrderModel();
     $sales_total = $order_model->getTotalSalesByProduct($product['id'], $product['currency']);
     $this->view->assign('sales', $sales_total);
     $profit = $sales_total['total'];
     $rows = $order_model->getSalesByProduct($product['id']);
     $date = strtotime(date('Y-m-d') . " -30 day");
     $sales_data = array();
     $i = 0;
     while ($date < time()) {
         $date = date('Y-m-d', $date);
         $sales_data[] = array($i++, isset($rows[$date]) ? (double) $rows[$date] : 0);
         $date = strtotime($date . " +1 day");
     }
     $this->view->assign('sales_plot_data', array($sales_data));
     if (count($product['skus']) > 1) {
         $sku_sales_data = array();
         $rows = $order_model->getTotalSkuSalesByProduct($product['id'], $product['currency']);
         foreach ($rows as $sku_id => $v) {
             $sku_sales_data[] = array($product['skus'][$sku_id]['name'], (double) $v['total']);
             if (!(double) $v['purchase']) {
                 $profit = false;
             } elseif ($profit) {
                 $profit -= $v['purchase'];
             }
         }
         $this->view->assign('sku_plot_data', array($sku_sales_data));
     } else {
         if ((double) $sales_total['purchase']) {
             $profit -= $sales_total['purchase'];
         } else {
             $profit = false;
         }
     }
     if ($profit) {
         $this->view->assign('profit', $profit);
     }
     $runout = array();
     $sales_rate = 0;
     if ($sales_total['quantity'] >= 3) {
         // < 3 means not enough data for proper statistic
         $sales_rate = $sales_total['quantity'] / 30;
         $runout = $product->getRunout($sales_rate);
     }
     $this->view->assign('runout', $runout);
     $this->view->assign('sales_rate', $sales_rate);
     $stocks_log_model = new shopProductStocksLogModel();
     $stocks_log = $stocks_log_model->getList('*,stock_name,sku_name,product_name', array('where' => array('product_id' => $product->id), 'limit' => 5, 'order' => 'datetime DESC'));
     $this->view->assign('stocks_log', $stocks_log);
 }