Commit fa33d79b7d0981e35607fb22d7fa2a63a4dc5362

Authored by Yarik
1 parent 8a7e6ecf

Namespaces

Showing 2 changed files with 240 additions and 13 deletions   Show diff stats
CatalogUrlManager.php 0 → 100644
  1 +<?php
  2 +
  3 + namespace common\modules\product;
  4 +
  5 + use common\modules\product\models\Category;
  6 + use common\modules\product\models\Product;
  7 + use common\modules\product\models\ProductSearch;
  8 + use common\modules\product\models\ProductVariant;
  9 + use yii\helpers\Url;
  10 + use yii\web\HttpException;
  11 + use yii\web\UrlRuleInterface;
  12 +
  13 + class CatalogUrlManager implements UrlRuleInterface
  14 + {
  15 + public $route_map = [];
  16 + /**
  17 + * Parses the given request and returns the corresponding route and parameters.
  18 + *
  19 + * @param \yii\web\UrlManager $manager the URL manager
  20 + * @param \yii\web\Request $request the request component
  21 + *
  22 + * @throws HttpException
  23 + * @return array|boolean the parsing result. The route and the parameters are returned as an array.
  24 + * If false, it means this rule cannot be used to parse this path info.
  25 + */
  26 + public function parseRequest($manager, $request)
  27 + {
  28 +
  29 + $pathInfo = $request->getPathInfo();
  30 + $paths = explode('/', $pathInfo);
  31 +
  32 + if (!array_key_exists($paths[ 0 ], $this->route_map)) {
  33 + return false;
  34 + }
  35 +
  36 + $params = [];
  37 + if ($paths[ 0 ] == 'catalog') {
  38 + $route = 'catalog/category';
  39 +
  40 + // Category
  41 + if (!empty( $paths[ 1 ] )) {
  42 + $category = Category::find()
  43 + ->joinWith('lang')
  44 + ->where(
  45 + [
  46 + 'category_lang.alias' => $paths[ 1 ],
  47 + ]
  48 + )
  49 + ->one();
  50 + if (empty( $category )) {
  51 + \Yii::$app->response->redirect('/');
  52 + }
  53 + $params[ 'category' ] = $category;
  54 + }
  55 + if (!empty( $paths[ 2 ] )) {
  56 + // Filter
  57 +
  58 + if (strpos($paths[ 2 ], 'filters:') === 0) {
  59 + if (!isset( $paths[ 3 ] )) {
  60 + $this->parseFilter($paths[ 2 ], $params);
  61 + } else {
  62 + throw new HttpException(404, 'Page not found');
  63 + }
  64 +
  65 + } else {
  66 + throw new HttpException(404, 'Page not found');
  67 + }
  68 + }
  69 + } elseif ($paths[ 0 ] == 'product') {
  70 +
  71 + if (!empty( $paths[ 3 ] )) {
  72 + throw new HttpException(404, 'Page not found');
  73 + }
  74 + $product = Product::find()
  75 + ->joinWith('lang')
  76 + ->where([ 'product_lang.alias' => $paths[ 1 ] ])
  77 + ->one();
  78 + $variant = ProductVariant::find()
  79 + ->joinWith('lang')
  80 + ->where([ 'sku' => $paths[ 2 ] ])
  81 + ->one();
  82 +
  83 + if (empty( $variant->id ) || empty( $product->id )) {
  84 + throw new HttpException(404, 'Page not found');
  85 + }
  86 + $route = 'catalog/product';
  87 + $params = [
  88 + 'product' => $product,
  89 + 'variant' => $variant,
  90 + ];
  91 + }
  92 +
  93 + return [
  94 + $route,
  95 + $params,
  96 + ];
  97 + }
  98 + /**
  99 + * Creates a URL according to the given route and parameters.
  100 + *
  101 + * @param \yii\web\UrlManager $manager the URL manager
  102 + * @param string $route the route. It should not have slashes at the beginning or the end.
  103 + * @param array $params the parameters
  104 + *
  105 + * @return string|boolean the created URL, or false if this rule cannot be used for creating this URL.
  106 + */
  107 + public function createUrl($manager, $route, $params)
  108 + {
  109 +
  110 + if (!in_array($route, $this->route_map)) {
  111 + return false;
  112 + }
  113 +
  114 + switch ($route) {
  115 + case 'catalog/category':
  116 + if (!empty( $params[ 'category' ] )) {
  117 + $category_alias = is_object(
  118 + $params[ 'category' ]
  119 + ) ? $params[ 'category' ]->lang->alias : strtolower(
  120 + $params[ 'category' ]
  121 + );
  122 + $url = 'catalog/' . $category_alias . '/';
  123 + unset( $params[ 'category' ] );
  124 + } else {
  125 + $url = 'catalog/';
  126 + }
  127 +
  128 + $this->setFilterUrl($params, $url);
  129 +
  130 + foreach ($params as $key => $param) {
  131 + if (empty( $params[ $key ] )) {
  132 + unset( $params[ $key ] );
  133 + }
  134 + }
  135 +
  136 + if (!empty( $params ) && ( $query = http_build_query($params) ) !== '') {
  137 + $url .= '?' . $query;
  138 + }
  139 +
  140 + return $url;
  141 + break;
  142 +
  143 + case 'catalog/product':
  144 + if (!empty( $params[ 'product' ] )) {
  145 + $product_alias = is_object($params[ 'product' ]) ? $params[ 'product' ]->alias : strtolower(
  146 + $params[ 'product' ]
  147 + );
  148 + unset( $params[ 'product' ] );
  149 + }
  150 + $url = 'product/' . $product_alias;
  151 +
  152 + if (!empty( $params ) && ( $query = http_build_query($params) ) !== '') {
  153 + $url .= '?' . $query;
  154 + }
  155 +
  156 + return $url;
  157 + break;
  158 +
  159 + }
  160 + }
  161 +
  162 + private function option_value_encode($value)
  163 + {
  164 + return str_replace(
  165 + [
  166 + ',',
  167 + '/',
  168 + ],
  169 + [
  170 + '~',
  171 + '&s;',
  172 + ],
  173 + $value
  174 + );
  175 + }
  176 +
  177 + private function setFilterUrl(&$params, &$url)
  178 + {
  179 + $filter = [];
  180 + if (!empty( $params[ 'filters' ] )) {
  181 + foreach ($params[ 'filters' ] as $key => $values) {
  182 + switch ($key) {
  183 + case 'prices':
  184 + $filter[] = $key . '=' . implode(':', $values);
  185 + break;
  186 +
  187 + default:
  188 + foreach ($values as &$value) {
  189 + $value = $this->option_value_encode($value);
  190 + if (empty( $value )) {
  191 + unset( $value );
  192 + }
  193 + }
  194 + $filter[] = $key . '=' . implode(',', $values);
  195 + break;
  196 + }
  197 + }
  198 + if (!empty( $filter )) {
  199 + $url .= 'filters:' . implode(';', $filter);
  200 + }
  201 + unset( $params[ 'filters' ] );
  202 + }
  203 + }
  204 +
  205 + private function parseFilter($paths, &$params)
  206 + {
  207 + $params[ 'filters' ] = [];
  208 + $filter_str = substr($paths, 8);
  209 + $filter_options = explode(';', $filter_str);
  210 + foreach ($filter_options as $filter_option) {
  211 + $filter_exp = explode('=', $filter_option);
  212 + if (!empty( $filter_exp[ 1 ] )) {
  213 + list( $filter_key, $filter_option ) = explode('=', $filter_option);
  214 + if ($filter_key == 'prices') { // price-interval section
  215 + $prices = explode(':', $filter_option);
  216 + $params[ 'filters' ][ $filter_key ] = [
  217 + 'min' => floatval($prices[ 0 ]),
  218 + 'max' => floatval($prices[ 1 ]),
  219 + ];
  220 + } else { // brands and other sections
  221 + $params[ 'filters' ][ $filter_key ] = explode(',', $filter_option);
  222 + }
  223 + } else {
  224 + throw new HttpException(404, 'Page not found');
  225 + }
  226 + }
  227 + }
  228 +
  229 + }
0 230 \ No newline at end of file
... ...
models/ProductSearch.php
... ... @@ -101,17 +101,14 @@
101 101 'categories',
102 102 'lang',
103 103 ]
104   - )
105   - ->joinWith(
106   - [
107   - 'brand' => function ($query) {
  104 + )// ->joinWith(
  105 + // [
  106 + // 'brand.lang',
  107 + // ]
  108 + // )
108 109 /**
109 110 * @var ActiveQuery $query
110 111 */
111   - $query->joinWith('lang');
112   - },
113   - ]
114   - )
115 112 ->joinWith('variants');
116 113  
117 114 $query->groupBy(
... ... @@ -135,10 +132,11 @@
135 132 'asc' => [ 'product_lang.title' => SORT_ASC ],
136 133 'desc' => [ 'product_lang.title' => SORT_DESC ],
137 134 ],
138   - 'brand_id' => [
139   - 'asc' => [ 'brand_lang.title' => SORT_ASC ],
140   - 'desc' => [ 'brand_lang.title' => SORT_DESC ],
141   - ],
  135 + // 'brand_id' => [
  136 + // 'asc' => [ 'brand_lang.title' => SORT_ASC ],
  137 + // 'desc' => [ 'brand_lang.title' => SORT_DESC ],
  138 + // 'default' => SORT_DESC,
  139 + // ],
142 140 ],
143 141 ]
144 142 );
... ... @@ -174,7 +172,7 @@
174 172 }
175 173 $query->andFilterWhere(
176 174 [
177   - 'product.brand_id' => $this->brand_id,
  175 + // 'product.brand_id' => $this->brand_id,
178 176 'product.id' => $this->id,
179 177 'product_category.category_id' => $this->categoryId,
180 178 ]
... ...