public function execute()
 {
     $type_model = new shopTypeModel();
     $types = $type_model->getAll('id');
     $category_model = new shopCategoryModel();
     $categories = $category_model->getFullTree('id, name, depth', true);
     $features_model = new shopFeatureModel();
     $features = $features_model->getAll('id');
     $data = array();
     $type_values = array();
     foreach ($types as $type_id => $type) {
         $type_values[] = array($type_id, $type['name']);
         $data[$type_id]['price'] = array('feature' => 'price');
         $data[$type_id]['type_id'] = array('feature' => 'type_id');
         $data[$type_id]['tag'] = array('feature' => 'tag');
     }
     $type_features_model = new shopTypeFeaturesModel();
     $rows = $type_features_model->getAll();
     foreach ($rows as $row) {
         if (isset($features[$row['feature_id']])) {
             $code = $features[$row['feature_id']]['code'];
             $data[$row['type_id']][$code] = array('feature' => $code, 'feature_id' => $row['feature_id']);
         }
     }
     $type_upselling_model = new shopTypeUpsellingModel();
     $rows = $type_upselling_model->getAll();
     foreach ($rows as $row) {
         $data[$row['type_id']][$row['feature']] = array('feature_id' => $row['feature_id'], 'feature' => $row['feature'], 'cond' => $row['cond'], 'value' => $row['value']);
     }
     foreach ($data as &$row) {
         $row = array_values($row);
     }
     unset($row);
     foreach ($types as &$type) {
         if ($type['upselling']) {
             $type['upselling_html'] = self::getConditionHTML($data[$type['id']], $features);
         }
     }
     unset($type);
     $fids = array();
     foreach ($features as $f_key => $f) {
         $features[$f_key]['selectable'] = (int) $f['selectable'];
         $features[$f_key]['multiple'] = (int) $f['multiple'];
         if ($f['selectable']) {
             $fids[$f['id']] = $f;
         }
     }
     if ($fids) {
         $fids = $features_model->getValues($fids);
         foreach ($fids as $feature_id => $f) {
             foreach ($f['values'] as $value_id => $value) {
                 $features[$feature_id]['values'][] = array($value_id, $value);
             }
         }
         unset($fids);
     }
     $features['type_id'] = array('name' => _w('Type'), 'type' => 'varchar', 'selectable' => 1, 'values' => $type_values);
     $this->view->assign(array('types' => $types, 'categories' => $categories, 'features' => $features, 'data' => $data));
 }
 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()
 {
     $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 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()
 {
     $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()
 {
     $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 getValues($feature, $to)
 {
     $values = array();
     if (!$this->isMultidimensional($feature)) {
         foreach ($this->feature_model->getValues(array($feature)) as $f) {
             foreach ($f['values'] as $k => $v) {
                 if ($feature['type'] === 'boolean' && ($to['type'] === 'double' || $to['type'] === 'range.double')) {
                     $values[-$k] = $v->value;
                 } else {
                     $values[-$k] = (string) $v;
                 }
             }
         }
     } else {
         $features = $this->getChildren($feature);
         foreach ($this->feature_model->getValues($features) as $f) {
             foreach ($f['values'] as $k => $v) {
                 $values[-$k] = array('feature_id' => $f['id'], 'value' => (string) $v);
             }
         }
     }
     return $values;
 }
 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);
     }
 }
 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;
 }
 /**
  * @param shopProduct $product
  * @return array|bool
  * @example <pre>
  * array(
  *  'feature_1'=>array(
  *      'selected'=>int,
  *      'values'=>array(
  *         %value_id%=> array(
  *              'value_id'=>int,
  *              'value'=>string,
  *              'selected'=>bool,
  *          ),
  *      ),
  *  ),
  * )
  * </pre>
  */
 public function getData(shopProduct $product)
 {
     $feature_model = new shopFeatureModel();
     if ($product->sku_type == shopProductModel::SKU_TYPE_SELECTABLE) {
         $selected = $this->getByProduct($product->id);
         $env = wa()->getEnv();
         if ($env == 'backend') {
             $features = $feature_model->getMultipleSelectableFeaturesByType($product->type_id);
         } else {
             $features = $feature_model->getById(array_keys($selected));
             if ($product->type_id) {
                 $types = array($product->type_id => true);
                 $type_features_model = new shopTypeFeaturesModel();
                 $type_features_model->fillTypes($features, $types);
                 foreach ($features as &$feature) {
                     unset($feature['types']);
                     $feature['sort'] = ifset($feature['sort'][$product->type_id]);
                     unset($feature);
                 }
                 uasort($features, create_function('$a,$b', 'return max(-1,min(1,$a["sort"]-$b["sort"]));'));
             }
         }
         // attach values
         $features = $feature_model->getValues($features);
         foreach ($features as &$f) {
             $count = 0;
             foreach ($f['values'] as $id => &$v) {
                 $is_selected = isset($selected[$f['id']][$id]);
                 if ($env == 'backend') {
                     if (is_object($v)) {
                         $v['selected'] = $is_selected;
                     } else {
                         $v = array('value' => htmlentities((string) $v, ENT_NOQUOTES, 'utf-8'), 'selected' => $is_selected);
                     }
                     unset($v);
                     if ($is_selected) {
                         $count += 1;
                     }
                 } elseif (!$is_selected) {
                     unset($f['values'][$id]);
                 }
             }
             $f['selected'] = $count;
             unset($f);
         }
     } else {
         if (wa()->getEnv() == 'backend') {
             $features = $feature_model->isTypeMultipleSelectable($product->type_id);
         } else {
             $features = array();
         }
     }
     return $features;
     //Frontend
     $data = $feature_model->getValues($data);
     foreach ($data as $code => $f) {
         foreach ($f['values'] as $id => $v) {
             if (!isset($v_id, $selected[$code][$id])) {
                 unset($data[$code]['values'][$id]);
             }
         }
     }
     return $data;
 }
 public function execute()
 {
     $category = $this->getCategory();
     $this->addCanonical();
     // breadcrumbs
     $root_category_id = $category['id'];
     if ($category['parent_id']) {
         $breadcrumbs = array();
         $path = array_reverse($this->getModel()->getPath($category['id']));
         $root_category = reset($path);
         $root_category_id = $root_category['id'];
         foreach ($path as $row) {
             $breadcrumbs[] = array('url' => wa()->getRouteUrl('/frontend/category', array('category_url' => waRequest::param('url_type') == 1 ? $row['url'] : $row['full_url'])), 'name' => $row['name']);
         }
         if ($breadcrumbs) {
             $this->view->assign('breadcrumbs', $breadcrumbs);
         }
     }
     $this->view->assign('root_category_id', $root_category_id);
     // sort
     if ($category['type'] == shopCategoryModel::TYPE_DYNAMIC && !$category['sort_products']) {
         $category['sort_products'] = 'create_datetime DESC';
     }
     if ($category['sort_products'] && !waRequest::get('sort')) {
         $sort = explode(' ', $category['sort_products']);
         $this->view->assign('active_sort', $sort[0] == 'count' ? 'stock' : $sort[0]);
     } elseif (!$category['sort_products'] && !waRequest::get('sort')) {
         $this->view->assign('active_sort', '');
     }
     $this->view->assign('category', $category);
     // products
     $collection = new shopProductsCollection('category/' . $category['id']);
     // filters
     if ($category['filter']) {
         $filter_ids = explode(',', $category['filter']);
         $feature_model = new shopFeatureModel();
         $features = $feature_model->getById(array_filter($filter_ids, 'is_numeric'));
         if ($features) {
             $features = $feature_model->getValues($features);
         }
         $category_value_ids = $collection->getFeatureValueIds();
         $filters = array();
         foreach ($filter_ids as $fid) {
             if ($fid == 'price') {
                 $range = $collection->getPriceRange();
                 if ($range['min'] != $range['max']) {
                     $filters['price'] = array('min' => shop_currency($range['min'], null, null, false), 'max' => shop_currency($range['max'], null, null, false));
                 }
             } elseif (isset($features[$fid]) && isset($category_value_ids[$fid])) {
                 $filters[$fid] = $features[$fid];
                 $min = $max = $unit = null;
                 foreach ($filters[$fid]['values'] as $v_id => $v) {
                     if (!in_array($v_id, $category_value_ids[$fid])) {
                         unset($filters[$fid]['values'][$v_id]);
                     } else {
                         if ($v instanceof shopRangeValue) {
                             $begin = $this->getFeatureValue($v->begin);
                             if ($min === null || $begin < $min) {
                                 $min = $begin;
                             }
                             $end = $this->getFeatureValue($v->end);
                             if ($max === null || $end > $max) {
                                 $max = $end;
                                 if ($v->end instanceof shopDimensionValue) {
                                     $unit = $v->end->unit;
                                 }
                             }
                         } else {
                             $tmp_v = $this->getFeatureValue($v);
                             if ($min === null || $tmp_v < $min) {
                                 $min = $tmp_v;
                             }
                             if ($max === null || $tmp_v > $max) {
                                 $max = $tmp_v;
                                 if ($v instanceof shopDimensionValue) {
                                     $unit = $v->unit;
                                 }
                             }
                         }
                     }
                 }
                 if (!$filters[$fid]['selectable'] && ($filters[$fid]['type'] == 'double' || substr($filters[$fid]['type'], 0, 6) == 'range.' || substr($filters[$fid]['type'], 0, 10) == 'dimension.')) {
                     if ($min == $max) {
                         unset($filters[$fid]);
                     } else {
                         $type = preg_replace('/^[^\\.]*\\./', '', $filters[$fid]['type']);
                         if ($type != 'double') {
                             $filters[$fid]['base_unit'] = shopDimension::getBaseUnit($type);
                             $filters[$fid]['unit'] = shopDimension::getUnit($type, $unit);
                             if ($filters[$fid]['base_unit']['value'] != $filters[$fid]['unit']['value']) {
                                 $dimension = shopDimension::getInstance();
                                 $min = $dimension->convert($min, $type, $filters[$fid]['unit']['value']);
                                 $max = $dimension->convert($max, $type, $filters[$fid]['unit']['value']);
                             }
                         }
                         $filters[$fid]['min'] = $min;
                         $filters[$fid]['max'] = $max;
                     }
                 }
             }
         }
         $this->view->assign('filters', $filters);
         $this->setCollection($collection);
         // fix prices
         $products = $this->view->getVars('products');
         $product_ids = array();
         foreach ($products as $p_id => $p) {
             if ($p['sku_count'] > 1) {
                 $product_ids[] = $p_id;
             }
         }
         if ($product_ids) {
             $min_price = $max_price = null;
             $tmp = array();
             foreach ($filters as $fid => $f) {
                 if ($fid == 'price') {
                     $min_price = waRequest::get('price_min');
                     if (!empty($min_price)) {
                         $min_price = (double) $min_price;
                     } else {
                         $min_price = null;
                     }
                     $max_price = waRequest::get('price_max');
                     if (!empty($max_price)) {
                         $max_price = (double) $max_price;
                     } else {
                         $max_price = null;
                     }
                 } else {
                     $fvalues = waRequest::get($f['code']);
                     if ($fvalues && !isset($fvalues['min']) && !isset($fvalues['max'])) {
                         $tmp[$fid] = $fvalues;
                     }
                 }
             }
             $product_skus = array();
             if ($tmp) {
                 $pf_model = new shopProductFeaturesModel();
                 $product_skus = $pf_model->getSkusByFeatures($product_ids, $tmp);
             } elseif ($min_price || $max_price) {
                 $ps_model = new shopProductSkusModel();
                 $rows = $ps_model->getByField('product_id', $product_ids, true);
                 foreach ($rows as $row) {
                     $product_skus[$row['product_id']][] = $row;
                 }
             }
             $default_currency = $this->getConfig()->getCurrency(true);
             if ($product_skus) {
                 foreach ($product_skus as $product_id => $skus) {
                     $currency = $products[$product_id]['currency'];
                     usort($skus, array($this, 'sortSkus'));
                     $k = 0;
                     if ($min_price || $max_price) {
                         foreach ($skus as $i => $sku) {
                             if ($min_price) {
                                 $tmp_price = shop_currency($min_price, true, $currency, false);
                                 if ($sku['price'] < $tmp_price) {
                                     continue;
                                 }
                             }
                             if ($max_price) {
                                 $tmp_price = shop_currency($max_price, true, $currency, false);
                                 if ($sku['price'] > $tmp_price) {
                                     continue;
                                 }
                             }
                             $k = $i;
                             break;
                         }
                     }
                     $sku = $skus[$k];
                     if ($products[$product_id]['sku_id'] != $sku['id']) {
                         $products[$product_id]['sku_id'] = $sku['id'];
                         $products[$product_id]['frontend_url'] .= '?sku=' . $sku['id'];
                         $products[$product_id]['price'] = shop_currency($sku['price'], $currency, $default_currency, false);
                         $products[$product_id]['compare_price'] = shop_currency($sku['compare_price'], $currency, $default_currency, false);
                     }
                 }
                 $this->view->assign('products', $products);
             }
         }
     } else {
         $this->setCollection($collection);
     }
     //отображение дополнительных размеров
     $products = $this->view->getVars('products');
     $product_features_model = new shopProductFeaturesSelectableModel();
     foreach ($products as &$p) {
         $sku_features = $product_features_model->getByProduct($p['id']);
         $sizes = $sku_features[3];
         if (!$sizes) {
             $p['sizes'] = array();
             continue;
         }
         $pf_names = $product_features_model->query("SELECT `id`, `value` FROM shop_feature_values_varchar where `id` IN (" . implode(',', $sizes) . ') ORDER BY `sort`;')->fetchAll();
         foreach ($pf_names as $key => $val) {
             $sizes[$val['id']] = $val['value'];
         }
         $p['sizes'] = $pf_names;
     }
     //отображение всех картинок
     foreach ($products as &$p) {
         $images_full = shopViewHelper::images($p['id']);
         if (isset($images_full[$p['id']])) {
             $p['image_ids'] = array_keys($images_full[$p['id']]);
         }
     }
     $this->view->assign('products', $products);
     // set meta
     $title = $category['meta_title'] ? $category['meta_title'] : $category['name'];
     wa()->getResponse()->setTitle($title);
     wa()->getResponse()->setMeta('keywords', $category['meta_keywords']);
     wa()->getResponse()->setMeta('description', $category['meta_description']);
     /**
      * @event frontend_category
      * @return array[string]string $return[%plugin_id%] html output for category
      */
     $this->view->assign('frontend_category', wa()->event('frontend_category', $category));
     $this->setThemeTemplate('category.html');
 }