public function execute() { $type = waRequest::get('type', '', waRequest::TYPE_STRING_TRIM); $parent_id = waRequest::get('parent_id', 0, waRequest::TYPE_INT); if ($parent_id) { $category_model = new shopCategoryModel(); $parent = $category_model->getById($parent_id); } $this->template = 'DialogProduct' . ucfirst($type) . 'Create'; $this->view->assign(array('type' => $type, 'parent' => $parent_id ? $parent : array())); if ($type == 'category') { $tag_model = new shopTagModel(); $stuff = '%category_url%'; $frontend_url = wa()->getRouteUrl('/frontend/category', array('category_url' => $stuff), true); $pos = strrpos($frontend_url, $stuff); $fontend_base_url = $pos !== false ? rtrim(substr($frontend_url, 0, $pos), '/') . '/' : $frontend_url; $feature_model = new shopFeatureModel(); $features = $feature_model->getFeatures('selectable', 1); $features += $feature_model->getFeatures('type', 'boolean'); $features = $feature_model->getValues($features); $this->view->assign(array('cloud' => $tag_model->getCloud(), 'currency' => wa()->getConfig()->getCurrency(), 'frontend_base_url' => $fontend_base_url, 'lang' => substr(wa()->getLocale(), 0, 2), 'features' => $features)); } else { if ($type == 'set') { $this->view->assign('default_count', $this->set_dynamic_default_count); } } }
public function execute() { if (!$this->getUser()->getRights('shop', 'settings')) { throw new waRightsException(_w('Access denied')); } $feature_model = new shopFeatureModel(); $values_per_feature = 7; $type = waRequest::get('type', waRequest::TYPE_STRING, ''); if ($type_id = intval($type)) { $features = $feature_model->getByType($type_id, 'id', $values_per_feature); } else { if ($type === 'empty') { $features = $feature_model->getByType(null, 'id', $values_per_feature); } elseif ($type === '') { $features = $feature_model->getFeatures(true, null, 'id', $values_per_feature); } else { $features = $feature_model->getByType(0, 'id', $values_per_feature); } } if ($features) { shopFeatureModel::appendTypeNames($features); $type_features_model = new shopTypeFeaturesModel(); $type_features_model->fillTypes($features); } $this->view->assign('features', $features); $this->view->assign('values_per_feature', $values_per_feature); }
public function execute() { if (!$this->getRights('settings')) { throw new waAPIException('access_denied', 403); } $code = $this->post('code', true); $type = $this->post('type', true); $this->post('name', true); $feature_model = new shopFeatureModel(); if ($feature_model->getByCode($code)) { throw new waAPIException('invalid_param', 'Code ' . $code . ' already exists'); } $types = array(shopFeatureModel::TYPE_BOOLEAN, shopFeatureModel::TYPE_DOUBLE, shopFeatureModel::TYPE_TEXT, shopFeatureModel::TYPE_VARCHAR, shopFeatureModel::TYPE_COLOR); if (!in_array($type, $types)) { throw new waAPIException('invalid_param', 'Invalid type: ' . $type); } $data = waRequest::post(); $feature_id = $feature_model->insert($data); if ($feature_id) { $_GET['id'] = $feature_id; $method = new shopFeatureGetInfoMethod(); $this->response = $method->getResponse(true); } else { throw new waAPIException('server_error', 500); } }
public function execute() { $feature_model = new shopFeatureModel(); if ($type_id = waRequest::get('type_id')) { $features = $feature_model->getByType($type_id, 'id'); } else { $features = $feature_model->getAll('id'); } $selectable = array(); foreach ($features as $f_id => $f) { if ($f['selectable']) { $selectable[$f_id] = $f; } } if ($selectable) { $selectable = $feature_model->getValues($selectable); foreach ($selectable as $f_id => $f) { $f['values'] = array_values($f['values']); $f['values']['_element'] = 'value'; $features[$f_id] = $f; } } $this->response = $features; $this->response['_element'] = 'feature'; }
public function execute() { if (!$this->getUser()->getRights('shop', 'settings')) { throw new waRightsException(_w('Access denied')); } $types_per_page = $this->getConfig()->getOption('types_per_page'); $values_per_feature = 7; $type_model = new shopTypeModel(); $type_features_model = new shopTypeFeaturesModel(); $feature_model = new shopFeatureModel(); $types = $type_model->getAll($type_model->getTableId(), true); $type_features_model->countFeatures($types); $show_all_features = $feature_model->countAll() < $this->getConfig()->getOption('features_per_page'); if ($show_all_features) { $feature_model = new shopFeatureModel(); if ($features = $feature_model->getFeatures(true, null, 'id', $values_per_feature)) { $show_all_features = count($features); $type_features_model->fillTypes($features, $types); shopFeatureModel::appendTypeNames($features); } } else { $features = array(); } $this->view->assign('type_templates', shopTypeModel::getTemplates()); $this->view->assign('show_all_features', $show_all_features); $this->view->assign('show_all_types', count($types) - $types_per_page < 3); $this->view->assign('types_per_page', $types_per_page); $this->view->assign('values_per_feature', $values_per_feature); $this->view->assign('icons', (array) $this->getConfig()->getOption('type_icons')); $this->view->assign('product_types', $types); $this->view->assign('features', $features); }
public function execute() { if (!$this->getUser()->getRights('shop', 'settings')) { throw new waRightsException(_w('Access denied')); } if ($features = waRequest::post('feature')) { $model = new shopFeatureModel(); $type_features_model = new shopTypeFeaturesModel(); foreach ($features as $feature_id => &$feature) { $feature['id'] = $model->save($feature, $feature_id); if ($feature['selectable']) { $feature['values'] = $model->setValues($feature, $feature['values']); } $feature['types'] = $type_features_model->updateByFeature($feature['id'], $feature['types']); if ($feature_id < $feature['id']) { $feature['sort'] = array(); foreach ($feature['types'] as $type) { $feature['sort'][$type] = $type_features_model->move(array('feature_id' => $feature['id'], 'type_id' => $type), null, $type); } } } unset($feature); shopFeatureModel::appendTypeNames($features); } $this->response = $features; }
public function execute() { $app_settings_model = new waAppSettingsModel(); $settings = $app_settings_model->get(array('shop', 'yoss')); if ($settings['status'] === 'on') { $query = waRequest::post('query', '', waRequest::TYPE_STRING_TRIM); $page = waRequest::post('page', 1, 'int'); $result = array(); $result['products'] = array(); $result['product_count'] = 0; $collection = new shopProductsCollection('search/query=' . $query); $product_limit = $settings['product_limit']; if (!$product_limit) { $product_limit = $this->getConfig()->getOption('products_per_page'); } $products = $collection->getProducts('*', ($page - 1) * $product_limit, $product_limit); if ($products) { $brands = array(); $categories = array(); $feature_model = new shopFeatureModel(); $result['searh_all_url'] = wa()->getRouteUrl('/frontend/search/query=') . '?query=' . $query; foreach ($products as $p) { $brand_feature = $feature_model->getByCode('brand'); $brand = ''; if ($brand_feature) { $feature_value_model = $feature_model->getValuesModel($brand_feature['type']); $product_brands = $feature_value_model->getProductValues($p['id'], $brand_feature['id']); $brands = array(); foreach ($product_brands as $k => $v) { $brand_id = $feature_value_model->getValueId($brand_feature['id'], $v); $brands[] = array('id' => $brand_id, 'brand' => '<a href="' . wa()->getRouteUrl('shop/frontend/brand', array('brand' => str_replace('%2F', '/', urlencode($v)))) . '">' . $v . '</a>'); } } $category_model = new shopCategoryModel(); $category = $category_model->getById($p['category_id']); $res_category = ''; if ($category) { $res_category = '<a href="' . wa()->getRouteUrl('/frontend/category', array('category_url' => $category['full_url'])) . '">' . $category['name'] . '</a>'; } $result['products'][] = array("name" => $p['name'], "url" => $p['frontend_url'], "image" => $p['image_id'] ? "<img src='" . shopImage::getUrl(array("product_id" => $p['id'], "id" => $p['image_id'], "ext" => $p['ext']), "48x48") . "' />" : "", "price" => shop_currency_html($p['price'], true), "brands" => $brands, "category" => $res_category); } $product_model = new shopProductModel(); $product_count = $collection->count(); $result['product_count'] = $product_count; if ($product_count > ($page - 1) * $product_limit + $product_limit) { $result['next_page'] = $page + 1; } else { $result['next_page'] = false; } } $this->response = $result; } else { $this->response = false; } }
public function execute() { if (!$this->getUser()->getRights('shop', 'settings')) { throw new waRightsException(_w('Access denied')); } $feature_id = waRequest::post('feature_id'); if ($feature_id) { $model = new shopFeatureModel(); $model->delete($feature_id); } }
public function execute() { if (!$this->getUser()->getRights('shop', 'settings')) { throw new waRightsException(_w('Access denied')); } $model = new shopPluginModel(); $this->view->assign('instances', $model->listPlugins(shopPluginModel::TYPE_SHIPPING, array('all' => true))); $this->view->assign('plugins', shopShipping::getList()); $feature_model = new shopFeatureModel(); $this->view->assign('no_weight', $feature_model->getByCode('weight') ? false : true); $this->view->assign('installer', $this->getUser()->getRights('installer', 'backend')); }
public function execute() { if (!$this->getUser()->getRights('shop', 'settings')) { throw new waRightsException(_w('Access denied')); } $model = new shopFeatureModel(); if (($id = waRequest::get('id', waRequest::TYPE_INT)) && ($feature = $model->getById($id))) { $feature['values'] = $model->getFeatureValues($feature); $this->view->assign('feature', $feature); } else { throw new waException(_w('Product feature not found'), 404); } }
public function execute() { if (!$this->getUser()->getRights('shop', 'settings')) { throw new waRightsException(_w('Access denied')); } $model = new shopFeatureModel(); $values = array(waRequest::post('value')); $code = waRequest::post('code'); if ($values && $code && ($feature = $model->getByField('code', $code))) { $this->response = $model->setValues($feature, $values); } else { $this->setError(_w('Product feature not found')); } }
public function getFeatures(shopProduct $product) { $features_model = new shopFeatureModel(); $product_features_model = new shopProductFeaturesModel(); $features = array(); foreach ($features_model->getByType($product->type_id, 'code', true) as $f) { if ($f['multiple'] || $f['code'] == 'weight') { $features[$f['code']] = $f; } } // attach values $features = $features_model->getValues($features); return $features; }
public function execute() { $items = waRequest::post('items'); $product_ids = array(); foreach ($items as $i) { $product_ids[] = $i['product_id']; } $product_ids = array_unique($product_ids); $feature_model = new shopFeatureModel(); $f = $feature_model->getByCode('weight'); if (!$f) { $values = array(); } else { $values_model = $feature_model->getValuesModel($f['type']); $values = $values_model->getProductValues($product_ids, $f['id']); } $contact = $this->getContact(); $shipping_address = $contact->getFirst('address.shipping'); if ($shipping_address) { $shipping_address = $shipping_address['data']; } $shipping_items = array(); foreach ($items as $i) { if (isset($values['skus'][$i['sku_id']])) { $w = $values['skus'][$i['sku_id']]; } else { $w = isset($values[$i['product_id']]) ? $values[$i['product_id']] : 0; } $shipping_items[] = array('name' => '', 'price' => $i['price'], 'quantity' => $i['quantity'], 'weight' => $w); } $order_id = waRequest::post('order_id'); if ($order_id) { $order_model = new shopOrderModel(); $order_info = $order_model->getById($order_id); $currency = $order_info['currency']; } else { $currency = $this->getConfig()->getCurrency(); } $total = waRequest::post('subtotal') - waRequest::post('discount'); $order = array('currency' => $currency, 'contact' => $contact, 'items' => $items, 'total' => waRequest::post('subtotal')); if ($order_id) { $order['id'] = $order_info['id']; } $this->response['discount'] = shopDiscounts::calculate($order_info); $this->response['shipping_methods'] = shopHelper::getShippingMethods($shipping_address, $shipping_items, array('currency' => $currency, 'total_price' => $total)); // for saving order in js $this->response['shipping_method_ids'] = array_keys($this->response['shipping_methods']); }
public function execute() { $feature_id = waRequest::post('feature_id'); $feature_model = new shopFeatureModel(); $feature = $feature_model->getById($feature_id); if (!$feature) { throw new waException(_w('Unknown feature')); } if (waRequest::post('subtype')) { $to = waRequest::post('subtype'); } else { $to = waRequest::post('type'); } $to = array('type' => $to, 'selectable' => (int) waRequest::post('selectable', 0, waRequest::TYPE_INT), 'multiple' => (int) waRequest::post('multiple', 0, waRequest::TYPE_INT)); $result = shopFeatureValuesConverter::run($feature_id, $to); if (!$result) { $this->errors[] = _w('Feature type conversion is not allowed or failed'); } else { if ($feature = $feature_model->getById($feature_id)) { $this->response = array($feature_id => &$feature); $feature['selectable'] = (int) $feature['selectable']; $feature['multiple'] = (int) $feature['multiple']; if ($feature['selectable']) { $this->response = $feature_model->getValues($this->response, true); $sort = 0; foreach ($feature['values'] as $id => &$value) { if (!is_object($value)) { $value = array('id' => $id, 'value' => $value, 'sort' => $sort++); unset($value); } else { if (method_exists($value, 'getRaw')) { $value = $value->getRaw(); } else { $value = array('id' => $id, 'value' => (string) $value, 'sort' => $sort++); } } } $feature['values'] = array_values($feature['values']); } shopFeatureModel::appendTypeNames($this->response); $type_features_model = new shopTypeFeaturesModel(); $type_features_model->fillTypes($this->response); $feature['types'] = array_keys($feature['types']); sort($feature['types']); } } }
public function execute() { $id = (int) waRequest::get('id'); $html = ''; $app_settings_model = new waAppSettingsModel(); $settings = $app_settings_model->get(array('shop', 'fprview')); $product = new shopProduct($id); $route_params = array('product_url' => $product['url']); if (isset($product['category_url'])) { $route_params['category_url'] = $product['category_url']; } $product['frontend_url'] = wa()->getRouteUrl('shop/frontend/product', $route_params); $feature_codes = array_keys($product->features); $feature_model = new shopFeatureModel(); $features = $feature_model->getByCode($feature_codes); $theme = waRequest::param('theme', 'default'); $theme_path = wa()->getDataPath('themes', true) . '/' . $theme; if (!file_exists($theme_path) || !file_exists($theme_path . '/theme.xml')) { $theme_path = wa()->getAppPath() . '/themes/' . $theme; } switch ($settings['template_type']) { case 'plugin': $view = wa()->getView(); $view->assign('features', $features); $view->assign('product', $product); $view->assign('fprview_settings', $settings); $html = $view->fetch(realpath(dirname(__FILE__) . "/../../") . '/templates/Frontend.html'); break; case 'theme': if ($settings['template_theme_file'] && file_exists($theme_path . '/' . $settings['template_theme_file'])) { $view = wa()->getView(array('template_dir' => $theme_path)); list($services, $skus_services) = $this->getServiceVars($product); $compare = waRequest::cookie('shop_compare', array(), waRequest::TYPE_ARRAY_INT); $stock_model = new shopStockModel(); $view->assign(array('sku_services' => $skus_services, 'services' => $services, 'compare' => in_array($product['id'], $compare) ? $compare : array(), 'currency_info' => $this->getCurrencyInfo(), 'stocks' => $stock_model->getAll('id'), 'reviews' => $this->getTopReviews($product['id']), 'rates' => $this->reviews_model->getProductRates($product['id']), 'reviews_total_count' => $this->getReviewsTotalCount($product['id']), 'features' => $features, 'product' => $product)); $view->assign('frontend_product', wa()->event('frontend_product', $product, array('menu', 'cart', 'block_aux', 'block'))); $template = $this->setThemeTemplate($settings['template_theme_file']); $html = $view->fetch($this->getTemplate()); } break; default: $html = ''; break; } echo $html; exit; }
public function execute() { $this->setLayout(new shopBackendLayout()); if ($data = waRequest::post('lang_plugin')) { $this->save($data); } $plugin = wa('shop')->getPlugin('lang'); $lang = $plugin->getSettings('langs'); $this->view->assign('langs', $lang); $fm = new shopFeatureModel(); $features = $fm->getAll(); $features = $fm->getValues($features, true); $this->view->assign('features', $features); $lm = new shopLangPluginFeatureModel(); $data = $lm->getTree(); $this->view->assign('data', $data); }
private function getOrder($order_id) { $order = $this->order_model->getOrder($order_id, true, true); if (!$order) { throw new waException("Unknow order", 404); } $order['shipping_id'] = ifset($order['params']['shipping_id'], '') . '.' . ifset($order['params']['shipping_rate_id'], ''); $sku_ids = array(); foreach ($order['items'] as $item) { foreach ($item['skus'] as $sku) { if (empty($sku['fake'])) { $sku_ids[] = $sku['id']; } } } $sku_stocks = $this->getSkuStocks(array_unique($sku_ids)); $subtotal = 0; $product_ids = array(); foreach ($order['items'] as $i) { $product_ids[] = $i['id']; $subtotal += $i['item']['price'] * $i['item']['quantity']; } $order['subtotal'] = $subtotal; $product_ids = array_unique($product_ids); $feature_model = new shopFeatureModel(); $f = $feature_model->getByCode('weight'); if (!$f) { $values = array(); } else { $values_model = $feature_model->getValuesModel($f['type']); $values = $values_model->getProductValues($product_ids, $f['id']); } foreach ($order['items'] as &$item) { if (isset($values['skus'][$item['item']['sku_id']])) { $w = $values['skus'][$item['item']['sku_id']]; } else { $w = isset($values[$item['id']]) ? $values[$item['id']] : 0; } $this->workupItems($item, $sku_stocks); $item['quantity'] = $item['item']['quantity']; $item['weight'] = $w; } unset($item); return $order; }
public function execute() { if (!$this->getRights('settings')) { throw new waAPIException('access_denied', 403); } $feature_model = new shopFeatureModel(); if ($id = $this->post('id')) { $feature = $feature_model->getById($id); } elseif ($code = $this->post('code')) { $feature = $feature_model->getByCode($code); } else { throw new waAPIException('invalid_param', 'Required parameter is missing: id or code', 400); } if (!$feature) { throw new waAPIException('invalid_param', 'Feature not found', 404); } $this->response = (bool) $feature_model->delete($feature['id']); }
public function execute() { $feature_model = new shopFeatureModel(); if ($id = $this->get('id')) { $feature = $feature_model->getById($id); } elseif ($code = $this->get('code')) { $feature = $feature_model->getByCode($code); } else { throw new waAPIException('invalid_param', 'Required parameter is missing: id or code', 400); } if (!$feature) { throw new waAPIException('invalid_param', 'Feature not found', 404); } if ($feature['selectable']) { $feature['values'] = array_values($feature_model->getFeatureValues($feature)); $feature['values']['_element'] = 'value'; } $this->response = $feature; }
private function _convert($feature, $to) { $feature_id = $feature['id']; // change only multiple/selectable flags if ($to['type'] == $feature['type']) { $this->feature_model->updateById($feature_id, array('multiple' => $to['multiple'], 'selectable' => $to['selectable'])); } else { // get all features values $values = $this->getValues($feature, $to); // change type of feature (with removing old values) $feature = $this->changeType($feature, $to); // reset values taking into account new type $new_values = $this->setValues($feature, $values); // bind new values to products $this->bindToProducts($feature, $new_values); } }
/** * @param int $id * @param array $data * @param bool $correct * @param shopProduct $product * @return array */ protected function updateSku($id = 0, $data, $correct = true, shopProduct $product = null) { /** * @var shopProductStocksModel $stocks_model */ static $stocks_model; /** * @var bool $multi_stock */ static $multi_stock = null; /** * @var shopFeatureModel $feature_model */ static $feature_model; /** * @var shopProductFeaturesModel $product_features_model */ static $product_features_model; if (isset($data['price'])) { $data['price'] = $this->castValue('double', $data['price']); } if (isset($data['purchase_price'])) { $data['purchase_price'] = $this->castValue('double', $data['purchase_price']); } if (isset($data['compare_price'])) { $data['compare_price'] = $this->castValue('double', $data['compare_price']); } if ($id > 0) { if ($product && (!isset($data['virtual']) || !empty($data['virtual']))) { #check changes for virtual SKU $virtual_sku_defaults = array('price' => $product->base_price_selectable, 'purchase_price' => $product->purchase_price_selectable, 'compare_price' => $product->compare_price_selectable, 'count' => 0); $virtual = null; foreach ($virtual_sku_defaults as $field => $default) { if (isset($data[$field])) { $value = $data[$field]; if (is_array($value)) { $value = max($value); } if ($value != $default) { if ($virtual === null) { $virtual = isset($product->skus[$id]) && !empty($product->skus[$id]['virtual']); } if ($virtual) { $data['virtual'] = 0; $virtual = false; } if (!$virtual) { break; } } } } } if (empty($data['eproduct']) && !empty($data['file_name'])) { $file_path = shopProduct::getPath($data['product_id'], "sku_file/{$id}." . pathinfo($data['file_name'], PATHINFO_EXTENSION)); waFiles::delete($file_path); $data['file_name'] = ''; $data['file_description'] = ''; } elseif (isset($data['file_name'])) { unset($data['file_name']); } $this->updateById($id, $data); } else { if (!isset($data['sku'])) { $data['sku'] = ''; } $id = $this->insert($data); } $data['id'] = $id; $sku_count = false; // if stocking for this sku if (isset($data['stock']) && count($data['stock'])) { if ($multi_stock === null) { $stock_model = new shopStockModel(); $stocks = $stock_model->getAll($stock_model->getTableId()); $multi_stock = $stocks ? array_keys($stocks) : false; } // not multistocking if (!$multi_stock || isset($data['stock'][0])) { $sku_count = self::castStock($data['stock'][0]); unset($data['stock']); $this->logCount($data['product_id'], $id, $sku_count); // multistocking } else { $sku_count = 0; $missed = array_combine($multi_stock, $multi_stock); if (!$stocks_model) { $stocks_model = new shopProductStocksModel(); } // need for track transition from aggregating mode to multistocking mode $has_any_stocks = $stocks_model->hasAnyStocks($id); if (!$has_any_stocks) { $this->writeOffCount($data['product_id'], $id); } foreach ($data['stock'] as $stock_id => $count) { if ($stock_id > 0 && isset($missed[$stock_id])) { unset($missed[$stock_id]); $field = array('sku_id' => $id, 'stock_id' => $stock_id, 'product_id' => $data['product_id']); $count = self::castStock($count); $stock = array('count' => $count); if ($count === null) { $sku_count = null; } else { // Once turned into NULL value is not changed if ($sku_count !== null) { $sku_count += $count; } } // there is taking into account stocks log inside this method $stocks_model->set(array_merge($field, $stock)); $data['stock'][$stock_id] = $count; } } //get stock_count for missed stocks if ($sku_count !== null && !empty($missed)) { $search = array('stock_id' => $missed, 'sku_id' => $id, 'product_id' => $data['product_id']); foreach ($stocks_model->getByField($search, 'stock_id') as $stock_id => $row) { $count = $row['count']; $data['stock'][$stock_id] = $count; if ($count === null) { $sku_count = null; } else { // Once turned into NULL value is not changed if ($sku_count !== null) { $sku_count += $count; } } } } } } if ($sku_count !== false) { $data['count'] = $sku_count; $this->updateById($id, array('count' => $sku_count)); } if (isset($data['features'])) { if (!$feature_model) { $feature_model = new shopFeatureModel(); } if (!$product_features_model) { $product_features_model = new shopProductFeaturesModel(); } $features = $data['features']; $data['features'] = array(); $skip_values = array('', false, null); foreach ($features as $code => $value) { if ($feature = $feature_model->getByField('code', $code)) { $model = shopFeatureModel::getValuesModel($feature['type']); $field = array('product_id' => $data['product_id'], 'sku_id' => $id, 'feature_id' => $feature['id']); $product_features_model->deleteByField($field); if (is_array($value)) { if (!empty($value['id'])) { $field['feature_value_id'] = $value['id']; } elseif (isset($value['value']) && !in_array($value['value'], $skip_values, true)) { $field['feature_value_id'] = $model->getId($feature['id'], $code == 'weight' ? $value : $value['value'], $feature['type']); } } elseif (!in_array($value, $skip_values, true)) { $field['feature_value_id'] = $model->getId($feature['id'], $value, $feature['type']); $value = array('value' => $value, 'id' => $field['feature_value_id']); } if (!empty($field['feature_value_id'])) { $product_features_model->insert($field); $data['features'][$code] = $value; } } elseif (is_numeric($code) && is_numeric($value)) { if ($feature = $feature_model->getById($code)) { $field = array('product_id' => $data['product_id'], 'sku_id' => $id, 'feature_id' => $code); $product_features_model->deleteByField($field); if (empty($value)) { continue; } $field['feature_value_id'] = $value; $product_features_model->insert($field); $data['features'][$feature['code']] = $feature_model->getValuesModel($feature['type'])->getFeatureValue($value); } } } } if ($correct) { $product_model = new shopProductModel(); $product_model->correct($data['product_id']); } return $data; }
/** * @param $template_id * @param bool $extend * @return array|null * @throws waException */ public function insertTemplate($template_id, $extend = false) { $types = self::getTemplates(); $feature_model = new shopFeatureModel(); $type_features_model = new shopTypeFeaturesModel(); $type = null; if (!empty($types[$template_id])) { $type = $types[$template_id]; $type['sort'] = $this->select('MAX(sort)+1 as max_sort')->fetchField('max_sort'); $type['id'] = $this->insert($type); if ($type['id'] && !empty($type['features'])) { foreach ($type['features'] as $code => &$feature) { $feature += array('type' => 'varchar', 'selectable' => false, 'multiple' => false); $feature['types'] = array($type['id']); $feature['name'] = ifempty(self::$translate[$feature['name']], $feature['name']); $feature['code'] = $code; $id = null; if ($data = $feature_model->getByField('code', $code)) { if ($feature['type'] == $data['type'] && $feature['selectable'] == $data['selectable'] && $feature['multiple'] == $data['multiple']) { $id = $data['id']; } } $feature['id'] = $feature_model->save($feature, $id); if ($feature['id']) { if (!empty($feature['selectable']) && !empty($feature['values'])) { foreach ($feature['values'] as &$value) { if (is_string($value)) { $value = ifempty(self::$translate[$value], $value); } elseif (isset($value['value'])) { $value['value'] = ifempty(self::$translate[$value['value']], $value['value']); } } unset($value); $feature['values'] = $feature_model->setValues($feature, $feature['values'], false, true); } $feature['types'] = $type_features_model->updateByFeature($feature['id'], $feature['types'], false); if ($id && $extend) { //TODO get exists feature values //$feature_model->getFeatureValues($feature); $feature['types'] = array_keys($type_features_model->getByField('feature_id', $feature['id'], 'type_id')); } } unset($feature); } if ($extend) { shopFeatureModel::appendTypeNames($type['features']); } } } return $type; }
public function execute() { if ($id = waRequest::get('id', 0, waRequest::TYPE_INT)) { #load product $this->view->assign('product', $product = new shopProduct($id)); #load product types $type_model = new shopTypeModel(); $this->view->assign('product_types', $product_types = $type_model->getAll($type_model->getTableId(), true)); if ($param = waRequest::request('param', array(), waRequest::TYPE_ARRAY_INT)) { $type_id = reset($param); if (!isset($product_types[$type_id])) { $type_id = $product->type_id; } } else { $type_id = $product->type_id; } $this->view->assign('type_id', $type_id); #load feature's values $model = new shopFeatureModel(); $changed_features = array(); if ($data = waRequest::post('product')) { $changed_features = empty($data['features']) || !is_array($data['features']) ? array() : $data['features']; foreach ($changed_features as $code => $value) { if (isset($product->features[$code])) { if (is_array($value)) { $intersect = array_unique(array_merge($value, (array) $product->features[$code])); if (count($value) == count($intersect)) { unset($changed_features[$code]); } } elseif ($value === $product->features[$code]) { unset($changed_features[$code]); } } } } #load changed feature's values $this->view->assign('changed_features', $changed_features); $codes = array_keys($product->features); foreach ($changed_features as $code => $value) { if ($value !== '') { $codes[] = $code; } } $codes = array_unique($codes); $features = $model->getByType($type_id, 'code'); foreach ($features as $code => &$feature) { $feature['internal'] = true; $key = array_search($code, $codes); if ($key !== false) { unset($codes[$key]); } } unset($feature); if ($codes) { $features += $model->getByField('code', $codes, 'code'); } foreach ($features as $code => &$feature) { $feature['feature_id'] = intval($feature['id']); } unset($feature); $features = $model->getValues($features); $this->view->assign('features', $features); } }
protected function init() { try { $backend = wa()->getEnv() == 'backend'; $profiles = new shopImportexportHelper('yandexmarket'); switch ($this->encoding) { case 'windows-1251': setlocale(LC_CTYPE, 'ru_RU.CP-1251', 'ru_RU.CP1251', 'ru_RU.win'); break; } $this->data['offset'] = array('offers' => 0); $this->data['timestamp'] = time(); $default_export_config = array('zero_stock' => 0, 'compare_price' => 0, 'sku' => 0, 'sku_group' => '', 'hidden_categories' => 0); if ($backend) { $hash = shopImportexportHelper::getCollectionHash(); $profile_config = array('hash' => $hash['hash'], 'domain' => waRequest::post('domain'), 'map' => array(), 'types' => array_filter((array) waRequest::post('types')), 'export' => (array) waRequest::post('export', array()) + $default_export_config, 'company' => waRequest::post('company'), 'company_name' => waRequest::post('company_name'), 'shop' => waRequest::post('shop'), 'lifetime' => waRequest::post('lifetime', 0, waRequest::TYPE_INT), 'utm_source' => waRequest::post('utm_source'), 'utm_medium' => waRequest::post('utm_medium'), 'utm_campaign' => waRequest::post('utm_campaign')); $this->data['map'] = $this->plugin()->map(waRequest::post('map', array()), $profile_config['types']); foreach ($this->data['map'] as $type => $offer_map) { foreach ($offer_map['fields'] as $field => $info) { if (!empty($info['source']) && preg_match('@^\\w+:(.+)$@', $info['source'], $matches) && $matches[1] != '%s') { $profile_config['map'][$type][$field] = $info['source']; } } if (empty($profile_config['map'][$type])) { unset($profile_config['map'][$type]); } } $profile_id = $profiles->setConfig($profile_config); $this->plugin()->getHash($profile_id); } else { $profile_id = waRequest::param('profile_id'); if (!$profile_id || !($profile = $profiles->getConfig($profile_id))) { throw new waException('Profile not found', 404); } $profile_config = $profile['config']; $profile_config['export'] += $default_export_config; $this->data['map'] = $this->plugin()->map($profile_config['map'], $profile_config['types']); foreach ($this->data['map'] as $type => &$offer_map) { foreach ($offer_map['fields'] as $field => &$info) { $info['source'] = ifempty($profile_config['map'][$type][$field], 'skip:'); } unset($offer_map); } } foreach ($this->data['map'] as $type => &$offer_map) { if ($type != 'simple') { $offer_map['fields']['type'] = array('source' => 'value:' . $type, 'attribute' => true); } unset($offer_map); } $feature_model = new shopFeatureModel(); foreach ($this->data['map'] as $type => &$offer_map) { foreach ($offer_map['fields'] as $field => &$info) { if (strpos($field, 'param.') === 0 && isset($info['source'])) { switch (preg_replace('@:.+$@', '', $info['source'])) { case 'feature': if ($feature = $feature_model->getByCode(preg_replace('@^[^:]+:@', '', $info['source']))) { $info['source_name'] = $feature['name']; } break; } } } unset($info); unset($offer_map); } $this->data['hash'] = $profile_config['hash']; if (!isset($this->data['categories'])) { $this->data['categories'] = array(); } $this->data['export'] = $profile_config['export']; $this->data['domain'] = $profile_config['domain']; $this->data['utm'] = array(); foreach (array('utm_source', 'utm_medium', 'utm_campaign') as $field) { if (!empty($profile_config[$field])) { $this->data['utm'][$field] = $profile_config[$field]; } } if ($this->data['utm']) { $this->data['utm'] = http_build_query(array_map('rawurlencode', $this->data['utm'])); } $this->data['types'] = array(); foreach ($profile_config['types'] as $type => $type_map) { $this->data['types'] += array_fill_keys(array_filter(array_map('intval', $type_map)), $type); } $this->initRouting(); $model = new shopCategoryModel(); if (empty($this->data['export']['hidden_categories'])) { $sql = <<<SQL SELECT COUNT(1) as `cnt` FROM shop_category c LEFT JOIN shop_category_routes cr ON (c.id = cr.category_id) WHERE ((cr.route IS NULL) OR (cr.route = s:route)) AND (`c`.`type`=i:type) AND (`c`.`status`=1) SQL; } else { $sql = <<<SQL SELECT COUNT(1) as `cnt` FROM shop_category c LEFT JOIN shop_category_routes cr ON (c.id = cr.category_id) WHERE ((cr.route IS NULL) OR (cr.route = s:route)) AND (`c`.`type`=i:type) SQL; } $params = array('route' => $this->data['domain'], 'type' => shopCategoryModel::TYPE_STATIC); $this->data['count'] = array('category' => (int) $model->query($sql, $params)->fetchField('cnt'), 'product' => $this->getCollection()->count()); $stages = array_keys($this->data['count']); $this->data['current'] = array_fill_keys($stages, 0); $this->data['processed_count'] = array_fill_keys($stages, 0); $this->data['stage'] = reset($stages); $this->data['stage_name'] = $this->getStageName($this->data['stage']); $this->data['memory'] = memory_get_peak_usage(); $this->data['memory_avg'] = memory_get_usage(); if (!class_exists('DOMDocument')) { throw new waException('PHP extension DOM required'); } $this->dom = new DOMDocument("1.0", $this->encoding); $this->dom->encoding = $this->encoding; $this->dom->preserveWhiteSpace = false; $this->dom->formatOutput = true; /** * @var shopConfig $config */ $config = wa('shop')->getConfig(); $xml = <<<XML <?xml version="1.0" encoding="{$this->encoding}"?> <!DOCTYPE yml_catalog SYSTEM "shops.dtd"> <yml_catalog date="%s"> </yml_catalog> XML; $original = shopYandexmarketPlugin::path('shops.dtd'); $target = $this->getTempPath('shops.dtd'); $ft = filesize($target); $fo = filesize($original); if (!file_exists($target) || filesize($target) != filesize($original) && waFiles::delete($target)) { waFiles::copy($original, $target); } $this->dom->loadXML(sprintf($xml, date("Y-m-d H:i"))); $this->dom->lastChild->appendChild($shop = $this->dom->createElement("shop")); $name = ifempty($profile_config['company_name'], $config->getGeneralSettings('name')); $name = str_replace('&', '&', $name); $name = str_replace("'", ''', $name); $this->addDomValue($shop, 'name', $name); $company = str_replace('&', '&', $profile_config['company']); $company = str_replace("'", ''', $company); $this->addDomValue($shop, 'company', $company); $this->addDomValue($shop, 'url', preg_replace('@^https@', 'http', wa()->getRouteUrl('shop/frontend', array(), true))); if ($phone = $config->getGeneralSettings('phone')) { $shop->appendChild($this->dom->createElement('phone', $phone)); } $this->addDomValue($shop, 'platform', 'Shop-Script'); $this->addDomValue($shop, 'version', wa()->getVersion('shop')); $currencies = $this->dom->createElement('currencies'); $model = new shopCurrencyModel(); $this->data['currency'] = array(); $available_currencies = shopYandexmarketPlugin::settingsPrimaryCurrencies(); if (empty($available_currencies)) { throw new waException('Экспорт не может быть выполнен: не задано ни одной валюты, которая могла бы использоваться в качестве основной.'); } unset($available_currencies['auto']); $primary_currency = $this->plugin()->getSettings('primary_currency'); $this->data['default_currency'] = $config->getCurrency(); if (!isset($available_currencies[$primary_currency])) { $primary_currency = $this->data['default_currency']; if (!isset($available_currencies[$primary_currency])) { reset($available_currencies); $primary_currency = key($available_currencies); } } $this->data['primary_currency'] = $primary_currency; $rate = $available_currencies[$primary_currency]['rate']; $available_currencies = $model->getCurrencies(shopYandexmarketPlugin::getConfigParam('currency')); foreach ($available_currencies as $info) { if ($info['rate'] > 0) { $info['rate'] = $info['rate'] / $rate; $this->data['currency'][] = $info['code']; if (abs(round($info['rate'], 4) - $info['rate']) / $info['rate'] > 0.01) { $info['rate'] = 'CB'; } $value = array('id' => $info['code'], 'rate' => $this->format('rate', $info['rate'])); $this->addDomValue($currencies, 'currency', $value); } } $shop->appendChild($currencies); $shop->appendChild($this->dom->createElement('categories')); $fields = array('store' => true, 'pickup' => true, 'delivery' => true, 'deliveryIncluded' => false, 'local_delivery_cost' => '%0.2f', 'adult' => true); foreach ($fields as $field => $include_value) { $value = ifset($profile_config['shop'][$field], ''); if ($value || $value !== '') { if ($include_value) { $value = $include_value === true ? $value : $this->format($field, $value, array('format', $include_value)); $this->addDomValue($shop, $field, $value); } else { $shop->appendChild($this->dom->createElement($field)); } } } $shop->appendChild($this->dom->createElement('offers')); if (!$this->data['currency']) { throw new waException('Не задано ни одной поддерживаемой валюты'); } if (!in_array($this->data['primary_currency'], $this->data['currency'])) { $this->data['primary_currency'] = reset($this->data['currency']); } $this->data['path'] = array('offers' => shopYandexmarketPlugin::path($profile_id . '.xml')); $this->save(); $this->dom = null; $this->loadDom(); } catch (waException $ex) { $this->error($ex->getMessage()); echo json_encode(array('error' => $ex->getMessage())); exit; } }
public function execute() { $ids = waRequest::param('id', array(), waRequest::TYPE_ARRAY_INT); if (!$ids) { $ids = waRequest::cookie('shop_compare', array(), waRequest::TYPE_ARRAY_INT); } $collection = new shopProductsCollection('id/' . implode(',', $ids)); $products = $collection->getProducts(); $features = array(); $i = 0; $compare_link = wa()->getRouteUrl('/frontend/compare', array('id' => '%ID%')); foreach ($products as &$p) { $p = new shopProduct($p); $temp_ids = $ids; unset($temp_ids[array_search($p['id'], $temp_ids)]); $p['delete_url'] = str_replace('%ID%', implode(',', $temp_ids), $compare_link); if (!$temp_ids) { $p['delete_url'] = substr($p['delete_url'], 0, -1); } foreach ($p->features as $code => $v) { if (is_object($v)) { $v = trim(isset($v['compare']) ? $v['compare'] : $v['value']); } elseif (is_array($v)) { foreach ($v as &$_v) { if (is_object($_v)) { $_v = trim(isset($_v['compare']) ? $_v['compare'] : $_v['value']); } else { $_v = trim($_v); } unset($_v); } sort($v, SORT_STRING); $v = serialize($v); } else { $v = trim($v); } if (isset($features[$code]) && $features[$code]['same']) { if ($v !== $features[$code]['value']) { $features[$code]['same'] = false; } } else { if (!isset($features[$code])) { $features[$code] = array(); } if (!$i) { $features[$code]['same'] = true; $features[$code]['value'] = $v; } else { $features[$code]['same'] = false; } } } foreach ($features as $code => $v) { if (!isset($p->features[$code])) { $features[$code]['same'] = false; } } $i++; unset($p); } if ($features) { $feature_model = new shopFeatureModel(); foreach ($all_features = $feature_model->getByCode(array_keys($features)) as $code => $f) { $features[$code] += $f; } } $this->view->assign('features', $features); $this->view->assign('products', $products); $this->setLayout(new shopFrontendLayout()); $this->setThemeTemplate('compare.html'); }
private function getCategorySettings($id) { $category_model = new shopCategoryModel(); $category_params_model = new shopCategoryParamsModel(); $settings = $category_model->getById($id); if (!$settings) { return array(); } /** * @event backend_category_dialog * @param array $category * @return array[string][string] $return[%plugin_id%] html output for dialog */ $this->view->assign('event_dialog', wa()->event('backend_category_dialog', $settings)); $category_routes_model = new shopCategoryRoutesModel(); $settings['routes'] = $category_routes_model->getRoutes($id); $settings['frontend_urls'] = array(); foreach ($category_model->getFrontendUrls($id) as $frontend_url) { $pos = strrpos($frontend_url, $settings['url']); $settings['frontend_urls'][] = array('url' => $frontend_url, 'base' => $pos !== false ? rtrim(substr($frontend_url, 0, $pos), '/') . '/' : ''); } $settings['params'] = $category_params_model->get($id); if (isset($settings['params']['enable_sorting'])) { $settings['enable_sorting'] = 1; unset($settings['params']['enable_sorting']); } else { $settings['enable_sorting'] = 0; } $feature_model = new shopFeatureModel(); $selectable_and_boolean_features = $feature_model->select('*')->where("(selectable=1 OR type='boolean' OR type='double' OR type LIKE 'dimension\\.%' OR type LIKE 'range\\.%') AND parent_id IS NULL")->fetchAll('id'); if ($settings['type'] == shopCategoryModel::TYPE_DYNAMIC) { if ($settings['conditions']) { $settings['conditions'] = shopProductsCollection::parseConditions($settings['conditions']); } else { $settings['conditions'] = array(); } $tag_model = new shopTagModel(); $cloud = $tag_model->getCloud('name'); if (!empty($settings['conditions']['tag'][1])) { foreach ($settings['conditions']['tag'][1] as $tag_name) { $cloud[$tag_name]['checked'] = true; } } $settings['cloud'] = $cloud; // extract conditions for features foreach ($settings['conditions'] as $name => $value) { if (substr($name, -9) === '.value_id') { unset($settings['conditions'][$name]); $settings['conditions']['feature'][substr($name, 0, -9)] = $value; } } $settings['custom_conditions'] = $this->extractCustomConditions($settings['conditions']); $settings['features'] = $selectable_and_boolean_features; $settings['features'] = $feature_model->getValues($settings['features']); } $filter = $settings['filter'] !== null ? explode(',', $settings['filter']) : null; $feature_filter = array(); $features['price'] = array('id' => 'price', 'name' => 'Price'); $features += $selectable_and_boolean_features; if (!empty($filter)) { foreach ($filter as $feature_id) { $feature_id = trim($feature_id); if (isset($features[$feature_id])) { $feature_filter[$feature_id] = $features[$feature_id]; $feature_filter[$feature_id]['checked'] = true; unset($features[$feature_id]); } } } $settings['allow_filter'] = (bool) $filter; $settings['filter'] = $feature_filter + $features; return $settings; }
/** * @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)); } }
private function stepExportProduct(&$current_stage, &$count, &$processed) { static $products; static $product_feature_model; static $feature_model; static $tags_model; static $size; if (!$products) { $offset = $current_stage[self::STAGE_PRODUCT] - ifset($this->data['map'][self::STAGE_PRODUCT], 0); $fields = '*'; if (!empty($this->data['options']['images'])) { $fields .= ', images'; } $products = $this->getCollection()->getProducts($fields, $offset, 50, false); } $chunk = 5; $non_sku_fields = array('summary', 'meta_title', 'meta_keywords', 'meta_description', 'description', 'sort', 'tags', 'images'); while ($chunk-- > 0 && ($product = reset($products))) { $exported = false; /* check rights per product type && settlement options */ $rights = empty($product['type_id']) || in_array($product['type_id'], $this->data['types']); $category_id = isset($product['category_id']) ? intval($product['category_id']) : null; /* check category match*/ $category_match = !$this->data['export_category'] || $category_id === $this->data['map'][self::STAGE_CATEGORY]; if ($rights && $category_match) { $shop_product = new shopProduct($product); if (!empty($this->data['options']['features'])) { if (!isset($product['features'])) { if (!$product_feature_model) { $product_feature_model = new shopProductFeaturesModel(); } $product['features'] = $product_feature_model->getValues($product['id']); } foreach ($product['features'] as $code => &$feature) { if (!empty($this->data['composite_features'][$code])) { $feature = str_replace('×', 'x', $feature); } unset($feature); } } if (!isset($product['tags'])) { if (!$tags_model) { $tags_model = new shopProductTagsModel(); } $product['tags'] = implode(',', $tags_model->getTags($product['id'])); } if (!empty($this->data['options']['images'])) { if (isset($product['images'])) { if (!$size) { /** * @var shopConfig $config */ $config = $this->getConfig(); $size = $config->getImageSize('big'); } foreach ($product['images'] as &$image) { $image = 'http://' . ifempty($this->data['base_url'], 'localhost') . shopImage::getUrl($image, $size); } $product['images'] = array_values($product['images']); } } $product['type_name'] = $shop_product->type['name']; $skus = $shop_product->skus; if (false && $product['sku_id']) { #default SKU reorder if (isset($skus[$product['sku_id']])) { $sku = $skus[$product['sku_id']]; $sku['stock'][0] = $sku['count']; $product['skus'] = array(-1 => $sku); unset($skus[$product['sku_id']]); } $this->writer->write($product); if (!empty($this->data['options']['images'])) { if (isset($product['images'])) { $processed[self::STAGE_IMAGE] += count($product['images']); } } $exported = true; if (!empty($this->data['options']['features'])) { unset($product['features']); } } if (!empty($product['tax_id'])) { $product['tax_name'] = ifset($this->data['taxes'][$product['tax_id']]); } if (!isset($product['features'])) { $product['features'] = array(); } foreach ($skus as $sku_id => $sku) { if ($exported) { foreach ($non_sku_fields as $field) { if (isset($product[$field])) { unset($product[$field]); } } } $sku['stock'][0] = $sku['count']; if (!empty($this->data['options']['features'])) { $sku['features'] = $product_feature_model->getValues($product['id'], -$sku_id); if ($product['sku_type'] == shopProductModel::SKU_TYPE_SELECTABLE) { if (!$exported) { $features_selectable_model = new shopProductFeaturesSelectableModel(); if ($selected = $features_selectable_model->getByProduct($product['id'])) { if (!$feature_model) { $feature_model = new shopFeatureModel(); } $features = $feature_model->getById(array_keys($selected)); $enclosure = $this->writer->enclosure; $pattern = sprintf("/(?:%s|%s|%s)/", preg_quote(',', '/'), preg_quote($enclosure, '/'), preg_quote($enclosure, '/')); foreach ($features as $feature_id => $feature) { $values = shopFeatureModel::getValuesModel($feature['type'])->getValues(array('feature_id' => $feature_id, 'id' => $selected[$feature_id])); if (!empty($values[$feature['id']])) { $f_values = $values[$feature['id']]; if (!isset($product['features'])) { $product['features'] = array(); } if (isset($sku['features'][$feature['code']])) { array_unshift($f_values, (string) $sku['features'][$feature['code']]); } foreach ($f_values as &$value) { if (preg_match($pattern, $value)) { $value = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $value) . $enclosure; } unset($value); } $f_values = array_unique($f_values); $product['features'][$feature['code']] = '<{' . implode(',', $f_values) . '}>'; } } } $virtual_product = $product; if (isset($skus[$product['sku_id']])) { $virtual_product['skus'] = array(-1 => $skus[$product['sku_id']]); } else { $virtual_product['skus'] = array(-1 => $sku); } $virtual_product['skus'][-1]['stock'] = array(0 => $product['count']); $this->writer->write($virtual_product); } $product['features'] = $sku['features']; } else { if (!$exported) { foreach ($product['features'] as $code => &$values) { if (isset($sku['features'][$code])) { $values = array_unique(array_merge($values, $sku['features'][$code])); } unset($values); } } else { $product['features'] = $sku['features']; } } } $product['skus'] = array(-1 => $sku); $this->writer->write($product); if (isset($product['images'])) { $processed[self::STAGE_IMAGE] += count($product['images']); } $exported = true; ++$current_stage[self::STAGE_SKU]; ++$processed[self::STAGE_SKU]; } } elseif (count($products) > 1) { ++$chunk; } array_shift($products); ++$current_stage[self::STAGE_PRODUCT]; if ($exported) { ++$processed[self::STAGE_PRODUCT]; } } return $current_stage[self::STAGE_PRODUCT] < $count[self::STAGE_PRODUCT]; }
/** * Filters collection products by specified conditions. * * @param array $data Product filtering conditions: * 'in_stock_only' => whether only products with positive or unlimited stock count must be returned * 'price_min' => minimum price limit * 'price_max' => maximum price limit * '%feature_code%' => feature value */ public function filters($data) { if ($this->filtered) { return; } $delete = array('page', 'sort', 'order'); foreach ($delete as $k) { if (isset($data[$k])) { unset($data[$k]); } } $config = wa('shop')->getConfig(); if (isset($data['in_stock_only'])) { $this->where[] = '(p.count > 0 OR p.count IS NULL)'; } if (isset($data['price_min']) && $data['price_min'] !== '') { $this->where[] = 'p.max_price >= ' . $this->toFloat(shop_currency($data['price_min'], true, $config->getCurrency(true), false)); unset($data['price_min']); } if (isset($data['price_max']) && $data['price_max'] !== '') { $this->where[] = 'p.min_price <= ' . $this->toFloat(shop_currency($data['price_max'], true, $config->getCurrency(true), false)); unset($data['price_max']); } $feature_model = new shopFeatureModel(); $features = $feature_model->getByField('code', array_keys($data), 'code'); foreach ($data as $feature_code => $values) { if (!is_array($values)) { if ($values === '') { continue; } $values = array($values); } if (isset($features[$feature_code])) { if (isset($values['min']) || isset($values['max']) || isset($values['unit'])) { if (ifset($values['min'], '') === '' && ifset($values['max'], '') === '') { continue; } else { $unit = ifset($values['unit']); $min = $max = null; if (isset($values['min'])) { $min = $values['min']; if ($unit) { $min = shopDimension::getInstance()->convert($min, $features[$feature_code]['type'], null, $unit); } } if (isset($values['max'])) { $max = $values['max']; if ($unit) { $max = shopDimension::getInstance()->convert($max, $features[$feature_code]['type'], null, $unit); } } $fm = $feature_model->getValuesModel($features[$feature_code]['type']); $values = $fm->getValueIdsByRange($features[$feature_code]['id'], $min, $max); } } else { foreach ($values as &$v) { $v = (int) $v; } } if ($values) { $this->addJoin('shop_product_features', 'p.id = :table.product_id AND :table.feature_id = ' . (int) $features[$feature_code]['id'], ':table.feature_value_id IN (' . implode(',', $values) . ')'); $this->group_by = 'p.id'; } else { $this->where[] = '0'; } } } $this->filtered = true; }
public function getValues($product_id, $lang, $sku_id = null, $type_id = null) { $sql = "SELECT " . ($type_id ? 'tf.sort, ' : '') . "f.code, f.type, f.multiple, pf.*\n FROM shop_product_features pf"; $sql .= " JOIN shop_feature f ON (pf.feature_id = f.id)"; if ($type_id) { $sql .= " LEFT JOIN shop_type_features tf ON ((tf.feature_id = IFNULL(f.parent_id,f.id)) AND (tf.type_id=i:type_id))"; } $sql .= " WHERE pf.product_id = i:id AND "; if ($sku_id) { if ($sku_id > 0) { $sql .= '(pf.sku_id = i:sku_id OR pf.sku_id IS NULL) ORDER BY pf.sku_id'; } else { $sql .= '(pf.sku_id = i:sku_id) ORDER BY pf.sku_id'; $sku_id = -$sku_id; } } else { $sql .= 'pf.sku_id IS NULL'; } if ($type_id) { $sql .= " ORDER BY tf.sort"; } $features = $storages = array(); $params = array('id' => $product_id, 'sku_id' => $sku_id, 'type_id' => $type_id); $data = $this->query($sql, $params); $result = array(); foreach ($data as $row) { if ($sku_id && $row['code'] == 'weight' && !$row['sku_id']) { continue; } $features[$row['feature_id']] = array('code' => $row['code'], 'multiple' => $row['multiple']); if (preg_match('/^(.+)\\.[0-2]$/', $row['code'], $matches)) { $result[$matches[1]] = null; } else { $result[$row['code']] = null; } $type = preg_replace('/\\..*$/', '', $row['type']); if ($type == shopFeatureModel::TYPE_BOOLEAN) { /** * @var shopFeatureValuesBooleanModel $model */ $model = shopFeatureModel::getValuesModel($type); $values = $model->getValues('id', $row['feature_value_id']); $result[$row['code']] = reset($values); } elseif ($type == shopFeatureModel::TYPE_DIVIDER) { /** * @var shopFeatureValuesDividerModel $model */ $model = shopFeatureModel::getValuesModel($type); $values = $model->getValues('id', $row['feature_value_id']); $result[$row['code']] = reset($values); } else { if ($sku_id) { $storages[$type][$row['feature_id']] = $row['feature_value_id']; } else { $storages[$type][] = $row['feature_value_id']; } } } foreach ($storages as $type => $value_ids) { $model = shopFeatureModel::getValuesModel($type); $feature_values = $model->getValues('id', $value_ids); $feature_values_tr = $this->select('id, value')->where('type = ? AND lang = ? AND id IN(?)', $type, $lang, $value_ids)->fetchAll('id', true); foreach ($feature_values as $feature_id => $values) { foreach ($values as $vid => $value) { if (!empty($feature_values_tr[$vid])) { $values[$vid] = $feature_values_tr[$vid]; } } if (isset($features[$feature_id])) { $f = $features[$feature_id]; $result[$f['code']] = $sku_id || empty($f['multiple']) ? reset($values) : $values; } else { //obsolete feature value } } } /** * composite fields workaround */ $composite = array_filter(array_keys($result), create_function('$a', 'return preg_match("/\\.0$/",$a);')); foreach ($composite as $code) { $code = preg_replace('/\\.0$/', '', $code); $result[$code] = new shopCompositeValue($code, $result); } return $result; }