Commit 0b45a9660a8f9083082cdc554bbb9ba69e854bdc

Authored by Eugeny Galkovskiy
2 parents 6e2c38b4 e7bfe165

Merge remote-tracking branch 'origin/master'

backend/components/Sitemap.php 0 → 100755
  1 +<?php
  2 +
  3 + namespace backend\components;
  4 +
  5 + use artbox\catalog\helpers\FilterHelper;
  6 + use artbox\catalog\models\Brand;
  7 + use artbox\catalog\models\Category;
  8 + use artbox\catalog\models\ProductOptionExcl;
  9 + use artbox\catalog\models\VariantOptionExcl;
  10 + use artbox\core\models\Alias;
  11 + use artbox\core\models\Page;
  12 + use artbox\core\models\SitemapStatic;
  13 + use artbox\weblog\models\Article;
  14 + use common\models\Product;
  15 + use common\models\VariantOptionGroupExcl;
  16 + use yii\base\Object;
  17 + use yii\db\Query;
  18 + use yii\helpers\Html;
  19 + use yii\helpers\Url;
  20 + use yii\web\UrlManager;
  21 +
  22 + class Sitemap extends Object
  23 + {
  24 + public $entities = [];
  25 + public $path = '@frontend/web/sitemap.xml';
  26 + public $url = 'sitemap.xml';
  27 +
  28 + /**
  29 + * Get absolute url to sitemap.xml
  30 + *
  31 + * @return string
  32 + */
  33 + public function getUrl(): string
  34 + {
  35 + /**
  36 + * @var UrlManager $urlManager
  37 + */
  38 + $urlManager = \Yii::$app->get('urlManagerFrontend');
  39 + return $urlManager->createAbsoluteUrl('/' . $this->url);
  40 + }
  41 +
  42 + /**
  43 + * Check whether sitemap.xml exist
  44 + *
  45 + * @return bool
  46 + */
  47 + public function checkFileExist(): bool
  48 + {
  49 + return file_exists(\Yii::getAlias($this->path));
  50 + }
  51 + /**
  52 + * Generate sitemap XML in $path
  53 + *
  54 + * @return bool
  55 + */
  56 + public function generateXML(): bool
  57 + {
  58 + return $this->saveXML($this->generateOneShot());
  59 + }
  60 +
  61 + /**
  62 + * Save generated xml to $path file
  63 + *
  64 + * @param string $xml
  65 + *
  66 + * @return bool
  67 + */
  68 + protected function saveXML(string $xml): bool
  69 + {
  70 + $realpath = \Yii::getAlias($this->path);
  71 + if (file_put_contents($realpath, $xml)) {
  72 + return true;
  73 + } else {
  74 + return false;
  75 + }
  76 + }
  77 +
  78 + /**
  79 + * Generate xml from configs
  80 + *
  81 + * @return string
  82 + */
  83 + public function generateOneShot(): string
  84 + {
  85 + /**
  86 + * @var UrlManager $urlManager
  87 + */
  88 + $urlManager = \Yii::$app->get('urlManagerFrontend');
  89 + $content = '<?xml version="1.0" encoding="UTF-8"?>';
  90 + $content .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" >';
  91 + /**
  92 + * @var SitemapStatic[] $static
  93 + */
  94 +
  95 + /**
  96 + * Main page
  97 + */
  98 + $content .= Html::tag(
  99 + 'url',
  100 + Html::tag('loc', Url::to("/", true)) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
  101 + 'changefreq',
  102 + 'Always'
  103 + ) . Html::tag('priority', 1)
  104 + ) . PHP_EOL;
  105 +
  106 + /**
  107 + * Products
  108 + */
  109 + $products = Product::find()
  110 + ->joinWith(
  111 + [
  112 + 'lang.alias',
  113 + 'image',
  114 + 'variant',
  115 + ]
  116 + )
  117 + ->innerJoinWith('category')
  118 + ->where(
  119 + [
  120 + '!=',
  121 + 'variant.price',
  122 + 0,
  123 + ]
  124 + )
  125 + ->where(
  126 + [
  127 + '!=',
  128 + 'variant.stock',
  129 + 0,
  130 + ]
  131 + )
  132 + ->asArray()
  133 + ->all();
  134 + foreach ($products as $key => $item) {
  135 + /**
  136 + * @var \common\models\Product $item
  137 + */
  138 + $content .= Html::tag(
  139 + 'url',
  140 + Html::tag('loc', Url::to($item[ 'lang' ][ 'alias' ][ 'value' ], true)) . Html::tag(
  141 + 'lastmod',
  142 + date('Y-m-d')
  143 + ) . Html::tag(
  144 + 'changefreq',
  145 + 'Weekly'
  146 + ) . ( !empty($item[ 'image' ]) ? Html::tag(
  147 + 'image:image',
  148 + Html::tag(
  149 + 'image:loc',
  150 + Url::to(
  151 + "/",
  152 + true
  153 + ) . 'storage/' . $item[ 'image' ][ 'id' ] . '_' . $item[ 'image' ][ 'fileHash' ] . '.' . pathinfo(
  154 + $item[ 'image' ][ 'fileName' ],
  155 + PATHINFO_EXTENSION
  156 + )
  157 + )
  158 + ) : '' ) . Html::tag('priority', 0.6)
  159 + ) . PHP_EOL;
  160 + }
  161 +
  162 + unset($products);
  163 +
  164 + /**
  165 + * Pages
  166 + */
  167 + $pages = Page::find()
  168 + ->where([ 'in_menu' => true ])
  169 + ->with('lang.alias')
  170 + ->asArray()
  171 + ->all();
  172 + foreach ($pages as $key => $item) {
  173 + $content .= Html::tag(
  174 + 'url',
  175 + Html::tag('loc', Url::to($item[ 'lang' ][ 'alias' ][ 'value' ], true)) . Html::tag(
  176 + 'lastmod',
  177 + date('Y-m-d')
  178 + ) . Html::tag(
  179 + 'changefreq',
  180 + 'Weekly'
  181 + ) . Html::tag('priority', 0.6)
  182 + ) . PHP_EOL;
  183 + }
  184 +
  185 + unset($pages);
  186 +
  187 + /**
  188 + * Blog articles
  189 + */
  190 + // $blog = Alias::find()->where(['entity' => 'artbox\weblog\models\CategoryLang'])->orWhere(['entity' => 'artbox\weblog\models\TagLang'])->orWhere(['entity'=> 'artbox\weblog\models\ArticleLang'])->all();
  191 + // foreach ($blog as $key => $item){
  192 + // $content .= Html::tag(
  193 + // 'url',
  194 + // Html::tag('loc', Url::to((($item->entity == 'artbox\weblog\models\ArticleLang')? 'articles/' : '').$item->value, true)) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
  195 + // 'changefreq',
  196 + // 'Weekly'
  197 + // ) . Html::tag('priority', ($item->entity == 'artbox\weblog\models\ArticleLang') ? 0.7 : 0.6)
  198 + // );
  199 + // }
  200 +
  201 + $articles = Article::find()
  202 + ->where([ 'status' => true ])
  203 + ->with('lang.alias')
  204 + ->asArray()
  205 + ->all();
  206 + foreach ($articles as $article) {
  207 + /**
  208 + * @var Article $article
  209 + */
  210 + $content .= Html::tag(
  211 + 'url',
  212 + Html::tag(
  213 + 'loc',
  214 + Url::to('articles/' . $article[ 'lang' ][ 'alias' ][ 'value' ], true)
  215 + ) . Html::tag(
  216 + 'lastmod',
  217 + date('Y-m-d')
  218 + ) . Html::tag(
  219 + 'changefreq',
  220 + 'Weekly'
  221 + ) . Html::tag('priority', 0.5)
  222 + ) . PHP_EOL;
  223 + }
  224 +
  225 + unset($articles);
  226 +
  227 + /**
  228 + * Filters
  229 + */
  230 + $open_filters = Alias::find()
  231 + ->where([ 'entity' => 'artbox\catalog\models\Filter' ])
  232 + ->asArray()
  233 + ->all();
  234 + foreach ($open_filters as $key => $item) {
  235 + $content .= Html::tag(
  236 + 'url',
  237 + Html::tag('loc', Url::to($item[ 'value' ], true)) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
  238 + 'changefreq',
  239 + 'daily'
  240 + ) . Html::tag('priority', 0.8)
  241 + ) . PHP_EOL;
  242 + }
  243 +
  244 + /**
  245 + * Brands
  246 + */
  247 +
  248 + $brands = Brand::find()
  249 + ->where([ 'status' => 1 ])
  250 + ->with(
  251 + [
  252 + 'image',
  253 + 'lang.alias',
  254 + ]
  255 + )
  256 + ->asArray()
  257 + ->all();
  258 + foreach ($brands as $item) {
  259 + $content .= Html::tag(
  260 + 'url',
  261 + Html::tag('loc', Url::to($item[ 'lang' ][ 'alias' ][ 'value' ], true)) . Html::tag(
  262 + 'lastmod',
  263 + date('Y-m-d')
  264 + ) . Html::tag(
  265 + 'changefreq',
  266 + 'Daily'
  267 + ) . ( !empty($item[ 'image' ]) ? Html::tag(
  268 + 'image:image',
  269 + Html::tag(
  270 + 'image:loc',
  271 + Url::to(
  272 + "/",
  273 + true
  274 + ) . 'storage/' . $item[ 'image' ][ 'id' ] . '_' . $item[ 'image' ][ 'fileHash' ] . '.' . pathinfo(
  275 + $item[ 'image' ][ 'fileName' ],
  276 + PATHINFO_EXTENSION
  277 + )
  278 + )
  279 + ) : '' ) . Html::tag('priority', 0.7)
  280 + ) . PHP_EOL;
  281 + }
  282 + unset($brands);
  283 + /**
  284 + * category level 1
  285 + */
  286 + $category = Category::find()
  287 + ->with([ 'lang.alias' ])
  288 + ->join('INNER JOIN', [ 'c' => 'category' ], 'c.parent_id = category.id')
  289 + ->andWhere([ 'category.level' => 1 ])
  290 + ->asArray()
  291 + ->all();
  292 + foreach ($category as $key => $item) {
  293 + $content .= Html::tag(
  294 + 'url',
  295 + Html::tag(
  296 + 'loc',
  297 + Url::to('category/' . $item[ 'lang' ][ 'alias' ][ 'value' ], true)
  298 + ) . Html::tag(
  299 + 'lastmod',
  300 + date('Y-m-d')
  301 + ) . Html::tag(
  302 + 'changefreq',
  303 + 'Daily'
  304 + ) . Html::tag('priority', 0.9)
  305 + ) . PHP_EOL;
  306 +
  307 + }
  308 + unset($category);
  309 + /**
  310 + * Other filters
  311 + *
  312 + * @var FilterHelper $filterHelper
  313 + */
  314 + $filterHelper = \Yii::$app->get('filter');
  315 +
  316 + $category = Category::find()
  317 + ->with(
  318 + [
  319 + 'lang.alias',
  320 + 'categories',
  321 + ]
  322 + )
  323 + ->where(
  324 + [
  325 + 'level' => 2,
  326 + ]
  327 + )
  328 + ->orWhere([ 'level' => 1 ])
  329 + ->asArray()
  330 + ->all();
  331 +
  332 + $rewritedFilters = $filterHelper->filterObj->getReplacedFilters();
  333 + foreach ($category as $key => $item) {
  334 + if ($item[ 'level' ] == 2 or ( count($item[ 'categories' ]) == 0 and $item[ 'level' ] == 1 )) {
  335 + $content .= Html::tag(
  336 + 'url',
  337 + Html::tag(
  338 + 'loc',
  339 + Url::to('catalog/' . $item[ 'lang' ][ 'alias' ][ 'value' ], true)
  340 + ) . Html::tag(
  341 + 'lastmod',
  342 + date('Y-m-d')
  343 + ) . Html::tag(
  344 + 'changefreq',
  345 + 'Daily'
  346 + ) . Html::tag('priority', 0.9)
  347 + ) . PHP_EOL;
  348 + } else {
  349 + continue;
  350 + }
  351 + $category_id = $item[ 'id' ];
  352 + $option_ids = ( new Query() )->select('product_option_excl.id')
  353 + ->from('product_option_excl')
  354 + ->innerJoin(
  355 + 'product_option_group_excl',
  356 + 'product_option_excl.product_option_group_excl_id = product_option_group_excl.id'
  357 + )
  358 + ->innerJoin(
  359 + 'product_option_group_excl_to_category',
  360 + 'product_option_group_excl.id = product_option_group_excl_to_category.product_option_group_excl_id'
  361 + )
  362 + ->where(
  363 + [ 'product_option_group_excl_to_category.category_id' => $category_id ]
  364 + )
  365 + ->andWhere([ 'product_option_group_excl_to_category.is_filter' => true ])
  366 + ->andWhere(
  367 + [
  368 + 'product_option_excl.id' => ( new Query() )->select(
  369 + 'product_to_product_option_excl.product_option_excl_id'
  370 + )
  371 + ->from(
  372 + 'product_to_product_option_excl'
  373 + )
  374 + ->innerJoin(
  375 + 'product',
  376 + 'product_to_product_option_excl.product_id = product.id'
  377 + )
  378 + ->innerJoin(
  379 + 'product_to_category',
  380 + 'product.id = product_to_category.product_id'
  381 + )
  382 + ->where(
  383 + [ 'product_to_category.category_id' => $category_id ]
  384 + ),
  385 + ]
  386 + )
  387 + ->column();
  388 +
  389 + $options = ProductOptionExcl::find()
  390 + ->with('lang.alias')
  391 + ->with('group.lang.alias')
  392 + ->where([ 'id' => $option_ids ])
  393 + ->asArray()
  394 + ->all();
  395 +
  396 + foreach ($options as $option) {
  397 + if (strpos($option[ 'group' ][ 'lang' ][ 'alias' ][ 'robots' ], 'noindex') !== false) {
  398 + continue;
  399 + }
  400 + $link = 'catalog/' . $item[ 'lang' ][ 'alias' ][ 'value' ] . '/' . $option[ 'lang' ][ 'alias' ][ 'value' ];
  401 + if (array_key_exists('/' . $link, $rewritedFilters)) {
  402 + continue;
  403 + }
  404 + $content .= Html::tag(
  405 + 'url',
  406 + Html::tag(
  407 + 'loc',
  408 + Url::to(
  409 + $link,
  410 + true
  411 + )
  412 + ) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
  413 + 'changefreq',
  414 + 'Daily'
  415 + ) . Html::tag('priority', 0.8)
  416 + ) . PHP_EOL;
  417 + }
  418 +
  419 + // VARIANTS
  420 + $option_ids = ( new Query() )->select('variant_option_excl.id')
  421 + ->from('variant_option_excl')
  422 + ->innerJoin(
  423 + 'variant_option_group_excl',
  424 + 'variant_option_excl.variant_option_group_excl_id = variant_option_group_excl.id'
  425 + )
  426 + ->innerJoin(
  427 + 'variant_option_group_excl_to_category',
  428 + 'variant_option_group_excl.id = variant_option_group_excl_to_category.variant_option_group_excl_id'
  429 + )
  430 + ->where(
  431 + [ 'variant_option_group_excl_to_category.category_id' => $category_id ]
  432 + )
  433 + ->andWhere([ 'variant_option_group_excl_to_category.is_filter' => true ])
  434 + ->andWhere(
  435 + [
  436 + 'variant_option_excl.id' => ( new Query() )->select(
  437 + 'variant_to_variant_option_excl.variant_option_excl_id'
  438 + )
  439 + ->from(
  440 + 'variant_to_variant_option_excl'
  441 + )
  442 + ->innerJoin(
  443 + 'variant',
  444 + 'variant_to_variant_option_excl.variant_id = variant.id'
  445 + )
  446 + ->innerJoin(
  447 + 'product_to_category',
  448 + 'variant.product_id = product_to_category.product_id'
  449 + )
  450 + ->where(
  451 + [ 'product_to_category.category_id' => $category_id ]
  452 + ),
  453 + ]
  454 + )
  455 + ->column();
  456 +
  457 + $options = VariantOptionExcl::find()
  458 + ->with('lang.alias')
  459 + ->with('group.lang.alias')
  460 + ->where([ 'id' => $option_ids ])
  461 + ->asArray()
  462 + ->all();
  463 +
  464 + foreach ($options as $option) {
  465 + if (strpos($option[ 'group' ][ 'lang' ][ 'alias' ][ 'robots' ], 'noindex') !== false) {
  466 + continue;
  467 + }
  468 + $link = 'catalog/' . $item[ 'lang' ][ 'alias' ][ 'value' ] . '/' . $option[ 'lang' ][ 'alias' ][ 'value' ];
  469 + if (array_key_exists('/' . $link, $rewritedFilters)) {
  470 + continue;
  471 + }
  472 + $content .= Html::tag(
  473 + 'url',
  474 + Html::tag(
  475 + 'loc',
  476 + Url::to(
  477 + $link,
  478 + true
  479 + )
  480 + ) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
  481 + 'changefreq',
  482 + 'Daily'
  483 + ) . Html::tag('priority', 0.8)
  484 + ) . PHP_EOL;
  485 + }
  486 +
  487 +
  488 +
  489 +
  490 +
  491 +
  492 + $brands_ids = ( new Query() )->select('brand.id')
  493 + ->from('brand')
  494 + ->innerJoin('product', 'product.brand_id = brand.id')
  495 + ->innerJoin(
  496 + 'product_to_category',
  497 + 'product.id = product_to_category.product_id'
  498 + )
  499 + ->andWhere([ 'product_to_category.category_id' => $item[ 'id' ] ])
  500 + ->groupBy('brand.id')
  501 + ->column();
  502 +
  503 + $brands = Brand::find()
  504 + ->with([ 'lang.alias' ])
  505 + ->where([ 'status' => true ])
  506 + ->andWhere([ 'id' => $brands_ids ])
  507 + ->asArray()
  508 + ->all();
  509 +
  510 + foreach ($brands as $brand) {
  511 + $link = 'catalog/' . $item[ 'lang' ][ 'alias' ][ 'value' ] . '/' . $brand[ 'lang' ][ 'alias' ][ 'value' ];
  512 + $content .= Html::tag(
  513 + 'url',
  514 + Html::tag(
  515 + 'loc',
  516 + Url::to(
  517 + $link,
  518 + true
  519 + )
  520 + ) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
  521 + 'changefreq',
  522 + 'Daily'
  523 + ) . Html::tag('priority', 0.8)
  524 + ) . PHP_EOL;
  525 + }
  526 +
  527 + }
  528 + $content .= '</urlset>';
  529 + return $content;
  530 + }
  531 +
  532 + }
0 533 \ No newline at end of file
... ...
backend/config/main.php
... ... @@ -25,8 +25,7 @@
25 25 'page-category' => 'artbox\core\controllers\PageCategoryController',
26 26 'alias' => 'artbox\core\seo\controllers\AliasController',
27 27 'seo' => 'artbox\core\controllers\SeoController',
28   - 'feedback' => 'artbox\core\controllers\FeedbackController',
29   - 'blog' => 'artbox\weblog\controllers\ArticleController',
  28 + 'blog' => 'backend\controllers\ArticleController',
30 29 'blog-category' => 'artbox\weblog\controllers\CategoryController',
31 30 'blog-tag' => 'artbox\weblog\controllers\TagController',
32 31 'comment' => 'artbox\webcomment\controllers\ManageController',
... ...
backend/controllers/ArticleController.php 0 → 100755
  1 +<?php
  2 +
  3 + namespace backend\controllers;
  4 +
  5 + use artbox\weblog\models\Category;
  6 + use artbox\weblog\models\Tag;
  7 + use Yii;
  8 + use common\models\Article;
  9 + use common\models\ArticleSearch;
  10 + use yii\helpers\ArrayHelper;
  11 + use yii\web\Controller;
  12 + use yii\web\NotFoundHttpException;
  13 + use yii\filters\VerbFilter;
  14 + use yii\web\Response;
  15 + use yii\filters\AccessControl;
  16 +
  17 + /**
  18 + * BlogArticleController implements the CRUD actions for BlogArticle model.
  19 + */
  20 + class ArticleController extends Controller
  21 + {
  22 + /**
  23 + * @inheritdoc
  24 + */
  25 + public function getViewPath()
  26 + {
  27 + return '@backend/views/blog-article';
  28 + }
  29 +
  30 + /**
  31 + * @inheritdoc
  32 + */
  33 + public function behaviors()
  34 + {
  35 + return [
  36 + 'verbs' => [
  37 + 'class' => VerbFilter::className(),
  38 + 'actions' => [
  39 + 'delete' => [ 'POST' ],
  40 + ],
  41 + ],
  42 + 'access' => [
  43 + 'class' => AccessControl::className(),
  44 + 'rules' => [
  45 + [
  46 + 'actions' => [
  47 + 'login',
  48 + 'error',
  49 + ],
  50 + 'allow' => true,
  51 + ],
  52 + [
  53 + 'allow' => true,
  54 + 'roles' => [ '@' ],
  55 + ],
  56 + ],
  57 + ],
  58 + ];
  59 + }
  60 +
  61 + /**
  62 + * Lists all BlogArticle models.
  63 + *
  64 + * @return mixed
  65 + */
  66 + public function actionIndex()
  67 + {
  68 + $searchModel = new ArticleSearch();
  69 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  70 +
  71 + return $this->render(
  72 + 'index',
  73 + [
  74 + 'searchModel' => $searchModel,
  75 + 'dataProvider' => $dataProvider,
  76 + ]
  77 + );
  78 + }
  79 +
  80 + /**
  81 + * Displays a single BlogArticle model.
  82 + *
  83 + * @param integer $id
  84 + *
  85 + * @return mixed
  86 + */
  87 + public function actionView($id)
  88 + {
  89 + return $this->render(
  90 + 'view',
  91 + [
  92 + 'model' => $this->findModel($id),
  93 + ]
  94 + );
  95 + }
  96 +
  97 + /**
  98 + * Creates a new BlogArticle model.
  99 + * If creation is successful, the browser will be redirected to the 'view' page.
  100 + *
  101 + * @return mixed
  102 + */
  103 + public function actionCreate()
  104 + {
  105 + $model = new Article();
  106 + $model->generateLangs();
  107 +
  108 + if (class_exists('\artbox\catalog\models\Product')) {
  109 + $model->productIds = ArrayHelper::map(
  110 + $model->relatedProducts,
  111 + 'id',
  112 + 'lang.title'
  113 + );
  114 + }
  115 +
  116 + if ($model->loadWithLangs(\Yii::$app->request) && $model->saveWithLangs()) {
  117 +
  118 + $categories = Category::find()
  119 + ->where([ 'id' => \Yii::$app->request->post('categoryIds') ])
  120 + ->all();
  121 +
  122 + if (class_exists('\artbox\catalog\models\Product')) {
  123 + /**
  124 + * @var \yii\db\ActiveQuery $query
  125 + */
  126 + $query = call_user_func(
  127 + [
  128 + '\artbox\catalog\models\Product',
  129 + 'find',
  130 + ]
  131 + );
  132 + /**
  133 + * @var \artbox\catalog\models\Product[] $products
  134 + */
  135 + $products = $query->where([ 'id' => \Yii::$app->request->post('productIds') ])
  136 + ->all();
  137 +
  138 + $model->linkMany('relatedProducts', $products);
  139 + }
  140 +
  141 +
  142 + $model->linkMany('categories', $categories);
  143 +
  144 + $tags = Tag::find()
  145 + ->where(
  146 + [
  147 + 'id' => \Yii::$app->request->post('tagIds'),
  148 + ]
  149 + )
  150 + ->all();
  151 +
  152 + $model->linkMany('tags', $tags);
  153 +
  154 + return $this->redirect(
  155 + [
  156 + 'view',
  157 + 'id' => $model->id,
  158 + ]
  159 + );
  160 + }
  161 +
  162 + return $this->render(
  163 + 'create',
  164 + [
  165 + 'model' => $model,
  166 + 'modelLangs' => $model->modelLangs,
  167 + ]
  168 + );
  169 +
  170 + }
  171 +
  172 + /**
  173 + * Updates an existing BlogArticle model.
  174 + * If update is successful, the browser will be redirected to the 'view' page.
  175 + *
  176 + * @param integer $id
  177 + *
  178 + * @return mixed
  179 + */
  180 + public function actionUpdate($id)
  181 + {
  182 + $model = $this->findModel($id);
  183 + $model->generateLangs();
  184 +
  185 + $model->categoryIds = ArrayHelper::map(
  186 + $model->categories,
  187 + 'id',
  188 + 'lang.title'
  189 + );
  190 +
  191 + $model->tagIds = ArrayHelper::map(
  192 + $model->tags,
  193 + 'id',
  194 + 'lang.label'
  195 + );
  196 +
  197 + $model->articleIds = ArrayHelper::map(
  198 + $model->articles,
  199 + 'id',
  200 + 'lang.title'
  201 + );
  202 +
  203 + if (class_exists('\artbox\catalog\models\Product')) {
  204 + $model->productIds = ArrayHelper::map(
  205 + $model->relatedProducts,
  206 + 'id',
  207 + 'lang.title'
  208 + );
  209 + }
  210 +
  211 + if ($model->loadWithLangs(\Yii::$app->request) && $model->saveWithLangs()) {
  212 + $categories = Category::find()
  213 + ->where([ 'id' => \Yii::$app->request->post('categoryIds') ])
  214 + ->all();
  215 +
  216 + $model->linkMany('categories', $categories);
  217 +
  218 + $tags = Tag::find()
  219 + ->where(
  220 + [
  221 + 'id' => \Yii::$app->request->post('tagIds'),
  222 + ]
  223 + )
  224 + ->all();
  225 +
  226 + $model->linkMany('tags', $tags);
  227 +
  228 + if (class_exists('\artbox\catalog\models\Product')) {
  229 + /**
  230 + * @var \yii\db\ActiveQuery $query
  231 + */
  232 + $query = call_user_func(
  233 + [
  234 + '\artbox\catalog\models\Product',
  235 + 'find',
  236 + ]
  237 + );
  238 + /**
  239 + * @var \artbox\catalog\models\Product[] $products
  240 + */
  241 + $products = $query->where([ 'id' => \Yii::$app->request->post('productIds') ])
  242 + ->all();
  243 +
  244 + $model->linkMany('relatedProducts', $products);
  245 + }
  246 +
  247 + return $this->redirect(
  248 + [
  249 + 'view',
  250 + 'id' => $model->id,
  251 + ]
  252 + );
  253 +
  254 + }
  255 + return $this->render(
  256 + 'update',
  257 + [
  258 + 'model' => $model,
  259 + 'modelLangs' => $model->modelLangs,
  260 + ]
  261 + );
  262 +
  263 + }
  264 +
  265 + /**
  266 + * Deletes an existing BlogArticle model.
  267 + * If deletion is successful, the browser will be redirected to the 'index' page.
  268 + *
  269 + * @param integer $id
  270 + *
  271 + * @return mixed
  272 + */
  273 + public function actionDelete($id)
  274 + {
  275 + $this->findModel($id)
  276 + ->delete();
  277 +
  278 + return $this->redirect([ 'index' ]);
  279 + }
  280 +
  281 + /**
  282 + * Finds the BlogArticle model based on its primary key value.
  283 + * If the model is not found, a 404 HTTP exception will be thrown.
  284 + *
  285 + * @param integer $id
  286 + *
  287 + * @return Article the loaded model
  288 + * @throws NotFoundHttpException if the model cannot be found
  289 + */
  290 + protected function findModel($id)
  291 + {
  292 + if (( $model = Article::findOne($id) ) !== null) {
  293 + return $model;
  294 + } else {
  295 + throw new NotFoundHttpException('The requested page does not exist.');
  296 + }
  297 + }
  298 +
  299 + /**
  300 + * @param string $q
  301 + * @param integer $id
  302 + *
  303 + * @return array
  304 + */
  305 + public function actionList(string $q = null, int $id = null)
  306 + {
  307 + \Yii::$app->response->format = Response::FORMAT_JSON;
  308 + $out = [
  309 + 'results' => [
  310 + 'id' => '',
  311 + 'text' => '',
  312 + ],
  313 + ];
  314 + if (!is_null($q)) {
  315 + $out[ 'results' ] = Article::find()
  316 + ->joinWith('lang')
  317 + ->select(
  318 + [
  319 + 'blog_article.id as id',
  320 + 'blog_article_lang.title as text',
  321 + ]
  322 + )
  323 + ->where(
  324 + [
  325 + 'like',
  326 + 'blog_article_lang.title',
  327 + $q,
  328 + ]
  329 + )
  330 + ->andFilterWhere(
  331 + [
  332 + '!=',
  333 + 'blog_article.id',
  334 + $id,
  335 + ]
  336 + )
  337 + ->limit(20)
  338 + ->asArray()
  339 + ->all();
  340 + }
  341 + return $out;
  342 + }
  343 + }
... ...
backend/controllers/FeedbackController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +
  5 +use Yii;
  6 +use common\models\Feedback;
  7 +use yii\data\ActiveDataProvider;
  8 +use yii\web\Controller;
  9 +use yii\web\NotFoundHttpException;
  10 +use yii\filters\VerbFilter;
  11 +use yii\filters\AccessControl;
  12 +use yii\web\Response;
  13 +use artbox\core\widgets\FeedbackWidget;
  14 +use yii\helpers\Html;
  15 +
  16 +/**
  17 + * FeedbackController implements the CRUD actions for Feedback model.
  18 + */
  19 +class FeedbackController extends Controller
  20 +{
  21 + /**
  22 + * @inheritdoc
  23 + */
  24 + public function behaviors()
  25 + {
  26 + return [
  27 + 'access' => [
  28 + 'class' => AccessControl::className(),
  29 + 'rules' => [
  30 + [
  31 + 'actions' => [
  32 + 'login',
  33 + 'error',
  34 + ],
  35 + 'allow' => true,
  36 + ],
  37 + [
  38 + 'allow' => true,
  39 + 'roles' => [ '@' ],
  40 + ],
  41 + ],
  42 + ],
  43 + 'verbs' => [
  44 + 'class' => VerbFilter::className(),
  45 + 'actions' => [
  46 + 'delete' => ['POST'],
  47 + ],
  48 + ],
  49 + ];
  50 + }
  51 +
  52 + /**
  53 + * Lists all Feedback models.
  54 + * @return mixed
  55 + */
  56 + public function actionIndex()
  57 + {
  58 + $dataProvider = new ActiveDataProvider(
  59 + [
  60 + 'query' => Feedback::find()->orderBy('created_at DESC'),
  61 + ]
  62 + );
  63 +
  64 + return $this->render(
  65 + 'index',
  66 + [
  67 + 'dataProvider' => $dataProvider,
  68 + ]
  69 + );
  70 + }
  71 +
  72 + /**
  73 + * Displays a single Feedback model.
  74 + * @param integer $id
  75 + * @return mixed
  76 + */
  77 + public function actionView($id)
  78 + {
  79 + $model = $this->findModel($id);
  80 +
  81 + $model->status = true;
  82 + $model->save(false, [ 'status' ]);
  83 +
  84 + return $this->render(
  85 + 'view',
  86 + [
  87 + 'model' => $model,
  88 + ]
  89 + );
  90 + }
  91 +
  92 + /**
  93 + * Creates a new Feedback model.
  94 + * If creation is successful, the browser will be redirected to the 'view' page.
  95 + * @return mixed
  96 + */
  97 + public function actionCreate()
  98 + {
  99 + $model = new Feedback();
  100 +
  101 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  102 + return $this->redirect(['view', 'id' => $model->id]);
  103 + } else {
  104 + return $this->render('create', [
  105 + 'model' => $model,
  106 + ]);
  107 + }
  108 + }
  109 +
  110 + /**
  111 + * Updates an existing Feedback model.
  112 + * If update is successful, the browser will be redirected to the 'view' page.
  113 + * @param integer $id
  114 + * @return mixed
  115 + */
  116 + public function actionUpdate($id)
  117 + {
  118 + $model = $this->findModel($id);
  119 +
  120 + $model->status = true;
  121 + $model->save(false, [ 'status' ]);
  122 +
  123 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  124 + return $this->redirect(['view', 'id' => $model->id]);
  125 + } else {
  126 + return $this->render('update', [
  127 + 'model' => $model,
  128 + ]);
  129 + }
  130 + }
  131 +
  132 + /**
  133 + * Deletes an existing Feedback model.
  134 + * If deletion is successful, the browser will be redirected to the 'index' page.
  135 + * @param integer $id
  136 + * @return mixed
  137 + */
  138 + public function actionDelete($id)
  139 + {
  140 + $this->findModel($id)->delete();
  141 +
  142 + return $this->redirect(['index']);
  143 + }
  144 +
  145 + /**
  146 + * Finds the Feedback model based on its primary key value.
  147 + * If the model is not found, a 404 HTTP exception will be thrown.
  148 + * @param integer $id
  149 + * @return Feedback the loaded model
  150 + * @throws NotFoundHttpException if the model cannot be found
  151 + */
  152 + protected function findModel($id)
  153 + {
  154 + if (($model = Feedback::findOne($id)) !== null) {
  155 + return $model;
  156 + } else {
  157 + throw new NotFoundHttpException('The requested page does not exist.');
  158 + }
  159 + }
  160 +
  161 + public function actionViewed($id)
  162 + {
  163 + if (Yii::$app->request->isPost) {
  164 + $model = $this->findModel($id);
  165 +
  166 + Yii::$app->response->format = Response::FORMAT_JSON;
  167 +
  168 + $model->status = true;
  169 + if ($model->save(false, [ 'status' ])) {
  170 +
  171 + $widget = FeedbackWidget::widget();
  172 +
  173 + return [
  174 + 'text' => Html::tag(
  175 + 'span',
  176 + '',
  177 + [
  178 + 'class' => 'glyphicon glyphicon-ok',
  179 + ]
  180 + ),
  181 + 'message' => [
  182 + 'title' => Yii::t('core', 'Notification') . ':',
  183 + 'text' => Yii::t('core', 'Status changed'),
  184 + ],
  185 + 'widget' => $widget,
  186 + ];
  187 + }
  188 + }
  189 + return [];
  190 + }
  191 +
  192 +}
... ...
backend/views/blog-article/_form.php 0 → 100755
  1 +<?php
  2 +
  3 + use artbox\core\components\imagemanager\components\ImageManagerInputWidget;
  4 + use artbox\weblog\models\Article;
  5 + use artbox\weblog\models\ArticleLang;
  6 + use artbox\weblog\models\Category;
  7 + use artbox\weblog\models\Tag;
  8 + use kartik\select2\Select2;
  9 + use yii\helpers\Html;
  10 + use yii\helpers\Url;
  11 + use yii\web\View;
  12 + use yii\widgets\ActiveForm;
  13 + use artbox\core\widgets\LanguageForm;
  14 + use yii\web\JsExpression;
  15 + use yii\widgets\InputWidget;
  16 +
  17 + /**
  18 + * @var View $this
  19 + * @var Article $model
  20 + * @var ActiveForm $form
  21 + * @var ArticleLang[] $modelLangs
  22 + * @var Category[] $categories
  23 + * @var Tag[] $tags
  24 + * @var array $products
  25 + * @var array $articles
  26 + */
  27 +?>
  28 +
  29 +<div class="blog-article-form">
  30 +
  31 + <?php $form = ActiveForm::begin(
  32 + [
  33 + 'options' => [ 'enctype' => 'multipart/form-data' ],
  34 + ]
  35 + ); ?>
  36 +
  37 + <?php
  38 + echo LanguageForm::widget(
  39 + [
  40 + 'modelLangs' => $modelLangs,
  41 + 'formView' => '@backend/views/blog-article/_form_language',
  42 + 'form' => $form,
  43 + ]
  44 + );
  45 + ?>
  46 +
  47 + <div class="form-group">
  48 + <label class="control-label"><?= \Yii::t('blog', 'Categories'); ?></label>
  49 + <?php
  50 + echo Select2::widget(
  51 + [
  52 + 'name' => 'categoryIds',
  53 + 'options' => [
  54 + 'placeholder' => \Yii::t('blog', 'Search for a categories ...'),
  55 + 'multiple' => true,
  56 +
  57 + ],
  58 +
  59 + 'value' => array_keys($model->categoryIds),
  60 + 'data' => $model->categoryIds,
  61 + 'toggleAllSettings' => [
  62 + 'selectLabel' => false,
  63 + ],
  64 + 'pluginOptions' => [
  65 + 'allowClear' => true,
  66 + 'minimumInputLength' => 3,
  67 + 'language' => [
  68 + 'errorLoading' => new JsExpression(
  69 + "function () { return 'Waiting for results...'; }"
  70 + ),
  71 + ],
  72 + 'ajax' => [
  73 + 'url' => Url::to([ '/blog-category/list' ]),
  74 + 'dataType' => 'json',
  75 + 'data' => new JsExpression(
  76 + 'function(params) {
  77 + return {
  78 + q:params.term
  79 + };
  80 + }'
  81 + ),
  82 + ],
  83 + 'escapeMarkup' => new JsExpression(
  84 + 'function (markup) {
  85 + return markup;
  86 + }'
  87 + ),
  88 + 'templateResult' => new JsExpression(
  89 + 'function (brand) {
  90 + return brand.text;
  91 + }'
  92 + ),
  93 + 'templateSelection' => new JsExpression(
  94 + 'function (brand) {
  95 + return brand.text;
  96 + }'
  97 + ),
  98 + ],
  99 + ]
  100 + );
  101 + ?>
  102 + </div>
  103 +
  104 + <div class="form-group">
  105 + <label class="control-label"><?= \Yii::t('blog', 'Tags'); ?></label>
  106 + <?php
  107 + echo Select2::widget(
  108 + [
  109 + 'name' => 'tagIds',
  110 + 'options' => [
  111 + 'placeholder' => \Yii::t('blog', 'Search for a tags ...'),
  112 + 'multiple' => true,
  113 + ],
  114 + 'toggleAllSettings' => [
  115 + 'selectLabel' => false,
  116 + ],
  117 + 'value' => array_keys($model->tagIds),
  118 + 'data' => $model->tagIds,
  119 + 'pluginOptions' => [
  120 + 'allowClear' => true,
  121 + 'minimumInputLength' => 3,
  122 + 'language' => [
  123 + 'errorLoading' => new JsExpression(
  124 + "function () { return 'Waiting for results...'; }"
  125 + ),
  126 + ],
  127 + 'ajax' => [
  128 + 'url' => Url::to([ '/blog-tag/list' ]),
  129 + 'dataType' => 'json',
  130 + 'data' => new JsExpression(
  131 + 'function(params) {
  132 + return {
  133 + q:params.term
  134 + };
  135 + }'
  136 + ),
  137 + ],
  138 + 'escapeMarkup' => new JsExpression(
  139 + 'function (markup) {
  140 + return markup;
  141 + }'
  142 + ),
  143 + 'templateResult' => new JsExpression(
  144 + 'function (brand) {
  145 + return brand.text;
  146 + }'
  147 + ),
  148 + 'templateSelection' => new JsExpression(
  149 + 'function (brand) {
  150 + return brand.text;
  151 + }'
  152 + ),
  153 + ],
  154 + ]
  155 + );
  156 + ?>
  157 + </div>
  158 +
  159 + <div class="form-group">
  160 + <label class="control-label"><?= \Yii::t('blog', 'Articles'); ?></label>
  161 + <?php
  162 + if ($model->isNewRecord) {
  163 + $condition = '';
  164 + } else {
  165 + $condition = ', id: ' . $model->id;
  166 + }
  167 + echo Select2::widget(
  168 + [
  169 + 'name' => 'articleIds',
  170 + 'options' => [
  171 + 'placeholder' => \Yii::t('blog', 'Search for an articles ...'),
  172 + 'multiple' => true,
  173 + ],
  174 + 'toggleAllSettings' => [
  175 + 'selectLabel' => false,
  176 + ],
  177 + 'value' => array_keys($model->articleIds),
  178 + 'data' => $model->articleIds,
  179 + 'pluginOptions' => [
  180 + 'allowClear' => true,
  181 + 'minimumInputLength' => 3,
  182 + 'language' => [
  183 + 'errorLoading' => new JsExpression(
  184 + "function () { return 'Waiting for results...'; }"
  185 + ),
  186 + ],
  187 + 'ajax' => [
  188 + 'url' => Url::to([ '/blog-article/list' ]),
  189 + 'dataType' => 'json',
  190 + 'data' => new JsExpression(
  191 + 'function(params) {
  192 + return {
  193 + q:params.term' . $condition . '
  194 + };
  195 + }'
  196 + ),
  197 + ],
  198 + 'escapeMarkup' => new JsExpression(
  199 + 'function (markup) {
  200 + return markup;
  201 + }'
  202 + ),
  203 + 'templateResult' => new JsExpression(
  204 + 'function (brand) {
  205 + return brand.text;
  206 + }'
  207 + ),
  208 + 'templateSelection' => new JsExpression(
  209 + 'function (brand) {
  210 + return brand.text;
  211 + }'
  212 + ),
  213 + ],
  214 + ]
  215 + );
  216 + ?>
  217 + </div>
  218 + <?php
  219 + if (class_exists('\artbox\catalog\models\Product')) {
  220 + ?>
  221 + <div class="form-group">
  222 + <label class="control-label"><?= \Yii::t('blog', 'Products'); ?></label>
  223 + <?php
  224 + echo Select2::widget(
  225 + [
  226 + 'name' => 'productIds',
  227 + 'options' => [
  228 + 'placeholder' => \Yii::t('blog', 'Search for products ...'),
  229 + 'multiple' => true,
  230 + ],
  231 + 'toggleAllSettings' => [
  232 + 'selectLabel' => false,
  233 + ],
  234 + 'value' => array_keys($model->productIds),
  235 + 'data' => $model->productIds,
  236 + 'pluginOptions' => [
  237 + 'allowClear' => true,
  238 + 'minimumInputLength' => 3,
  239 + 'language' => [
  240 + 'errorLoading' => new JsExpression(
  241 + "function () { return 'Waiting for results...'; }"
  242 + ),
  243 + ],
  244 + 'ajax' => [
  245 + 'url' => Url::to([ '/product/list' ]),
  246 + 'dataType' => 'json',
  247 + 'data' => new JsExpression(
  248 + 'function(params) {
  249 + return {
  250 + q:params.term
  251 + };
  252 + }'
  253 + ),
  254 + ],
  255 + 'escapeMarkup' => new JsExpression(
  256 + 'function (markup) {
  257 + return markup;
  258 + }'
  259 + ),
  260 + 'templateResult' => new JsExpression(
  261 + 'function (product) {
  262 + return product.text;
  263 + }'
  264 + ),
  265 + 'templateSelection' => new JsExpression(
  266 + 'function (product) {
  267 + return product.text;
  268 + }'
  269 + ),
  270 + ],
  271 + ]
  272 + );
  273 + ?>
  274 + </div>
  275 + <?php
  276 + }
  277 + ?>
  278 +
  279 + <?= $form->field($model, 'sort')
  280 + ->textInput() ?>
  281 +
  282 + <?= $form->field($model, 'status')
  283 + ->checkbox(
  284 + [
  285 + 'class' => 'flat',
  286 + ]
  287 + ) ?>
  288 +
  289 + <?= $form->field($model, 'author_id')
  290 + ->textInput() ?>
  291 +
  292 + <div class="form-group">
  293 + <?= Html::submitButton(
  294 + $model->isNewRecord ? 'Create' : 'Update',
  295 + [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ]
  296 + ) ?>
  297 + </div>
  298 +
  299 + <?php ActiveForm::end(); ?>
  300 +
  301 +</div>
... ...
backend/views/blog-article/_form_language.php 0 → 100755
  1 +<?php
  2 + use artbox\core\helpers\SlugifyDecorator;
  3 + use artbox\weblog\models\ArticleLang;
  4 + use artbox\core\models\Language;
  5 + use dosamigos\tinymce\TinyMce;
  6 + use yii\helpers\Url;
  7 + use yii\web\JsExpression;
  8 + use yii\web\View;
  9 + use artbox\core\components\imagemanager\components\ImageManagerInputWidget;
  10 +
  11 +
  12 +/**
  13 + * @var ArticleLang $model_lang
  14 + * @var Language $language
  15 + * @var ActiveForm $form
  16 + * @var View $this
  17 + */
  18 +?>
  19 +<?php
  20 + $attributeField = $form->field($model_lang, '[' . $language->id . ']title')
  21 + ->textInput([ 'maxlength' => true ]);
  22 + echo $attributeField;
  23 +?>
  24 +
  25 +<?= SlugifyDecorator::decorate(
  26 + $form->field($model_lang, '[' . $language->id . ']aliasValue'),
  27 + [ '/alias/slugify' ],
  28 + $attributeField,
  29 + false,
  30 + $language->id
  31 +)
  32 + ->textInput([ 'maxlength' => true ]); ?>
  33 +
  34 +<?= $form->field($model_lang, '[' . $language->id . ']body')
  35 + ->widget(
  36 + TinyMce::className(),
  37 + [
  38 + 'options' => [ 'rows' => 30 ],
  39 + 'language' => 'ru',
  40 + 'clientOptions' => [
  41 + 'file_browser_callback' => new JsExpression(
  42 + "function(field_name, url, type, win) {
  43 +window.open('" . Url::to(
  44 + [
  45 + 'imagemanager/manager',
  46 + 'view-mode' => 'iframe',
  47 + 'select-type' => 'tinymce',
  48 + ]
  49 + ) . "&tag_name='+field_name,'','width=800,height=540 ,toolbar=no,status=no,menubar=no,scrollbars=no,resizable=no');
  50 +}"
  51 + ),
  52 + 'plugins' => [
  53 + "advlist autolink lists link charmap print preview anchor",
  54 + "searchreplace visualblocks code fullscreen",
  55 + "insertdatetime media table contextmenu paste image",
  56 + ],
  57 + 'toolbar' => "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | code",
  58 + 'image_advtab' => true,
  59 + ],
  60 + ]
  61 + ); ?>
  62 +
  63 +<?= $form->field($model_lang, '[' . $language->id . ']body_preview')
  64 + ->textarea(
  65 + [
  66 + 'rows' => '10',
  67 + ]
  68 + ) ?>
  69 +<?= $form->field($model_lang, '[' . $language->id . ']image_id')
  70 + ->widget(
  71 + ImageManagerInputWidget::className(),
  72 + [
  73 + 'aspectRatio' => ( 16 / 9 ),
  74 + //set the aspect ratio
  75 + 'showPreview' => true,
  76 + //false to hide the preview
  77 + 'showDeletePickedImageConfirm' => false,
  78 + //on true show warning before detach image
  79 + ]
  80 + ); ?>
... ...
backend/views/blog-article/_search.php 0 → 100755
  1 +<?php
  2 +
  3 + use artbox\weblog\models\ArticleSearch;
  4 + use yii\helpers\Html;
  5 + use yii\widgets\ActiveForm;
  6 +
  7 + /* @var $this yii\web\View */
  8 + /* @var $model ArticleSearch */
  9 + /* @var $form yii\widgets\ActiveForm */
  10 +?>
  11 +
  12 +<div class="blog-article-search">
  13 +
  14 + <?php $form = ActiveForm::begin(
  15 + [
  16 + 'action' => [ 'index' ],
  17 + 'method' => 'get',
  18 + ]
  19 + ); ?>
  20 +
  21 + <?= $form->field($model, 'id') ?>
  22 +
  23 + <?= $form->field($model, 'image') ?>
  24 +
  25 + <?= $form->field($model, 'created_at') ?>
  26 +
  27 + <?= $form->field($model, 'updated_at') ?>
  28 +
  29 + <?= $form->field($model, 'deleted_at') ?>
  30 +
  31 + <?php // echo $form->field($model, 'sort') ?>
  32 +
  33 + <?php // echo $form->field($model, 'status')->checkbox() ?>
  34 +
  35 + <?php // echo $form->field($model, 'author_id') ?>
  36 +
  37 + <div class="form-group">
  38 + <?= Html::submitButton('Search', [ 'class' => 'btn btn-primary' ]) ?>
  39 + <?= Html::resetButton('Reset', [ 'class' => 'btn btn-default' ]) ?>
  40 + </div>
  41 +
  42 + <?php ActiveForm::end(); ?>
  43 +
  44 +</div>
... ...
backend/views/blog-article/create.php 0 → 100755
  1 +<?php
  2 +
  3 + use artbox\weblog\models\Article;
  4 + use artbox\weblog\models\ArticleLang;
  5 + use yii\web\View;
  6 + use yiister\gentelella\widgets\Panel;
  7 +
  8 + /**
  9 + * @var View $this
  10 + * @var Article $model
  11 + * @var ArticleLang[] $modelLangs
  12 + * @var array $products
  13 + * @var array $articles
  14 + */
  15 +
  16 + $this->title = \Yii::t('blog', 'Create Blog Article');
  17 + $this->params[ 'breadcrumbs' ][] = [
  18 + 'label' => \Yii::t('blog', 'Blog Articles'),
  19 + 'url' => [ 'index' ],
  20 + ];
  21 + $this->params[ 'breadcrumbs' ][] = $this->title;
  22 +?>
  23 +<div class="blog-article-create">
  24 +
  25 + <?php $panel = Panel::begin(
  26 + [
  27 + 'header' => $this->title,
  28 + ]
  29 + ); ?>
  30 +
  31 + <?= $this->render(
  32 + '_form',
  33 + [
  34 + 'model' => $model,
  35 + 'modelLangs' => $modelLangs,
  36 + ]
  37 + ) ?>
  38 +
  39 + <?php $panel::end(); ?>
  40 +
  41 +</div>
... ...
backend/views/blog-article/index.php 0 → 100755
  1 +<?php
  2 +
  3 + use common\models\Article;
  4 + use common\models\ArticleSearch;
  5 + use artbox\weblog\models\Category;
  6 + use artbox\weblog\models\Tag;
  7 + use yii\data\ActiveDataProvider;
  8 + use yii\helpers\ArrayHelper;
  9 + use yii\helpers\Html;
  10 + use yii\grid\GridView;
  11 + use yii\web\View;
  12 + use yiister\gentelella\widgets\Panel;
  13 +
  14 + /**
  15 + * @var View $this
  16 + * @var ArticleSearch $searchModel
  17 + * @var ActiveDataProvider $dataProvider
  18 + */
  19 +
  20 + $this->title = \Yii::t('blog', 'Blog Articles');
  21 + $this->params[ 'breadcrumbs' ][] = $this->title;
  22 +?>
  23 +<div class="blog-article-index">
  24 +
  25 + <?php $panel = Panel::begin(
  26 + [
  27 + 'header' => $this->title,
  28 + ]
  29 + ); ?>
  30 + <p>
  31 + <?= Html::a(
  32 + \Yii::t('app', 'create_item', [ 'item' => 'Blog Article' ]),
  33 + [ 'create' ],
  34 + [ 'class' => 'btn btn-success' ]
  35 + ) ?>
  36 + </p>
  37 + <?= GridView::widget(
  38 + [
  39 + 'dataProvider' => $dataProvider,
  40 + 'filterModel' => $searchModel,
  41 + 'columns' => [
  42 + 'id',
  43 + [
  44 + 'attribute' => 'title',
  45 + 'value' => 'lang.title',
  46 + ],
  47 + [
  48 + 'attribute' => 'category',
  49 + 'label' => \Yii::t('blog', 'Categories'),
  50 + 'value' => function (Article $model) {
  51 + if (empty($model->categories)) {
  52 + return \Yii::$app->formatter->asText(null);
  53 + } else {
  54 + return implode(
  55 + ',<br>',
  56 + ArrayHelper::getColumn(
  57 + $model->categories,
  58 + function (Category $category) {
  59 + return $category->lang->title;
  60 + }
  61 + )
  62 + );
  63 + }
  64 + },
  65 + 'format' => 'html',
  66 + ],
  67 + [
  68 + 'attribute' => 'tag',
  69 + 'label' => \Yii::t('blog', 'Tags'),
  70 + 'value' => function (Article $model) {
  71 + if (empty($model->tags)) {
  72 + return \Yii::$app->formatter->asText(null);
  73 + } else {
  74 + return implode(
  75 + ',<br>',
  76 + ArrayHelper::getColumn(
  77 + $model->tags,
  78 + function (Tag $tag) {
  79 + return $tag->lang->label;
  80 + }
  81 + )
  82 + );
  83 + }
  84 + },
  85 + 'format' => 'html',
  86 + ],
  87 + [
  88 + 'attribute' => 'image_id',
  89 + 'value' => function (Article $model) {
  90 + if (empty($model->image_id)) {
  91 + return '';
  92 + } else {
  93 + return $model->image->getImg(
  94 + [
  95 + 'width' => '300px',
  96 + ]
  97 + );
  98 + }
  99 + },
  100 + 'format' => 'html',
  101 + ],
  102 + [
  103 + 'attribute' => 'status',
  104 + 'value' => function (Article $model) {
  105 + return ( !$model->status ) ? \Yii::t('blog', 'Not active') : \Yii::t('blog', 'Active');
  106 + },
  107 + 'filter' => [
  108 + 0 => \Yii::t('blog', 'Not active'),
  109 + 1 => \Yii::t('blog', 'Active'),
  110 + ],
  111 + ],
  112 + 'created_at:date',
  113 + 'updated_at:date',
  114 + [ 'class' => 'yii\grid\ActionColumn' ],
  115 + ],
  116 + ]
  117 + ); ?>
  118 +
  119 + <?php $panel::end(); ?>
  120 +
  121 +</div>
... ...
backend/views/blog-article/update.php 0 → 100755
  1 +<?php
  2 +
  3 + use artbox\weblog\models\Article;
  4 + use artbox\weblog\models\ArticleLang;
  5 + use yii\web\View;
  6 + use yiister\gentelella\widgets\Panel;
  7 +
  8 + /**
  9 + * @var View $this
  10 + * @var Article $model
  11 + * @var ArticleLang[] $modelLangs
  12 + */
  13 +
  14 + $this->title = \Yii::t('blog', 'Update Blog Article: ') . $model->lang->title;
  15 + $this->params[ 'breadcrumbs' ][] = [
  16 + 'label' => \Yii::t('blog', 'Blog Articles'),
  17 + 'url' => [ 'index' ],
  18 + ];
  19 + $this->params[ 'breadcrumbs' ][] = [
  20 + 'label' => $model->lang->title,
  21 + 'url' => [
  22 + 'view',
  23 + 'id' => $model->id,
  24 + ],
  25 + ];
  26 + $this->params[ 'breadcrumbs' ][] = \Yii::t('blog', 'Update');
  27 +?>
  28 +<div class="blog-article-update">
  29 +
  30 + <?php $panel = Panel::begin(
  31 + [
  32 + 'header' => $this->title,
  33 + ]
  34 + ); ?>
  35 +
  36 + <?= $this->render(
  37 + '_form',
  38 + [
  39 + 'model' => $model,
  40 + 'modelLangs' => $modelLangs,
  41 + ]
  42 + ) ?>
  43 +
  44 + <?php $panel::end(); ?>
  45 +
  46 +</div>
... ...
backend/views/blog-article/view.php 0 → 100755
  1 +<?php
  2 +
  3 + use common\models\Article;
  4 + use yii\helpers\Html;
  5 + use yii\web\View;
  6 + use yii\widgets\DetailView;
  7 + use yiister\gentelella\widgets\Panel;
  8 +
  9 + /**
  10 + * @var View $this
  11 + * @var Article $model
  12 + */
  13 +
  14 + $this->title = $model->lang->title;
  15 + $this->params[ 'breadcrumbs' ][] = [
  16 + 'label' => \Yii::t('blog', 'Blog Articles'),
  17 + 'url' => [ 'index' ],
  18 + ];
  19 + $this->params[ 'breadcrumbs' ][] = $this->title;
  20 +?>
  21 +<div class="blog-article-view">
  22 +
  23 + <?php $panel = Panel::begin(
  24 + [
  25 + 'header' => $this->title,
  26 + ]
  27 + ); ?>
  28 +
  29 + <p>
  30 + <?= Html::a(
  31 + 'Update',
  32 + [
  33 + 'update',
  34 + 'id' => $model->id,
  35 + ],
  36 + [ 'class' => 'btn btn-primary' ]
  37 + ) ?>
  38 + <?= Html::a(
  39 + 'Delete',
  40 + [
  41 + 'delete',
  42 + 'id' => $model->id,
  43 + ],
  44 + [
  45 + 'class' => 'btn btn-danger',
  46 + 'data' => [
  47 + 'confirm' => 'Are you sure you want to delete this item?',
  48 + 'method' => 'post',
  49 + ],
  50 + ]
  51 + ) ?>
  52 + </p>
  53 +
  54 + <?= DetailView::widget(
  55 + [
  56 + 'model' => $model,
  57 + 'attributes' => [
  58 + 'id',
  59 + [
  60 + 'attribute' => 'image_id',
  61 + 'value' => function (Article $model) {
  62 + if (empty($model->lang->image_id)) {
  63 + return '';
  64 + } else {
  65 + return $model->lang->image->getImg(
  66 + [
  67 + 'width' => '500px',
  68 + ]
  69 + );
  70 + }
  71 + },
  72 + 'format' => 'html',
  73 + ],
  74 + 'created_at:date',
  75 + 'updated_at:date',
  76 + [
  77 + 'attribute' => 'status',
  78 + 'value' => ( !$model->status ) ? \Yii::t('blog', 'Not active') : \Yii::t('blog', 'Active'),
  79 + ],
  80 + 'lang.body:html',
  81 + ],
  82 + ]
  83 + ) ?>
  84 +
  85 + <?php $panel::end(); ?>
  86 +
  87 +</div>
... ...
backend/views/feedback/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\Feedback */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="feedback-form">
  12 +
  13 + <?php $form = ActiveForm::begin(); ?>
  14 +
  15 + <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
  16 +
  17 + <?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>
  18 +
  19 + <?= $form->field($model, 'phone')->textInput(['maxlength' => true]) ?>
  20 +
  21 + <?= $form->field($model, 'message')->textarea(['rows' => 6]) ?>
  22 +
  23 + <?= $form->field($model, 'status')->checkbox() ?>
  24 +
  25 + <?= $form->field($model, 'topic')->textInput(['maxlength' => true]) ?>
  26 +
  27 + <div class="form-group">
  28 + <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  29 + </div>
  30 +
  31 + <?php ActiveForm::end(); ?>
  32 +
  33 +</div>
... ...
backend/views/feedback/_search.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\ObjectkbSearchFeedback */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="feedback-search">
  12 +
  13 + <?php $form = ActiveForm::begin([
  14 + 'action' => ['index'],
  15 + 'method' => 'get',
  16 + ]); ?>
  17 +
  18 + <?= $form->field($model, 'id') ?>
  19 +
  20 + <?= $form->field($model, 'name') ?>
  21 +
  22 + <?= $form->field($model, 'email') ?>
  23 +
  24 + <?= $form->field($model, 'phone') ?>
  25 +
  26 + <?= $form->field($model, 'message') ?>
  27 +
  28 + <?php // echo $form->field($model, 'created_at') ?>
  29 +
  30 + <?php // echo $form->field($model, 'ip') ?>
  31 +
  32 + <?php // echo $form->field($model, 'url') ?>
  33 +
  34 + <?php // echo $form->field($model, 'status')->checkbox() ?>
  35 +
  36 + <?php // echo $form->field($model, 'topic') ?>
  37 +
  38 + <?php // echo $form->field($model, 'calc_json_info') ?>
  39 +
  40 + <div class="form-group">
  41 + <?= Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
  42 + <?= Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-default']) ?>
  43 + </div>
  44 +
  45 + <?php ActiveForm::end(); ?>
  46 +
  47 +</div>
... ...
backend/views/feedback/create.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\Feedback */
  8 +
  9 +$this->title = Yii::t('app', 'Create Feedback');
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Feedbacks'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="feedback-create">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <?= $this->render('_form', [
  18 + 'model' => $model,
  19 + ]) ?>
  20 +
  21 +</div>
... ...
backend/views/feedback/index.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\grid\GridView;
  5 +use yii\widgets\Pjax;
  6 +use common\models\Feedback;
  7 +use yiister\gentelella\widgets\Panel;
  8 +/* @var $this yii\web\View */
  9 +/* @var $searchModel common\models\ObjectkbSearchFeedback */
  10 +/* @var $dataProvider yii\data\ActiveDataProvider */
  11 +
  12 +$this->title = Yii::t('app', 'Feedbacks');
  13 +$this->params['breadcrumbs'][] = $this->title;
  14 +?>
  15 +<div class="feedback-index">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 + <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
  19 +
  20 + <p>
  21 + <?= Html::a(Yii::t('app', 'Create Feedback'), ['create'], ['class' => 'btn btn-success']) ?>
  22 + </p>
  23 +
  24 + <?= GridView::widget([
  25 + 'dataProvider' => $dataProvider,
  26 + 'rowOptions' => function (Feedback $model) {
  27 + if ($model->status) {
  28 + return [];
  29 + } else {
  30 + return [
  31 + 'class' => 'success',
  32 + ];
  33 + }
  34 + },
  35 + 'columns' => [
  36 + ['class' => 'yii\grid\SerialColumn'],
  37 +
  38 + 'id',
  39 + 'topic',
  40 + 'name',
  41 + 'email:email',
  42 + 'phone',
  43 + [
  44 + 'attribute' => 'created_at',
  45 + 'format' => [
  46 + 'datetime',
  47 + 'php:d.m.Y H:i',
  48 + ],
  49 + ],
  50 + [
  51 + 'class' => 'yii\grid\ActionColumn',
  52 + 'buttons' => [
  53 + 'viewed' => function (string $url, Feedback $model) {
  54 + if ($model->status) {
  55 + return Html::tag(
  56 + 'span',
  57 + '',
  58 + [
  59 + 'class' => 'glyphicon glyphicon-ok',
  60 + ]
  61 + );
  62 + } else {
  63 + return Html::a(
  64 + Html::tag(
  65 + 'span',
  66 + '',
  67 + [
  68 + 'class' => 'glyphicon glyphicon-flag',
  69 + ]
  70 + ),
  71 + $url,
  72 + [
  73 + 'class' => 'viewed-toggle',
  74 + ]
  75 + );
  76 + }
  77 + },
  78 + ],
  79 + 'template' => '{viewed} {view} {update} {delete}',
  80 + ],
  81 + ],
  82 + ]); ?>
... ...
backend/views/feedback/update.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +/* @var $this yii\web\View */
  6 +/* @var $model common\models\Feedback */
  7 +
  8 +$this->title = Yii::t('app', 'Update {modelClass}: ', [
  9 + 'modelClass' => 'Feedback',
  10 +]) . $model->name;
  11 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Feedbacks'), 'url' => ['index']];
  12 +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
  13 +$this->params['breadcrumbs'][] = Yii::t('app', 'Update');
  14 +?>
  15 +<div class="feedback-update">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <?= $this->render('_form', [
  20 + 'model' => $model,
  21 + ]) ?>
  22 +
  23 +</div>
... ...
backend/views/feedback/view.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\DetailView;
  5 +use common\models\Feedback;
  6 +
  7 +/* @var $this yii\web\View */
  8 +/* @var $model common\models\Feedback */
  9 +
  10 +$this->title = $model->name;
  11 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Feedbacks'), 'url' => ['index']];
  12 +$this->params['breadcrumbs'][] = $this->title;
  13 +?>
  14 +<div class="feedback-view">
  15 +
  16 + <h1><?= Html::encode($this->title) ?></h1>
  17 +
  18 + <p>
  19 + <?= Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
  20 + <?= Html::a(Yii::t('app', 'Delete'), ['delete', 'id' => $model->id], [
  21 + 'class' => 'btn btn-danger',
  22 + 'data' => [
  23 + 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'),
  24 + 'method' => 'post',
  25 + ],
  26 + ]) ?>
  27 + </p>
  28 +
  29 + <?= DetailView::widget([
  30 + 'model' => $model,
  31 + 'attributes' => [
  32 + 'id',
  33 + 'name',
  34 + 'email:email',
  35 + 'phone',
  36 + 'message:ntext',
  37 + 'created_at',
  38 + 'ip',
  39 + 'url:url',
  40 + 'status:boolean',
  41 + 'topic',
  42 + [
  43 + 'attribute' => 'calc_json_info',
  44 + 'label' => 'calculation info',
  45 + 'value' => function(\common\models\Feedback $model, $widget) {
  46 +
  47 + return json_decode($model->calc_json_info, true);
  48 +
  49 + },
  50 + ],
  51 + ],
  52 + 'template' => function ($attribute, $index, $widget){
  53 + if(
  54 + $attribute['attribute'] === 'calc_json_info' &&
  55 + !is_null($attribute['value'])
  56 + ){
  57 + $result = '';
  58 + foreach ($attribute['value'] as $attr => $value){
  59 + $result .= "<tr>";
  60 + $result .= "<th>".Feedback::translate_attributes[$attr]."</th>";
  61 + $result .= "<td>{$value}</td>";
  62 + $result .= "</tr>";
  63 + }
  64 +
  65 + return $result;
  66 +
  67 + }
  68 + elseif ($attribute['attribute'] === 'created_at'){
  69 + return "<tr><th>{$attribute['label']}</th><td>".\yii::$app->formatter->asDatetime($attribute['value'], 'php:d.m.Y H:i')."</td></tr>";
  70 + }
  71 + else{
  72 + return "<tr><th>{$attribute['label']}</th><td>{$attribute['value']}</td></tr>";
  73 + }
  74 + },
  75 + ]) ?>
  76 +
  77 +</div>
... ...
backend/views/layouts/menu_items.php
... ... @@ -75,7 +75,7 @@
75 75 ],
76 76 [
77 77 'label' => \Yii::t('core', 'Блог'),
78   - 'url' => ['#'],
  78 + 'url' => '#',
79 79 'icon' => 'book',
80 80 'items' => [
81 81 [
... ...
common/models/Article.php 0 → 100755
  1 +<?php
  2 +
  3 + namespace common\models;
  4 +
  5 + use artbox\core\behaviors\ManyToManyBehavior;
  6 + use artbox\core\models\Image;
  7 + use artbox\webcomment\models\CommentModel;
  8 + use artbox\weblog\models\ArticleToProduct;
  9 + use artbox\weblog\models\Category;
  10 + use artbox\weblog\models\Tag;
  11 + use yii\behaviors\TimestampBehavior;
  12 + use yii\db\ActiveRecord;
  13 + use artbox\core\behaviors\LanguageBehavior;
  14 + use artbox\core\models\Language;
  15 + use yii\db\ActiveQuery;
  16 + use yii\db\Query;
  17 + use yii\helpers\Url;
  18 + use yii\web\Request;
  19 +
  20 + /**
  21 + * This is the model class for table "blog_article".
  22 + *
  23 + * @property integer $id
  24 + * @property Image $image
  25 + * @property integer $created_at
  26 + * @property integer $updated_at
  27 + * @property integer $deleted_at
  28 + * @property integer $sort
  29 + * @property boolean $status
  30 + * @property integer $author_id
  31 + * @property integer $image_id
  32 + * @property ArticleLang[] $blogArticleLangs
  33 + * @property Language[] $languages
  34 + * @property Article[] $relatedBlogArticles
  35 + * @property Article[] $articles
  36 + * @property Category[] $categories
  37 + * @property Category $category
  38 + * @property Tag[] $tags
  39 + * @property \artbox\catalog\models\Product[] $relatedProducts
  40 + * * * From language behavior *
  41 + * @property ArticleLang $lang
  42 + * @property ArticleLang[] $langs
  43 + * @property ArticleLang $objectLang
  44 + * @property string $ownerKey
  45 + * @property string $langKey
  46 + * @property ArticleLang[] $modelLangs
  47 + * @property bool $transactionStatus
  48 + * @method string getOwnerKey()
  49 + * @method void setOwnerKey( string $value )
  50 + * @method string getLangKey()
  51 + * @method void setLangKey( string $value )
  52 + * @method ActiveQuery getLangs()
  53 + * @method ActiveQuery getLang( integer $language_id )
  54 + * @method ArticleLang[] generateLangs()
  55 + * @method void loadLangs( Request $request )
  56 + * @method bool linkLangs()
  57 + * @method bool saveLangs()
  58 + * @method bool getTransactionStatus()
  59 + * @method bool loadWithLangs( Request $request )
  60 + * @method bool saveWithLangs()
  61 + * * End language behavior *
  62 + * @method void linkMany( string $link, array $models )
  63 + */
  64 + class Article extends ActiveRecord
  65 + {
  66 + public $categoryIds = [];
  67 +
  68 + public $tagIds = [];
  69 +
  70 + public $articleIds = [];
  71 +
  72 + public $productIds = [];
  73 +
  74 + /**
  75 + * @inheritdoc
  76 + */
  77 + public static function tableName()
  78 + {
  79 + return 'blog_article';
  80 + }
  81 +
  82 + public function behaviors()
  83 + {
  84 + return [
  85 + [
  86 + 'class' => TimestampBehavior::className(),
  87 + ],
  88 + 'language' => [
  89 + 'class' => LanguageBehavior::className(),
  90 + ],
  91 + [
  92 + 'class' => ManyToManyBehavior::className(),
  93 + ],
  94 + ];
  95 + }
  96 + /**
  97 + * @inheritdoc
  98 + */
  99 + public function rules()
  100 + {
  101 + return [
  102 + [
  103 + [
  104 + 'created_at',
  105 + 'updated_at',
  106 + 'deleted_at',
  107 + 'sort',
  108 + 'author_id',
  109 + 'image_id',
  110 + ],
  111 + 'integer',
  112 + ],
  113 + [
  114 + [ 'status' ],
  115 + 'boolean',
  116 + ],
  117 + ];
  118 + }
  119 +
  120 + /**
  121 + * @inheritdoc
  122 + */
  123 + public function attributeLabels()
  124 + {
  125 + return [
  126 + 'id' => 'ID',
  127 + 'image' => 'Image',
  128 + 'created_at' => 'Created At',
  129 + 'updated_at' => 'Updated At',
  130 + 'deleted_at' => 'Deleted At',
  131 + 'sort' => 'Sort',
  132 + 'status' => 'Status',
  133 + 'author_id' => 'Author ID',
  134 + ];
  135 + }
  136 +
  137 + /**
  138 + * @return \yii\db\ActiveQuery
  139 + */
  140 + public function getRelatedBlogArticles()
  141 + {
  142 + return $this->hasMany(Article::className(), [ 'id' => 'related_blog_article_id' ])
  143 + ->viaTable('blog_article_to_article', [ 'blog_article_id' => 'id' ]);
  144 + }
  145 +
  146 + /**
  147 + * @return Query
  148 + */
  149 + public function getRelatedProducts()
  150 + {
  151 + if (class_exists('\artbox\catalog\models\Product')) {
  152 + return $this->hasMany('\artbox\catalog\models\Product', [ 'id' => 'product_id' ])
  153 + ->via('articleToProduct');
  154 + } else {
  155 + return ( new Query() )->where('1 = 0');
  156 + }
  157 + }
  158 +
  159 + public function getCommentsCount()
  160 + {
  161 +
  162 + if (class_exists('\artbox\webcomment\models\CommentModel')) {
  163 + $comments = CommentModel::find()->where("status = 1 and entity = 'artbox\weblog\models\Article' and entity_id = ".$this->id)->count();
  164 + return $comments;
  165 + } else {
  166 + return null;
  167 + }
  168 + }
  169 +
  170 + /**
  171 + * @return Query
  172 + */
  173 + public function getArticleToProduct()
  174 + {
  175 +
  176 + if (class_exists('\artbox\catalog\models\Product')) {
  177 + return $this->hasMany(ArticleToProduct::className(), [ 'article_id' => 'id' ]);
  178 + } else {
  179 + return ( new Query() )->where('1 = 0');
  180 + }
  181 + }
  182 +
  183 + /**
  184 + * @return \yii\db\ActiveQuery
  185 + */
  186 + public function getImage()
  187 + {
  188 + return $this->hasOne(Image::className(), [ 'id' => 'image_id' ]);
  189 + }
  190 +
  191 + /**
  192 + * @return \yii\db\ActiveQuery
  193 + */
  194 + public function getArticles()
  195 + {
  196 + return $this->hasMany(Article::className(), [ 'id' => 'blog_article_id' ])
  197 + ->viaTable('blog_article_to_article', [ 'related_blog_article_id' => 'id' ]);
  198 + }
  199 +
  200 + /**
  201 + * @return \yii\db\ActiveQuery
  202 + */
  203 + public function getCategories()
  204 + {
  205 + return $this->hasMany(Category::className(), [ 'id' => 'blog_category_id' ])
  206 + ->viaTable('blog_article_to_category', [ 'blog_article_id' => 'id' ]);
  207 + }
  208 +
  209 + /**
  210 + * @return \yii\db\ActiveQuery
  211 + */
  212 + public function getCategory()
  213 + {
  214 + return $this->hasOne(Category::className(), [ 'id' => 'blog_category_id' ])
  215 + ->viaTable('blog_article_to_category', [ 'blog_article_id' => 'id' ]);
  216 + }
  217 +
  218 + /**
  219 + * @return \yii\db\ActiveQuery
  220 + */
  221 + public function getTags()
  222 + {
  223 + return $this->hasMany(Tag::className(), [ 'id' => 'blog_tag_id' ])
  224 + ->viaTable('blog_article_to_tag', [ 'blog_article_id' => 'id' ]);
  225 + }
  226 + }
... ...
common/models/ArticleLang.php 0 → 100755
  1 +<?php
  2 +
  3 + namespace common\models;
  4 +
  5 + use artbox\core\behaviors\SlugBehavior;
  6 + use artbox\core\models\Alias;
  7 + use artbox\core\models\Language;
  8 + use artbox\core\models\Image;
  9 + use yii\db\ActiveRecord;
  10 +
  11 + /**
  12 + * This is the model class for table "blog_article_lang".
  13 +
  14 + *
  15 +*@property integer $id
  16 + * @property integer $blog_article_id
  17 + * @property integer $language_id
  18 + * @property string $title
  19 + * @property string $body
  20 + * @property string $body_preview
  21 + * @property string $meta_title
  22 + * @property string $meta_description
  23 + * @property string $h1
  24 + * @property string $seo_text
  25 + * @property Article $article
  26 + * @property Language $language
  27 + * @property Alias $alias
  28 + */
  29 + class ArticleLang extends ActiveRecord
  30 + {
  31 + /**
  32 + * @inheritdoc
  33 + */
  34 + public static function tableName()
  35 + {
  36 + return 'blog_article_lang';
  37 + }
  38 +
  39 + public function behaviors()
  40 + {
  41 + return [
  42 + 'slug' => [
  43 + 'class' => SlugBehavior::className(),
  44 + 'action' => 'blog/article',
  45 + 'params' => [
  46 + 'id' => 'blog_article_id',
  47 + ],
  48 + 'fields' => [
  49 + 'title' => 'Article title',
  50 + ],
  51 + ],
  52 + ];
  53 + }
  54 +
  55 + /**
  56 + * @inheritdoc
  57 + */
  58 + public function rules()
  59 + {
  60 + return [
  61 + [
  62 + [
  63 + 'blog_article_id',
  64 + 'language_id',
  65 + 'title',
  66 + ],
  67 + 'required',
  68 + ],
  69 + [
  70 + [
  71 + 'blog_article_id',
  72 + 'language_id',
  73 + 'image_id',
  74 + ],
  75 + 'integer',
  76 + ],
  77 + [
  78 + [
  79 + 'body',
  80 + 'body_preview',
  81 + ],
  82 + 'string',
  83 + ],
  84 + [
  85 + [
  86 + 'title',
  87 + ],
  88 + 'string',
  89 + 'max' => 255,
  90 + ],
  91 +
  92 + [
  93 + [
  94 + 'blog_article_id',
  95 + 'language_id',
  96 + ],
  97 + 'unique',
  98 + 'targetAttribute' => [
  99 + 'blog_article_id',
  100 + 'language_id',
  101 + ],
  102 + 'message' => 'The combination of Blog Article ID and Language ID has already been taken.',
  103 + ],
  104 + [
  105 + [ 'blog_article_id' ],
  106 + 'exist',
  107 + 'skipOnError' => true,
  108 + 'targetClass' => Article::className(),
  109 + 'targetAttribute' => [ 'blog_article_id' => 'id' ],
  110 + ],
  111 + [
  112 + [ 'language_id' ],
  113 + 'exist',
  114 + 'skipOnError' => true,
  115 + 'targetClass' => Language::className(),
  116 + 'targetAttribute' => [ 'language_id' => 'id' ],
  117 + ],
  118 + ];
  119 + }
  120 +
  121 + /**
  122 + * @inheritdoc
  123 + */
  124 + public function attributeLabels()
  125 + {
  126 + return [
  127 + 'id' => 'ID',
  128 + 'blog_article_id' => 'Blog Article ID',
  129 + 'language_id' => 'Language ID',
  130 + 'title' => 'Title',
  131 + 'body' => 'Body',
  132 + 'body_preview' => 'Body Preview',
  133 + 'alias' => 'Alias',
  134 + 'meta_title' => 'Meta Title',
  135 + 'meta_description' => 'Meta Description',
  136 + 'h1' => 'H1',
  137 + 'seo_text' => 'Seo Text',
  138 + ];
  139 + }
  140 +
  141 + /**
  142 + * @return \yii\db\ActiveQuery
  143 + */
  144 + public function getArticle()
  145 + {
  146 + return $this->hasOne(Article::className(), [ 'id' => 'blog_article_id' ]);
  147 + }
  148 +
  149 + /**
  150 + * @return \yii\db\ActiveQuery
  151 + */
  152 + public function getImage()
  153 + {
  154 + return $this->hasOne(Image::className(), [ 'id' => 'image_id' ]);
  155 + }
  156 +
  157 + /**
  158 + * @return \yii\db\ActiveQuery
  159 + */
  160 + public function getLanguage()
  161 + {
  162 + return $this->hasOne(Language::className(), [ 'id' => 'language_id' ]);
  163 + }
  164 +
  165 + /**
  166 + * @return \yii\db\ActiveQuery
  167 + */
  168 + public function getAlias()
  169 + {
  170 + return $this->hasOne(Alias::className(), [ 'id' => 'alias_id' ]);
  171 + }
  172 + }
... ...
common/models/ArticleSearch.php 0 → 100755
  1 +<?php
  2 +
  3 + namespace common\models;
  4 +
  5 + use yii\base\Model;
  6 + use yii\data\ActiveDataProvider;
  7 +
  8 + /**
  9 + * BlogArticleSearch represents the model behind the search form about `artweb\artbox\blog\models\BlogArticle`.
  10 + */
  11 + class ArticleSearch extends Article
  12 + {
  13 + /**
  14 + * @var string
  15 + */
  16 + public $title;
  17 +
  18 + public $tag;
  19 +
  20 + public $category;
  21 +
  22 + /**
  23 + * @inheritdoc
  24 + */
  25 + public function rules()
  26 + {
  27 + return [
  28 + [
  29 + [
  30 + 'id',
  31 + 'deleted_at',
  32 + 'sort',
  33 + 'author_id',
  34 + ],
  35 + 'integer',
  36 + ],
  37 + [
  38 + [ 'status' ],
  39 + 'boolean',
  40 + ],
  41 + [
  42 + [
  43 + 'title',
  44 + 'tag',
  45 + 'category',
  46 + ],
  47 + 'string',
  48 + ],
  49 + ];
  50 + }
  51 +
  52 + /**
  53 + * @inheritdoc
  54 + */
  55 + public function behaviors()
  56 + {
  57 + return [];
  58 + }
  59 +
  60 + /**
  61 + * @inheritdoc
  62 + */
  63 + public function scenarios()
  64 + {
  65 + // bypass scenarios() implementation in the parent class
  66 + return Model::scenarios();
  67 + }
  68 +
  69 + /**
  70 + * Creates data provider instance with search query applied
  71 + *
  72 + * @param array $params
  73 + *
  74 + * @return ActiveDataProvider
  75 + */
  76 + public function search($params)
  77 + {
  78 + $query = Article::find()
  79 + ->joinWith(
  80 + [
  81 + 'lang',
  82 +
  83 + ]
  84 + )
  85 + ->with(
  86 + [
  87 + 'tags.lang',
  88 + 'categories.lang',
  89 + ]
  90 + );
  91 +
  92 + // add conditions that should always apply here
  93 +
  94 + $dataProvider = new ActiveDataProvider(
  95 + [
  96 + 'query' => $query,
  97 + 'sort' => [
  98 + 'attributes' => [
  99 + 'id',
  100 + 'created_at',
  101 + 'updated_at',
  102 + 'title' => [
  103 + 'asc' => [ 'blog_article_lang.title' => SORT_ASC ],
  104 + 'desc' => [ 'blog_article_lang.title' => SORT_DESC ],
  105 + ],
  106 + ],
  107 + ],
  108 + ]
  109 + );
  110 +
  111 + $this->load($params);
  112 +
  113 + if (!$this->validate()) {
  114 + // uncomment the following line if you do not want to return any records when validation fails
  115 + // $query->where('0=1');
  116 + return $dataProvider;
  117 + }
  118 +
  119 + // grid filtering conditions
  120 + $query->andFilterWhere(
  121 + [
  122 + 'blog_article.id' => $this->id,
  123 + 'blog_article.status' => $this->status,
  124 + 'author_id' => $this->author_id,
  125 + ]
  126 + );
  127 +
  128 + $query->andFilterWhere(
  129 + [
  130 + 'ilike',
  131 + 'blog_article_lang.title',
  132 + $this->title,
  133 + ]
  134 + );
  135 +
  136 + $query->andFilterWhere(
  137 + [
  138 + 'ilike',
  139 + 'blog_tag_lang.label',
  140 + $this->tag,
  141 + ]
  142 + );
  143 +
  144 + $query->andFilterWhere(
  145 + [
  146 + 'ilike',
  147 + 'blog_category_lang.title',
  148 + $this->category,
  149 + ]
  150 + );
  151 +
  152 + return $dataProvider;
  153 + }
  154 + }
... ...
common/models/LangRedirect.php 0 → 100644
  1 +<?php
  2 + /**
  3 + * Created by PhpStorm.
  4 + * User: stes
  5 + * Date: 01.03.18
  6 + * Time: 16:00
  7 + */
  8 +
  9 + namespace common\models;
  10 +
  11 + use artbox\core\models\interfaces\RedirectInterface;
  12 + use artbox\core\models\Language;
  13 + use yii\base\Object;
  14 +
  15 + class LangRedirect extends Object implements RedirectInterface
  16 + {
  17 + protected $link = '';
  18 +
  19 + public function doRedirect(string $url): bool
  20 + {
  21 + $language = Language::getCurrent();
  22 + if(\Yii::$app->request->url == '/'.$language->url and $language->default){
  23 + $this->link = '';
  24 + return true;
  25 + }else{
  26 + return false;
  27 + }
  28 + }
  29 + public function getLink(): string
  30 + {
  31 + return $this->link;
  32 + }
  33 + }
0 34 \ No newline at end of file
... ...
console/migrations/m180306_103852_add_image_id_column_to_blog_article_lang.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Migration;
  4 +
  5 +class m180306_103852_add_image_id_column_to_blog_article_lang extends Migration
  6 +{
  7 + public function up()
  8 + {
  9 + $this->addColumn('blog_article_lang', 'image_id', $this->integer());
  10 + }
  11 +
  12 + public function down()
  13 + {
  14 + $this->dropColumn('blog_article_lang', 'image_id');
  15 + }
  16 +}
... ...
frontend/config/main.php
... ... @@ -2,6 +2,7 @@
2 2  
3 3 use artbox\core\components\LanguageRequest;
4 4 use artbox\core\components\SeoUrlManager;
  5 + use common\models\LangRedirect;
5 6  
6 7 $params = array_merge(
7 8 require( __DIR__ . '/../../common/config/params.php' ),
... ... @@ -54,6 +55,7 @@
54 55 'errorAction' => 'site/error',
55 56 ],
56 57 'urlManager' => [
  58 + 'baseUrl' => '/',
57 59 'class' => SeoUrlManager::className(),
58 60 'enablePrettyUrl' => true,
59 61 'forceRedirect' => true,
... ... @@ -77,6 +79,9 @@
77 79 'site/contact',
78 80  
79 81 ],
  82 + 'redirects' => [
  83 + LangRedirect::className(),
  84 + ],
80 85 ],
81 86 'assetsAutoCompress' => [
82 87 'class' => '\skeeks\yii2\assetsAuto\AssetsAutoCompressComponent',
... ...
frontend/controllers/BlogController.php
... ... @@ -5,7 +5,7 @@
5 5 use yii\helpers\Html;
6 6 use yii\helpers\Url;
7 7 use yii\web\Controller;
8   - use artbox\weblog\models\Article;
  8 + use common\models\Article;
9 9 use yii\web\NotFoundHttpException;
10 10 use yii\db\ActiveQuery;
11 11  
... ... @@ -40,6 +40,7 @@
40 40 {
41 41  
42 42 $query = Article::find()
  43 + ->with('lang.image')
43 44 ->where(
44 45 [
45 46 'status' => true,
... ... @@ -67,12 +68,14 @@
67 68 protected function findModel($id)
68 69 {
69 70 $model = Article::find()
70   - ->where(
  71 + ->with('lang.image')
  72 +
  73 + ->where(
71 74 [
72 75 'id' => $id
73 76 ]
74 77 )
75   - ->with("lang")
  78 + ->with("lang.image")
76 79 ->one();
77 80  
78 81 if ( $model !== NULL) {
... ... @@ -92,7 +95,7 @@
92 95 if (!empty($req->post("title"))){
93 96 $title = Html::encode($req->post("title"));
94 97 $query = Article::find()
95   - ->joinWith("lang")
  98 + ->joinWith("lang.image")
96 99 ->where(
97 100 [
98 101 'status' => true,
... ... @@ -116,7 +119,7 @@
116 119 public function actionCategory($id) {
117 120  
118 121 $query = Article::find()
119   - ->joinWith("categories.lang")
  122 + ->joinWith(["categories.lang", 'lang.image'])
120 123 ->where(
121 124 [
122 125 'blog_article.status' => true,
... ... @@ -135,7 +138,7 @@
135 138  
136 139 public function actionTag($id){
137 140 $query = Article::find()
138   - ->joinWith("tags.lang")
  141 + ->joinWith(["tags.lang", 'lang.image'])
139 142 ->where(
140 143 [
141 144 'blog_article.status' => true,
... ...
frontend/views/blog/_article_item.php
... ... @@ -7,7 +7,7 @@
7 7 * @var Article $model
8 8 */
9 9  
10   - use artbox\weblog\models\Article;
  10 + use common\models\Article;
11 11 use yii\helpers\Url;
12 12  
13 13 ?>
... ... @@ -62,7 +62,7 @@
62 62 ]
63 63 )?>"
64 64 >
65   - <?=$model->image->getImg(
  65 + <?=$model->lang->image->getImg(
66 66 [
67 67 'class' => "img-responsive"
68 68 ]
... ...
frontend/views/blog/view.php
... ... @@ -45,7 +45,7 @@
45 45 <div id="post-content" class="post-blog">
46 46  
47 47 <p>
48   - <?= $article->image->getImg(
  48 + <?= $article->lang->image->getImg(
49 49 [
50 50 'class' => "img-responsive",
51 51 ]
... ...