From 9ceae125eed9d5a83efc00a4dfeb8ec1a2a7e288 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 20 Oct 2016 19:05:00 +0300 Subject: [PATCH] -Lazy load (now need to configure) -Seo started -Some other stuff --- common/components/artboximage/ArtboxImageHelper.php | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- common/modules/product/models/ProductVariant.php | 1 + common/widgets/Seo.php | 444 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/assets/AppAsset.php | 2 +- frontend/views/catalog/_product_list.php | 6 +++--- frontend/views/category/collection.php | 4 +--- frontend/views/category/index.php | 1 + frontend/views/layouts/main.php | 13 ++++++++++++- frontend/web/js/jquery.lazy.min.js | 2 ++ frontend/web/js/script.js | 4 ++++ 10 files changed, 544 insertions(+), 16 deletions(-) create mode 100644 common/widgets/Seo.php create mode 100644 frontend/web/js/jquery.lazy.min.js diff --git a/common/components/artboximage/ArtboxImageHelper.php b/common/components/artboximage/ArtboxImageHelper.php index 3cf795c..705d8af 100755 --- a/common/components/artboximage/ArtboxImageHelper.php +++ b/common/components/artboximage/ArtboxImageHelper.php @@ -18,7 +18,13 @@ class ArtboxImageHelper extends Object { } return self::$imageDriver; } - + + /** + * Returns the preset from config array + * @param $preset + * + * @return null + */ public function getPreset($preset) { if (empty(self::$presets)) { @@ -26,12 +32,39 @@ class ArtboxImageHelper extends Object { } return empty(self::$presets[$preset]) ? null : self::$presets[$preset]; } - + + /** + * Gets html image tag with needed image + * @param $file + * @param $preset + * @param array $imgOptions + * + * @return string + */ public static function getImage($file, $preset, $imgOptions = []) { $preset_alias = is_array($preset) ? array_keys($preset)[0] : null; return Html::img(self::getImageSrc($file, $preset, $preset_alias), $imgOptions); } - + + public static function getLazyDiv($file, $preset, $options = [], $content = '') { + $preset_alias = is_array($preset) ? array_keys($preset)[0] : null; + if(!empty($options['class'])) { + $options['class'] = $options['class'] . ' lazy'; + } else { + $options['class'] = 'lazy'; + } + $options['data-src'] = self::getImageSrc($file, $preset, $preset_alias); + return Html::tag('div', $content, $options); + } + + /** + * Gets path to image with selected preset + * @param $file + * @param $preset + * @param null $preset_alias + * + * @return bool|mixed + */ public static function getImageSrc($file, $preset, $preset_alias = null) { if (is_string($preset)) { $preset_alias = $preset; @@ -47,19 +80,45 @@ class ArtboxImageHelper extends Object { } return self::getPresetUrl($filePath, $preset, $preset_alias); } - + + /** + * @param $model + * @param $modelField + * @param string $formField + * @param bool $multiple + * + * @return mixed + */ public static function fileinputWidget($model, $modelField, $formField = 'fileUpload', $multiple = false) { return Yii::$app->artboximage->fileinputWidget($model, $modelField, $formField, $multiple); } - + + /** + * @param $url + * + * @return mixed + */ private static function getPathFromUrl($url) { return substr_replace($url, self::getDriver()->rootPath, 0, strlen(self::getDriver()->rootUrl)); } - + + /** + * @param $path + * + * @return mixed + */ private static function getUrlFromPath($path) { return substr_replace($path, self::getDriver()->rootUrl, 0, strlen(self::getDriver()->rootPath)); } - + + /** + * Gets path to image with preset + * @param $filePath + * @param $preset + * @param $preset_alias + * + * @return bool|mixed + */ private static function getPresetUrl($filePath, $preset, $preset_alias) { $pathinfo = pathinfo($filePath); $presetPath = $pathinfo['dirname'] .'/styles/'. strtolower($preset_alias); @@ -80,7 +139,15 @@ class ArtboxImageHelper extends Object { } return false; } - + + /** + * Create new image from existing one and with selected preset + * @param $filePath + * @param $preset + * @param $preset_alias + * + * @return string + */ private static function createPresetImage($filePath, $preset, $preset_alias) { $image = self::getDriver()->load($filePath); diff --git a/common/modules/product/models/ProductVariant.php b/common/modules/product/models/ProductVariant.php index f6fb4f7..1b0623b 100755 --- a/common/modules/product/models/ProductVariant.php +++ b/common/modules/product/models/ProductVariant.php @@ -66,6 +66,7 @@ [ 'product_id', 'product_unit_id', + 'sku', ], 'required', ], diff --git a/common/widgets/Seo.php b/common/widgets/Seo.php new file mode 100644 index 0000000..308701b --- /dev/null +++ b/common/widgets/Seo.php @@ -0,0 +1,444 @@ +url = \Yii::$app->request->url; + $this->project_name = \Yii::$app->name; + if(empty(self::$optionsList)){ + self::$optionsList = ArrayHelper::getColumn(TaxGroup::find()->where(['is_filter' => 'TRUE'])->all(),'alias'); + } + + 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 ($this->checkFilter($filter)) { + + $array = $this->arrayBuilder($filter); + return $this->getNameString($array); + + + } 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'] || !empty($filter) && empty($title)) { + $array = $this->arrayBuilder($filter); + + $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 + ]); + + } else { + + $filter = \Yii::$app->request->get('filters', []); + + if(!empty($filter)){ + $array = $this->arrayBuilder($filter); + $this->getView()->registerMetaTag([ + 'name' => 'description', + 'content' => $this->getDescriptionString($array) + ]); + } + + } + + 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) && $this->checkFilter($filter) + + ) { + $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,nofollow' + ]); + } 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){ + // "{Название раздела: Название блока фильтра | Фильтр 1 | Название блока фильтра: Фильтр 2 | Название блока фильтра: Фильтр 3} - купить в Киеве, Украине - интернет магазин Лінія Світла"; + $row = ''; + foreach($array as $name => $field){ + + if($name == 'category' ){ + $row = $field.' | '.$row; + } else { + $row .= $field['name'] .' '.$field['value'].' | ' ; + } + + + + } + $row = substr($row, 0,-2 ); + $row .= " - купить в Киеве, Украине - интернет магазин Лінія Світла"; + return $row; +// $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; + + } + + + public function getDescriptionString($array){ + // "Лучшие цены на {Название раздела | Название блока фильтра: Фильтр 1 | Название блока фильтра: Фильтр 2 | Название блока фильтра: Фильтр 3}. Лінія Світла"; + $row = 'Лучшие цены на '; + foreach($array as $name => $field){ + + if($name == 'category' ){ + $row = $field.' | '.$row; + } else { + $row .= $field['name'] .' '.$field['value'].' | ' ; + } + + + + } + $row = substr($row, 0,-2 ); + $row .= ". Лінія Світла"; + return $row; + + } + + + public function getNameString($array){ + // "Лучшие цены на {Название раздела | Название блока фильтра: Фильтр 1 | Название блока фильтра: Фильтр 2 | Название блока фильтра: Фильтр 3}. Лінія Світла"; + $row = ''; + foreach($array as $name => $field){ + + if($name == 'category' ){ + $row = $field.' | '.$row; + } else { + $row .= $field['name'] .' '.$field['value'].' | ' ; + } + + + + } + $row = substr($row, 0,-2 ); + return $row; + + } + + public function arrayBuilder($filter) + { + + $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']['name'] = 'Бренд'; + $array['brand']['value'] = $model->name; + } + + } + + + $optionsList = ArrayHelper::map(TaxGroup::find()->where(['is_filter' => 'TRUE'])->all(), 'alias', 'name'); + + + foreach ($optionsList as $optionList => $name) { + + + 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]['value'] = $model->value; + $array[$optionList]['name'] = $name; + } + + + } + + + } + + return $array; + + } + + protected function checkFilter($filter){ + foreach(self::$optionsList as $optionList){ + + if(isset($filter[$optionList]) && count($filter[$optionList]) == 1){ + return true; + } + + } + return false; + } + + +} \ No newline at end of file diff --git a/frontend/assets/AppAsset.php b/frontend/assets/AppAsset.php index 81940af..bd082da 100755 --- a/frontend/assets/AppAsset.php +++ b/frontend/assets/AppAsset.php @@ -16,7 +16,7 @@ class AppAsset extends AssetBundle 'css/fonts.css', ]; public $js = [ -// 'js/npm.js', + 'js/jquery.lazy.min.js', 'js/script.js', ]; public $depends = [ diff --git a/frontend/views/catalog/_product_list.php b/frontend/views/catalog/_product_list.php index 35eadff..cf8010c 100755 --- a/frontend/views/catalog/_product_list.php +++ b/frontend/views/catalog/_product_list.php @@ -21,9 +21,9 @@ use yii\widgets\ListView; 'product' => $model->alias, 'variant' => $model->variant->sku, ])?>"> -
+ getImageUrl(), 'product_list_item', ['class' => 'picture']); + ?>
name; ?>
variant->sku; ?>
diff --git a/frontend/views/category/collection.php b/frontend/views/category/collection.php index 732c2c4..a71e727 100755 --- a/frontend/views/category/collection.php +++ b/frontend/views/category/collection.php @@ -53,9 +53,7 @@ $this->params['breadcrumbs'][] = $this->title; 'product' => $product->alias, 'variant' => $product->variant->sku, ]); ?>" alt="nabuco"> -
name; ?>variant->sku; - ?>
+
name; ?>
getImageUrl(), 'collections_thumb');?> diff --git a/frontend/views/category/index.php b/frontend/views/category/index.php index 08cbbdf..edaadee 100755 --- a/frontend/views/category/index.php +++ b/frontend/views/category/index.php @@ -9,6 +9,7 @@ use yii\widgets\ListView; * @var ActiveDataProvider $dataProvider * @var View $this */ + $this->params[ 'seo' ][ 'title' ] = !empty($category->meta_title) ? $category->meta_title : $category->name; $this->title = $category->name; $this->params[ 'breadcrumbs' ][] = $this->title; diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php index 9b5d81c..62b6df1 100755 --- a/frontend/views/layouts/main.php +++ b/frontend/views/layouts/main.php @@ -9,6 +9,7 @@ use common\models\Page; use common\modules\product\models\Category; + use common\widgets\Seo; use frontend\assets\AppAsset; use yii\helpers\Html; use yii\helpers\Url; @@ -54,7 +55,17 @@ - <?= Html::encode($this->title); ?> + <?php echo Seo::widget([ + 'row' => Seo::TITLE, + ]); ?> + Seo::DESCRIPTION, + ]); + echo Seo::widget([ + 'row' => Seo::META, + ]); + ?> head(); ?> diff --git a/frontend/web/js/jquery.lazy.min.js b/frontend/web/js/jquery.lazy.min.js new file mode 100644 index 0000000..aa71f14 --- /dev/null +++ b/frontend/web/js/jquery.lazy.min.js @@ -0,0 +1,2 @@ +/*! jQuery & Zepto Lazy v1.7.3 - http://jquery.eisbehr.de/lazy - MIT&GPL-2.0 license - Copyright 2012-2016 Daniel 'Eisbehr' Kern */ +!function(t,e){"use strict";function r(r,a,i,l,u){function c(){L=t.devicePixelRatio>1,f(i),a.delay>=0&&setTimeout(function(){s(!0)},a.delay),(a.delay<0||a.combined)&&(l.e=v(a.throttle,function(t){"resize"===t.type&&(w=B=-1),s(t.all)}),l.a=function(t){f(t),i.push.apply(i,t)},l.g=function(){return i=n(i).filter(function(){return!n(this).data(a.loadedName)})},s(),n(a.appendScroll).on("scroll."+u+" resize."+u,l.e))}function f(t){var i=a.defaultImage,o=a.placeholder,l=a.imageBase,u=a.srcsetAttribute,c=a.loaderAttribute,f=a._f||{};t=n(t).filter(function(){var t=n(this),r=b(this);return!t.data(a.handledName)&&(t.attr(a.attribute)||t.attr(u)||t.attr(c)||f[r]!==e)}).data("plugin_"+a.name,r);for(var s=0,d=t.length;se.top&&-ne.left&&-n=0?w:w=n(t).width()}function h(){return B>=0?B:B=n(t).height()}function b(t){return t.tagName.toLowerCase()}function g(t,e){if(e){var r=t.split(",");t="";for(var a=0,n=r.length;at||!a.enableThrottle||l?u():n=setTimeout(u,t-c)}}function p(){--z,i.length||z||y("onFinishedAll")}function y(t,e,n){return!!(t=a[t])&&(t.apply(r,[].slice.call(arguments,1)),!0)}var z=0,w=-1,B=-1,L=!1,T="afterLoad",D="load",I="error",N="img",E="src",F="srcset",C="sizes",O="background-image";"event"==a.bind||o?c():n(t).on(D+"."+u,c)}function a(a,o){var l=this,u=n.extend({},l.config,o),c={},f=u.name+"-"+ ++i;return l.config=function(t,r){return r===e?u[t]:(u[t]=r,l)},l.addItems=function(t){return c.a&&c.a("string"===n.type(t)?n(t):t),l},l.getItems=function(){return c.g?c.g():{}},l.update=function(t){return c.e&&c.e({},!t),l},l.loadAll=function(){return c.e&&c.e({all:!0},!0),l},l.destroy=function(){return n(u.appendScroll).off("."+f,c.e),n(t).off("."+f),c={},e},r(l,u,a,c,f),u.chainable?a:l}var n=t.jQuery||t.Zepto,i=0,o=!1;n.fn.Lazy=n.fn.lazy=function(t){return new a(this,t)},n.Lazy=n.lazy=function(t,r,i){if(n.isFunction(r)&&(i=r,r=[]),n.isFunction(i)){t=n.isArray(t)?t:[t],r=n.isArray(r)?r:[r];for(var o=a.prototype.config,l=o._f||(o._f={}),u=0,c=t.length;u