public function execute() { $this->setLayout(new shopFrontendLayout()); if ($this->params) { $product = $this->params; } else { $product_model = new shopProductModel(); $product = $product_model->getByField('url', waRequest::param('product_url')); } if (!$product) { throw new waException(_w('Product not found'), 404); } if ($types = waRequest::param('type_id')) { if (!in_array($product['type_id'], (array) $types)) { throw new waException(_w('Product not found'), 404); } } $is_cart = waRequest::get('cart'); if ($is_cart) { $this->setLayout(null); } $product = new shopProduct($product); if (!$is_cart) { $this->getBreadcrumbs($product); } // check url $product['num'] = 141; if ($product['url'] !== urldecode(waRequest::param('product_url'))) { $url_params = array('product_url' => $product['url']); if ($product['category_id']) { $url_params['category_url'] = $product['category_url']; } $q = waRequest::server('QUERY_STRING'); $this->redirect(wa()->getRouteUrl('/frontend/product', $url_params) . ($q ? '?' . $q : ''), 301); } $this->prepareProduct($product); $this->addCanonical(); // get services $type_services_model = new shopTypeServicesModel(); $services = $type_services_model->getServiceIds($product['type_id']); $service_model = new shopServiceModel(); $product_services_model = new shopProductServicesModel(); $services = array_merge($services, $product_services_model->getServiceIds($product['id'])); $services = array_unique($services); $services = $service_model->getById($services); $variants_model = new shopServiceVariantsModel(); $rows = $variants_model->getByField('service_id', array_keys($services), true); foreach ($rows as $row) { if (!$row['price']) { $row['price'] = $services[$row['service_id']]['price']; } $services[$row['service_id']]['variants'][$row['id']] = $row; } $rows = $product_services_model->getByField('product_id', $product['id'], true); $skus_services = array(); foreach ($product['skus'] as $sku) { $skus_services[$sku['id']] = array(); } foreach ($rows as $row) { if (!$row['sku_id']) { // remove disabled services and variantsimg if (!$row['status']) { unset($services[$row['service_id']]['variants'][$row['service_variant_id']]); } elseif ($row['price'] !== null) { // update price $services[$row['service_id']]['variants'][$row['service_variant_id']]['price'] = $row['price']; } if ($row['status'] == shopProductServicesModel::STATUS_DEFAULT) { // update default $services[$row['service_id']]['variant_id'] = $row['service_variant_id']; } } else { if (!$row['status']) { $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = false; } else { $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = $row['price']; } } } foreach ($skus_services as $sku_id => &$sku_services) { $sku_price = $product['skus'][$sku_id]['price']; foreach ($services as $service_id => $service) { if (isset($sku_services[$service_id])) { if ($sku_services[$service_id]) { foreach ($service['variants'] as $v) { if (!isset($sku_services[$service_id][$v['id']]) || $sku_services[$service_id][$v['id']] === null) { $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency'])); } elseif ($sku_services[$service_id][$v['id']]) { $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($sku_services[$service_id][$v['id']], $service['currency'], $sku_price, $product['currency'])); } } } } else { foreach ($service['variants'] as $v) { $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency'])); } } } } unset($sku_services); // disable service if all variants disabled foreach ($skus_services as $sku_id => $sku_services) { foreach ($sku_services as $service_id => $service) { if (is_array($service)) { $disabled = true; foreach ($service as $v) { if ($v !== false) { $disabled = false; break; } } if ($disabled) { $skus_services[$sku_id][$service_id] = false; } } } } foreach ($services as $s_id => &$s) { if (!$s['variants']) { unset($services[$s_id]); continue; } if ($s['currency'] == '%') { foreach ($s['variants'] as $v_id => $v) { $s['variants'][$v_id]['price'] = $v['price'] * $product['skus'][$product['sku_id']]['price'] / 100; } $s['currency'] = $product['currency']; } if (count($s['variants']) == 1) { $v = reset($s['variants']); if ($v['name']) { $s['name'] .= ' ' . $v['name']; } $s['variant_id'] = $v['id']; $s['price'] = $v['price']; unset($s['variants']); foreach ($skus_services as $sku_id => $sku_services) { if (isset($sku_services[$s_id]) && isset($sku_services[$s_id][$v['id']])) { $skus_services[$sku_id][$s_id] = $sku_services[$s_id][$v['id']][1]; } } } } unset($s); uasort($services, array('shopServiceModel', 'sortServices')); $this->view->assign('sku_services', $skus_services); $this->view->assign('services', $services); $compare = waRequest::cookie('shop_compare', array(), waRequest::TYPE_ARRAY_INT); $this->view->assign('compare', in_array($product['id'], $compare) ? $compare : array()); if (!$is_cart) { $this->view->assign('reviews', $this->getTopReviews($product['id'])); $this->view->assign('rates', $this->reviews_model->getProductRates($product['id'])); $this->view->assign('reviews_total_count', $this->getReviewsTotalCount($product['id'])); $meta_fields = $this->getMetafields($product); $title = $meta_fields['meta_title'] ? $meta_fields['meta_title'] : $product['name']; wa()->getResponse()->setTitle($title); wa()->getResponse()->setMeta('keywords', $meta_fields['meta_keywords']); wa()->getResponse()->setMeta('description', $meta_fields['meta_description']); $feature_codes = array_keys($product->features); $feature_model = new shopFeatureModel(); $features = $feature_model->getByCode($feature_codes); $this->view->assign('features', $features); } $this->view->assign('currency_info', $this->getCurrencyInfo()); /** * @event frontend_product * @param shopProduct $product * @return array[string][string]string $return[%plugin_id%]['menu'] html output * @return array[string][string]string $return[%plugin_id%]['cart'] html output * @return array[string][string]string $return[%plugin_id%]['block_aux'] html output * @return array[string][string]string $return[%plugin_id%]['block'] html output */ $this->view->assign('frontend_product', wa()->event('frontend_product', $product, array('menu', 'cart', 'block_aux', 'block'))); $sku_stocks = array(); foreach ($product->skus as $sku) { $sku_stocks[$sku_id] = array($sku['count'], $sku['stock']); } $stock_model = new shopStockModel(); $this->view->assign('stocks', $stock_model->getAll('id')); $duble = db_query("SELECT * FROM shop_product where id=" . $product['id']); $dubles = mysql_fetch_assoc($duble); $dubles_sku = db_query("SELECT * FROM shop_product_skus where product_id=" . $product['id'] . " and id=" . $dubles['sku_id']); $dubl_sku = mysql_fetch_assoc($dubles_sku); $dubles_prod = db_query("SELECT * FROM shop_product_skus where product_id!=" . $product['id'] . " and sku='" . $dubl_sku['sku'] . "' Group by product_id"); while ($dubl_product = mysql_fetch_array($dubles_prod)) { $dubles_img_pr = db_query("SELECT * FROM shop_product p, shop_product_images img where p.id=" . $dubl_product['product_id'] . " and img.product_id=" . $dubl_product['product_id'] . ""); $dubles_img = mysql_fetch_assoc($dubles_img_pr); if ($dubles_img['status'] != 0) { $koldz = substr($dubles_img['product_id'], -2, 2); $kolds = str_replace($koldz, '', $dubles_img['product_id']); if (preg_match_all("#\\d#", $kolds) < 2) { $kolds = '0' . $kolds; } if ($kolds == 0) { $kolds = '00'; } $alt_test = db_query("SELECT * FROM shop_product_features_selectable where feature_id=12 and product_id=" . $dubles_img['product_id'] . ""); $alt_t = mysql_fetch_assoc($alt_test); $alt_value = db_query("SELECT * FROM shop_feature_values_color where id=" . $alt_t['value_id'] . ""); $alt = mysql_fetch_assoc($alt_value); $dubl_p = $dubl_p . ' <a class="duble_prod" href="http://' . $_SERVER['HTTP_HOST'] . '/index.php/' . $dubles_img['url'] . '" > <img alt="' . $alt['value'] . '" title="' . $alt['value'] . '" style="width:50px" src="/wa-data/public/shop/products/' . $koldz . '/' . $kolds . '/' . $dubles_img['product_id'] . '/images/' . $dubles_img['id'] . '/' . $dubles_img['id'] . '.96x96.jpg"/></a>'; $dubl_p2 = $dubl_p2 . '<a onclick="doubl(' . $dubles_img['product_id'] . ')" class="duble_prod" > <img alt="' . $alt['value'] . '" title="' . $alt['value'] . '" style="width:50px" src="/wa-data/public/shop/products/' . $koldz . '/' . $kolds . '/' . $dubles_img['product_id'] . '/images/' . $dubles_img['id'] . '/' . $dubles_img['id'] . '.96x96.jpg"/></a>'; } $dubl_p = $dubl_p; $dubl_p2 = $dubl_p2; } $this->view->assign('duble', $dubl_p); $this->view->assign('duble2', $dubl_p2); $this->view->assign('duble_list', $dubl_p); $product['num'] = $_GET['num']; $this->view->assign('numis', $_GET['num']); $this->setThemeTemplate($is_cart ? 'product.cart.html' : 'product.html'); }
/** * @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; }
protected function getServiceVars($product) { $type_services_model = new shopTypeServicesModel(); $services = $type_services_model->getServiceIds($product['type_id']); // Fetch services $service_model = new shopServiceModel(); $product_services_model = new shopProductServicesModel(); $services = array_merge($services, $product_services_model->getServiceIds($product['id'])); $services = array_unique($services); $services = $service_model->getById($services); shopRounding::roundServices($services); // Convert service.price from default currency to service.currency foreach ($services as &$s) { $s['price'] = shop_currency($s['price'], null, $s['currency'], false); } unset($s); // Fetch service variants $variants_model = new shopServiceVariantsModel(); $rows = $variants_model->getByField('service_id', array_keys($services), true); shopRounding::roundServiceVariants($rows, $services); foreach ($rows as $row) { if (!$row['price']) { $row['price'] = $services[$row['service_id']]['price']; } else { if ($services[$row['service_id']]['variant_id'] == $row['id']) { $services[$row['service_id']]['price'] = $row['price']; } } $services[$row['service_id']]['variants'][$row['id']] = $row; } // Fetch service prices for specific products and skus $rows = $product_services_model->getByField('product_id', $product['id'], true); shopRounding::roundServiceVariants($rows, $services); $skus_services = array(); // sku_id => [service_id => price] $frontend_currency = wa('shop')->getConfig()->getCurrency(false); foreach ($product['skus'] as $sku) { $skus_services[$sku['id']] = array(); } foreach ($rows as $row) { if (!$row['sku_id']) { if (!$row['status']) { // remove disabled services and variants unset($services[$row['service_id']]['variants'][$row['service_variant_id']]); } elseif ($row['price'] !== null) { // update price for service variant, when it is specified for this product $services[$row['service_id']]['variants'][$row['service_variant_id']]['price'] = $row['price']; // !!! also set other keys related to price } if ($row['status'] == shopProductServicesModel::STATUS_DEFAULT) { // default variant is different for this product $services[$row['service_id']]['variant_id'] = $row['service_variant_id']; } } else { if (!$row['status']) { $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = false; } else { $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = $row['price']; } } } // Fill in gaps in $skus_services foreach ($skus_services as $sku_id => &$sku_services) { $sku_price = $product['skus'][$sku_id]['price']; foreach ($services as $service_id => $service) { if (isset($sku_services[$service_id])) { if ($sku_services[$service_id]) { foreach ($service['variants'] as $v) { if (!isset($sku_services[$service_id][$v['id']]) || $sku_services[$service_id][$v['id']] === null) { $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency'])); } elseif ($sku_services[$service_id][$v['id']]) { $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($sku_services[$service_id][$v['id']], $service['currency'], $sku_price, $product['currency'])); } } } } else { foreach ($service['variants'] as $v) { $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency'])); } } } } unset($sku_services); // disable service if all variants are disabled foreach ($skus_services as $sku_id => $sku_services) { foreach ($sku_services as $service_id => $service) { if (is_array($service)) { $disabled = true; foreach ($service as $v) { if ($v !== false) { $disabled = false; break; } } if ($disabled) { $skus_services[$sku_id][$service_id] = false; } } } } // Calculate prices for %-based services, // and disable variants selector when there's only one value available. foreach ($services as $s_id => &$s) { if (!$s['variants']) { unset($services[$s_id]); continue; } if ($s['currency'] == '%') { foreach ($s['variants'] as $v_id => $v) { $s['variants'][$v_id]['price'] = $v['price'] * $product['skus'][$product['sku_id']]['price'] / 100; } $s['currency'] = $product['currency']; } if (count($s['variants']) == 1) { $v = reset($s['variants']); if ($v['name']) { $s['name'] .= ' ' . $v['name']; } $s['variant_id'] = $v['id']; $s['price'] = $v['price']; unset($s['variants']); foreach ($skus_services as $sku_id => $sku_services) { if (isset($sku_services[$s_id]) && isset($sku_services[$s_id][$v['id']])) { $skus_services[$sku_id][$s_id] = $sku_services[$s_id][$v['id']][1]; } } } } unset($s); uasort($services, array('shopServiceModel', 'sortServices')); return array($services, $skus_services); }