CatalogUrlManager.php 11.9 KB
<?php

namespace common\modules\product;


use common\modules\product\models\CategorySearch;
use common\modules\product\models\ProductSearch;

use common\modules\product\models\ProductVariant;
use Yii;
use yii\helpers\Url;
use yii\web\HttpException;
use yii\web\UrlRuleInterface;

class CatalogUrlManager implements UrlRuleInterface {
    public $route_map = [];
    /**
     * Parses the given request and returns the corresponding route and parameters.
     * @param \yii\web\UrlManager $manager the URL manager
     * @param \yii\web\Request $request the request component
     * @return array|boolean the parsing result. The route and the parameters are returned as an array.
     * If false, it means this rule cannot be used to parse this path info.
     */
    public function parseRequest($manager, $request)
    {


        $pathInfo = $request->getPathInfo();
        $paths = explode('/', $pathInfo);
        /**
         * linija-svitla.ua only
         */
        $pattern = '/^(.+)\.htm$/';
        if(isset($paths[0])){
            preg_match($pattern,$paths[0], $match );
            if(!empty($match)){
                $old_item_name = explode('-',$paths[0] );
                array_pop($old_item_name);
                $count = count($old_item_name)-1;

                if(isset($old_item_name[$count]) && $old_item_name[$count] == 'dis' ){

                    $sku = $old_item_name[$count-3].'/'.$old_item_name[$count-2].'/'.$old_item_name[$count-1].'_'.$old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();
                    if($product_variant instanceof ProductVariant){

                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }
                }


                if(isset($old_item_name[$count-3]) && isset($old_item_name[$count-2]) && isset($old_item_name[$count-1]) && isset($old_item_name[$count])){

                    $sku = $old_item_name[$count-3].'/'.$old_item_name[$count-2].'/'.$old_item_name[$count-1].'/'.$old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();
                    if($product_variant instanceof ProductVariant){

                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }
                }

                if(isset($old_item_name[$count-2]) && isset($old_item_name[$count-1]) && isset($old_item_name[$count])){
                    $sku = $old_item_name[$count-2].'/'.$old_item_name[$count-1].'/'.$old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();

                    if($product_variant instanceof ProductVariant){

                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }
                    $sku = $old_item_name[$count-2].'/'.$old_item_name[$count-1].' '.$old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();

                    if($product_variant instanceof ProductVariant){
                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }

                    $sku = $old_item_name[$count-2].'/'.$old_item_name[$count-1].'-'.$old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();

                    if($product_variant instanceof ProductVariant){
                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }

                    $sku = $old_item_name[$count-2].'/'.$old_item_name[$count-1].'_'.$old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();

                    if($product_variant instanceof ProductVariant){
                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }

                }

                if(isset($old_item_name[$count-1]) && isset($old_item_name[$count])){
                    $sku = $old_item_name[$count-1].'/'.$old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();
                    if($product_variant instanceof ProductVariant){

                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }
                }

                if(isset($old_item_name[$count])){
                    $sku = $old_item_name[$count];
                    $product_variant = ProductVariant::find()->where(['sku'=>$sku])->one();
                    if($product_variant instanceof ProductVariant){

                        $link = 'product'.'/'. $product_variant->product->alias;
                        header("HTTP/1.1 301 Moved Permanently");
                        header("Location: http://www.linija-svitla.ua/".$link);
                        die();
                    }
                }
            }
        }

        /**
         * end linija-svitla.ua only
         */





        if (!array_key_exists($paths[0], $this->route_map)) {
            return false;
        }

        $params = [];
        if ($paths[0] == 'catalog') {
            $route = 'catalog/category';

            // Category
            if (!empty($paths[1])) {
                $category = CategorySearch::findByAlias($paths[1]);
                if (empty($category)) {
                    http_redirect(Url::to(['/']));
                }
                $params['category'] = $category;
            }
            if (!empty($paths[2])) {
                // Filter

                if (strpos($paths[2], 'filters:') === 0) {
                    if(!isset($paths[3]) ){
                        $this->parseFilter($paths[2], $params);
                    } else {
                        throw new HttpException(404 ,'Page not found');
                    }


                }
                else {
                    throw new HttpException(404 ,'Page not found');
                }
            }
        } elseif ($paths[0] == 'product') {

            if (!empty($paths[2])) {
                throw new HttpException(404 ,'Page not found');
            }
            $product = ProductSearch::findByAlias($paths[1]);
            if (empty($product->product_id)) {
                throw new HttpException(404 ,'Page not found');
            }
            $route = 'catalog/product';
            $params = [
                'product' => $product,
            ];
        }

        return [$route, $params];
    }
    /**
     * Creates a URL according to the given route and parameters.
     * @param \yii\web\UrlManager $manager the URL manager
     * @param string $route the route. It should not have slashes at the beginning or the end.
     * @param array $params the parameters
     * @return string|boolean the created URL, or false if this rule cannot be used for creating this URL.
     */
    public function createUrl($manager, $route, $params)
    {

        if (!in_array($route, $this->route_map)) {
            return false;
        }

        switch($route) {
            case 'catalog/category':
                if (!empty($params['category'])) {
                    $category_alias = is_object($params['category']) ? $params['category']->alias : strtolower($params['category']);
                    $url = 'cataloq/'. $category_alias;
                    unset($params['category']);
                } else {
                    $url = 'cataloq';
                }

                $this->setFilterUrl($params, $url);

                foreach ($params as $key => $param) {
                    if (empty($params[$key])) {
                        unset($params[$key]);
                    }
                }

                if (!empty($params) && ($query = http_build_query($params)) !== '') {
                    $url .= '?' . $query;
                }

                return $url;
                break;

            case 'catalog/product':
                if (!empty($params['product'])) {
                    $product_alias = is_object($params['product']) ? $params['product']->alias : strtolower($params['product']);
                    unset($params['product']);
                }
                $url = 'product/'. $product_alias;

                if (!empty($params) && ($query = http_build_query($params)) !== '') {
                    $url .= '?' . $query;
                }



                return $url;
                break;

        }
    }

    private function option_value_encode($value) {
        return str_replace(array(',', '/'), array('~', '&s;'), $value);
    }

    private function setFilterUrl(&$params, &$url) {
        $filter = [];
        if (!empty($params['filters'])) {
            foreach ($params['filters'] as $key => $values) {
                switch($key) {
                    case 'prices':
                        $filter[] = $key .'='. implode(':', $values);
                        break;

                    default:
                        foreach($values as &$value) {
                            $value = $this->option_value_encode($value);
                            if (empty($value)) {
                                unset($value);
                            }
                        }
                        $filter[] = $key .'='. implode(',', $values);
                        break;
                }
            }
            if (!empty($filter)) {
                $url .= 'filters:'. implode(';', $filter);
            }
            unset($params['filters']);
        }
    }

    private function parseFilter($paths, &$params) {
        $params['filters'] = [];
        $filter_str = substr($paths, 8);
        $filter_options = explode(';', $filter_str);
        foreach ($filter_options as $filter_option) {
            $filter_exp = explode('=', $filter_option);
            if(!empty($filter_exp[1])){
                list($filter_key, $filter_option) = explode('=', $filter_option);
                if($filter_key == 'prices') { // price-interval section
                    $prices = explode(':', $filter_option);
                    $params['filters'][$filter_key] = [
                        'min' => floatval($prices[0]),
                        'max' => floatval($prices[1]),
                    ];
                }
                else { // brands and other sections
                    $params['filters'][$filter_key] = explode(',', $filter_option);
                }
            } else {
                throw new HttpException(404 ,'Page not found');
            }
        }
    }

}