Seo.php 10.6 KB
<?php
namespace frontend\widgets;

use common\models\SeoDynamic;
use Yii;
use common\modules\product\models\Brand;
use common\modules\rubrication\models\TaxGroup;
use common\modules\rubrication\models\TaxOption;
use yii\base\Widget;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Url;
use yii\web\HttpException;

class Seo extends Widget
{
    private $url;
    public $row;
    public $own_attr;
    public $fields;
    public $category_name;
    public $description;
    public $title;
    public $meta;
    public $seo_text;
    public $h1;
    public $key;
    public $name;
    public $project_name;
    protected static $check_url;
    protected static $check_url_bool;


    const SEO_TEXT = 'seo_text';
    const DESCRIPTION = 'description';
    const META = 'meta';
    const H1 = 'h1';
    const TITLE = 'title';

    public function init()
    {
        $this->url = \Yii::$app->request->url;
        $this->project_name = \Yii::$app->name;
        parent::init();

    }


    public function run()
    {

        $seoData = $this->getViewData();
        foreach ($seoData as $key => $value) {
            $this->$key = $value;
        }
 

        switch ($this->row) {
            case self::SEO_TEXT:


                $filter = \Yii::$app->request->get('filters', []);
                $sort = \Yii::$app->request->get('sort', []);
                $paginate = \Yii::$app->request->get('page', []);

                if(empty($filter) && empty($sort) && empty($paginate) ){

                    return $this->selectSeoData(self::SEO_TEXT);

                } else {

                    $widgetData = static::findSeoByUrl($this->url);

                    $result = '';

                    if ($widgetData instanceof \common\models\Seo) {

                        $result = $widgetData->{self::SEO_TEXT};

                    } else {

                        $widgetData = $this->findSeoByDynamic();

                        if ($widgetData instanceof SeoDynamic) {

                            $result = $widgetData->{self::SEO_TEXT};

                        }

                    }

                    return $this->replaceData($result);
                }


                break;
            case self::H1:

                $filter = \Yii::$app->request->get('filters', []);



                if (isset($filter['brands']) && count($filter['brands']) == 1) {

                    $model = Brand::find()->where(['alias' => $filter['brands'][0]])->one();
                    if(!$model instanceof Brand){

                        \Yii::$app->response->redirect(['/site/error'],404);
                    } else {
                        if($this->selectSeoData(self::H1) == $this->category_name) {

                            return $this->selectSeoData(self::H1) . ' ' . $model->name;
                        }else {

                            return $this->selectSeoData(self::H1);

                        }
                    }



                } else  if (isset($filter["naznacenie"]) && count($filter["naznacenie"]) == 1) {

                $model = TaxOption::find()->where(['alias' => $filter["naznacenie"]])->one();
                    if(!$model instanceof TaxOption){

                        \Yii::$app->response->redirect(['/site/error'],404);
                    } else {
                        if($this->selectSeoData(self::H1) == $this->category_name) {

                            return $this->selectSeoData(self::H1) . ' ' . $model->value->value;
                        }else {

                            return $this->selectSeoData(self::H1);

                        }

                    }



                } else {
                    return $this->selectSeoData(self::H1);
                }
                    break;
            case self::TITLE:

                $filter = \Yii::$app->request->get('filters', []);


                $title = $this->selectSeoData(self::TITLE);


                if(!empty($filter) && isset($this->fields['meta-title']) && $title == $this->fields['meta-title']) {

                    $array = [
                        'category' => $this->category_name
                    ];


                    if (isset($filter['brands']) && count($filter['brands']) == 1) {
                        $model = Brand::find()->where(['alias' => $filter['brands'][0]])->one();
                        if(!$model instanceof Brand){

                            \Yii::$app->response->redirect(['/site/error'],404);
                        } else {
                            $array['brand'] = $model->name;
                        }

                    }


                    $optionsList = ArrayHelper::getColumn(TaxGroup::find()->where(['is_filter' => 'TRUE'])->all(),'alias');


                    foreach($optionsList as $optionList){


                        if (isset($filter[$optionList]) && count($filter[$optionList]) == 1) {

                            $model = TaxOption::find()->where(['alias' =>$filter[$optionList]])->one();
                            if(!$model instanceof TaxOption){

                                \Yii::$app->response->redirect(['site/error'],404);
                            } else {
                                $array[$optionList] = $model->value->value;
                            }



                        }



                    }

                    $title_string = $this->getTitleString($array);

                    if($title_string){
                        return $title_string;
                    }

                }

                if (!empty($title)) {
                    return $title;
                } else  {
                    return $this->project_name;
                }

                break;
            case self::DESCRIPTION:
                $description = $this->selectSeoData(self::DESCRIPTION);

                if (!empty($description)) {

                    $this->getView()->registerMetaTag([
                        'name' => 'description',
                        'content' => $description
                    ]);

                }

                break;
            case self::META:

                $meta = $this->selectSeoData(self::META);

                $filter = \Yii::$app->request->get('filters', []);
                $sort = \Yii::$app->request->get('sort', []);
                $paginate = \Yii::$app->request->get('page', []);



                if (!empty($meta)) {

                    $this->getView()->registerMetaTag([
                        'name' => 'robots',
                        'content' => $meta
                    ]);

                } else if(!empty($filter['special'])){

                    $this->getView()->registerMetaTag([
                        'name' => 'robots',
                        'content' => 'noindex,follow'
                    ]);

                } else if (
                    isset($filter['brands']) && count($filter['brands']) > 1
                    || isset($filter["pol"]) && count($filter["pol"]) > 1
                    || isset($filter["naznacenie"]) && count($filter["naznacenie"]) > 1
                    || isset($filter["god"]) && count($filter["god"]) > 1

                ) {
                    $this->getView()->registerMetaTag([
                        'name' => 'robots',
                        'content' => 'noindex,nofollow'
                    ]);

                } else if (
                    isset($filter['brands']) && count($filter['brands']) <= 1 && isset($filter) && count($filter, COUNT_RECURSIVE) >= 4
                    || isset($filter) && count($filter, COUNT_RECURSIVE) > 4
                    || !empty($sort) ||  !empty($paginate) || isset($filter['prices'])
                ) {
                    $this->getView()->registerMetaTag([
                        'name' => 'robots',
                        'content' => 'noindex,follow'
                    ]);
                } else {

                    $this->getView()->registerMetaTag([
                        'name' => 'robots',
                        'content' => 'index,follow'
                    ]);
                }




                break;
        }


    }

    protected function replaceData($str)
    {

        if (!empty($this->fields)) {
            foreach ($this->fields as $field_name => $field_value) {
                $str = str_replace('{' . $field_name . '}', $field_value, $str);
            }
        }
        $str = str_replace('{project_name}', $this->project_name, $str);
        return $str;
    }

    protected static function findSeoByUrl($url)
    {
        if(empty(self::$check_url_bool)){
            self::$check_url = \common\models\Seo::findOne(['url' => $url]);
            self::$check_url_bool = true;
        }
        return self::$check_url;
    }

    protected function findSeoByDynamic()
    {

        if(!empty($this->key)){

            $query = SeoDynamic::find()->joinWith('seoCategory')->where(['controller' => \Yii::$app->controller->id, 'action' => \Yii::$app->controller->action->id, 'key' => $this->key]);
        } else {


            $query = SeoDynamic::find()->joinWith('seoCategory')->where(['controller' => \Yii::$app->controller->id, 'action' => \Yii::$app->controller->action->id]);
        }

        return $query->one();
    }


    protected function findSeoByDynamicForFilters(){
        return SeoDynamic::find()->joinWith('seoCategory')->where(['param' =>'filters'])->one();
    }


    protected function getViewData()
    {
        $params = $this->getView()->params;
        if (isset($params['seo'])) {
            return $params['seo'];
        } else {
            return [];
        }
    }

    protected function selectSeoData($param)
    {
        $result = '';

        $widgetData = static::findSeoByUrl($this->url);

        if ($widgetData instanceof \common\models\Seo) {

            $result = $widgetData->$param;

        } else if (!empty($this->$param)) {

            $result = $this->$param;
        } else {

            $widgetData = $this->findSeoByDynamic();

            if ($widgetData instanceof SeoDynamic) {

                $result = $widgetData->$param;

            }

        }

        return $this->replaceData($result);

    }

    public function getTitleString($array){

        $template = SeoDynamic::find()->select('title')->where(['param' =>'filters'])->one();
        if($template instanceof SeoDynamic){
            foreach ($array as $field_name => $field_value) {
                $template->title = str_replace('{' . $field_name . '}', mb_strtolower($field_value), $template->title);
            }
            $template =  preg_replace('/\{.[^\}]*\}\s/','',$template->title);
            return $template;
        }

        return false;

    }


}