/** * @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); } }
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); } }
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)); }
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; }
/** * @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; }
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)); }
/** * 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); } } }
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); }
/** * @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)); } }
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()); } }
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(); }
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; }
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); }