protected function prepareProduct(shopProduct $product) { if (waRequest::get('sku')) { $url_params = array('product_url' => $product['url']); if ($product['category_url']) { $url_params['category_url'] = $product['category_url']; } if (isset($product->skus[waRequest::get('sku')])) { $product['sku_id'] = waRequest::get('sku'); $s = $product->skus[$product['sku_id']]; if ($s['image_id'] && isset($product->images[$s['image_id']])) { $product['image_id'] = $s['image_id']; $product['ext'] = $product->images[$s['image_id']]['ext']; } } } if (!isset($product->skus[$product->sku_id])) { $product->sku_id = $product->skus ? key($product->skus) : null; } if (!$product->skus) { $product->skus = array(null => array('name' => '', 'sku' => '', 'id' => null, 'available' => false, 'count' => 0, 'price' => null, 'stock' => array())); } if ($this->getConfig()->getOption('can_use_smarty') && $product->description) { $product->description = wa()->getView()->fetch('string:' . $product->description); } if ((double) $product->compare_price <= (double) $product->price) { $product->compare_price = 0; } // check categories if ($product['categories']) { $categories = $product['categories']; $route = wa()->getRouting()->getDomain(null, true) . '/' . wa()->getRouting()->getRoute('url'); $category_routes_model = new shopCategoryRoutesModel(); $routes = $category_routes_model->getRoutes(array_keys($categories)); foreach ($categories as $c) { if (isset($routes[$c['id']]) && !in_array($route, $routes[$c['id']])) { unset($categories[$c['id']]); } } $product['categories'] = $categories; } $this->view->assign('product', $product); if ($product->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) { $features_selectable = $product->features_selectable; $this->view->assign('features_selectable', $features_selectable); $product_features_model = new shopProductFeaturesModel(); $sku_features = $product_features_model->getSkuFeatures($product->id); $sku_selectable = array(); foreach ($sku_features as $sku_id => $sf) { if (!isset($product->skus[$sku_id])) { continue; } $sku_f = ""; foreach ($features_selectable as $f_id => $f) { if (isset($sf[$f_id])) { $sku_f .= $f_id . ":" . $sf[$f_id] . ";"; } } $sku = $product->skus[$sku_id]; $sku_selectable[$sku_f] = array('id' => $sku_id, 'price' => (double) shop_currency($sku['price'], $product['currency'], null, false), 'num' => 141, 'available' => $product->status && $sku['available'] && ($this->getConfig()->getGeneralSettings('ignore_stock_count') || $sku['count'] === null || $sku['count'] > 0), 'image_id' => (int) $sku['image_id']); if ($sku['compare_price']) { $sku_selectable[$sku_f]['compare_price'] = (double) shop_currency($sku['compare_price'], $product['currency'], null, false); } } $product['sku_features'] = ifset($sku_features[$product->sku_id], array()); $this->view->assign('sku_features_selectable', $sku_selectable); } }
/** * @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; }
/** * @todo use delta/absolute price * @param shopProduct $product * @param array $selected * @param array $data * @return array */ private function generateSku(shopProduct $product, $selected, &$data) { $skus = $product->skus; if (empty($skus)) { $skus = array(); } #build features map for exists SKUs $sku_map = array(); $product_features_model = new shopProductFeaturesModel(); foreach ($z = $product_features_model->getSkuFeatures($product->id) as $sku_id => $f) { $key = ""; foreach ($f as $feature_id => $value_id) { $key .= $feature_id . ":" . $value_id . ";"; } $sku_map[$key] = $sku_id; } $map = array(); foreach ($data as $code => $d) { $map[$d['feature_id']] = $code; } $default_sku = array('sku' => '', 'virtual' => 1, 'available' => 1, 'count' => null); $i = 0; foreach ($this->arrayCartesian($selected) as $features) { $sku = array('name' => array(), 'features' => array(), 'price' => $product->base_price_selectable, 'compare_price' => $product->compare_price_selectable, 'purchase_price' => $product->purchase_price_selectable); $sku_key = ""; $last_value_id = end($features); foreach ($features as $feature_id => $value_id) { $code = $map[$feature_id]; $value = $data[$code]['values'][$value_id]; $sku['features'][$code] = $value; $sku['name'][] = ifset($value['value'], $value['id']); #correct price if (isset($data[$feature_id]['values'][$value_id]['price'])) { self::parseSkuPrice($sku, $data[$feature_id]['values'][$value_id]['price']); } #set counts per stock if (isset($data[$feature_id]['stock'])) { self::parseSkuStock($sku, $data[$feature_id]['stock'], $value_id == $last_value_id ? count($f) : null); } $sku_key .= $feature_id . ":" . $value_id . ";"; $sku['key'] = $sku_key; } #concat name from feature values $sku['name'] = implode(', ', $sku['name']); if (isset($sku_map[$sku_key])) { // already exists $sku_id = $sku_map[$sku_key]; if (!empty($skus[$sku_id]['virtual'])) { //update SKU if still virtual $skus[$sku_id] = array_merge($skus[$sku_id], $sku); } $sku_map[$sku_key] = false; } else { # get free sku_id do { --$i; } while (isset($skus[$i])); $skus[$i] = array_merge($default_sku, $sku); } } if ($product->id) { // remove old virtual skus $sku_map = array_filter($sku_map); foreach ($sku_map as $key => $sku_id) { if (isset($skus[$sku_id])) { if (empty($skus[$sku_id]['virtual'])) { unset($sku_map[$key]); } else { unset($skus[$sku_id]); } } } if ($sku_map && false) { $product_skus_model = new shopProductSkusModel(); $product_skus_model->deleteJoin('shop_product_features', $product->id, array('virtual' => 1, 'id' => $sku_map)); $product_skus_model->deleteByField(array('product_id' => $product->id, 'virtual' => 1, 'id' => $sku_map)); } } $product->skus = $skus; return $sku_map; }