Commit 415bd38a8cc8c6c3020bb6dd9ff5836741840c87

Authored by Karnovsky A
2 parents 85261b14 f7aa643c

Merge branch 'master' of gitlab.artweb.com.ua:root/baucenter

Showing 424 changed files with 29973 additions and 178 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 424 files are displayed.

.gitignore
... ... @@ -39,4 +39,5 @@ frontend/config/params-local.php
39 39  
40 40 backend/web/assets/
41 41 frontend/web/assets/
42   -frontend/web/css/node_modules/
43 42 \ No newline at end of file
  43 +frontend/views/ะฒะตั€ั‚ัะบะฐ
  44 +frontend/web/css/node_modules
... ...
backend/config/main.php
... ... @@ -16,14 +16,14 @@ return [
16 16 'rubrication' => [
17 17 'class' => 'common\modules\rubrication\Module',
18 18 'types' => [
19   - 'string' => 'String',
20   - 'int' => 'Integer',
21   - 'float' => 'Float',
  19 + 'string' => 'Strings',
  20 + 'float' => 'Floating number',
  21 + 'int' => 'Integer number',
  22 + 'link' => 'Web-link',
22 23 ]
23   -
24 24 ],
25 25 'product' => [
26   - 'class' => 'common\modules\product\Module',
  26 + 'class' => 'common\modules\product\Module'
27 27 ],
28 28 ],
29 29 'components' => [
... ...
backend/views/blog/_form.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use common\widgets\FieldEditor;
  4 +use yii\helpers\Html;
  5 +use yii\widgets\ActiveForm;
  6 +use common\modules\file\widgets\ImageUploader;
  7 +use mihaildev\ckeditor\CKEditor;
  8 +use mihaildev\elfinder\ElFinder;
  9 +use common\components\Request;
  10 +
  11 +/* @var $this yii\web\View */
  12 +/* @var $model common\models\Blog */
  13 +/* @var $form yii\widgets\ActiveForm */
  14 +?>
  15 +
  16 +<div class="blog-form">
  17 +
  18 + <?php $form = ActiveForm::begin(); ?>
  19 +
  20 + <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
  21 +
  22 + <?= $form->field($model, 'link')->textInput(['maxlength' => true]) ?>
  23 +
  24 + <?= $form->field($model, 'description')->widget(CKEditor::className(),
  25 + [
  26 + 'editorOptions' => ElFinder::ckeditorOptions('elfinder',[
  27 + 'preset' => 'full', //ั€ะฐะทั€ะฐะฑะพั‚ะฐะฝะฝั‹ ัั‚ะฐะฝะดะฐั€ั‚ะฝั‹ะต ะฝะฐัั‚ั€ะพะนะบะธ basic, standard, full ะดะฐะฝะฝัƒัŽ ะฒะพะทะผะพะถะฝะพัั‚ัŒ ะฝะต ะพะฑัะทะฐั‚ะตะปัŒะฝะพ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ
  28 + 'inline' => false, //ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ false]),
  29 + 'filebrowserUploadUrl'=>Yii::$app->getUrlManager()->createUrl('file/uploader/images-upload')
  30 + ]
  31 + )
  32 + ]) ?>
  33 +
  34 + <?= ImageUploader::widget([
  35 + 'model'=> $model,
  36 + 'field'=>'cover',
  37 + 'size' => [
  38 + [
  39 + 'width'=>340,
  40 + 'height'=>260,
  41 + ]
  42 + ],
  43 + 'multi'=>true,
  44 + 'gallery' =>$model->cover,
  45 + 'name' => 'ะ—ะฐะณั€ัƒะทะธั‚ัŒ ะผะธะฝะธะฐั‚ัŽั€ัƒ ัั‚ะฐั‚ัŒะธ'
  46 + ]);
  47 + ?>
  48 +
  49 + <?= FieldEditor::widget([
  50 + 'template' => 'education',
  51 + 'item_id' => $model->blog_id,
  52 + 'model' => 'common\models\Blog',
  53 + 'language' => 'ru',
  54 + ]); ?>
  55 + <div class="form-group">
  56 + <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  57 + </div>
  58 +
  59 + <?php ActiveForm::end(); ?>
  60 +
  61 +</div>
... ...
backend/views/blog/index.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\grid\GridView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $searchModel common\models\BlogSearch */
  8 +/* @var $dataProvider yii\data\ActiveDataProvider */
  9 +
  10 +$this->title = 'Blogs';
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="blog-index">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 + <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
  17 +
  18 + <p>
  19 + <?= Html::a('Create Blog', ['create'], ['class' => 'btn btn-success']) ?>
  20 + </p>
  21 + <?= GridView::widget([
  22 + 'dataProvider' => $dataProvider,
  23 + 'filterModel' => $searchModel,
  24 + 'columns' => [
  25 + ['class' => 'yii\grid\SerialColumn'],
  26 +
  27 + 'blog_id',
  28 + 'user_id',
  29 + 'name',
  30 + 'link',
  31 + 'date_add',
  32 + // 'user_add_id',
  33 + // 'view_count',
  34 + // 'description:ntext',
  35 + // 'cover',
  36 +
  37 + ['class' => 'yii\grid\ActionColumn'],
  38 + ],
  39 + ]); ?>
  40 +</div>
... ...
backend/views/layouts/admin.php
... ... @@ -31,5 +31,4 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;);
31 31 <!-- Add the sidebar's background. This div must be placed
32 32 immediately after the control sidebar -->
33 33 <div class="control-sidebar-bg"></div>
34   -
35 34 <?php $this->endContent() ?>
36 35 \ No newline at end of file
... ...
backend/web/.gitignore 0 โ†’ 100644
  1 +/index.php
  2 +/index-test.php
... ...
backend/web/assets/.gitignore 0 โ†’ 100644
  1 +*
  2 +!.gitignore
... ...
backend/web/css/site.css 0 โ†’ 100644
  1 +html,
  2 +body {
  3 + height: 100%;
  4 +}
  5 +
  6 +.wrap {
  7 + min-height: 100%;
  8 + height: auto;
  9 + margin: 0 auto -60px;
  10 + padding: 0 0 60px;
  11 +}
  12 +
  13 +.wrap > .container {
  14 + padding: 70px 15px 20px;
  15 +}
  16 +
  17 +.footer {
  18 + height: 60px;
  19 + background-color: #f5f5f5;
  20 + border-top: 1px solid #ddd;
  21 + padding-top: 20px;
  22 +}
  23 +
  24 +.jumbotron {
  25 + text-align: center;
  26 + background-color: transparent;
  27 +}
  28 +
  29 +.jumbotron .btn {
  30 + font-size: 21px;
  31 + padding: 14px 24px;
  32 +}
  33 +
  34 +.not-set {
  35 + color: #c55;
  36 + font-style: italic;
  37 +}
  38 +
  39 +/* add sorting icons to gridview sort links */
  40 +a.asc:after, a.desc:after {
  41 + position: relative;
  42 + top: 1px;
  43 + display: inline-block;
  44 + font-family: 'Glyphicons Halflings';
  45 + font-style: normal;
  46 + font-weight: normal;
  47 + line-height: 1;
  48 + padding-left: 5px;
  49 +}
  50 +
  51 +a.asc:after {
  52 + content: /*"\e113"*/ "\e151";
  53 +}
  54 +
  55 +a.desc:after {
  56 + content: /*"\e114"*/ "\e152";
  57 +}
  58 +
  59 +.sort-numerical a.asc:after {
  60 + content: "\e153";
  61 +}
  62 +
  63 +.sort-numerical a.desc:after {
  64 + content: "\e154";
  65 +}
  66 +
  67 +.sort-ordinal a.asc:after {
  68 + content: "\e155";
  69 +}
  70 +
  71 +.sort-ordinal a.desc:after {
  72 + content: "\e156";
  73 +}
  74 +
  75 +.grid-view td {
  76 + white-space: nowrap;
  77 +}
  78 +
  79 +.grid-view .filters input,
  80 +.grid-view .filters select {
  81 + min-width: 50px;
  82 +}
  83 +
  84 +.hint-block {
  85 + display: block;
  86 + margin-top: 5px;
  87 + color: #999;
  88 +}
  89 +
  90 +.error-summary {
  91 + color: #a94442;
  92 + background: #fdf7f7;
  93 + border-left: 3px solid #eed3d7;
  94 + padding: 10px 20px;
  95 + margin: 0 0 15px 0;
  96 +}
  97 +
  98 +/* align the logout "link" (button in form) of the navbar */
  99 +.nav > li > form {
  100 + padding: 8px;
  101 +}
  102 +
  103 +.nav > li > form > button:hover {
  104 + text-decoration: none;
  105 +}
... ...
backend/web/favicon.ico 0 โ†’ 100644
No preview for this file type
backend/web/js/fieldWidget.js 0 โ†’ 100644
  1 +$(function(){
  2 + $.each($('.delete-field-item'), function(index, value) {
  3 + var container = $(value).parents('.field_list').first();
  4 + var count = $(container).find('.form-group').length;
  5 + if(count <= 1) {
  6 + $(container).find('.delete-field-item').addClass('hidden');
  7 + }
  8 + });
  9 + $(document).on('click', '.delete-field-item', function(){
  10 + var container = $(this).parents('.field_list').first();
  11 + $(this).parent('.form-group').remove();
  12 + var count = $(container).find('.form-group').length;
  13 + if(count <= 1) {
  14 + $(container).find('.delete-field-item').addClass('hidden');
  15 + }
  16 + });
  17 + $(document).on('click', '[class*=add_field_w]', function() {
  18 + var container = $(this).siblings('.field_list').first();
  19 + var count = $(container).find('.form-group').length;
  20 + if(count > 1) {
  21 + $(container).find('.delete-field-item').removeClass('hidden');
  22 + }
  23 + });
  24 +});
0 25 \ No newline at end of file
... ...
backend/web/robots.txt 0 โ†’ 100644
  1 +User-agent: *
  2 +Disallow: /
... ...
common/behaviors/ShowImage.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\behaviors;
  4 +
  5 +use yii;
  6 +use yii\base\Behavior;
  7 +
  8 +class ShowImage extends Behavior
  9 +{
  10 + function minImg($dir, $width, $height=null){
  11 + if(empty($dir)){
  12 + return $dir;
  13 + }
  14 +
  15 + if($width=='original'){
  16 + $preg = '/\/(.[^\/]*)$/';
  17 + preg_match('/\.(.[^.]*)$/', $dir, $type);
  18 + $row = preg_replace( $preg, '/original.'.$type[1], $dir);
  19 + } else {
  20 + $preg = '/\/(.[^\/]*)$/';
  21 + preg_match('/\.(.[^.]*)$/', $dir, $type);
  22 + $row = preg_replace( $preg, '/'.$width.'x'.$height.'.'.$type[1], $dir);
  23 + }
  24 +
  25 + return $row;
  26 +
  27 +
  28 + }
  29 +
  30 + function ShowGallery($array){
  31 +
  32 + $gallery = explode(',', $array );
  33 + if(is_array($gallery)){
  34 + array_splice($gallery,-1);
  35 + return $gallery;
  36 + } else {
  37 + return [];
  38 + }
  39 +
  40 + }
  41 +
  42 +
  43 +}
0 44 \ No newline at end of file
... ...
common/behaviors/Slug.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\behaviors;
  4 +
  5 +use yii;
  6 +use yii\base\Behavior;
  7 +use yii\db\ActiveRecord;
  8 +use dosamigos\transliterator\TransliteratorHelper;
  9 +class Slug extends Behavior
  10 +{
  11 + public $in_attribute = 'name';
  12 + public $out_attribute = 'slug';
  13 + public $translit = true;
  14 +
  15 + public function events()
  16 + {
  17 + return [
  18 + ActiveRecord::EVENT_BEFORE_VALIDATE => 'getSlug'
  19 + ];
  20 + }
  21 +
  22 + public function getSlug( $event )
  23 + {
  24 + if ( empty( $this->owner->{$this->out_attribute} ) ) {
  25 + $this->owner->{$this->out_attribute} = $this->generateSlug( $this->owner->{$this->in_attribute} );
  26 + } else {
  27 + $this->owner->{$this->out_attribute} = $this->generateSlug( $this->owner->{$this->out_attribute} );
  28 + }
  29 + }
  30 +
  31 + private function generateSlug( $slug )
  32 + {
  33 + $slug = $this->slugify( $slug );
  34 + if ( $this->checkUniqueSlug( $slug ) ) {
  35 + return $slug;
  36 + } else {
  37 + for ( $suffix = 2; !$this->checkUniqueSlug( $new_slug = $slug . '-' . $suffix ); $suffix++ ) {}
  38 + return $new_slug;
  39 + }
  40 + }
  41 +
  42 + private function slugify( $slug )
  43 + {
  44 + if ( $this->translit ) {
  45 + return yii\helpers\Inflector::slug( TransliteratorHelper::process( $slug ), '-', true );
  46 + } else {
  47 + return $this->slug( $slug, '-', true );
  48 + }
  49 + }
  50 +
  51 + private function slug( $string, $replacement = '-', $lowercase = true )
  52 + {
  53 + $string = preg_replace( '/[^\p{L}\p{Nd}]+/u', $replacement, $string );
  54 + $string = trim( $string, $replacement );
  55 + return $lowercase ? strtolower( $string ) : $string;
  56 + }
  57 +
  58 + private function checkUniqueSlug( $slug )
  59 + {
  60 + $pk = $this->owner->primaryKey();
  61 + $pk = $pk[0];
  62 +
  63 + $condition = $this->out_attribute . ' = :out_attribute';
  64 + $params = [ ':out_attribute' => $slug ];
  65 + if ( !$this->owner->isNewRecord ) {
  66 + $condition .= ' and ' . $pk . ' != :pk';
  67 + $params[':pk'] = $this->owner->{$pk};
  68 + }
  69 +
  70 + return !$this->owner->find()
  71 + ->where( $condition, $params )
  72 + ->one();
  73 + }
  74 +
  75 +}
0 76 \ No newline at end of file
... ...
common/components/LangRequest.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components;
  4 +
  5 +use Yii;
  6 +use yii\base\InvalidConfigException;
  7 +use yii\web\Request;
  8 +use common\models\Language;
  9 +use common\models\Page;
  10 +use yii\helpers\Url;
  11 +
  12 +class LangRequest extends Request
  13 +{
  14 + private $_lang_url;
  15 +
  16 + public function getBaseUrl()
  17 + {
  18 + return str_replace ((IS_FRONT ? '/frontend/web' : '/backend/web'), '', parent::getBaseUrl()) . (IS_FRONT ? '' : '/admin');
  19 + }
  20 +
  21 + public function getLangUrl()
  22 + {
  23 + if ($this->_lang_url === null)
  24 + {
  25 + $this->_lang_url = $this->getUrl();
  26 +
  27 + $url_list = explode ('/', $this->_lang_url);
  28 +
  29 + $lang_url = isset ($url_list[1]) ? $url_list[1] : null;
  30 +
  31 + Language::setCurrent($lang_url);
  32 +
  33 + if ($lang_url !== null && $lang_url === Language::getCurrent()->language_code
  34 + && strpos($this->_lang_url, Language::getCurrent()->language_code) === 1)
  35 + {
  36 + $this->_lang_url = substr ($this->_lang_url, strlen (Language::getCurrent()->language_code) + 1);
  37 + }
  38 + }
  39 +
  40 + return $this->_lang_url;
  41 + }
  42 +
  43 + protected function resolvePathInfo()
  44 + {
  45 + $pathInfo = $this->getLangUrl();
  46 +
  47 + if (($pos = strpos ($pathInfo, '?')) !== false)
  48 + {
  49 + $pathInfo = substr ($pathInfo, 0, $pos);
  50 + }
  51 +
  52 + $pathInfo = urldecode ($pathInfo);
  53 +
  54 + // try to encode in UTF8 if not so
  55 + // http://w3.org/International/questions/qa-forms-utf-8.html
  56 + if (! preg_match ('%^(?:
  57 + [\x09\x0A\x0D\x20-\x7E] # ASCII
  58 + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
  59 + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
  60 + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
  61 + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
  62 + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
  63 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
  64 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
  65 + )*$%xs', $pathInfo)
  66 + )
  67 + {
  68 + $pathInfo = utf8_encode($pathInfo);
  69 + }
  70 +
  71 + $scriptUrl = $this->getScriptUrl();
  72 +
  73 + $baseUrl = $this->getBaseUrl();
  74 +
  75 + if (strpos($pathInfo, $scriptUrl) === 0)
  76 + {
  77 + $pathInfo = substr($pathInfo, strlen($scriptUrl));
  78 + }
  79 + else if ($baseUrl === '' || strpos($pathInfo, $baseUrl) === 0)
  80 + {
  81 + $pathInfo = substr($pathInfo, strlen($baseUrl));
  82 + }
  83 + elseif (isset ($_SERVER['PHP_SELF']) && strpos ($_SERVER['PHP_SELF'], $scriptUrl) === 0)
  84 + {
  85 + $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl));
  86 + }
  87 + else
  88 + {
  89 + throw new InvalidConfigException('Unable to determine the path info of the current request.');
  90 + }
  91 +
  92 + if ($pathInfo[0] === '/')
  93 + {
  94 + $pathInfo = substr ($pathInfo, 1);
  95 + }
  96 +
  97 + return (string) $pathInfo;
  98 + }
  99 +}
0 100 \ No newline at end of file
... ...
common/components/LangUrlManager.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components;
  4 +
  5 +use yii\web\UrlManager;
  6 +use common\models\Language;
  7 +
  8 +class LangUrlManager extends UrlManager
  9 +{
  10 + public function createUrl ($params)
  11 + {
  12 + if (isset ($params['language_id']))
  13 + {
  14 + //ะ•ัะปะธ ัƒะบะฐะทะฐะฝ ะธะดะตะฝั‚ะธั„ะธะบะฐั‚ะพั€ ัะทั‹ะบะฐ, ั‚ะพ ะดะตะปะฐะตะผ ะฟะพะฟั‹ั‚ะบัƒ ะฝะฐะนั‚ะธ ัะทั‹ะบ ะฒ ะ‘ะ”,
  15 + //ะธะฝะฐั‡ะต ั€ะฐะฑะพั‚ะฐะตะผ ั ัะทั‹ะบะพะผ ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ
  16 + if (($lang_code = Language::findOne($params['language_id'])) === null)
  17 + {
  18 + $lang_code = Language::getDefaultLang();
  19 + }
  20 +
  21 + unset ($params['language_id']);
  22 +
  23 + }
  24 + else
  25 + {
  26 + //ะ•ัะปะธ ะฝะต ัƒะบะฐะทะฐะฝ ะฟะฐั€ะฐะผะตั‚ั€ ัะทั‹ะบะฐ, ั‚ะพ ั€ะฐะฑะพั‚ะฐะตะผ ั ั‚ะตะบัƒั‰ะธะผ ัะทั‹ะบะพะผ
  27 + $lang_code = Language::getCurrent();
  28 + }
  29 +
  30 + //ะŸะพะปัƒั‡ะฐะตะผ ัั„ะพั€ะผะธั€ะพะฒะฐะฝะฝั‹ะน URL(ะฑะตะท ะฟั€ะตั„ะธะบัะฐ ะธะดะตะฝั‚ะธั„ะธะบะฐั‚ะพั€ะฐ ัะทั‹ะบะฐ)
  31 + $url = parent::createUrl($params);
  32 +
  33 + // ะ”ะพะฑะฐะฒะปัะตะผ ะบ URL ะฟั€ะตั„ะธะบั - ะฑัƒะบะฒะตะฝะฝั‹ะน ะธะดะตะฝั‚ะธั„ะธะบะฐั‚ะพั€ ัะทั‹ะบะฐ
  34 +
  35 + return $url == '/' ? '/'.$url : ($lang_code->is_default == 1 ? $url : '/'.$lang_code->lang_code.$url);
  36 + }
  37 +}
0 38 \ No newline at end of file
... ...
common/components/Request.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\components;
  3 +
  4 +class Request extends \yii\web\Request
  5 +
  6 +{
  7 +
  8 + public $web;
  9 +
  10 + public $adminUrl;
  11 +
  12 +
  13 +
  14 + public function getBaseUrl()
  15 +
  16 + {
  17 +
  18 + return str_replace($this->web, "", parent::getBaseUrl()) . $this->adminUrl;
  19 +
  20 + }
  21 +
  22 +
  23 +
  24 + public function resolvePathInfo()
  25 +
  26 + {
  27 +
  28 + if ($this->getUrl() === $this->adminUrl) {
  29 +
  30 + return "";
  31 +
  32 + } else {
  33 +
  34 + return parent::resolvePathInfo();
  35 +
  36 + }
  37 +
  38 + }
  39 +
  40 +}
0 41 \ No newline at end of file
... ...
common/components/artboxtree/ArtboxTreeBehavior.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree;
  4 +
  5 +use common\modules\rubrication\models\TaxOption;
  6 +use Yii;
  7 +use yii\base\Behavior;
  8 +use yii\base\Exception;
  9 +use yii\base\NotSupportedException;
  10 +use yii\db\ActiveRecord;
  11 +use yii\db\Expression;
  12 +
  13 +class ArtboxTreeBehavior extends Behavior {
  14 +
  15 + /** @var ActiveRecord $owner */
  16 + public $owner;
  17 +
  18 + public $keyNameId;
  19 + public $keyNameParentId = 'parent_id';
  20 + public $keyNameGroup = 'group';
  21 + public $keyNamePath = 'path_int';
  22 + public $keyNameDepth = 'depth'; // @todo -> $keyNameDepth;
  23 +
  24 + /**
  25 + * @var string
  26 + */
  27 + public $delimiter = '|';
  28 +
  29 + /**
  30 + * @var ActiveRecord|self|null
  31 + */
  32 + protected $entity;
  33 +
  34 + /**
  35 + * @param ActiveRecord $owner
  36 + * @throws Exception
  37 + */
  38 + public function attach($owner)
  39 + {
  40 + parent::attach($owner);
  41 + if ($this->keyNameId === null) {
  42 + $primaryKey = $owner->primaryKey();
  43 + if (!isset($primaryKey[0])) {
  44 + throw new Exception('"' . $owner->className() . '" must have a primary key.');
  45 + }
  46 + $this->keyNameId = $primaryKey[0];
  47 + }
  48 + }
  49 +
  50 + public function events()
  51 + {
  52 + return [
  53 + // @todo Use beforeSave for automatic set MP-params
  54 + ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeUpdate',
  55 + ActiveRecord::EVENT_AFTER_INSERT => 'afterInsert',
  56 + ];
  57 + }
  58 +
  59 + /*
  60 + * Main methods
  61 + */
  62 +
  63 + /*
  64 + * get one parent
  65 + * use AL-method
  66 + */
  67 + public function getParent() {
  68 + return $this->getParentAL();
  69 + }
  70 +
  71 + /*
  72 + * get all parents
  73 + * use MP-method
  74 + */
  75 + public function getParents() {
  76 + return $this->getParentsMP();
  77 + }
  78 +
  79 + /*
  80 + * get one-level children items
  81 + * use AL-method
  82 + */
  83 + public function getChildren() {
  84 + return $this->getChildrenAL();
  85 + }
  86 +
  87 + /*
  88 + * get all-level children items
  89 + * use MP-method
  90 + */
  91 + public function getAllChildren($depth = null) {
  92 + return $this->getAllChildrenMP($depth);
  93 + }
  94 +
  95 +
  96 + /*
  97 + * ================================
  98 + * MP-methods
  99 + * ================================
  100 + */
  101 +
  102 + /*
  103 + * Full-path (use MP-method)
  104 + */
  105 + public function getParentsMP($depth = null) {
  106 + $path = $this->getParentPath();
  107 + if ($path !== null) {
  108 + $paths = str_replace(['{', '}'], '', explode(',', $path));
  109 + if (!$this->primaryKeyMode) {
  110 + $path = null;
  111 + $paths = array_map(
  112 + function ($value) use (&$path) {
  113 + return $path = ($path !== null ? $path . ',' : '') . $value;
  114 + },
  115 + $paths
  116 + );
  117 + }
  118 + if ($depth !== null) {
  119 + $paths = array_slice($paths, -$depth);
  120 + }
  121 + } else {
  122 + $paths = [];
  123 + }
  124 +
  125 + $tableName = $this->owner->tableName();
  126 + $condition = ['and'];
  127 + if ($this->primaryKeyMode) {
  128 + $condition[] = ["{$tableName}.[[{$this->keyNameId}]]" => $paths];
  129 + } else {
  130 + $condition[] = ["{$tableName}.[[{$this->keyNamePath}]]" => $paths];
  131 + }
  132 +
  133 + $query = $this->owner->find()
  134 + ->andWhere($condition)
  135 + ->andWhere($this->treeCondition())
  136 + ->addOrderBy(["{$tableName}.[[{$this->keyNamePath}]]" => SORT_ASC]);
  137 + $query->multiple = true;
  138 +
  139 + return $query;
  140 + }
  141 +
  142 + /**
  143 + * @param bool $asArray = false
  144 + * @return null|string|array
  145 + */
  146 + public function getParentPath($asArray = false)
  147 + {
  148 + return static::getParentPathInternal($this->owner->getAttribute($this->keyNamePath), $asArray);
  149 + }
  150 +
  151 + public function getAllChildrenMP($depth = null)
  152 + {
  153 + $tableName = $this->owner->tableName();
  154 + $path = $this->owner->getAttribute($this->keyNamePath);
  155 + $query = $this->owner->find()
  156 + ->andWhere(['@>', "{$tableName}.[[{$this->keyNamePath}]]", $this->getLike($path), false]);
  157 +
  158 +
  159 + if ($depth > 0) {
  160 + $query->andWhere(['<=', "{$tableName}.[[{$this->keyNameDepth}]]", $this->owner->getAttribute($this->keyNameDepth) + $depth]);
  161 + }
  162 +
  163 + $orderBy = [];
  164 + $orderBy["{$tableName}.[[{$this->keyNameDepth}]]"] = SORT_ASC;
  165 + $orderBy["{$tableName}.[[{$this->keyNameId}]]"] = SORT_ASC;
  166 +
  167 + $query
  168 + ->andWhere($this->treeCondition())
  169 + ->addOrderBy($orderBy);
  170 + $query->multiple = true;
  171 +
  172 + return $query;
  173 + }
  174 +
  175 + /*
  176 + * ================================
  177 + * AL methods
  178 + * ================================
  179 + */
  180 +
  181 + /*
  182 + * Parent entity (use AL-method)
  183 + * @return \yii\db\ActiveRecord
  184 + */
  185 + public function getParentAL() {
  186 + $parent_id = $this->owner->getAttribute($this->keyNameParentId);
  187 + if (empty($parent_id))
  188 + return null;
  189 + return $this->owner->find()->where([$this->keyNameId => $parent_id, $this->keyNameGroup => $this->owner->getAttribute($this->keyNameGroup)])->one();
  190 + }
  191 +
  192 + /*
  193 + * Get parents by AL-method
  194 + * @return array
  195 + */
  196 + public function getParentsAL() {
  197 + $parent_id = $this->owner->getAttribute($this->keyNameParentId);
  198 + if ($parent_id == 0) {
  199 + return [];
  200 + }
  201 +
  202 + $parent = $this->owner;
  203 + $parents = [];
  204 + while(true) {
  205 + $parent = $parent->getParentAL();
  206 + if (is_null($parent))
  207 + break;
  208 + $parents[] = $parent;
  209 + }
  210 +
  211 + return array_reverse($parents);
  212 + }
  213 +
  214 + /*
  215 + * Children entities (one-step) (use AL-method)
  216 + * @return ActiveQuery
  217 + */
  218 + public function getChildrenAL() {
  219 + return $this->owner->find()->where([$this->keyNameParentId => $this->owner->getAttribute($this->keyNameId), $this->keyNameGroup => $this->owner->getAttribute($this->keyNameGroup)]);
  220 + }
  221 +
  222 + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  223 +
  224 + /**
  225 + * @param array $changedAttributes
  226 + * @throws Exception
  227 + */
  228 + protected function _rebuildChildren($changedAttributes)
  229 + {
  230 + $path = isset($changedAttributes[$this->keyNamePath]) ? $changedAttributes[$this->keyNamePath] : $this->owner->getAttribute($this->keyNamePath);
  231 + $update = [];
  232 + $condition = [
  233 + 'and',
  234 + ['@>', "[[{$this->keyNamePath}]]", $path, false],
  235 + ];
  236 + if ($this->keyNameGroup !== null) {
  237 + $group = isset($changedAttributes[$this->keyNameGroup]) ? $changedAttributes[$this->keyNameGroup] : $this->owner->getAttribute($this->keyNameGroup);
  238 + $condition[] = [$this->keyNameGroup => $group];
  239 + }
  240 + $params = [];
  241 +
  242 + if (isset($changedAttributes[$this->keyNamePath])) {
  243 + $substringExpr = $this->substringExpression(
  244 + "[[{$this->keyNamePath}]]",
  245 + 'array_length(:pathOld) + 1',
  246 + "array_length([[{$this->keyNamePath}]]) - array_length(:pathOld)"
  247 + );
  248 + $update[$this->keyNamePath] = new Expression($this->concatExpression([':pathNew', $substringExpr]));
  249 + $params[':pathOld'] = $path;
  250 + $params[':pathNew'] = $this->owner->getAttribute($this->keyNamePath);
  251 + }
  252 +
  253 + if ($this->keyNameGroup !== null && isset($changedAttributes[$this->keyNameGroup])) {
  254 + $update[$this->keyNameGroup] = $this->owner->getAttribute($this->keyNameGroup);
  255 + }
  256 +
  257 + if ($this->keyNameDepth !== null && isset($changedAttributes[$this->keyNameDepth])) {
  258 + $delta = $this->owner->getAttribute($this->keyNameDepth) - $changedAttributes[$this->keyNameDepth];
  259 + $update[$this->keyNameDepth] = new Expression("[[{$this->keyNameDepth}]]" . sprintf('%+d', $delta));
  260 + }
  261 + if (!empty($update)) {
  262 + $this->owner->updateAll($update, $condition, $params);
  263 + }
  264 + }
  265 +
  266 + /**
  267 + * @param string $path
  268 + * @param string $delimiter
  269 + * @param bool $asArray = false
  270 + * @return null|string|array
  271 + */
  272 + protected static function getParentPathInternal($path, $asArray = false)
  273 + {
  274 + $path = str_replace(['{', '}'], '', explode(',', $path));
  275 + array_pop($path);
  276 + if ($asArray) {
  277 + return $path;
  278 + }
  279 + return count($path) > 0 ? implode(',', $path) : null;
  280 + }
  281 +
  282 + protected function toLike($path) {
  283 + return strtr($path . ',', ['%' => '\%', '_' => '\_', '\\' => '\\\\']) . '%';
  284 + }
  285 +
  286 + protected function concatExpression($items)
  287 + {
  288 + if ($this->owner->getDb()->driverName === 'sqlite' || $this->owner->getDb()->driverName === 'pgsql') {
  289 + return implode(' || ', $items);
  290 + }
  291 + return 'CONCAT(' . implode(',', $items) . ')';
  292 + }
  293 +
  294 + protected function substringExpression($string, $from, $length)
  295 + {
  296 + if ($this->owner->getDb()->driverName === 'sqlite') {
  297 + return "SUBSTR({$string}, {$from}, {$length})";
  298 + }
  299 + return "SUBSTRING({$string}, {$from}, {$length})";
  300 + }
  301 +
  302 + // =======================================================
  303 + public function afterInsert() {
  304 + $this->withSave();
  305 + $this->owner->updateAttributes([$this->keyNamePath => $this->owner->getAttribute($this->keyNamePath), $this->keyNameDepth => $this->owner->getAttribute($this->keyNameDepth)]);
  306 + }
  307 +
  308 + public function beforeUpdate()
  309 + {
  310 + if ($this->owner->getIsNewRecord()) {
  311 + throw new NotSupportedException('Method "' . $this->owner->className() . '::insert" is not supported for inserting new entitys.');
  312 + }
  313 + $this->withSave();
  314 + }
  315 +
  316 + protected function withSave() {
  317 + $id = $this->owner->getAttribute($this->keyNameId);
  318 + $parent_id = $this->owner->getAttribute($this->keyNameParentId);
  319 +
  320 + if (is_null($parent_id)) {
  321 + $parent_id = 0;
  322 + }
  323 +
  324 + // check parent_id value is changed!
  325 + /*if ($this->owner->getOldAttribute($this->keyNameParentId) == $parent_id) {
  326 + return;
  327 + }*/
  328 +
  329 + // rebuild parents entities
  330 + if ($parent_id == 0) {
  331 + $depth = 0;
  332 + $path = [intval($id)];
  333 + } else {
  334 + $parents = $this->getParentsAL();
  335 + $path = [];
  336 + $depth = 0;
  337 + foreach ($parents as $entity) {
  338 + $path[] = $entity->getAttribute($this->keyNameId);
  339 + $depth++;
  340 + }
  341 + $path[] = intval($id);
  342 + }
  343 +
  344 + $path = '{'. implode(',', $path) .'}';
  345 +
  346 + // rebuild children entities (recurcive)
  347 +// $this->_rebuildChildren([
  348 +// $this->keyNamePath => $path
  349 +// ]);
  350 +
  351 + $this->owner->setAttribute('path_int', $path);
  352 +// $this->owner->setAttribute($this->keyNamePath, $path);
  353 + $this->owner->setAttribute($this->keyNameDepth, $depth);
  354 + }
  355 +
  356 + public function _recursiveRebuildChildren() {
  357 + $children = $this->getChildrenAL()->all();
  358 + $root_path = explode(',', $this->owner->getAttribute($this->keyNamePath));
  359 + $root_depth = $this->owner->getAttribute($this->keyNameDepth);
  360 +
  361 + /** @var $child ActiveRecord */
  362 + foreach ($children as $child) {
  363 + $path = $root_path;
  364 + $path[] = $child->getAttribute($this->keyNameId);
  365 + $depth = $root_depth + 1;
  366 +
  367 + $child->_recursiveRebuildChildren();
  368 + }
  369 + }
  370 +}
0 371 \ No newline at end of file
... ...
common/components/artboxtree/ArtboxTreeHelper.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree;
  4 +
  5 +use yii\base\Object;
  6 +use yii\helpers\ArrayHelper;
  7 +
  8 +class ArtboxTreeHelper extends Object {
  9 + public static function treeMap($tree, $from, $to, $symbol = '.')
  10 + {
  11 + $result = [];
  12 +
  13 + self::_recursiveTreeMap($result, $tree, $from, $to, $symbol);
  14 +
  15 + return $result;
  16 + }
  17 +
  18 + protected static function _recursiveTreeMap(&$result, $tree, $from, $to, $symbol = '&ndash;') {
  19 + foreach ($tree as $item) {
  20 + $element = $item['item'];
  21 + $key = ArrayHelper::getValue($element, $from);
  22 + $value = ArrayHelper::getValue($element, $to);
  23 + $row = str_repeat($symbol, $element->depth+1) . $value;
  24 + $result[$key] = $row;
  25 + if (!empty($item['children'])) {
  26 + self::_recursiveTreeMap($result, $item['children'], $from, $to, $symbol);
  27 + }
  28 + }
  29 + }
  30 +}
0 31 \ No newline at end of file
... ...
common/components/artboxtree/ArtboxTreeQueryTrait.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree;
  4 +
  5 +use common\components\artboxtree\ArtboxTreeHelper;
  6 +
  7 +trait ArtboxTreeQueryTrait {
  8 +
  9 + static public $cache_tree = [];
  10 +
  11 + /** @var \yii\db\ActiveQuery $this */
  12 + static $model;
  13 +
  14 + /*
  15 + * @return \yii\db\ActiveQuery
  16 + */
  17 + private function getModel()
  18 + {
  19 + if (empty(self::$model)) {
  20 + $class = $this->modelClass;
  21 + self::$model = new $class;
  22 + }
  23 + return self::$model;
  24 + }
  25 +
  26 + public function getTree($group, $cached = true) {
  27 + if ($cached && isset(self::$cache_tree[$group]))
  28 + return self::$cache_tree[$group];
  29 +
  30 + $model = $this->getModel();
  31 + $data = $this->andWhere([$model->keyNameGroup => $group])->all();
  32 + if (empty($data))
  33 + return [];
  34 +
  35 + self::$cache_tree[$group] = $this->buildTree($data);
  36 +
  37 + return self::$cache_tree[$group];
  38 + }
  39 +
  40 + private function _recursiveRebuild($tree, $parentPath = null, $depth = 0) {
  41 + $model = $this->getModel();
  42 +
  43 + foreach ($tree as $row) {
  44 + $path = (is_null($parentPath) ? '' : $parentPath . $model->delimiter) . $row['item']->getAttribute($model->keyNameId);
  45 + $row['item']->setAttribute($model->keyNamePath, $path);
  46 + $row['item']->setAttribute($model->keyNameDepth, $depth);
  47 + $row['item']->save();
  48 + if (!empty($row['children'])) {
  49 + $this->_recursiveRebuild($row['children'], $path, $depth+1);
  50 + }
  51 + }
  52 + }
  53 +
  54 + /**
  55 + * @param int $group
  56 + */
  57 + public function rebuildMP($group) {
  58 + $tree = $this->getTree($group);
  59 +
  60 + $this->_recursiveRebuild($tree);
  61 + }
  62 +
  63 + protected function buildTree(array $data, $parentId = 0) {
  64 + $model = $this->getModel();
  65 +
  66 + $result = [];
  67 + foreach ($data as $element) {
  68 + if ($element[$model->keyNameParentId] == $parentId) {
  69 + $children = $this->buildTree($data, $element[$model->keyNameId]);
  70 + $result[] = [
  71 + 'item' => $element,
  72 + 'children' => $children
  73 + ];
  74 + }
  75 + }
  76 + return $result;
  77 + }
  78 +
  79 + public function normalizeTreeData(array $data, $parentId = null)
  80 + {
  81 + $model = $this->getModel();
  82 +
  83 + $result = [];
  84 + foreach ($data as $element) {
  85 + if ($element[$model->keyNameParentId] == $parentId) {
  86 + $result[] = $element;
  87 + $children = $this->normalizeTreeData($data, $element[$model->keyNameId]);
  88 + if ($children) {
  89 + $result = array_merge($result, $children);
  90 + }
  91 + }
  92 + }
  93 + return $result;
  94 + }
  95 +}
0 96 \ No newline at end of file
... ...
common/components/artboxtree/ArtboxTreeWidget.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree;
  4 +
  5 +use Yii;
  6 +use yii\base\Widget;
  7 +use yii\i18n\Formatter;
  8 +use yii\base\InvalidConfigException;
  9 +
  10 +class ArtboxTreeWidget extends Widget
  11 +{
  12 +
  13 + /**
  14 + * @var \yii\data\DataProviderInterface the data provider for the view. This property is required.
  15 + */
  16 + public $dataProvider;
  17 +
  18 + /**
  19 + * @var string
  20 + */
  21 + public $keyNameId = 'id';
  22 +
  23 + /**
  24 + * @var string
  25 + */
  26 + public $keyNameParentId = 'parent_id';
  27 +
  28 + /**
  29 + * @var integer or null
  30 + */
  31 + public $maxLevel = null;
  32 +
  33 + /**
  34 + * @var integer
  35 + */
  36 + public $rootParentId = 0;
  37 +
  38 + /**
  39 + * @var string
  40 + */
  41 + public $emptyResult;
  42 +
  43 + /**
  44 + * @var boolean include the CSS and JS files. Default is true.
  45 + * If this is set false, you are responsible to explicitly include the necessary CSS and JS files in your page.
  46 + */
  47 + public $assetBundle;
  48 +
  49 + /**
  50 + * @var array|Formatter the formatter used to format model attribute values into displayable texts.
  51 + * This can be either an instance of [[Formatter]] or an configuration array for creating the [[Formatter]]
  52 + * instance. If this property is not set, the "formatter" application component will be used.
  53 + */
  54 + public $formatter;
  55 +
  56 + /**
  57 + * Init the widget object.
  58 + */
  59 + public function init()
  60 + {
  61 + parent::init();
  62 + if ($this->dataProvider === null) {
  63 + throw new InvalidConfigException('The "dataProvider" property must be set.');
  64 + }
  65 + if ($this->keyNameId === null) {
  66 + throw new InvalidConfigException('The "keyNameId" property must be set.');
  67 + }
  68 + if ($this->formatter == null) {
  69 + $this->formatter = Yii::$app->getFormatter();
  70 + } elseif (is_array($this->formatter)) {
  71 + $this->formatter = Yii::createObject($this->formatter);
  72 + }
  73 + if (!$this->formatter instanceof Formatter) {
  74 + throw new InvalidConfigException('The "formatter" property must be either a Format object or a configuration array.');
  75 + }
  76 + }
  77 +
  78 + /**
  79 + * Runs the widget.
  80 + */
  81 + public function run()
  82 + {
  83 + if (!empty($this->assetBundle) && class_exists($this->assetBundle)) {
  84 + $view = $this->getView();
  85 + $assetBundle = $this->assetBundle;
  86 + $assetBundle::register($view);
  87 + }
  88 + if ($this->dataProvider->getCount() == 0) {
  89 + return $this->renderEmptyResult();
  90 + }
  91 +
  92 + parent::run();
  93 + }
  94 +
  95 + protected function renderEmptyResult() {
  96 + return empty($this->emptyResult) ? Yii::t('artbox', 'TreeViewEmptyResult') : Yii::t('artbox', $this->emptyResult);
  97 + }
  98 +
  99 + /**
  100 + * Normalize tree data
  101 + * @param array $data
  102 + * @param string $parentId
  103 + * @return array
  104 + */
  105 + protected function _normalizeTreeData(array $data, $parentId = null) {
  106 + $result = [];
  107 + foreach ($data as $element) {
  108 + if ($element[$this->keyNameParentId] == $parentId) {
  109 + $result[] = $element;
  110 + $children = $this->_normalizeTreeData($data, $element[$this->keyNameId]);
  111 + if ($children) {
  112 + $result = array_merge($result, $children);
  113 + }
  114 + }
  115 + }
  116 + return $result;
  117 + }
  118 +
  119 + /**
  120 + * Hierarchy tree data
  121 + * @param array $data
  122 + * @param string $parentId
  123 + * @return array
  124 + */
  125 + protected function _hierarchyTreeData(array $data, $parentId = null) {
  126 + $result = [];
  127 + foreach ($data as $element) {
  128 + if ($element[$this->keyNameParentId] == $parentId) {
  129 + $children = $this->_hierarchyTreeData($data, $element[$this->keyNameId]);
  130 + $result[] = [
  131 + 'item' => $element,
  132 + 'children' => $children
  133 + ];
  134 + }
  135 + }
  136 + return $result;
  137 + }
  138 +}
0 139 \ No newline at end of file
... ...
common/components/artboxtree/treegrid/TreeGridColumn.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree\treegrid;
  4 +
  5 +use Closure;
  6 +use Yii;
  7 +use yii\base\Model;
  8 +use yii\base\Object;
  9 +use yii\data\ActiveDataProvider;
  10 +use yii\db\ActiveQueryInterface;
  11 +use yii\helpers\ArrayHelper;
  12 +use yii\helpers\Html;
  13 +use yii\helpers\Inflector;
  14 +
  15 +/**
  16 + * Column is the base class of all [[TreeGrid]] column classes.
  17 + * The code was based in: https://github.com/yiisoft/yii2/blob/master/framework/grid/DataColumn.php
  18 + *
  19 + * @author Leandro Gehlen <leandrogehlen@gmail.com>
  20 + */
  21 +class TreeGridColumn extends Object {
  22 +
  23 + /**
  24 + * @var TreeGrid the grid view object that owns this column.
  25 + */
  26 + public $grid;
  27 +
  28 + /**
  29 + * @var string the header cell content. Note that it will not be HTML-encoded.
  30 + */
  31 + public $header;
  32 +
  33 + /**
  34 + * @var string the footer cell content. Note that it will not be HTML-encoded.
  35 + */
  36 + public $footer;
  37 +
  38 + /**
  39 + * @var callable This is a callable that will be used to generate the content of each cell.
  40 + * The signature of the function should be the following: `function ($model, $key, $index, $column)`.
  41 + * Where `$model`, `$key`, and `$index` refer to the model, key and index of the row currently being rendered
  42 + * and `$column` is a reference to the [[TreeColumn]] object.
  43 + */
  44 + public $content;
  45 +
  46 + /**
  47 + * @var boolean whether this column is visible. Defaults to true.
  48 + */
  49 + public $visible = true;
  50 +
  51 + /**
  52 + * @var array the HTML attributes for the column group tag.
  53 + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  54 + */
  55 + public $options = [];
  56 +
  57 + /**
  58 + * @var array the HTML attributes for the header cell tag.
  59 + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  60 + */
  61 + public $headerOptions = [];
  62 +
  63 + /**
  64 + * @var array|\Closure the HTML attributes for the data cell tag. This can either be an array of
  65 + * attributes or an anonymous function ([[Closure]]) that returns such an array.
  66 + * The signature of the function should be the following: `function ($model, $key, $index, $column)`.
  67 + * Where `$model`, `$key`, and `$index` refer to the model, key and index of the row currently being rendered
  68 + * and `$column` is a reference to the [[Column]] object.
  69 + * A function may be used to assign different attributes to different rows based on the data in that row.
  70 + *
  71 + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  72 + */
  73 + public $contentOptions = [];
  74 +
  75 + /**
  76 + * @var array the HTML attributes for the footer cell tag.
  77 + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  78 + */
  79 + public $footerOptions = [];
  80 +
  81 + /**
  82 + * @var string the attribute name associated with this column. When neither [[content]] nor [[value]]
  83 + * is specified, the value of the specified attribute will be retrieved from each data model and displayed.
  84 + *
  85 + * Also, if [[label]] is not specified, the label associated with the attribute will be displayed.
  86 + */
  87 + public $attribute;
  88 +
  89 + /**
  90 + * @var string label to be displayed in the [[header|header cell]] and also to be used as the sorting
  91 + * link label when sorting is enabled for this column.
  92 + * If it is not set and the models provided by the GridViews data provider are instances
  93 + * of [[\yii\db\ActiveRecord]], the label will be determined using [[\yii\db\ActiveRecord::getAttributeLabel()]].
  94 + * Otherwise [[\yii\helpers\Inflector::camel2words()]] will be used to get a label.
  95 + */
  96 + public $label;
  97 +
  98 + /**
  99 + * @var boolean whether the header label should be HTML-encoded.
  100 + * @see label
  101 + */
  102 + public $encodeLabel = true;
  103 +
  104 + /**
  105 + * @var string|\Closure an anonymous function or a string that is used to determine the value to display in the current column.
  106 + *
  107 + * If this is an anonymous function, it will be called for each row and the return value will be used as the value to
  108 + * display for every data model. The signature of this function should be: `function ($model, $key, $index, $column)`.
  109 + * Where `$model`, `$key`, and `$index` refer to the model, key and index of the row currently being rendered
  110 + * and `$column` is a reference to the [[DataColumn]] object.
  111 + *
  112 + * You may also set this property to a string representing the attribute name to be displayed in this column.
  113 + * This can be used when the attribute to be displayed is different from the [[attribute]] that is used for
  114 + * sorting and filtering.
  115 + *
  116 + * If this is not set, `$model[$attribute]` will be used to obtain the value, where `$attribute` is the value of [[attribute]].
  117 + */
  118 + public $value;
  119 +
  120 + /**
  121 + * @var string|array in which format should the value of each data model be displayed as (e.g. `"raw"`, `"text"`, `"html"`,
  122 + * `['date', 'php:Y-m-d']`). Supported formats are determined by the [[GridView::formatter|formatter]] used by
  123 + * the [[GridView]]. Default format is "text" which will format the value as an HTML-encoded plain text when
  124 + * [[\yii\i18n\Formatter]] is used as the [[GridView::$formatter|formatter]] of the GridView.
  125 + */
  126 + public $format = 'text';
  127 +
  128 + /**
  129 + * Renders the header cell.
  130 + */
  131 + public function renderHeaderCell()
  132 + {
  133 + return Html::tag('th', $this->renderHeaderCellContent(), $this->headerOptions);
  134 + }
  135 +
  136 + /**
  137 + * Renders the footer cell.
  138 + */
  139 + public function renderFooterCell()
  140 + {
  141 + return Html::tag('td', $this->renderFooterCellContent(), $this->footerOptions);
  142 + }
  143 +
  144 + /**
  145 + * Renders a data cell.
  146 + * @param mixed $model the data model being rendered
  147 + * @param mixed $key the key associated with the data model
  148 + * @param integer $index the zero-based index of the data item among the item array returned by [[GridView::dataProvider]].
  149 + * @return string the rendering result
  150 + */
  151 + public function renderDataCell($model, $key, $index, $is_first = false, $symbol = '&ndash;')
  152 + {
  153 + if ($this->contentOptions instanceof Closure) {
  154 + $options = call_user_func($this->contentOptions, $model, $key, $index, $this);
  155 + } else {
  156 + $options = $this->contentOptions;
  157 + }
  158 + return Html::tag('td', ($is_first ? str_repeat($symbol, $model->depth) : '') . $this->renderDataCellContent($model, $key, $index), $options);
  159 + }
  160 +
  161 + /**
  162 + * Renders the header cell content.
  163 + * The default implementation simply renders [[header]].
  164 + * This method may be overridden to customize the rendering of the header cell.
  165 + * @return string the rendering result
  166 + */
  167 + protected function renderHeaderCellContent()
  168 + {
  169 + if ($this->header !== null || $this->label === null && $this->attribute === null) {
  170 + return trim($this->header) !== '' ? $this->header : $this->grid->emptyCell;
  171 + }
  172 +
  173 + $provider = $this->grid->dataProvider;
  174 +
  175 + if ($this->label === null) {
  176 + if ($provider instanceof ActiveDataProvider && $provider->query instanceof ActiveQueryInterface) {
  177 + /* @var $model Model */
  178 + $model = new $provider->query->modelClass;
  179 + $label = $model->getAttributeLabel($this->attribute);
  180 + } else {
  181 + $models = $provider->getModels();
  182 + if (($model = reset($models)) instanceof Model) {
  183 + /* @var $model Model */
  184 + $label = $model->getAttributeLabel($this->attribute);
  185 + } else {
  186 + $label = Inflector::camel2words($this->attribute);
  187 + }
  188 + }
  189 + } else {
  190 + $label = $this->label;
  191 + }
  192 +
  193 + return $this->encodeLabel ? Html::encode($label) : $label;
  194 + }
  195 +
  196 + /**
  197 + * Renders the footer cell content.
  198 + * The default implementation simply renders [[footer]].
  199 + * This method may be overridden to customize the rendering of the footer cell.
  200 + * @return string the rendering result
  201 + */
  202 + protected function renderFooterCellContent()
  203 + {
  204 + return trim($this->footer) !== '' ? $this->footer : $this->grid->emptyCell;
  205 + }
  206 +
  207 + /**
  208 + * Renders the data cell content.
  209 + * @param mixed $model the data model
  210 + * @param mixed $key the key associated with the data model
  211 + * @param integer $index the zero-based index of the data model among the models array returned by [[GridView::dataProvider]].
  212 + * @return string the rendering result
  213 + */
  214 + protected function renderDataCellContent($model, $key, $index)
  215 + {
  216 + if ($this->content === null) {
  217 + return $this->grid->formatter->format($this->getDataCellValue($model, $key, $index), $this->format);
  218 + } else {
  219 + if ($this->content !== null) {
  220 + return call_user_func($this->content, $model, $key, $index, $this);
  221 + } else {
  222 + return $this->grid->emptyCell;
  223 + }
  224 + }
  225 +
  226 +
  227 + }
  228 +
  229 + /**
  230 + * Returns the data cell value.
  231 + * @param mixed $model the data model
  232 + * @param mixed $key the key associated with the data model
  233 + * @param integer $index the zero-based index of the data model among the models array returned by [[GridView::dataProvider]].
  234 + * @return string the data cell value
  235 + */
  236 + public function getDataCellValue($model, $key, $index)
  237 + {
  238 + if ($this->value !== null) {
  239 + if (is_string($this->value)) {
  240 + return ArrayHelper::getValue($model, $this->value);
  241 + } else {
  242 + return call_user_func($this->value, $model, $key, $index, $this);
  243 + }
  244 + } elseif ($this->attribute !== null) {
  245 + return ArrayHelper::getValue($model, $this->attribute);
  246 + }
  247 + return null;
  248 + }
  249 +
  250 +}
0 251 \ No newline at end of file
... ...
common/components/artboxtree/treegrid/TreeGridWidget.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree\treegrid;
  4 +
  5 +use common\modules\rubrication\models\TaxOption;
  6 +use Yii;
  7 +use yii\helpers\Html;
  8 +use yii\helpers\ArrayHelper;
  9 +
  10 +class TreeGridWidget extends \common\components\artboxtree\ArtboxTreeWidget {
  11 +
  12 + /**
  13 + * @var array grid column configuration. Each array element represents the configuration
  14 + * for one particular grid column.
  15 + * @see \yii\grid::$columns for details.
  16 + */
  17 + public $columns = [];
  18 +
  19 + /**
  20 + * @var string the default data column class if the class name is not explicitly specified when configuring a data column.
  21 + * Defaults to 'leandrogehlen\treegrid\TreeGridColumn'.
  22 + */
  23 + public $dataColumnClass;
  24 +
  25 + /**
  26 + * @var array the HTML attributes for the container tag of the grid view.
  27 + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  28 + */
  29 + public $options = ['class' => 'table table-striped table-bordered'];
  30 +
  31 + /**
  32 + * @var array The plugin options
  33 + */
  34 + public $pluginOptions = [];
  35 +
  36 + /**
  37 + * @var boolean whether to show the grid view if [[dataProvider]] returns no data.
  38 + */
  39 + public $showOnEmpty = true;
  40 +
  41 + public $rowOptions = [];
  42 +
  43 + /**
  44 + * @var Closure an anonymous function that is called once BEFORE rendering each data model.
  45 + * It should have the similar signature as [[rowOptions]]. The return result of the function
  46 + * will be rendered directly.
  47 + */
  48 + public $beforeRow;
  49 +
  50 + /**
  51 + * @var Closure an anonymous function that is called once AFTER rendering each data model.
  52 + * It should have the similar signature as [[rowOptions]]. The return result of the function
  53 + * will be rendered directly.
  54 + */
  55 + public $afterRow;
  56 +
  57 + /**
  58 + * @var boolean whether to show the header section of the grid table.
  59 + */
  60 + public $showHeader = true;
  61 +
  62 + /**
  63 + * @var array the HTML attributes for the table header row.
  64 + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  65 + */
  66 + public $headerRowOptions = [];
  67 +
  68 + /**
  69 + * @var boolean whether to show the footer section of the grid table.
  70 + */
  71 + public $showFooter = false;
  72 +
  73 + /**
  74 + * @var string the HTML display when the content of a cell is empty
  75 + */
  76 + public $emptyCell = '&nbsp;';
  77 +
  78 + public $levelSymbol = '&ndash;';
  79 +
  80 + /**
  81 + * Init the widget object.
  82 + */
  83 + public function init() {
  84 + parent::init();
  85 +
  86 + $this->initColumns();
  87 + }
  88 +
  89 + /**
  90 + * Runs the widget.
  91 + */
  92 + public function run() {
  93 + $run = parent::run();
  94 + if (!is_null($run))
  95 + return $run;
  96 +
  97 + if ($this->showOnEmpty || $this->dataProvider->getCount() > 0) {
  98 + $pagination = $this->dataProvider->getPagination();
  99 + $pagination->setPageSize($this->dataProvider->getTotalCount());
  100 +
  101 + $header = $this->showHeader ? $this->renderTableHeader() : false;
  102 + $body = $this->renderItems();
  103 + $footer = $this->showFooter ? $this->renderTableFooter() : false;
  104 +
  105 + $content = array_filter([
  106 + $header,
  107 + $body,
  108 + $footer
  109 + ]);
  110 +
  111 + return Html::tag('table', implode("\n", $content), $this->options);
  112 + } else {
  113 + return $this->renderEmptyResult();
  114 + }
  115 + }
  116 +
  117 + /**
  118 + * Renders the table header.
  119 + * @return string the rendering result.
  120 + */
  121 + public function renderTableHeader()
  122 + {
  123 + $cells = [];
  124 + foreach ($this->columns as $column) {
  125 + /* @var $column TreeGridColumn */
  126 + $cells[] = $column->renderHeaderCell();
  127 + }
  128 + $content = Html::tag('tr', implode('', $cells), $this->headerRowOptions);
  129 + return "<thead>\n" . $content . "\n</thead>";
  130 + }
  131 +
  132 + /**
  133 + * Renders the table footer.
  134 + * @return string the rendering result.
  135 + */
  136 + public function renderTableFooter()
  137 + {
  138 + $cells = [];
  139 + foreach ($this->columns as $column) {
  140 + /* @var $column TreeGridColumn */
  141 + $cells[] = $column->renderFooterCell();
  142 + }
  143 + $content = Html::tag('tr', implode('', $cells), $this->footerRowOptions);
  144 + return "<tfoot>\n" . $content . "\n</tfoot>";
  145 + }
  146 +
  147 + /**
  148 + * Renders the data models for the grid view.
  149 + */
  150 + public function renderItems()
  151 + {
  152 + $rows = [];
  153 + $models = array_values($this->dataProvider->getModels());
  154 + $keys = $this->dataProvider->getKeys();
  155 + $models = TaxOption::find()->normalizeTreeData($models, $this->rootParentId);
  156 + foreach ($models as $index => $model) {
  157 + $key = $keys[$index];
  158 + if ($this->beforeRow !== null) {
  159 + $row = call_user_func($this->beforeRow, $model, $key, $index, $this);
  160 + if (!empty($row)) {
  161 + $rows[] = $row;
  162 + }
  163 + }
  164 +
  165 + $rows[] = $this->renderTableRow($model, $key, $index);
  166 +
  167 + if ($this->afterRow !== null) {
  168 + $row = call_user_func($this->afterRow, $model, $key, $index, $this);
  169 + if (!empty($row)) {
  170 + $rows[] = $row;
  171 + }
  172 + }
  173 + }
  174 +
  175 + if (empty($rows)) {
  176 + $colspan = count($this->columns);
  177 + return "<tr><td colspan=\"$colspan\">" . $this->renderEmpty() . "</td></tr>";
  178 + } else {
  179 + return implode("\n", $rows);
  180 + }
  181 + }
  182 +
  183 + /**
  184 + * Renders a table row with the given data model and key.
  185 + * @param mixed $model the data model to be rendered
  186 + * @param mixed $key the key associated with the data model
  187 + * @param integer $index the zero-based index of the data model among the model array returned by [[dataProvider]].
  188 + * @return string the rendering result
  189 + */
  190 + public function renderTableRow($model, $key, $index)
  191 + {
  192 + $cells = [];
  193 + /* @var $column TreeGridColumn */
  194 + $i = 0;
  195 + foreach ($this->columns as $column) {
  196 + $cells[] = $column->renderDataCell($model, $key, $index, $i == 0, $this->levelSymbol);
  197 + $i++;
  198 + }
  199 + if ($this->rowOptions instanceof Closure) {
  200 + $options = call_user_func($this->rowOptions, $model, $key, $index, $this);
  201 + } else {
  202 + $options = $this->rowOptions;
  203 + }
  204 + $options['data-key'] = is_array($key) ? json_encode($key) : (string) $key;
  205 +
  206 + $id = ArrayHelper::getValue($model, $this->keyNameId);
  207 + Html::addCssClass($options, "treegrid-$id");
  208 +
  209 + $parentId = ArrayHelper::getValue($model, $this->keyNameParentId);
  210 + if ($parentId) {
  211 + Html::addCssClass($options, "treegrid-parent-$parentId");
  212 + }
  213 +
  214 + return Html::tag('tr', implode('', $cells), $options);
  215 + }
  216 +
  217 + /**
  218 + * Creates column objects and initializes them.
  219 + */
  220 + protected function initColumns()
  221 + {
  222 + if (empty($this->columns)) {
  223 + $this->guessColumns();
  224 + }
  225 + foreach ($this->columns as $i => $column) {
  226 + if (is_string($column)) {
  227 + $column = $this->createDataColumn($column);
  228 + } else {
  229 + $column = Yii::createObject(array_merge([
  230 + 'class' => $this->dataColumnClass ? : TreeGridColumn::className(),
  231 + 'grid' => $this,
  232 + ], $column));
  233 + }
  234 + if (!$column->visible) {
  235 + unset($this->columns[$i]);
  236 + continue;
  237 + }
  238 + $this->columns[$i] = $column;
  239 + }
  240 + }
  241 +
  242 + /**
  243 + * Creates a [[DataColumn]] object based on a string in the format of "attribute:format:label".
  244 + * @param string $text the column specification string
  245 + * @return DataColumn the column instance
  246 + * @throws InvalidConfigException if the column specification is invalid
  247 + */
  248 + protected function createDataColumn($text)
  249 + {
  250 + if (!preg_match('/^([^:]+)(:(\w*))?(:(.*))?$/', $text, $matches)) {
  251 + throw new InvalidConfigException('The column must be specified in the format of "attribute", "attribute:format" or "attribute:format:label"');
  252 + }
  253 +
  254 + return Yii::createObject([
  255 + 'class' => $this->dataColumnClass ? : TreeGridColumn::className(),
  256 + 'grid' => $this,
  257 + 'attribute' => $matches[1],
  258 + 'format' => isset($matches[3]) ? $matches[3] : 'text',
  259 + 'label' => isset($matches[5]) ? $matches[5] : null,
  260 + ]);
  261 + }
  262 +
  263 + /**
  264 + * This function tries to guess the columns to show from the given data
  265 + * if [[columns]] are not explicitly specified.
  266 + */
  267 + protected function guessColumns()
  268 + {
  269 + $models = $this->dataProvider->getModels();
  270 + $model = reset($models);
  271 + if (is_array($model) || is_object($model)) {
  272 + foreach ($model as $name => $value) {
  273 + $this->columns[] = $name;
  274 + }
  275 + }
  276 + }
  277 +}
0 278 \ No newline at end of file
... ...
common/components/artboxtree/treelist/TreeListWidget.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree\treelist;
  4 +
  5 +use Yii;
  6 +use yii\helpers\Html;
  7 +use yii\helpers\ArrayHelper;
  8 +
  9 +class TreeListWidget extends \common\components\artboxtree\ArtboxTreeWidget {
  10 +
  11 + public $displayField = 'name';
  12 +
  13 + /**
  14 + * Init the widget object.
  15 + */
  16 + public function init() {
  17 + parent::init();
  18 + }
  19 +
  20 + /**
  21 + * Runs the widget.
  22 + */
  23 + public function run() {
  24 + $run = parent::run();
  25 + if (!is_null($run))
  26 + return $run;
  27 +
  28 + $models = $this->_hierarchyTreeData(array_values($this->dataProvider->getModels()), $this->rootParentId);
  29 + return $this->renderTreelist($models);
  30 + }
  31 +
  32 + protected function renderTreelist($models) {
  33 + foreach ($models as $index => $model) {
  34 + $row = $this->renderTreelistItem($model['item']);
  35 + $children = empty($model['children']) ? '' : $this->renderTreelist($model['children']);
  36 + $output[] = '<li>'. $row . $children .'</li>';
  37 + }
  38 +
  39 + if (!empty($output))
  40 + return '<ul>'. implode("\n", $output) .'</ul>';
  41 + }
  42 +
  43 + protected function renderTreelistItem($model)
  44 + {
  45 + $options = [];
  46 + $id = ArrayHelper::getValue($model, $this->keyNameId);
  47 + Html::addCssClass($options, "treelistitem-$id");
  48 +
  49 + $parent_id = ArrayHelper::getValue($model, $this->keyNameParentId);
  50 + if ($parent_id) {
  51 + Html::addCssClass($options, "treelistitem-parent-$parent_id");
  52 + }
  53 +
  54 +// if (is_string($this->value)) {
  55 +// return ArrayHelper::getValue($model, $this->value);
  56 +// } else {
  57 +// return call_user_func($this->value, $model, $key, $index, $this);
  58 +// }
  59 +
  60 + return Html::tag('span', ArrayHelper::getValue($model, $this->displayField), $options);
  61 + }
  62 +}
0 63 \ No newline at end of file
... ...
common/components/artboxtree/treemenu/TreeMenuWidget.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\components\artboxtree\treemenu;
  4 +
  5 +use Yii;
  6 +use yii\helpers\Html;
  7 +use yii\helpers\ArrayHelper;
  8 +
  9 +class TreeMenuWidget extends \common\components\artboxtree\ArtboxTreeWidget {
  10 +
  11 + public $displayField = 'name';
  12 +
  13 + /**
  14 + * Init the widget object.
  15 + */
  16 + public function init() {
  17 + parent::init();
  18 + }
  19 +
  20 + /**
  21 + * Runs the widget.
  22 + */
  23 + public function run() {
  24 + $run = parent::run();
  25 + if (!is_null($run))
  26 + return $run;
  27 +
  28 + $models = $this->_hierarchyTreeData(array_values($this->dataProvider->getModels()), $this->rootParentId);
  29 + return $this->renderTreelist($models);
  30 + }
  31 +
  32 + protected function renderTreelist($models) {
  33 + foreach ($models as $index => $model) {
  34 + $row = $this->renderTreelistItem($model['item']);
  35 + $children = empty($model['children']) ? '' : $this->renderTreelist($model['children']);
  36 + $output[] = '<li>'. $row . $children .'</li>';
  37 + }
  38 +
  39 + if (!empty($output))
  40 + return '<ul>'. implode("\n", $output) .'</ul>';
  41 + }
  42 +
  43 + protected function renderTreelistItem($model)
  44 + {
  45 + $options = [];
  46 + $id = ArrayHelper::getValue($model, $this->keyNameId);
  47 + Html::addCssClass($options, "treelistitem-$id");
  48 +
  49 + $parent_id = ArrayHelper::getValue($model, $this->keyNameParentId);
  50 + if ($parent_id) {
  51 + Html::addCssClass($options, "treelistitem-parent-$parent_id");
  52 + }
  53 +
  54 +// if (is_string($this->value)) {
  55 +// return ArrayHelper::getValue($model, $this->value);
  56 +// } else {
  57 +// return call_user_func($this->value, $model, $key, $index, $this);
  58 +// }
  59 +
  60 + return Html::tag('span', ArrayHelper::getValue($model, $this->displayField), $options);
  61 + }
  62 +}
0 63 \ No newline at end of file
... ...
common/config/.gitignore 0 โ†’ 100644
  1 +main-local.php
  2 +params-local.php
... ...
common/config/bootstrap.php 0 โ†’ 100644
  1 +<?php
  2 +Yii::setAlias('@common', dirname(__DIR__));
  3 +Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
  4 +Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
  5 +Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');
  6 +Yii::setAlias('storage', dirname(dirname(__DIR__)) . '/storage');
... ...
common/config/main.php 0 โ†’ 100644
  1 +<?php
  2 +return [
  3 + 'language' => 'ru-RU',
  4 + 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
  5 + 'controllerMap' => [
  6 + 'elfinder' => [
  7 + 'class' => 'mihaildev\elfinder\Controller',
  8 + 'access' => ['@'], //ะณะปะพะฑะฐะปัŒะฝั‹ะน ะดะพัั‚ัƒะฟ ะบ ั„ะฐะธะป ะผะตะฝะตะดะถะตั€ัƒ @ - ะดะปั ะฐะฒั‚ะพั€ะธะทะพั€ะพะฒะฐะฝะฝั‹ั… , ? - ะดะปั ะณะพัั‚ะตะน , ั‡ั‚ะพะฑ ะพั‚ะบั€ั‹ั‚ัŒ ะฒัะตะผ ['@', '?']
  9 + 'disabledCommands' => ['netmount'], //ะพั‚ะบะปัŽั‡ะตะฝะธะต ะฝะตะฝัƒะถะฝั‹ั… ะบะพะผะฐะฝะด https://github.com/Studio-42/elFinder/wiki/Client-configuration-options#commands
  10 + 'roots' => [
  11 + [
  12 + 'class' => 'mihaildev\elfinder\UserPath',
  13 + 'path' => '../../storage/user_{id}',
  14 + 'name' => 'My Documents'
  15 + ],
  16 + ],
  17 + 'watermark' => [
  18 + 'source' => __DIR__.'/logo.png', // Path to Water mark image
  19 + 'marginRight' => 5, // Margin right pixel
  20 + 'marginBottom' => 5, // Margin bottom pixel
  21 + 'quality' => 95, // JPEG image save quality
  22 + 'transparency' => 70, // Water mark image transparency ( other than PNG )
  23 + 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
  24 + 'targetMinPixel' => 200 // Target image minimum pixel size
  25 + ]
  26 + ],
  27 + 'artbox-comment' => [
  28 + 'class' => \common\modules\comment\Controller::className(),
  29 + ],
  30 + ],
  31 + 'components' => [
  32 + 'assetManager' => [
  33 + 'bundles' => [
  34 + 'yii\web\JqueryAsset' =>[
  35 + 'jsOptions' => ['position' => \yii\web\View::POS_HEAD]
  36 + ]
  37 + ],
  38 + ],
  39 + 'cache' => [
  40 + 'class' => 'yii\caching\FileCache',
  41 + ],
  42 + 'urlManager' => [
  43 + 'enablePrettyUrl' => true,
  44 + 'showScriptName' => false,
  45 + 'rules' => [
  46 + 'module/<module:\w+>/<controller:\w+>/<action:\w+>' => '<module>/<controller>/<action>',
  47 + ]
  48 + ],
  49 + 'i18n' => [
  50 + 'translations' => [
  51 + '*' => [
  52 + 'class' => 'yii\i18n\PhpMessageSource',
  53 + 'basePath' => '@common/translation',
  54 + 'fileMap' => [
  55 + 'app' => 'app.php',
  56 + 'app/error' => 'error.php',
  57 + ],
  58 + ],
  59 + 'app' => [
  60 + 'class' => 'yii\i18n\PhpMessageSource',
  61 + 'basePath' => '@common/translation',
  62 + 'fileMap' => [
  63 + 'app' => 'app.php',
  64 + 'app/error' => 'error.php',
  65 + ],
  66 + ],
  67 + ],
  68 + ],
  69 + ],
  70 +
  71 + 'modules' => [
  72 + 'file' => [
  73 + 'class' => 'common\modules\file\Module',
  74 + ],
  75 + 'relation' => [
  76 + 'class' => 'common\modules\relation\Module',
  77 + 'relations' => [
  78 + 'product_categories' => [
  79 + 'name' => Yii::t('product', 'Categories'),
  80 + 'field' => 'categories',
  81 + 'entity1' => [
  82 + 'model' => '\common\modules\product\models\Product',
  83 + 'label' => 'Product',
  84 + 'listField' => 'fullname',
  85 + 'key' => 'product_id',
  86 + 'linked_key' => 'product_id',
  87 + ],
  88 + 'entity2' => [
  89 + 'model' => '\common\modules\rubrication\models\TaxOption',
  90 + 'label' => 'Category',
  91 + 'listField' => 'ValueRenderFlash',
  92 + 'key' => 'tax_option_id',
  93 + 'linked_key' => 'category_id',
  94 + 'where' => [
  95 + 'tax_group_id' => 1
  96 + ],
  97 + 'hierarchy' => [
  98 + 'key' => 'tax_option_id',
  99 + 'parentKey' => 'parent_id',
  100 + ]
  101 + ],
  102 + 'via' => [
  103 + 'model' => '\common\modules\product\models\ProductCategory',
  104 + ]
  105 + ],
  106 + 'relation_categories' => [
  107 + 'name' => Yii::t('relation', 'Relation categories'),
  108 + 'field' => 'categories',
  109 + 'entity1' => [
  110 + 'model' => '\common\modules\product\models\Product',
  111 + 'label' => 'Product',
  112 + 'listField' => 'fullname',
  113 + 'key' => 'product_id',
  114 + 'linked_key' => 'product_id',
  115 + ],
  116 + 'entity2' => [
  117 + 'model' => '\common\modules\rubrication\models\TaxOption',
  118 + 'label' => 'Category',
  119 + 'listField' => 'ValueRenderFlash',
  120 + 'key' => 'tax_option_id',
  121 + 'linked_key' => 'category_id',
  122 + 'where' => [
  123 + 'tax_group_id' => 1
  124 + ]
  125 + ],
  126 + 'via' => [
  127 + 'model' => '\common\modules\relation\models\Relation',
  128 + 'alias' => 'alias',
  129 + ]
  130 + ],
  131 + 'tax_option_to_group' => [
  132 + 'name' => 'Options-Groups',
  133 + 'field' => 'tax_option_to_group',
  134 + 'linked_table' => 'tax_option_to_group',
  135 + 'entity1' => [
  136 + 'label' => 'Option',
  137 + 'listField' => 'ValueRenderFlash',
  138 + 'model' => '\common\modules\rubrication\models\TaxOption',
  139 + 'key' => 'tax_option_id',
  140 + 'linked_key' => 'tax_option_id',
  141 + ],
  142 + 'entity2' => [
  143 + 'label' => 'Group',
  144 + 'listField' => 'name',
  145 + 'model' => '\common\modules\rubrication\models\TaxGroup',
  146 + 'key' => 'tax_group_id',
  147 + 'linked_key' => 'tax_group_id',
  148 + ],
  149 + 'via' => [
  150 + 'model' => 'common\modules\rubrication\models\TaxOptionToGroup',
  151 + 'alias' => 'alias',
  152 + ]
  153 + ],
  154 + 'tax_option_to_option' => [
  155 + 'name' => 'Options-Options',
  156 + 'field' => 'tax_option_to_option',
  157 + 'entity1' => [
  158 + 'label' => 'Option',
  159 + 'listField' => 'ValueRenderFlash',
  160 + 'model' => '\common\modules\rubrication\models\TaxOption',
  161 + 'key' => 'tax_option_id',
  162 + 'linked_key' => 'tax_option1_id',
  163 + ],
  164 + 'entity2' => [
  165 + 'label' => 'Option',
  166 + 'listField' => 'ValueRenderFlash',
  167 + 'model' => '\common\modules\rubrication\models\TaxOption',
  168 + 'key' => 'tax_option_id',
  169 + 'linked_key' => 'tax_option2_id',
  170 + ],
  171 + 'via' => [
  172 + 'model' => 'common\modules\rubrication\models\TaxOptionRelation',
  173 + 'alias' => 'alias',
  174 + ]
  175 + ],
  176 + 'brand_cats' => [
  177 + 'name' => 'ะšะฐั‚ะตะณะพั€ะธะธ ะฟั€ะพะธะทะฒะพะดะธั‚ะตะปะตะน',
  178 + 'field' => 'tax_option_to_option',
  179 + 'entity1' => [
  180 + 'label' => 'ะ‘ั€ะตะฝะด',
  181 + 'listField' => 'ValueRenderFlash',
  182 + 'model' => '\common\modules\rubrication\models\TaxOption',
  183 + 'key' => 'tax_option_id',
  184 + 'linked_key' => 'tax_option1_id',
  185 + ],
  186 + 'entity2' => [
  187 + 'label' => 'ะšะฐั‚ะตะณะพั€ะธั',
  188 + 'listField' => 'ValueRenderFlash',
  189 + 'model' => '\common\modules\rubrication\models\TaxOption',
  190 + 'key' => 'tax_option_id',
  191 + 'linked_key' => 'tax_option2_id',
  192 + ],
  193 + 'via' => [
  194 + 'model' => 'common\modules\rubrication\models\TaxOptionRelation',
  195 + 'alias' => 'alias',
  196 + ]
  197 + ]
  198 + ]
  199 + ],
  200 + 'comment' => [
  201 + 'class' => 'common\modules\comment\Module',
  202 + 'useRbac' => true,
  203 + 'rbac' => [
  204 + 'rules' => [
  205 + \common\modules\comment\rbac\ArtboxCommentCreateRule::className(),
  206 + \common\modules\comment\rbac\ArtboxCommentDeleteRule::className(),
  207 + \common\modules\comment\rbac\ArtboxCommentUpdateRule::className(),
  208 + \common\modules\comment\rbac\ArtboxCommentUpdateOwnRule::className(),
  209 + \common\modules\comment\rbac\ArtboxCommentDeleteOwnRule::className(),
  210 + ],
  211 + 'permissions' => [
  212 + [
  213 + 'name' => common\modules\comment\Permissions::CREATE,
  214 + 'description' => 'Can create comments',
  215 + 'ruleName' =>(new \common\modules\comment\rbac\ArtboxCommentCreateRule())->name,
  216 + ],
  217 + [
  218 + 'name' => common\modules\comment\Permissions::UPDATE,
  219 + 'description' => 'Can update comments',
  220 + 'ruleName' =>(new \common\modules\comment\rbac\ArtboxCommentUpdateRule())->name,
  221 + ],
  222 + [
  223 + 'name' => common\modules\comment\Permissions::DELETE,
  224 + 'description' => 'Can delete comments',
  225 + 'ruleName' =>(new \common\modules\comment\rbac\ArtboxCommentDeleteRule())->name,
  226 + ],
  227 + [
  228 + 'name' => common\modules\comment\Permissions::UPDATE_OWN,
  229 + 'description' => 'Can update own comments',
  230 + 'ruleName' =>(new \common\modules\comment\rbac\ArtboxCommentUpdateOwnRule())->name,
  231 + ],
  232 + [
  233 + 'name' => common\modules\comment\Permissions::DELETE_OWN,
  234 + 'description' => 'Can delete own comments',
  235 + 'ruleName' =>(new \common\modules\comment\rbac\ArtboxCommentDeleteOwnRule())->name,
  236 + ],
  237 + ],
  238 + ],
  239 +
  240 + ],
  241 + ],
  242 +];
... ...
common/config/params.php 0 โ†’ 100644
  1 +<?php
  2 +return [
  3 + 'adminEmail' => 'admin@example.com',
  4 + 'supportEmail' => 'support@example.com',
  5 + 'user.passwordResetTokenExpire' => 3600,
  6 +];
... ...
common/mail/layouts/html.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\helpers\Html;
  3 +
  4 +/* @var $this \yii\web\View view component instance */
  5 +/* @var $message \yii\mail\MessageInterface the message being composed */
  6 +/* @var $content string main view render result */
  7 +?>
  8 +<?php $this->beginPage() ?>
  9 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  10 +<html xmlns="http://www.w3.org/1999/xhtml">
  11 +<head>
  12 + <meta http-equiv="Content-Type" content="text/html; charset=<?= Yii::$app->charset ?>" />
  13 + <title><?= Html::encode($this->title) ?></title>
  14 + <?php $this->head() ?>
  15 +</head>
  16 +<body>
  17 + <?php $this->beginBody() ?>
  18 + <?= $content ?>
  19 + <?php $this->endBody() ?>
  20 +</body>
  21 +</html>
  22 +<?php $this->endPage() ?>
... ...
common/mail/layouts/text.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\helpers\Html;
  3 +
  4 +/* @var $this \yii\web\View view component instance */
  5 +/* @var $message \yii\mail\MessageInterface the message being composed */
  6 +/* @var $content string main view render result */
  7 +?>
  8 +<?php $this->beginPage() ?>
  9 +<?php $this->beginBody() ?>
  10 +<?= $content ?>
  11 +<?php $this->endBody() ?>
  12 +<?php $this->endPage() ?>
... ...
common/mail/passwordResetToken-html.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\helpers\Html;
  3 +
  4 +/* @var $this yii\web\View */
  5 +/* @var $user common\models\User */
  6 +
  7 +$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
  8 +?>
  9 +<div class="password-reset">
  10 + <p>Hello <?= Html::encode($user->username) ?>,</p>
  11 +
  12 + <p>Follow the link below to reset your password:</p>
  13 +
  14 + <p><?= Html::a(Html::encode($resetLink), $resetLink) ?></p>
  15 +</div>
... ...
common/mail/passwordResetToken-text.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/* @var $this yii\web\View */
  4 +/* @var $user common\models\User */
  5 +
  6 +$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
  7 +?>
  8 +Hello <?= $user->username ?>,
  9 +
  10 +Follow the link below to reset your password:
  11 +
  12 +<?= $resetLink ?>
... ...
common/models/Blog.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace common\models;
  4 +
  5 + use Yii;
  6 + use yii\behaviors\BlameableBehavior;
  7 + use yii\behaviors\TimestampBehavior;
  8 + use yii\db\Expression;
  9 +
  10 + /**
  11 + * This is the model class for table "blog".
  12 + * @property integer $blog_id
  13 + * @property integer $user_id
  14 + * @property string $name
  15 + * @property string $link
  16 + * @property string $date_add
  17 + * @property integer $user_add_id
  18 + * @property integer $view_count
  19 + * @property string $description
  20 + * @property string $cover
  21 + */
  22 + class Blog extends \yii\db\ActiveRecord
  23 + {
  24 +
  25 + /**
  26 + * @inheritdoc
  27 + */
  28 + public static function tableName()
  29 + {
  30 + return 'blog';
  31 + }
  32 +
  33 +
  34 + /**
  35 + * @inheritdoc
  36 + */
  37 + public function behaviors()
  38 + {
  39 + return [
  40 + [
  41 + 'class' => BlameableBehavior::className(),
  42 + 'createdByAttribute' => 'user_id',
  43 + 'updatedByAttribute' => false,
  44 + ],
  45 + [
  46 + 'class' => TimestampBehavior::className(),
  47 + 'createdAtAttribute' => 'date_add',
  48 + 'updatedAtAttribute' => false,
  49 + 'value' => new Expression('NOW()'),
  50 + ],
  51 + 'slug' => [
  52 + 'class' => 'common\behaviors\Slug',
  53 + 'in_attribute' => 'name',
  54 + 'out_attribute' => 'link',
  55 + 'translit' => true
  56 + ]
  57 + ];
  58 + }
  59 +
  60 + /**
  61 + * @inheritdoc
  62 + */
  63 + public function rules()
  64 + {
  65 + return [
  66 + [
  67 + [ 'name', 'description' ],
  68 + 'required',
  69 + ],
  70 + [
  71 + [ 'description' ],
  72 + 'string',
  73 + ],
  74 + [
  75 + [
  76 + 'name',
  77 + 'link',
  78 + 'cover',
  79 + ],
  80 + 'string',
  81 + 'max' => 255,
  82 + ],
  83 + ];
  84 + }
  85 +
  86 + public function getDateCreate(){
  87 + return date('Y-m-d',strtotime($this->date_add));
  88 + }
  89 +
  90 + /**
  91 + * @inheritdoc
  92 + */
  93 + public function attributeLabels()
  94 + {
  95 + return [
  96 + 'blog_id' => Yii::t('app', 'Blog ID'),
  97 + 'user_id' => Yii::t('app', 'User ID'),
  98 + 'name' => Yii::t('app', 'ะะฐะทะฒะฐะฝะธะต'),
  99 + 'link' => Yii::t('app', 'URL'),
  100 + 'date_add' => Yii::t('app', 'ะ”ะฐั‚ะฐ ะดะพะฑะฐะฒะปะตะฝะธั'),
  101 + 'user_add_id' => Yii::t('app', 'User Add ID'),
  102 + 'view_count' => Yii::t('app', 'ะšะพะปะธั‡ะตัั‚ะฒะพ ะฟั€ะพัะผะพั‚ั€ะพะฒ'),
  103 + 'description' => Yii::t('app', 'ะžะฟะธัะฐะฝะธะต'),
  104 + 'cover' => Yii::t('app', 'ะคะพั‚ะพ ะณะปะฐะฒะฝะพะต'),
  105 + ];
  106 + }
  107 + }
... ...
common/models/BlogSearch.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace common\models;
  4 +
  5 + use Yii;
  6 + use yii\base\Model;
  7 + use yii\bootstrap\ActiveForm;
  8 + use yii\data\ActiveDataProvider;
  9 + use common\models\Blog;
  10 + use yii\db\ActiveQuery;
  11 + use yii\db\ActiveRecord;
  12 +
  13 + /**
  14 + * BlogSearch represents the model behind the search form about `common\models\Blog`.
  15 + */
  16 + class BlogSearch extends Blog
  17 + {
  18 +
  19 + public $date_add_from;
  20 + public $date_add_to;
  21 + /**
  22 + * @inheritdoc
  23 + */
  24 + public function rules()
  25 + {
  26 + return [
  27 + [
  28 + [
  29 + 'blog_id',
  30 + 'user_id',
  31 + 'user_add_id',
  32 + 'view_count',
  33 + ],
  34 + 'integer',
  35 + ],
  36 + [
  37 + [
  38 + 'name',
  39 + 'link',
  40 + 'date_add',
  41 + 'description',
  42 + 'cover',
  43 + 'date_add_from',
  44 + 'date_add_to',
  45 + ],
  46 + 'safe',
  47 + ],
  48 + [
  49 + [
  50 + 'date_add_from',
  51 + ],
  52 + 'default',
  53 + 'value' => date('Y-m-d', 0),
  54 + ],
  55 + [
  56 + [
  57 + 'date_add_to',
  58 + ],
  59 + 'default',
  60 + 'value' => date('Y-m-d'),
  61 + ],
  62 + ];
  63 + }
  64 +
  65 + /**
  66 + * @inheritdoc
  67 + */
  68 + public function scenarios()
  69 + {
  70 + // bypass scenarios() implementation in the parent class
  71 + return Model::scenarios();
  72 + }
  73 +
  74 + /**
  75 + * Creates data provider instance with search query applied
  76 + *
  77 + * @param array $params
  78 + *
  79 + * @return ActiveDataProvider
  80 + */
  81 + public function search($params)
  82 + {
  83 + $query = Blog::find();
  84 +
  85 + // add conditions that should always apply here
  86 +
  87 + $dataProvider = new ActiveDataProvider([
  88 + 'query' => $query,
  89 + ]);
  90 +
  91 + $this->load($params);
  92 +
  93 + if(!$this->validate()) {
  94 + // uncomment the following line if you do not want to return any records when validation fails
  95 + // $query->where('0=1');
  96 + return $dataProvider;
  97 + }
  98 +
  99 + $query->andWhere([ 'user_id' => \Yii::$app->user->getId() ]);
  100 +
  101 + // grid filtering conditions
  102 + $query->andFilterWhere([
  103 + 'blog_id' => $this->blog_id,
  104 + 'date_add' => $this->date_add,
  105 + 'user_add_id' => $this->user_add_id,
  106 + 'view_count' => $this->view_count,
  107 + ]);
  108 +
  109 + $query->andFilterWhere([
  110 + 'between',
  111 + 'date_add',
  112 + $this->date_add_from,
  113 + (new \DateTime($this->date_add_to))->modify('+1 day')->format('Y-m-d')
  114 + ]);
  115 +
  116 + $query->andFilterWhere([
  117 + 'like',
  118 + 'name',
  119 + $this->name,
  120 + ])
  121 + ->andFilterWhere([
  122 + 'like',
  123 + 'description',
  124 + $this->description,
  125 + ])
  126 + ->andFilterWhere([
  127 + 'like',
  128 + 'cover',
  129 + $this->cover,
  130 + ]);
  131 +
  132 + return $dataProvider;
  133 + }
  134 +
  135 + }
... ...
common/models/Customers.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +use yii\behaviors\TimestampBehavior;
  7 +/**
  8 + * This is the model class for table "customers".
  9 + *
  10 + * @property integer $id
  11 + * @property string $username
  12 + * @property string $surname
  13 + * @property string $auth_key
  14 + * @property string $password_hash
  15 + * @property string $password_reset_token
  16 + * @property string $email
  17 + * @property string $phone
  18 + * @property integer $status
  19 + * @property integer $created_at
  20 + * @property integer $updated_at
  21 + */
  22 +class Customers extends User
  23 +{
  24 + /**
  25 + * @inheritdoc
  26 + */
  27 + public static function tableName()
  28 + {
  29 + return 'customers';
  30 + }
  31 +
  32 + /**
  33 + * @inheritdoc
  34 + */
  35 + public function rules()
  36 + {
  37 + return [
  38 + [['username', 'auth_key', 'password_hash', 'email', 'phone'], 'required'],
  39 + [['status', 'created_at', 'updated_at'], 'integer'],
  40 + [['username', 'password_hash', 'password_reset_token', 'email', 'phone','surname'], 'string', 'max' => 255],
  41 + [['auth_key'], 'string', 'max' => 32],
  42 + [['email'], 'unique'],
  43 + [['password_reset_token'], 'unique'],
  44 + [['phone'], 'unique'],
  45 + ];
  46 + }
  47 +
  48 +
  49 + /**
  50 + * @inheritdoc
  51 + */
  52 + public function behaviors()
  53 + {
  54 + return [
  55 + TimestampBehavior::className(),
  56 + ];
  57 + }
  58 +
  59 + /**
  60 + * Finds user by email
  61 + *
  62 + * @param string $email
  63 + * @return static|null
  64 + */
  65 + public static function findByEmail($email)
  66 + {
  67 + return static::findOne(['email' => $email, 'status' => self::STATUS_ACTIVE]);
  68 + }
  69 +
  70 + public function getName(){
  71 + return $this->username. ' '.$this->surname;
  72 + }
  73 +
  74 +
  75 + /**
  76 + * @inheritdoc
  77 + */
  78 + public function attributeLabels()
  79 + {
  80 + return [
  81 + 'id' => Yii::t('app', 'ID'),
  82 + 'username' => Yii::t('app', 'Username'),
  83 + 'surname' => Yii::t('app', 'Surname'),
  84 + 'auth_key' => Yii::t('app', 'Auth Key'),
  85 + 'password_hash' => Yii::t('app', 'Password Hash'),
  86 + 'password_reset_token' => Yii::t('app', 'Password Reset Token'),
  87 + 'email' => Yii::t('app', 'Email'),
  88 + 'phone' => Yii::t('app', 'Phone'),
  89 + 'status' => Yii::t('app', 'Status'),
  90 + 'created_at' => Yii::t('app', 'Created At'),
  91 + 'updated_at' => Yii::t('app', 'Updated At'),
  92 + ];
  93 + }
  94 +}
... ...
common/models/Fields.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +use yii\helpers\ArrayHelper;
  7 +
  8 +/**
  9 + * This is the model class for table "{{%fields}}".
  10 + *
  11 + * @property integer $id
  12 + * @property string $table_name
  13 + * @property integer $table_id
  14 + * @property string $value
  15 + * @property string $field_name
  16 + * @property string $field_type
  17 + * @property string $language
  18 + * @property string $parent_key
  19 + * @property string $key
  20 + */
  21 +class Fields extends \yii\db\ActiveRecord
  22 +{
  23 + /**
  24 + * @inheritdoc
  25 + */
  26 + public static function tableName()
  27 + {
  28 + return '{{%fields}}';
  29 + }
  30 +
  31 + /**
  32 + * @inheritdoc
  33 + */
  34 + public function rules()
  35 + {
  36 + return [
  37 + [['table_name', 'table_id',], 'required'],
  38 + [['table_id','parent_key','key'], 'integer'],
  39 + [['table_name', 'value', 'field_name','field_type','language'], 'string', 'max' => 255]
  40 + ];
  41 + }
  42 +
  43 + /**
  44 + * @inheritdoc
  45 + */
  46 + public function attributeLabels()
  47 + {
  48 + return [
  49 + 'id' => 'ID',
  50 + 'table_name' => 'Model Name',
  51 + 'table_id' => 'Model ID',
  52 + 'value' => 'Value',
  53 + 'field_name' => 'Field Name',
  54 + 'language' => 'Language',
  55 + ];
  56 + }
  57 +
  58 + public static function getData($id, $model, $type){
  59 + $data = ArrayHelper::toArray(self::find()->where(['table_id'=>$id, 'table_name'=>$model, 'field_type'=>$type])->all());
  60 + $result = [];
  61 + for($i=0; $i < count($data); $i ++){
  62 + $result[$data[$i]['parent_key']][$data[$i]['field_name']] = $data[$i]['value'];
  63 + }
  64 +
  65 + return $result;
  66 + }
  67 +
  68 +
  69 + /**
  70 + * @param $post - array with field data
  71 + * @param $table_id - row id in model table
  72 + * @param $table_name - madel table name
  73 + * @param $language - language id
  74 + */
  75 +
  76 + public static function saveFieldData($post,$table_id,$table_name, $language){
  77 +
  78 + self::deleteAll(['table_id'=>$table_id, 'table_name'=>$table_name, 'language' => $language, 'field_type' => array_keys($post)]);
  79 +
  80 + if($post){
  81 +
  82 +
  83 + foreach($post as $k => $field){
  84 +
  85 +
  86 +
  87 + foreach($field as $parent_key => $row){
  88 +
  89 + foreach($row as $key => $value){
  90 +
  91 + $field_model = new Fields();
  92 + $field_model->field_name = array_keys($value)[0];
  93 + $field_model->value = $value[array_keys($value)[0]];
  94 + $field_model->table_name = $table_name;
  95 + $field_model->table_id = $table_id;
  96 + $field_model->field_type = $k;
  97 + $field_model->language = 'ru';
  98 + $field_model->parent_key = $parent_key;
  99 + $field_model->key = $key;
  100 + $field_model->save();
  101 + }
  102 +
  103 + }
  104 + }
  105 + }
  106 + }
  107 +
  108 +
  109 + /**
  110 + * @param $post - array with field data
  111 + * @param $table_id - row id in model table
  112 + * @param $table_name - madel table name
  113 + * @param $language - language id
  114 + */
  115 +
  116 + public static function saveFieldVideoData($post,$table_id,$table_name, $language){
  117 +
  118 + self::deleteAll(['table_id'=>$table_id, 'table_name'=>$table_name, 'language' => $language, 'field_type' => array_keys($post)]);
  119 +
  120 + if($post){
  121 +
  122 +
  123 + foreach($post as $k => $field){
  124 +
  125 +
  126 +
  127 + foreach($field as $parent_key => $row){
  128 +
  129 + foreach($row as $key => $value){
  130 +
  131 + preg_match('/src=\"(.[^"]*)\"/', $value[array_keys($value)[0]], $video_url);
  132 +
  133 + if(isset($video_url[1]) && !empty($video_url[1])){
  134 +
  135 + $field_model = new Fields();
  136 + $field_model->field_name = array_keys($value)[0];
  137 + $field_model->value = $video_url[1].'?showinfo=0&autoplay=0';
  138 + $field_model->table_name = $table_name;
  139 + $field_model->table_id = $table_id;
  140 + $field_model->field_type = $k;
  141 + $field_model->language = 'ru';
  142 + $field_model->parent_key = $parent_key;
  143 + $field_model->key = $key;
  144 + $field_model->save();
  145 +
  146 + }
  147 +
  148 +
  149 + }
  150 +
  151 + }
  152 + }
  153 + }
  154 + }
  155 +}
... ...
common/models/LoginForm.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\models;
  3 +
  4 +use Yii;
  5 +use yii\base\Model;
  6 +
  7 +/**
  8 + * Login form
  9 + */
  10 +class LoginForm extends Model
  11 +{
  12 + public $password;
  13 + public $rememberMe = true;
  14 + public $email;
  15 +
  16 + private $_user;
  17 +
  18 +
  19 + /**
  20 + * @inheritdoc
  21 + */
  22 + public function rules()
  23 + {
  24 + return [
  25 + // username and password are both required
  26 + [['email', 'password'], 'required'],
  27 + // rememberMe must be a boolean value
  28 + ['rememberMe', 'boolean'],
  29 + // password is validated by validatePassword()
  30 + ['password', 'validatePassword'],
  31 + ];
  32 + }
  33 +
  34 + /**
  35 + * Validates the password.
  36 + * This method serves as the inline validation for password.
  37 + *
  38 + * @param string $attribute the attribute currently being validated
  39 + * @param array $params the additional name-value pairs given in the rule
  40 + */
  41 + public function validatePassword($attribute, $params)
  42 + {
  43 + if (!$this->hasErrors()) {
  44 + $user = $this->getUser();
  45 + if (!$user || !$user->validatePassword($this->password)) {
  46 + $this->addError($attribute, 'Incorrect username or password.');
  47 + }
  48 + }
  49 + }
  50 +
  51 + /**
  52 + * Logs in a user using the provided username and password.
  53 + *
  54 + * @return boolean whether the user is logged in successfully
  55 + */
  56 + public function login()
  57 + {
  58 + if ($this->validate()) {
  59 + return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
  60 + } else {
  61 + return false;
  62 + }
  63 + }
  64 +
  65 + /**
  66 + * Finds user by [[username]]
  67 + *
  68 + * @return User|null
  69 + */
  70 + protected function getUser()
  71 + {
  72 + if ($this->_user === null) {
  73 + $this->_user = Customers::findByEmail($this->email);
  74 + }
  75 +
  76 + return $this->_user;
  77 + }
  78 +
  79 + /**
  80 + * @inheritdoc
  81 + */
  82 + public function attributeLabels()
  83 + {
  84 + return [
  85 + 'rememberMe' => Yii::t('app', 'rememberMe'),
  86 + ];
  87 + }
  88 +}
... ...
common/models/OrderItems.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "order_items".
  9 + *
  10 + * @property integer $order_items_id
  11 + * @property integer $order_id
  12 + * @property integer $item_id
  13 + * @property integer $item_count
  14 + * @property double $price
  15 + *
  16 + * @property Orders $order
  17 + * @property Product $item
  18 + */
  19 +class OrderItems extends \yii\db\ActiveRecord
  20 +{
  21 + /**
  22 + * @inheritdoc
  23 + */
  24 + public static function tableName()
  25 + {
  26 + return 'order_items';
  27 + }
  28 +
  29 + /**
  30 + * @inheritdoc
  31 + */
  32 + public function rules()
  33 + {
  34 + return [
  35 + [['order_id', 'item_id', 'item_count'], 'integer'],
  36 + [['price'], 'number'],
  37 + [['order_id'], 'exist', 'skipOnError' => true, 'targetClass' => Orders::className(), 'targetAttribute' => ['order_id' => 'order_id']],
  38 + [['item_id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::className(), 'targetAttribute' => ['item_id' => 'product_id']],
  39 + ];
  40 + }
  41 +
  42 + /**
  43 + * @inheritdoc
  44 + */
  45 + public function attributeLabels()
  46 + {
  47 + return [
  48 + 'order_items_id' => Yii::t('app', 'Order Items ID'),
  49 + 'order_id' => Yii::t('app', 'Order ID'),
  50 + 'item_id' => Yii::t('app', 'Item ID'),
  51 + 'item_count' => Yii::t('app', 'Item Count'),
  52 + 'price' => Yii::t('app', 'Price'),
  53 + ];
  54 + }
  55 +
  56 + /**
  57 + * @return \yii\db\ActiveQuery
  58 + */
  59 + public function getOrder()
  60 + {
  61 + return $this->hasOne(Orders::className(), ['order_id' => 'order_id']);
  62 + }
  63 +
  64 + /**
  65 + * @return \yii\db\ActiveQuery
  66 + */
  67 + public function getItem()
  68 + {
  69 + return $this->hasOne(Product::className(), ['product_id' => 'item_id']);
  70 + }
  71 +}
... ...
common/models/Orders.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "orders".
  9 + *
  10 + * @property integer $order_id
  11 + * @property integer $customer_id
  12 + * @property string $name
  13 + * @property string $email
  14 + * @property string $phone
  15 + * @property integer $delivery
  16 + * @property integer $payment
  17 + * @property string $code
  18 + * @property integer $status
  19 + * @property integer $created_at
  20 + * @property integer $updated_at
  21 + *
  22 + * @property OrderItems[] $orderItems
  23 + */
  24 +class Orders extends \yii\db\ActiveRecord
  25 +{
  26 + /**
  27 + * @inheritdoc
  28 + */
  29 + public static function tableName()
  30 + {
  31 + return 'orders';
  32 + }
  33 +
  34 + /**
  35 + * @inheritdoc
  36 + */
  37 + public function rules()
  38 + {
  39 + return [
  40 + [['customer_id', 'delivery', 'payment', 'status', 'created_at', 'updated_at'], 'integer'],
  41 + [['name', 'email', 'phone', 'created_at', 'updated_at'], 'required'],
  42 + [['name', 'email', 'code'], 'string', 'max' => 255],
  43 + [['phone'], 'string', 'max' => 32],
  44 + ];
  45 + }
  46 +
  47 + /**
  48 + * @inheritdoc
  49 + */
  50 + public function attributeLabels()
  51 + {
  52 + return [
  53 + 'order_id' => Yii::t('app', 'Order ID'),
  54 + 'customer_id' => Yii::t('app', 'Customer ID'),
  55 + 'name' => Yii::t('app', 'Name'),
  56 + 'email' => Yii::t('app', 'Email'),
  57 + 'phone' => Yii::t('app', 'Phone'),
  58 + 'delivery' => Yii::t('app', 'Delivery'),
  59 + 'payment' => Yii::t('app', 'Payment'),
  60 + 'code' => Yii::t('app', 'Code'),
  61 + 'status' => Yii::t('app', 'Status'),
  62 + 'created_at' => Yii::t('app', 'Created At'),
  63 + 'updated_at' => Yii::t('app', 'Updated At'),
  64 + ];
  65 + }
  66 +
  67 + /**
  68 + * @return \yii\db\ActiveQuery
  69 + */
  70 + public function getOrderItems()
  71 + {
  72 + return $this->hasMany(OrderItems::className(), ['order_id' => 'order_id']);
  73 + }
  74 +}
... ...
common/models/User.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\models;
  3 +
  4 +use Yii;
  5 +use yii\base\NotSupportedException;
  6 +use yii\behaviors\TimestampBehavior;
  7 +use yii\db\ActiveRecord;
  8 +use yii\web\IdentityInterface;
  9 +
  10 +/**
  11 + * User model
  12 + *
  13 + * @property integer $id
  14 + * @property string $username
  15 + * @property string $password_hash
  16 + * @property string $password_reset_token
  17 + * @property string $email
  18 + * @property string $auth_key
  19 + * @property integer $status
  20 + * @property integer $created_at
  21 + * @property integer $updated_at
  22 + * @property string $password write-only password
  23 + */
  24 +class User extends ActiveRecord implements IdentityInterface
  25 +{
  26 + const STATUS_DELETED = 0;
  27 + const STATUS_ACTIVE = 10;
  28 +
  29 + /**
  30 + * @inheritdoc
  31 + */
  32 + public static function tableName()
  33 + {
  34 + return '{{%user}}';
  35 + }
  36 +
  37 + /**
  38 + * @inheritdoc
  39 + */
  40 + public function behaviors()
  41 + {
  42 + return [
  43 + TimestampBehavior::className(),
  44 + ];
  45 + }
  46 +
  47 + /**
  48 + * @inheritdoc
  49 + */
  50 + public function rules()
  51 + {
  52 + return [
  53 + ['status', 'default', 'value' => self::STATUS_ACTIVE],
  54 + ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
  55 + ];
  56 + }
  57 +
  58 + /**
  59 + * @inheritdoc
  60 + */
  61 + public static function findIdentity($id)
  62 + {
  63 + return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
  64 + }
  65 +
  66 + /**
  67 + * @inheritdoc
  68 + */
  69 + public static function findIdentityByAccessToken($token, $type = null)
  70 + {
  71 + throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
  72 + }
  73 +
  74 + /**
  75 + * Finds user by username
  76 + *
  77 + * @param string $username
  78 + * @return static|null
  79 + */
  80 + public static function findByUsername($username)
  81 + {
  82 + return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
  83 + }
  84 +
  85 + /**
  86 + * Finds user by password reset token
  87 + *
  88 + * @param string $token password reset token
  89 + * @return static|null
  90 + */
  91 + public static function findByPasswordResetToken($token)
  92 + {
  93 + if (!static::isPasswordResetTokenValid($token)) {
  94 + return null;
  95 + }
  96 +
  97 + return static::findOne([
  98 + 'password_reset_token' => $token,
  99 + 'status' => self::STATUS_ACTIVE,
  100 + ]);
  101 + }
  102 +
  103 + /**
  104 + * Finds out if password reset token is valid
  105 + *
  106 + * @param string $token password reset token
  107 + * @return boolean
  108 + */
  109 + public static function isPasswordResetTokenValid($token)
  110 + {
  111 + if (empty($token)) {
  112 + return false;
  113 + }
  114 +
  115 + $timestamp = (int) substr($token, strrpos($token, '_') + 1);
  116 + $expire = Yii::$app->params['user.passwordResetTokenExpire'];
  117 + return $timestamp + $expire >= time();
  118 + }
  119 +
  120 + /**
  121 + * @inheritdoc
  122 + */
  123 + public function getId()
  124 + {
  125 + return $this->getPrimaryKey();
  126 + }
  127 +
  128 + /**
  129 + * @inheritdoc
  130 + */
  131 + public function getAuthKey()
  132 + {
  133 + return $this->auth_key;
  134 + }
  135 +
  136 + /**
  137 + * @inheritdoc
  138 + */
  139 + public function validateAuthKey($authKey)
  140 + {
  141 + return $this->getAuthKey() === $authKey;
  142 + }
  143 +
  144 + /**
  145 + * Validates password
  146 + *
  147 + * @param string $password password to validate
  148 + * @return boolean if password provided is valid for current user
  149 + */
  150 + public function validatePassword($password)
  151 + {
  152 + return Yii::$app->security->validatePassword($password, $this->password_hash);
  153 + }
  154 +
  155 + /**
  156 + * Generates password hash from password and sets it to the model
  157 + *
  158 + * @param string $password
  159 + */
  160 + public function setPassword($password)
  161 + {
  162 + $this->password_hash = Yii::$app->security->generatePasswordHash($password);
  163 + }
  164 +
  165 + /**
  166 + * Generates "remember me" authentication key
  167 + */
  168 + public function generateAuthKey()
  169 + {
  170 + $this->auth_key = Yii::$app->security->generateRandomString();
  171 + }
  172 +
  173 + /**
  174 + * Generates new password reset token
  175 + */
  176 + public function generatePasswordResetToken()
  177 + {
  178 + $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
  179 + }
  180 +
  181 + /**
  182 + * Removes password reset token
  183 + */
  184 + public function removePasswordResetToken()
  185 + {
  186 + $this->password_reset_token = null;
  187 + }
  188 +}
... ...
common/modules/blog/Module.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog;
  3 +
  4 +use yii\base\BootstrapInterface;
  5 +
  6 +class Module extends \yii\base\Module
  7 +{
  8 + public function init()
  9 + {
  10 + parent::init();
  11 +
  12 + \Yii::configure($this, require(__DIR__.'/config.php'));
  13 + }
  14 +
  15 +}
... ...
common/modules/blog/behaviors/Autocomplete.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog\behaviors;
  3 +
  4 +use common\models\Tools;
  5 +use yii\db\ActiveRecord;
  6 +use yii\base\Behavior;
  7 +use yii\helpers\StringHelper;
  8 +
  9 +/**
  10 + * ะšะปะฐัั ะดะปั ะฐะฒั‚ะพะทะฐะฟะพะปะฝะตะฝะธั ะฟะพะปะตะน ะฝะตะบะธะผะธ ะดะฐะฝะฝั‹ะผะธ ะธะปะธ ะธั… ั„ะพั€ะผะฐั‚ะธั€ะพะฒะฐะฝะธั
  11 + *
  12 + * ะšะปะฐั ะฟั€ะตะดะฝะฐะทะฝะฐั‡ะตะฝ ะดะปั ะทะฐะฟะพะปะฝะตะฝะธั ะฟะพะปะตะน ะดะฐะฝะฝั‹ะผะธ ะธะปะธ ั„ะพั€ะผะฐั‚ะธั€ะพะฒะฐะฝะธั ะดะฐะฝะฝั‹ั…
  13 + *
  14 + */
  15 +
  16 +class Autocomplete extends Behavior
  17 +{
  18 + /**
  19 + * ะั‚ั€ะธะฑัƒั‚ั‹ ะดะปั ะพะฑั€ะฐะฑะพั‚ะบะธ
  20 + *
  21 + * ะั‚ั€ะธะฑัƒั‚ั‹ ัั‡ะธั‚ั‹ะฒะฐัŽั‚ัั ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธ ั ะฝะฐัั‚ั€ะพะตะบ ะฟะพะฒะตะดะตะฝะธั ะฒ ะบะพะฝะบั€ะตั‚ะฝะพะผ ะพะฑัŒะตะบั‚ะต.
  22 + * ะ˜ะผะตะตั‚ ะฒะธะด ะฐััะพั†ะธะฐั‚ะธะฒะฝะพะณะพ ะผะฐััะธะฒะฐ, ะณะดะต ะบะปัŽั‡ - ะผะตั‚ะพะด ะฐะฒั‚ะพะทะฐะฟะพะปะฝะตะฝะธั, ะฐ ะทะฝะฐั‡ะตะฝะธะต - ะผะฐััะธะฒ, ะบะฐะถะดั–ะน ั”ะปะตะผะตะฝั‚
  23 + * ะบะพั‚ะพั€ะพะณะพ - ัะฒะพะนัั‚ะฒะพ ะพะฑัŒะตะบั‚ะฐ ะดะปั ะพะฑั€ะฐะฑะพั‚ะบะธ, ะผะพะถะตั‚ ะฒะบะปัŽั‡ะฐั‚ัŒ ะผะฐััะธะฒ - ะฟะตั€ะฒั‹ะน ั”ะปะตะผะตะฝั‚ ะบะพั‚ะพั€ะพะณะพ ัะฒะพะนัั‚ะฒะพ,
  24 + * ะฐ ะดะฐะปัŒะฝะตะนัˆะธะต ะบะพะฝั„ะธะณัƒั€ะฐั†ะธะธ.
  25 + *
  26 + * @var array ะััะพั†ะธะฐั‚ะธะฒะฝั‹ ะผะฐััะธะฒ [key(ะผะตั‚ะพะด ะทะฐะฟะพะปะฝะตะฝะธั) => [[0 => property(ัะฒะพะนัั‚ะฒะพ ะพะฑัŒะตะบั‚ะฐ), ... ะดะพะฟะพะปะฝะธั‚ะตะปัŒะฝั‹ะต
  27 + * ะฝะฐัั‚ั€ะพะนะบะธ]], ...[]]
  28 + *
  29 + */
  30 + public $attributes;
  31 +
  32 + /**
  33 + * ะกะพะฑั‹ั‚ะธั
  34 + *
  35 + * ะกะพะฑั‹ั‚ะธั ะฝะฐ ะบะพั‚ะพั€ั‹ะต ะดะพะปะถะฝะพ ัั€ะฐะฑะฐั‚ั‹ะฒะฐั‚ัŒ ะฟะพะฒะตะดะตะฝะธะต. ะ—ะฐะดะฐะตั‚ัั ะฐััะพั†ะธะฐั‚ะธะฒะฝั‹ะน ะผะฐััะธะฒ, ะฒ ะบะพั‚ะพั€ะพะผ ะบะปัŽั‡ - ัะพะฑั‹ั‚ะธะต
  36 + * ัะฒัะทะฐะฝะฝะพะณะพ ะพะฑัŒะตะบั‚ะฐ, ะฐ ะทะฝะฐั‡ะตะฝะธะต - ะผะตั‚ะพะด, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทั‹ะฒะฐะตั‚ัั ะฟั€ะธ ัั‚ะพะผ ัะพะฑั‹ั‚ะธะธ
  37 + *
  38 + * @return array [key(event) => val(method)]
  39 + *
  40 + */
  41 + public function events()
  42 + {
  43 + return [
  44 + ActiveRecord::EVENT_BEFORE_INSERT => 'autocomplete',
  45 + ActiveRecord::EVENT_BEFORE_UPDATE => 'autocomplete',
  46 + ];
  47 + }
  48 +
  49 + /**
  50 + * ะกะพะฑั‹ั‚ะธั
  51 + *
  52 + * ะกะพะฑั‹ั‚ะธั ะฝะฐ ะบะพั‚ะพั€ั‹ะต ะดะพะปะถะฝะพ ัั€ะฐะฑะฐั‚ั‹ะฒะฐั‚ัŒ ะฟะพะฒะตะดะตะฝะธะต. ะ—ะฐะดะฐะตั‚ัั ะฐััะพั†ะธะฐั‚ะธะฒะฝั‹ะน ะผะฐััะธะฒ, ะฒ ะบะพั‚ะพั€ะพะผ ะบะปัŽั‡ - ัะพะฑั‹ั‚ะธะต
  53 + * ัะฒัะทะฐะฝะฝะพะณะพ ะพะฑัŒะตะบั‚ะฐ, ะฐ ะทะฝะฐั‡ะตะฝะธะต - ะผะตั‚ะพะด, ะบะพั‚ะพั€ั‹ะน ะฒั‹ะทั‹ะฒะฐะตั‚ัั ะฟั€ะธ ัั‚ะพะผ ัะพะฑั‹ั‚ะธะธ
  54 + * ะ”ะพัั‚ัƒะฟะฝั‹ะต ะฐะฒั‚ะพะทะฐะฟะพะปะฝะตะฝะธั:
  55 + * ['translit' => ['prop1', ... 'prop2']],
  56 + * ะณะดะต prop - ัะฒะพะนัั‚ะฒะพ ะฟะพะดะปะตะถะฐั‰ะตะต ั‚ั€ะฐะฝัะปะธั‚ะตั€ะฐั†ะธะธ
  57 + * ['repeat' => [[string 'prop1', string 'target1', boolean 'skipFilled', int 'count', boolean 'truncate', string 'suffix'], ...[]],
  58 + * ะณะดะต prop - ัะฒะพะนัั‚ะฒะพ ะดะปั ะฟั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธั,
  59 + * target - ัะฒะพะนัั‚ะฒะพ ั ะบะพั‚ะพั€ะพะณะพ ะฒะทัั‚ัŒ ะดะฐะฝะฝั‹ะต,
  60 + * count - ั‡ะธัะปะพ ะดะปั ะฟั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธั,
  61 + * skipFilled - ะฟั€ะพะฟัƒัั‚ะธั‚ัŒ ะฝะตะฟัƒัั‚ั‹ะต,
  62 + * truncate - true - ะพะฑั€ะตะทะฐั‚ัŒ ะฟะพ ัะปะพะฒะฐะผ, false - ะฟะพ ัะธะผะฒะพะปะฐะผ,
  63 + * suffix - ััƒั„ั„ะธะบั, ะบะพั‚ะพั€ั‹ะน ะดะพะฑะฐะฒะธั‚ัŒ ะฟะพัะปะต ะพะฑั€ะตะทะบะธ
  64 + *
  65 + * @param mixed $event Yii ะพะฑัŒะตะบั‚ ัะฒะพะนัั‚ะฐ https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/concept-events.md
  66 + *
  67 + */
  68 + public function autocomplete($event)
  69 + {
  70 + if(!empty($this->attributes['translit'])) {
  71 + foreach($this->attributes['translit'] as $translit) {
  72 + if($this->owner->hasAttribute($translit)) {
  73 + $this->owner->$translit = Tools::translit($this->owner->$translit);
  74 + }
  75 + }
  76 + }
  77 + if(!empty($this->attributes['repeat'])) {
  78 + foreach($this->attributes['repeat'] as $repeat) {
  79 + if(is_array($repeat) && $this->owner->hasAttribute($repeat[0]) && $this->owner->hasAttribute($repeat[1]) && is_int($repeat[3]) && (empty($this->owner->$repeat[0]) || $repeat[2])) {
  80 + $suffix = $repeat[5]?:'';
  81 + $truncate = $repeat[4]?'truncateWords':'truncate';
  82 + $this->owner->$repeat[0] = StringHelper::$truncate($this->owner->$repeat[1], $repeat[3], $suffix);
  83 + }
  84 + }
  85 + }
  86 + }
  87 +}
0 88 \ No newline at end of file
... ...
common/modules/blog/config.php 0 โ†’ 100644
  1 +<?php
  2 +return [
  3 + 'components' => [
  4 +
  5 + ],
  6 + 'params' => [
  7 + 'test' => 'Hello',
  8 + ],
  9 +];
... ...
common/modules/blog/controllers/AjaxController.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog\controllers;
  3 +
  4 +use common\models\Language;
  5 +use common\modules\blog\models\ArticleCategory;
  6 +use common\modules\blog\models\ArticleCategoryLang;
  7 +use common\modules\blog\models\ArticleCategoryMedia;
  8 +use common\modules\blog\models\ArticleLang;
  9 +use common\modules\blog\models\ArticleMedia;
  10 +use yii\base\InvalidParamException;
  11 +use yii\web\Controller;
  12 +use yii\web\ForbiddenHttpException;
  13 +use yii\web\NotFoundHttpException;
  14 +
  15 +class AjaxController extends Controller
  16 +{
  17 + public function beforeAction($action)
  18 + {
  19 + if(!\Yii::$app->request->getIsAjax()) {
  20 + //throw new ForbiddenHttpException('Permission denied');
  21 + }
  22 +
  23 + if(!parent::beforeAction($action)) {
  24 + return false;
  25 + }
  26 +
  27 + return true;
  28 + }
  29 +
  30 + public function actionCategoryForm($language_id, $widget_id)
  31 + {
  32 + $model = Language::find()->where(['>=', 'language_id', 1])->andWhere(['status' => 1, 'language_id' => $language_id])->one();
  33 + if(!$model) {
  34 + throw new NotFoundHttpException('Language not found');
  35 + }
  36 + $category_lang = new ArticleCategoryLang();
  37 + return $this->renderAjax('_category_form', ['model' => $model, 'category_lang' => $category_lang, 'widget_id' => $widget_id]);
  38 + }
  39 +
  40 + public function actionArticleForm($language_id, $widget_id)
  41 + {
  42 + $model = Language::find()->where(['>=', 'language_id', 1])->andWhere(['status' => 1, 'language_id' => $language_id])->one();
  43 + if(!$model) {
  44 + throw new NotFoundHttpException('Language not found');
  45 + }
  46 + $article_lang = new ArticleLang();
  47 + return $this->renderAjax('_article_form', ['model' => $model, 'article_lang' => $article_lang, 'widget_id' => $widget_id]);
  48 + }
  49 +
  50 + public function actionArticleMediaForm($language_id, $widget_id, $type)
  51 + {
  52 + $model = Language::find()->where(['>=', 'language_id', 1])->andWhere(['status' => 1, 'language_id' => $language_id])->one();
  53 + if(!$model) {
  54 + throw new NotFoundHttpException('Language not found');
  55 + }
  56 + if(!in_array($type, ['full', 'preview'])) {
  57 + throw new InvalidParamException('Type must only be full/preview');
  58 + }
  59 + $article_lang = new ArticleMedia();
  60 + return $this->renderAjax('_article_media_form', ['model' => $model, 'article_lang' => $article_lang, 'widget_id' => $widget_id, 'type' => $type]);
  61 + }
  62 +
  63 + public function actionArticleCategoryMediaForm($language_id, $widget_id, $type)
  64 + {
  65 + $model = Language::find()->where(['>=', 'language_id', 1])->andWhere(['status' => 1, 'language_id' => $language_id])->one();
  66 + if(!$model) {
  67 + throw new NotFoundHttpException('Language not found');
  68 + }
  69 + if(!in_array($type, ['full', 'preview'])) {
  70 + throw new InvalidParamException('Type must only be full/preview');
  71 + }
  72 + $article_lang = new ArticleCategoryMedia();
  73 + return $this->renderAjax('_article_media_form', ['model' => $model, 'article_lang' => $article_lang, 'widget_id' => $widget_id, 'type' => $type]);
  74 + }
  75 +
  76 + public function actionRemoveImage()
  77 + {
  78 + $post = \Yii::$app->request->post();
  79 + if(!empty($post['article_media_id'])) {
  80 + $article_media = ArticleMedia::findOne($post['article_media_id']);
  81 + if($post['remove_media']) {
  82 + $media = $article_media->media->delete();
  83 + }
  84 + if(!empty($article_media)) {
  85 + $article_media->delete();
  86 + }
  87 + return true;
  88 + } else {
  89 + return false;
  90 + }
  91 + }
  92 +
  93 + public function actionRemoveCategoryImage()
  94 + {
  95 + $post = \Yii::$app->request->post();
  96 + if(!empty($post['category_media_id'])) {
  97 + $category_media = ArticleCategoryMedia::findOne($post['category_media_id']);
  98 + if($post['remove_media']) {
  99 + $media = $category_media->media->delete();
  100 + }
  101 + if(!empty($category_media)) {
  102 + $category_media->delete();
  103 + }
  104 + return true;
  105 + } else {
  106 + return false;
  107 + }
  108 + }
  109 +
  110 + public function actionRemoveImageCategory()
  111 + {
  112 + $post = \Yii::$app->request->post();
  113 + if(!empty($post['category_media_id'])) {
  114 + $category_media = ArticleCategoryMedia::findOne($post['category_media_id']);
  115 + if($post['remove_media']) {
  116 + $media = $category_media->media->delete();
  117 + }
  118 + if(!empty($category_media)) {
  119 + $category_media->delete();
  120 + }
  121 + return true;
  122 + } else {
  123 + return false;
  124 + }
  125 + }
  126 +
  127 + public function actionMultilangForm($model, $ajaxView, $widget_id, $language_id = NULL)
  128 + {
  129 + $model = new $model(['language_id' => $language_id]);
  130 + return $this->renderAjax($ajaxView, ['model' => $model, 'widget_id' => $widget_id]);
  131 + }
  132 +
  133 +}
... ...
common/modules/blog/controllers/ArticleController.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog\controllers;
  3 +
  4 +use common\components\rules\CommentRule;
  5 +use common\components\rules\DeleteRule;
  6 +use common\components\rules\UpdateRule;
  7 +use common\components\rules\ViewRule;
  8 +use common\models\Language;
  9 +use common\modules\blog\models\Article;
  10 +use common\modules\blog\models\ArticleLang;
  11 +use common\modules\blog\models\ArticleMedia;
  12 +use common\modules\blog\models\ArticleToCategory;
  13 +use yii\data\ActiveDataProvider;
  14 +use yii\rbac\DbManager;
  15 +use yii\web\Controller;
  16 +use yii\web\UploadedFile;
  17 +
  18 +class ArticleController extends Controller
  19 +{
  20 +
  21 + public function actionIndex()
  22 + {
  23 + $dataProvider = new ActiveDataProvider([
  24 + 'query' => Article::find(),
  25 + 'pagination' => [
  26 + 'pageSize' => 1,
  27 + ],
  28 + ]);
  29 + return $this->render('index', ['dataProvider' => $dataProvider]);
  30 + }
  31 +
  32 + public function actionCreate()
  33 + {
  34 + $article_langs = array();
  35 + $article = new Article();
  36 + $default_lang = Language::getDefaultLang();
  37 + $images = array();
  38 + $images[$default_lang->language_id]['full'] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_FULL]);
  39 + $images[$default_lang->language_id]['preview'] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_PREVIEW]);
  40 + $images[0]['additional'] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_ADDITIONAL]);
  41 + $article->loadDefaultValues();
  42 + $langs = Language::getActiveLanguages();
  43 + $isValid = false;
  44 + if(!empty(\Yii::$app->request->post())) {
  45 + $isValid = true;
  46 + $article->load(\Yii::$app->request->post());
  47 + $article->user_id = \Yii::$app->user->getId();
  48 + $isValid = $article->validate();
  49 + foreach(\Yii::$app->request->post()['ArticleMedia'] as $lang => $value) {
  50 + foreach($value as $type => $fields) {
  51 + $images[$lang][$type] = new ArticleMedia(['scenario' => $type]);
  52 + $images[$lang][$type]->type = $type;
  53 + $images[$lang][$type]->language_id = $lang;
  54 + $images[$lang][$type]->imageFile = UploadedFile::getInstance($images[$lang][$type], "[{$lang}][{$type}]imageFile");
  55 + $isValid = $images[$lang][$type]->validate(['imageFile']) && $isValid;
  56 + }
  57 + }
  58 + $images[0]['additional']->language_id = 0;
  59 + $images[0]['additional']->type = 'additional';
  60 + $images[0]['additional']->imageFile = UploadedFile::getInstances($images[0]['additional'], "[0][additional]imageFile");
  61 + if(empty(\Yii::$app->request->post()['ArticleLang'])) {
  62 + $article_langs[$default_lang->language_id] = new ArticleLang();
  63 + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid;
  64 + } else {
  65 + foreach(\Yii::$app->request->post()['ArticleLang'] as $index => $article_lang) {
  66 + $article_langs[$index] = new ArticleLang();
  67 + }
  68 + ArticleLang::loadMultiple($article_langs, \Yii::$app->request->post());
  69 + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid;
  70 + }
  71 + } else {
  72 + $article_langs[$default_lang->language_id] = new ArticleLang();
  73 + }
  74 + if($isValid) {
  75 + $article->save(false);
  76 + $article_categories = \Yii::$app->request->post('Article')['articleCategoriesArray'];
  77 + if(!empty($article_categories)) {
  78 + foreach($article_categories as $article_category) {
  79 + $articletocategory[$article_category] = new ArticleToCategory();
  80 + $articletocategory[$article_category]->article_category_id = $article_category;
  81 + $articletocategory[$article_category]->link('article', $article);
  82 + }
  83 + }
  84 + $first = 1;
  85 + foreach($images as $lang => $value) {
  86 + foreach($value as $type => $fields) {
  87 + $images[$lang][$type]->upload($article->article_id);
  88 + if($first && $type != 'additional') {
  89 + $media_clone = clone $images[$lang][$type];
  90 + $media_clone->setIsNewRecord(true);
  91 + unset($media_clone->article_media_id);
  92 + $media_clone->language_id = 0;
  93 + $media_clone->upload($article->article_id);
  94 + unset($media_clone);
  95 + $first = 0;
  96 + }
  97 + }
  98 + }
  99 + $first = 1;
  100 + foreach($article_langs as $article_lang) {
  101 + if($first) {
  102 + $article_lang_clone = clone $article_lang;
  103 + $article_lang_clone->language_id = 0;
  104 + $article_lang_clone->link('article', $article);
  105 + unset($article_lang_clone);
  106 + }
  107 + $article_lang->link('article', $article);
  108 + $first = 0;
  109 + }
  110 + echo "ok";
  111 + //$this->redirect('index');
  112 + } else {
  113 + return $this->render('create', [
  114 + 'article_langs' => $article_langs,
  115 + 'article' => $article,
  116 + 'langs' => $langs,
  117 + 'images' => $images
  118 + ]);
  119 + }
  120 + }
  121 +
  122 + public function actionUpdate($id)
  123 + {
  124 + $article = Article::findOne($id);
  125 + $imagestack = $article->getArticleMedia()->all();
  126 + $images = [];
  127 + $images[0]['additional'][0] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_ADDITIONAL]);
  128 + $images[0]['additional'][0]->type = 'additional';
  129 + $images[0]['additional'][0]->language_id = 0;
  130 + foreach($imagestack as $image) {
  131 + if(in_array($image->type, ['full', 'preview'])) {
  132 + $images[$image->language_id][$image->type] = $image;
  133 + $images[$image->language_id][$image->type]->scenario = $image->type;
  134 + } else {
  135 + $images[$image->language_id][$image->type][$image->article_media_id] = $image;
  136 + $images[$image->language_id][$image->type][$image->article_media_id]->scenario = $image->type;
  137 + }
  138 + }
  139 + foreach($images as $lang => $value) {
  140 + $images[$lang]['additional'][0] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_ADDITIONAL]);
  141 + }
  142 + $article_langs = $article->getArticleLangs()->where(['>=', 'language_id', '1'])->indexBy('language_id')->all();
  143 + $langs = Language::getActiveLanguages();
  144 + $default_lang = Language::getDefaultLang();
  145 + $isValid = false;
  146 + if(!empty(\Yii::$app->request->post())) {
  147 + $isValid = true;
  148 + $article->load(\Yii::$app->request->post());
  149 + ArticleToCategory::deleteAll(['article_id' => $article->article_id]);
  150 + $article_categories = \Yii::$app->request->post('Article')['articleCategoriesArray'];
  151 + if(!empty($article_categories)) {
  152 + foreach($article_categories as $article_category) {
  153 + $articletocategory[$article_category] = new ArticleToCategory();
  154 + $articletocategory[$article_category]->article_category_id = $article_category;
  155 + $articletocategory[$article_category]->link('article', $article);
  156 + }
  157 + }
  158 + $isValid = $article->validate();
  159 + $images[0]['additional'][0]->type = 'additional';
  160 + $images[0]['additional'][0]->language_id = 0;
  161 + $images[0]['additional'][0]->imageFile = UploadedFile::getInstances($images[0]['additional'][0], "[0][additional]imageFile");
  162 + $isValid = $images[0]['additional'][0]->validate(['imageFile']) && $isValid;
  163 + foreach(\Yii::$app->request->post()['ArticleMedia'] as $lang => $value) {
  164 + foreach($value as $type => $fields) {
  165 + if(!in_array($type, ['full', 'preview'])) continue;
  166 + $images[$lang][$type] = new ArticleMedia(['scenario' => $type]);
  167 + $images[$lang][$type]->language_id = $lang;
  168 + $images[$lang][$type]->type = $type;
  169 + $images[$lang][$type]->imageFile = UploadedFile::getInstance($images[$lang][$type], "[{$lang}][{$type}]imageFile");
  170 + $isValid = $images[$lang][$type]->validate(['imageFile']) && $isValid;
  171 + }
  172 + }
  173 + if(empty(\Yii::$app->request->post()['ArticleLang'])) {
  174 + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid;
  175 + } else {
  176 + foreach(\Yii::$app->request->post()['ArticleLang'] as $index => $article_lang) {
  177 + if (!array_key_exists($index, $article_langs)) {
  178 + $article_langs[$index] = new ArticleLang();
  179 + $article_langs[$index]->article_id = $article->article_id;
  180 + }
  181 + }
  182 + ArticleLang::loadMultiple($article_langs, \Yii::$app->request->post());
  183 + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid;
  184 + }
  185 + }
  186 + if($isValid) {
  187 + $article->save(false);
  188 + foreach($images as $lang => $value) {
  189 + foreach($value as $type => $fields) {
  190 + if($type == 'additional') {
  191 + $images[$lang][$type][0]->upload($article->id);
  192 + } else {
  193 + if(!empty($images[$lang][$type]->imageFile)) {
  194 + $images[$lang][$type]->replace($article->article_id);
  195 + }
  196 + }
  197 + }
  198 + }
  199 + foreach($article_langs as $article_lang) {
  200 + $article_lang->save(false);
  201 + }
  202 + echo "ok";
  203 + //$this->redirect('index');
  204 + } else {
  205 + return $this->render('update', [
  206 + 'article_langs' => $article_langs,
  207 + 'article' => $article,
  208 + 'langs' => $langs,
  209 + 'images' => $images
  210 + ]);
  211 + }
  212 + }
  213 +
  214 + public function actionDelete($id)
  215 + {
  216 + $this->findModel($id)->delete();
  217 + return $this->redirect(['index']);
  218 + }
  219 +
  220 + protected function findModel($id)
  221 + {
  222 + if (($model = Article::findOne($id)) !== null) {
  223 + return $model;
  224 + } else {
  225 + throw new NotFoundHttpException('The requested page does not exist.');
  226 + }
  227 + }
  228 +}
... ...
common/modules/blog/controllers/CategoryController.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog\controllers;
  3 +
  4 +use common\models\Language;
  5 +use common\modules\blog\models\Article;
  6 +use common\modules\blog\models\ArticleCategory;
  7 +use common\modules\blog\models\ArticleCategoryLang;
  8 +use common\modules\blog\models\ArticleCategoryMedia;
  9 +use common\modules\blog\models\ArticleLang;
  10 +use yii\data\ActiveDataProvider;
  11 +use yii\filters\VerbFilter;
  12 +use yii\web\Controller;
  13 +use yii\web\NotFoundHttpException;
  14 +use yii\web\UploadedFile;
  15 +
  16 +class CategoryController extends Controller
  17 +{
  18 + public function behaviors()
  19 + {
  20 + return [
  21 + 'verbs' => [
  22 + 'class' => VerbFilter::className(),
  23 + 'actions' => [
  24 + 'delete' => ['post']
  25 + ]
  26 + ]
  27 + ];
  28 + }
  29 +
  30 + public function actionIndex()
  31 + {
  32 + $dataProvider = new ActiveDataProvider([
  33 + 'query' => ArticleCategory::find(),
  34 + 'pagination' => [
  35 + 'pageSize' => 1,
  36 + ],
  37 + ]);
  38 + return $this->render('index', ['dataProvider' => $dataProvider]);
  39 + }
  40 +
  41 + public function actionCreate()
  42 + {
  43 + $category_langs = array();
  44 + $category = new ArticleCategory();
  45 + $default_lang = Language::getDefaultLang();
  46 + $images = array();
  47 + $images[$default_lang->language_id]['full'] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_FULL]);
  48 + $images[$default_lang->language_id]['preview'] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_PREVIEW]);
  49 + $images[0]['additional'] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_ADDITIONAL]);
  50 + $category->loadDefaultValues();
  51 + $langs = Language::getActiveLanguages();
  52 + $isValid = false;
  53 + if(!empty(\Yii::$app->request->post())) {
  54 + $isValid = true;
  55 + $category->load(\Yii::$app->request->post());
  56 + $isValid = $category->validate();
  57 + foreach(\Yii::$app->request->post()['ArticleCategoryMedia'] as $lang => $value) {
  58 + foreach($value as $type => $fields) {
  59 + $images[$lang][$type] = new ArticleCategoryMedia(['scenario' => $type]);
  60 + $images[$lang][$type]->type = $type;
  61 + $images[$lang][$type]->language_id = $lang;
  62 + $images[$lang][$type]->imageFile = UploadedFile::getInstance($images[$lang][$type], "[{$lang}][{$type}]imageFile");
  63 + $isValid = $images[$lang][$type]->validate(['imageFile']) && $isValid;
  64 + }
  65 + }
  66 + $images[0]['additional']->language_id = 0;
  67 + $images[0]['additional']->type = 'additional';
  68 + $images[0]['additional']->imageFile = UploadedFile::getInstances($images[0]['additional'], "[0][additional]imageFile");
  69 + if(empty(\Yii::$app->request->post()['ArticleCategoryLang'])) {
  70 + $category_langs[$default_lang->language_id] = new ArticleCategoryLang();
  71 + $isValid = ArticleCategoryLang::validateMultiple($category_langs) && $isValid;
  72 + } else {
  73 + foreach(\Yii::$app->request->post()['ArticleCategoryLang'] as $index => $category_lang) {
  74 + $category_langs[$index] = new ArticleCategoryLang();
  75 + }
  76 + ArticleCategoryLang::loadMultiple($category_langs, \Yii::$app->request->post());
  77 + $isValid = ArticleCategoryLang::validateMultiple($category_langs) && $isValid;
  78 + }
  79 + } else {
  80 + $category_langs[$default_lang->language_id] = new ArticleCategoryLang();
  81 + }
  82 + if($isValid) {
  83 + $category->save(false);
  84 + $first = 1;
  85 + foreach($images as $lang => $value) {
  86 + foreach($value as $type => $fields) {
  87 + $images[$lang][$type]->upload($category->article_category_id);
  88 + if($first && $type != 'additional') {
  89 + $media_clone = clone $images[$lang][$type];
  90 + $media_clone->setIsNewRecord(true);
  91 + unset($media_clone->article_category_media_id);
  92 + $media_clone->language_id = 0;
  93 + $media_clone->upload($category->article_category_id);
  94 + unset($media_clone);
  95 + $first = 0;
  96 + }
  97 + }
  98 + }
  99 + $first = 1;
  100 + foreach($category_langs as $category_lang) {
  101 + if($first) {
  102 + $category_lang_clone = clone $category_lang;
  103 + $category_lang_clone->language_id = 0;
  104 + $category_lang_clone->link('category', $category);
  105 + unset($category_lang_clone);
  106 + }
  107 + $category_lang->link('category', $category);
  108 + $first = 0;
  109 + }
  110 + echo "ok";
  111 + //$this->redirect('index');
  112 + } else {
  113 + return $this->render('create', [
  114 + 'category_langs' => $category_langs,
  115 + 'category' => $category,
  116 + 'langs' => $langs,
  117 + 'images' => $images
  118 + ]);
  119 + }
  120 + }
  121 +
  122 + public function actionUpdate($id)
  123 + {
  124 + $category = ArticleCategory::findOne($id);
  125 + $imagestack = $category->getArticleCategoryMedia()->all();
  126 + $images = [];
  127 + $images[0]['additional'][0] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_ADDITIONAL]);
  128 + $images[0]['additional'][0]->type = 'additional';
  129 + $images[0]['additional'][0]->language_id = 0;
  130 + foreach($imagestack as $image) {
  131 + if(in_array($image->type, ['full', 'preview'])) {
  132 + $images[$image->language_id][$image->type] = $image;
  133 + $images[$image->language_id][$image->type]->scenario = $image->type;
  134 + } else {
  135 + $images[$image->language_id][$image->type][$image->article_category_media_id] = $image;
  136 + $images[$image->language_id][$image->type][$image->article_category_media_id]->scenario = $image->type;
  137 + }
  138 + }
  139 + foreach($images as $lang => $value) {
  140 + $images[$lang]['additional'][0] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_ADDITIONAL]);
  141 + }
  142 + $category_langs = $category->getArticleCategoryLangs()->where(['>=', 'language_id', '1'])->indexBy('language_id')->all();
  143 + $langs = Language::getActiveLanguages();
  144 + $default_lang = Language::getDefaultLang();
  145 + $isValid = false;
  146 + if(!empty(\Yii::$app->request->post())) {
  147 + $isValid = true;
  148 + $category->load(\Yii::$app->request->post());
  149 + $isValid = $category->validate();
  150 + $images[0]['additional'][0]->type = 'additional';
  151 + $images[0]['additional'][0]->language_id = 0;
  152 + $images[0]['additional'][0]->imageFile = UploadedFile::getInstances($images[0]['additional'][0], "[0][additional]imageFile");
  153 + $isValid = $images[0]['additional'][0]->validate(['imageFile']) && $isValid;
  154 + foreach(\Yii::$app->request->post()['ArticleCategoryMedia'] as $lang => $value) {
  155 + foreach($value as $type => $fields) {
  156 + if(!in_array($type, ['full', 'preview'])) continue;
  157 + $images[$lang][$type] = new ArticleCategoryMedia(['scenario' => $type]);
  158 + $images[$lang][$type]->language_id = $lang;
  159 + $images[$lang][$type]->type = $type;
  160 + $images[$lang][$type]->imageFile = UploadedFile::getInstance($images[$lang][$type], "[{$lang}][{$type}]imageFile");
  161 + $isValid = $images[$lang][$type]->validate(['imageFile']) && $isValid;
  162 + }
  163 + }
  164 + if(empty(\Yii::$app->request->post()['ArticleCategoryLang'])) {
  165 + $isValid = ArticleCategoryLang::validateMultiple($category_langs) && $isValid;
  166 + } else {
  167 + foreach(\Yii::$app->request->post()['ArticleCategoryLang'] as $index => $category_lang) {
  168 + if(!array_key_exists($index, $category_langs)) {
  169 + $category_langs[$index] = new ArticleCategoryLang();
  170 + $category_langs[$index]->article_category_id = $category->article_category_id;
  171 + }
  172 + }
  173 + ArticleCategoryLang::loadMultiple($category_langs, \Yii::$app->request->post());
  174 + $isValid = ArticleCategoryLang::validateMultiple($category_langs) && $isValid;
  175 + }
  176 + }
  177 + if($isValid) {
  178 + $category->save(false);
  179 + foreach($images as $lang => $value) {
  180 + foreach($value as $type => $fields) {
  181 + if($type == 'additional') {
  182 + $images[$lang][$type][0]->upload($category->article_category_id);
  183 + } else {
  184 + if(!empty($images[$lang][$type]->imageFile)) {
  185 + $images[$lang][$type]->replace($category->article_category_id);
  186 + }
  187 + }
  188 + }
  189 + }
  190 + foreach($category_langs as $category_lang) {
  191 + $category_lang->save(false);
  192 + }
  193 + echo "ok";
  194 + //$this->redirect('index');
  195 + } else {
  196 + return $this->render('update', [
  197 + 'category_langs' => $category_langs,
  198 + 'category' => $category,
  199 + 'langs' => $langs,
  200 + 'images' => $images
  201 + ]);
  202 + }
  203 + }
  204 +
  205 + public function actionDelete($id)
  206 + {
  207 + $this->findModel($id)->delete();
  208 + return $this->redirect(['index']);
  209 + }
  210 +
  211 + protected function findModel($id)
  212 + {
  213 + if (($model = ArticleCategory::findOne($id)) !== null) {
  214 + return $model;
  215 + } else {
  216 + throw new NotFoundHttpException('The requested page does not exist.');
  217 + }
  218 + }
  219 +}
... ...
common/modules/blog/controllers/DefaultController.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog\controllers;
  3 +
  4 +use yii\web\Controller;
  5 +
  6 +class DefaultController extends Controller
  7 +{
  8 + public function actionIndex()
  9 + {
  10 + return $this->render('index');
  11 + }
  12 +}
... ...
common/modules/blog/controllers/MediaController.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog\controllers;
  3 +
  4 +use common\models\Media;
  5 +use common\modules\blog\models\Article;
  6 +use yii\web\Controller;
  7 +use yii\web\UploadedFile;
  8 +
  9 +class MediaController extends Controller
  10 +{
  11 + public function actionIndex()
  12 + {
  13 + $model = new Media();
  14 + if(\Yii::$app->request->isPost) {
  15 + $model->imageFile = UploadedFile::getInstance($model, 'imageFile');
  16 + if($model->upload()) {
  17 + return true;
  18 + } else {
  19 + return false;
  20 + }
  21 + }
  22 + return $this->render('index', ['model' => $model]);
  23 + }
  24 +
  25 + public function actionCreate()
  26 + {
  27 +
  28 + }
  29 +
  30 + public function actionUpdate($id)
  31 + {
  32 +
  33 + }
  34 +
  35 + public function actionDelete($id)
  36 + {
  37 + $model = Media::findOne($id);
  38 + return $model->delete();
  39 + }
  40 +
  41 + protected function findModel($id)
  42 + {
  43 +
  44 + }
  45 +}
... ...
common/modules/blog/controllers/TestController.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\blog\controllers;
  3 +
  4 +use common\models\Language;
  5 +use common\modules\blog\models\ArticleLang;
  6 +use yii\console\Controller;
  7 +
  8 +class TestController extends Controller
  9 +{
  10 + public function actionIndex()
  11 + {
  12 + $default_lang = Language::getDefaultLang();
  13 + $model[$default_lang->language_id] = new ArticleLang();
  14 + $model[3] = new ArticleLang();
  15 + return $this->render('index', ['model' => $model]);
  16 + }
  17 +}
0 18 \ No newline at end of file
... ...
common/modules/blog/models/Article.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\blog\models;
  4 +
  5 +use common\models\ActiveRecordRule;
  6 +use common\models\Media;
  7 +use common\models\User;
  8 +use common\modules\blog\behaviors\Autocomplete;
  9 +use Yii;
  10 +use yii\db\Query;
  11 +
  12 +/**
  13 + * This is the model class for table "article".
  14 + *
  15 + * @property integer $article_id
  16 + * @property integer $sort
  17 + * @property string $date_add
  18 + * @property string $date_update
  19 + * @property string $code
  20 + * @property integer $user_id
  21 + * @property string $tag
  22 + * @property integer $article_pid
  23 + * @property integer $status
  24 + * @property integer $comment
  25 + * @property integer $vote
  26 + *
  27 + * @property Article $parent
  28 + * @property Article[] $articles
  29 + * @property User $user
  30 + * @property ArticleLang[] $articleLangs
  31 + * @property ArticleMedia[] $articleMedia
  32 + * @property ArticleToCategory[] $articleToCategories
  33 + * @property Media[] $media
  34 + */
  35 +class Article extends ActiveRecordRule
  36 +{
  37 + /**
  38 + * @inheritdoc
  39 + */
  40 + public static function tableName()
  41 + {
  42 + return 'article';
  43 + }
  44 +
  45 + public function behaviors()
  46 + {
  47 + return [
  48 + [
  49 + 'class' => Autocomplete::className(),
  50 + 'attributes' => [
  51 + 'translit' => ['code'],
  52 + ]
  53 + ]
  54 + ];
  55 + }
  56 + /**
  57 + * @inheritdoc
  58 + */
  59 + public function rules()
  60 + {
  61 + return [
  62 + [['sort', 'article_pid', 'status', 'comment', 'vote'], 'integer'],
  63 + [['date_add', 'date_update'], 'safe'],
  64 + [['code'], 'required'],
  65 + [['code', 'tag'], 'string']
  66 + ];
  67 + }
  68 +
  69 + /**
  70 + * @inheritdoc
  71 + */
  72 + public function attributeLabels()
  73 + {
  74 + return [
  75 + 'article_id' => Yii::t('app', 'ID'),
  76 + 'sort' => Yii::t('app', 'Sort'),
  77 + 'date_add' => Yii::t('app', 'Create At'),
  78 + 'date_update' => Yii::t('app', 'Update At'),
  79 + 'code' => Yii::t('app', 'Code'),
  80 + 'user_id' => Yii::t('app', 'Author'),
  81 + 'tag' => Yii::t('app', 'Tags'),
  82 + 'article_pid' => Yii::t('app', 'Parent ID'),
  83 + 'status' => Yii::t('app', 'Active'),
  84 + 'comment' => Yii::t('app', 'Comments'),
  85 + 'vote' => Yii::t('app', 'Voting'),
  86 + ];
  87 + }
  88 +
  89 + /**
  90 + * @return \yii\db\ActiveQuery
  91 + */
  92 + public function getParent()
  93 + {
  94 + return $this->hasOne(Article::className(), ['article_id' => 'article_pid']);
  95 + }
  96 +
  97 + /**
  98 + * @return \yii\db\ActiveQuery
  99 + */
  100 + public function getArticles()
  101 + {
  102 + return $this->hasMany(Article::className(), ['article_pid' => 'article_id']);
  103 + }
  104 +
  105 + /**
  106 + * @return \yii\db\ActiveQuery
  107 + */
  108 + public function getUser()
  109 + {
  110 + return $this->hasOne(User::className(), ['id' => 'user_id']);
  111 + }
  112 +
  113 + /**
  114 + * @return \yii\db\ActiveQuery
  115 + */
  116 + public function getArticleLangs()
  117 + {
  118 + return $this->hasMany(ArticleLang::className(), ['article_id' => 'article_id']);
  119 + }
  120 +
  121 + /**
  122 + * @return \yii\db\ActiveQuery
  123 + */
  124 + public function getArticleMedia()
  125 + {
  126 + return $this->hasMany(ArticleMedia::className(), ['article_id' => 'article_id']);
  127 + }
  128 +
  129 + public function getMedia()
  130 + {
  131 + return $this->hasMany(Media::className(), ['article_id' => 'media_id'])->via('articleMedia');
  132 + }
  133 + /**
  134 + * @return \yii\db\ActiveQuery
  135 + */
  136 + public function getArticleToCategories()
  137 + {
  138 + return $this->hasMany(ArticleToCategory::className(), ['article_id' => 'article_id']);
  139 + }
  140 +
  141 + public function getArticleCategories()
  142 + {
  143 + return $this->hasMany(ArticleCategory::className(), ['article_category_id' => 'article_category_id'])->viaTable('article_to_category', ['article_id' => 'article_category_id']);
  144 + }
  145 +
  146 + public static function findArticleDropdown($id)
  147 + {
  148 + $query = new Query();
  149 + return $query->select(['l.name', 'a.article_id'])
  150 + ->from(['article a'])
  151 + ->leftJoin(['article_lang l'], 'a.article_id = l.article_id')
  152 + ->where(['l.language_id' => 0, 'a.status' => 1])
  153 + ->andWhere(['not', ['a.article_id' => $id]])
  154 + ->indexBy('article_id')
  155 + ->column();
  156 + }
  157 +
  158 + public function getArticleCategoriesArray()
  159 + {
  160 + return $this->getArticleToCategories()->select('article_category_id')->column();
  161 + }
  162 +
  163 +}
... ...
common/modules/blog/models/ArticleCategory.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\blog\models;
  4 +
  5 +use common\modules\blog\behaviors\Autocomplete;
  6 +use Yii;
  7 +use yii\behaviors\TimestampBehavior;
  8 +use yii\db\ActiveRecord;
  9 +use yii\db\Query;
  10 +
  11 +/**
  12 + * This is the model class for table "article_category".
  13 + *
  14 + * @property integer $article_category_id
  15 + * @property integer $status
  16 + * @property integer $sort
  17 + * @property string $code
  18 + * @property string $date_add
  19 + * @property string $date_update
  20 + * @property string $tag
  21 + * @property integer $artucle_category_pid
  22 + *
  23 + * @property Article[] $articles
  24 + * @property ArticleCategory $parent
  25 + * @property ArticleCategory[] $articleCategories
  26 + * @property ArticleCategoryLang[] $articleCategoryLangs
  27 + * @property ArticleCategoryMedia[] $articleCategoryMedia
  28 + */
  29 +class ArticleCategory extends ActiveRecord
  30 +{
  31 + /**
  32 + * @inheritdoc
  33 + */
  34 + public static function tableName()
  35 + {
  36 + return 'article_category';
  37 + }
  38 +
  39 + public function behaviors()
  40 + {
  41 + return [
  42 + [
  43 + 'class' => Autocomplete::className(),
  44 + 'attributes' => [
  45 + 'translit' => ['code'],
  46 + ]
  47 + ]
  48 + ];
  49 + }
  50 + /**
  51 + * @inheritdoc
  52 + */
  53 + public function rules()
  54 + {
  55 + return [
  56 + [['status', 'sort', 'article_category_pid'], 'integer'],
  57 + [['code'], 'required'],
  58 + [['code', 'tag'], 'string'],
  59 + [['date_add', 'date_update'], 'safe'],
  60 + [['status'], 'boolean'],
  61 + ];
  62 + }
  63 +
  64 + /**
  65 + * @inheritdoc
  66 + */
  67 + public function attributeLabels()
  68 + {
  69 + return [
  70 + 'article_category_id' => Yii::t('app', 'ID'),
  71 + 'status' => Yii::t('app', 'Active'),
  72 + 'sort' => Yii::t('app', 'Sort'),
  73 + 'code' => Yii::t('app', 'Code'),
  74 + 'date_add' => Yii::t('app', 'Created At'),
  75 + 'date_update' => Yii::t('app', 'Updated At'),
  76 + 'tag' => Yii::t('app', 'Tags'),
  77 + 'article_category_pid' => Yii::t('app', 'Parent ID'),
  78 + ];
  79 + }
  80 +
  81 + /**
  82 + * @return \yii\db\ActiveQuery
  83 + */
  84 + public function getArticles()
  85 + {
  86 + return $this->hasMany(Article::className(), ['article_id' => 'article_id'])->viaTable('article_to_category', ['article_category_id' => 'article_category_id']) ;
  87 + }
  88 +
  89 + /**
  90 + * @return \yii\db\ActiveQuery
  91 + */
  92 + public function getParent()
  93 + {
  94 + return $this->hasOne(ArticleCategory::className(), ['article_category_id' => 'article_category_pid']);
  95 + }
  96 +
  97 + /**
  98 + * @return \yii\db\ActiveQuery
  99 + */
  100 + public function getArticleCategories()
  101 + {
  102 + return $this->hasMany(ArticleCategory::className(), ['article_category_pid' => 'article_category_id']);
  103 + }
  104 +
  105 + /**
  106 + * @return \yii\db\ActiveQuery
  107 + */
  108 + public function getArticleCategoryLangs()
  109 + {
  110 + return $this->hasMany(ArticleCategoryLang::className(), ['article_category_id' => 'article_category_id']);
  111 + }
  112 +
  113 + /**
  114 + * @return \yii\db\ActiveQuery
  115 + */
  116 + public function getArticleCategoryMedia()
  117 + {
  118 + return $this->hasMany(ArticleCategoryMedia::className(), ['article_category_id' => 'article_category_id']);
  119 + }
  120 +
  121 + public static function findArticleCategoryDropdown($id)
  122 + {
  123 + $query = new Query();
  124 + return $query->select(['l.name', 'c.article_category_id'])
  125 + ->from(['article_category c'])
  126 + ->leftJoin(['article_category_lang l'], 'c.article_category_id = l.article_category_id')
  127 + ->where(['l.language_id' => 0, 'c.status' => 1])
  128 + ->andWhere(['not', ['c.article_category_id' => $id]])
  129 + ->indexBy('article_category_id')
  130 + ->column();
  131 + }
  132 +
  133 +}
... ...
common/modules/blog/models/ArticleCategoryLang.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\blog\models;
  4 +
  5 +use common\modules\blog\behaviors\Autocomplete;
  6 +use Yii;
  7 +
  8 +/**
  9 + * This is the model class for table "article_category_lang".
  10 + *
  11 + * @property integer $article_category_language_id
  12 + * @property integer $language_id
  13 + * @property integer $article_category_id
  14 + * @property string $text
  15 + * @property string $preview
  16 + * @property string $seo_url
  17 + * @property string $name
  18 + * @property string $meta_title
  19 + * @property string $meta_descr
  20 + * @property string $meta_keyword
  21 + * @property string $h1_tag
  22 + * @property string $tag
  23 + *
  24 + * @property ArticleCategory $category
  25 + * @property Language $lang
  26 + */
  27 +class ArticleCategoryLang extends \yii\db\ActiveRecord
  28 +{
  29 + /**
  30 + * @inheritdoc
  31 + */
  32 + public static function tableName()
  33 + {
  34 + return 'article_category_lang';
  35 + }
  36 +
  37 + public function behaviors()
  38 + {
  39 + return [
  40 + [
  41 + 'class' => Autocomplete::className(),
  42 + 'attributes' => [
  43 + 'repeat' => [['preview', 'text', false, 5, true, '...']],
  44 + ]
  45 + ]
  46 + ];
  47 + }
  48 + /**
  49 + * @inheritdoc
  50 + */
  51 + public function rules()
  52 + {
  53 + return [
  54 + [['language_id', 'article_category_id'], 'integer'],
  55 + [['text', 'name'], 'required'],
  56 + [['text', 'preview', 'seo_url', 'name', 'meta_title', 'meta_descr', 'meta_keyword', 'h1_tag', 'tag'], 'string'],
  57 + ['seo_url', function($attribute, $params) {
  58 + $pattern = "/^[a-zA-Z\d_-]+$/";
  59 + if(!preg_match($pattern, $this->$attribute)) {
  60 + $this->addError($attribute, Yii::t('app', "Pattern doesn't match."));
  61 + }
  62 + }]
  63 + ];
  64 + }
  65 +
  66 + /**
  67 + * @inheritdoc
  68 + */
  69 + public function attributeLabels()
  70 + {
  71 + return [
  72 + 'article_category_language_id' => Yii::t('app', 'ID'),
  73 + 'language_id' => Yii::t('app', 'Lang ID'),
  74 + 'article_category_id' => Yii::t('app', 'Category ID'),
  75 + 'text' => Yii::t('app', 'Text'),
  76 + 'preview' => Yii::t('app', 'Preview'),
  77 + 'seo_url' => Yii::t('app', 'Seo Url'),
  78 + 'name' => Yii::t('app', 'Name'),
  79 + 'meta_title' => Yii::t('app', 'Meta Title'),
  80 + 'meta_descr' => Yii::t('app', 'Meta Descr'),
  81 + 'meta_keyword' => Yii::t('app', 'Meta Keywords'),
  82 + 'h1_tag' => Yii::t('app', 'H1 Tag'),
  83 + 'tag' => Yii::t('app', 'Tags'),
  84 + ];
  85 + }
  86 +
  87 + /**
  88 + * @return \yii\db\ActiveQuery
  89 + */
  90 + public function getCategory()
  91 + {
  92 + return $this->hasOne(ArticleCategory::className(), ['article_category_id' => 'article_category_id']);
  93 + }
  94 +
  95 + /**
  96 + * @return \yii\db\ActiveQuery
  97 + */
  98 + public function getLang()
  99 + {
  100 + return $this->hasOne(Language::className(), ['language_id' => 'language_id']);
  101 + }
  102 +}
... ...
common/modules/blog/models/ArticleCategoryMedia.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\blog\models;
  4 +
  5 +use common\models\Media;
  6 +use Yii;
  7 +
  8 +/**
  9 + * This is the model class for table "article_category_media".
  10 + *
  11 + * @property integer $article_category_media_id
  12 + * @property integer $article_category_id
  13 + * @property integer $media_id
  14 + * @property string $media_alt
  15 + * @property string $media_title
  16 + * @property string $media_caption
  17 + * @property string $type
  18 + * @property string $language_id
  19 + *
  20 + * @property ArticleCategory $category
  21 + * @property Media $media
  22 + * @property Language $lang
  23 + */
  24 +class ArticleCategoryMedia extends \yii\db\ActiveRecord
  25 +{
  26 + const SCENARIO_FULL = 'full';
  27 + const SCENARIO_PREVIEW = 'preview';
  28 + const SCENARIO_ADDITIONAL = 'additional';
  29 + public $imageFile;
  30 + /**
  31 + * @inheritdoc
  32 + */
  33 + public static function tableName()
  34 + {
  35 + return 'article_category_media';
  36 + }
  37 +
  38 + public function scenarios()
  39 + {
  40 + $scenarios = parent::scenarios();
  41 + $scenarios[self::SCENARIO_FULL] = ['article_category_media_id', 'article_category_id', 'media_id', 'type', 'media_alt', 'media_title', 'media_caption', 'imageFile'];
  42 + $scenarios[self::SCENARIO_PREVIEW] = ['article_category_media_id', 'article_category_id', 'media_id', 'type', 'media_alt', 'media_title', 'media_caption', 'imageFile'];
  43 + $scenarios[self::SCENARIO_ADDITIONAL] = ['article_category_media_id', 'article_category_id', 'media_id', 'type', 'imageFile'];
  44 + return $scenarios;
  45 + }
  46 +
  47 + /**
  48 + * @inheritdoc
  49 + */
  50 + public function rules()
  51 + {
  52 + return [
  53 + [['article_category_id', 'media_id'], 'required'],
  54 + [['article_category_id', 'media_id'], 'integer'],
  55 + [['media_alt', 'media_title', 'media_caption'], 'string'],
  56 + [['type'], 'string', 'max' => 10],
  57 + [['imageFile'], 'file', 'extensions' => 'png, gif, jpg, jpeg', 'skipOnEmpty' => true, 'on' => self::SCENARIO_FULL],
  58 + [['imageFile'], 'file', 'extensions' => 'png, gif, jpg, jpeg', 'skipOnEmpty' => true, 'on' => self::SCENARIO_PREVIEW],
  59 + [['imageFile'], 'file', 'extensions' => 'png, gif, jpg, jpeg', 'skipOnEmpty' => true, 'maxFiles' => 10, 'on' => self::SCENARIO_ADDITIONAL]
  60 + ];
  61 + }
  62 +
  63 + /**
  64 + * @inheritdoc
  65 + */
  66 + public function attributeLabels()
  67 + {
  68 + return [
  69 + 'article_category_media_id' => Yii::t('app', 'ID'),
  70 + 'article_category_id' => Yii::t('app', 'Category ID'),
  71 + 'media_id' => Yii::t('app', 'Media ID'),
  72 + 'media_alt' => Yii::t('app', 'Media Alt'),
  73 + 'media_title' => Yii::t('app', 'Media Title'),
  74 + 'media_caption' => Yii::t('app', 'Media Caption'),
  75 + 'type' => Yii::t('app', 'Type'),
  76 + 'imageFile' => Yii::t('app', 'Image File'),
  77 + 'language_id' => Yii::t('app', 'Language ID'),
  78 + ];
  79 + }
  80 +
  81 + /**
  82 + * @return \yii\db\ActiveQuery
  83 + */
  84 + public function getCategory()
  85 + {
  86 + return $this->hasOne(ArticleCategory::className(), ['article_category_id' => 'article_category_id']);
  87 + }
  88 +
  89 + /**
  90 + * @return \yii\db\ActiveQuery
  91 + */
  92 + public function getMedia()
  93 + {
  94 + return $this->hasOne(Media::className(), ['media_id' => 'media_id']);
  95 + }
  96 +
  97 + public function upload($category_id)
  98 + {
  99 + $this->article_category_id = $category_id;
  100 + if(is_array($this->imageFile)) {
  101 + $ok = true;
  102 + foreach($this->imageFile as $image) {
  103 + $media_category = clone $this;
  104 + $media = new Media();
  105 + $media->imageFile = $image;
  106 + $media->upload();
  107 + $media_category->media_id = $media->media_id;
  108 + $ok = $media_category->save() && $ok;
  109 + unset($media_category);
  110 + }
  111 + return $ok;
  112 + } elseif(!empty($this->imageFile)) {
  113 + $media = new Media();
  114 + $media->imageFile = $this->imageFile;
  115 + $media->upload();
  116 + $this->media_id = $media->media_id;
  117 + return $this->save();
  118 + }
  119 + }
  120 +
  121 + public function replace($category_id, $removeMedia = false)
  122 + {
  123 + $this->article_category_id = $category_id;
  124 + if($removeMedia) {
  125 + $category_media = ArticleCategoryMedia::find()->select('media_id')->where(['article_category_id' => $this->article_category_id, 'type' => $this->type])->column();
  126 + $media = array();
  127 + foreach($category_media as $media_id) {
  128 + $media[] = Media::findOne(['media_id' => $media_id]);
  129 + }
  130 + $media = array_unique($media);
  131 + foreach($media as $one_media) {
  132 + if($one_media instanceof Media) {
  133 + $one_media->delete();
  134 + }
  135 + }
  136 + unset($media);
  137 + unset($category_media);
  138 + }
  139 + if(is_array($this->imageFile)) {
  140 + $ok = true;
  141 + foreach($this->imageFile as $image) {
  142 + $media_category = clone $this;
  143 + $media = new Media();
  144 + $media->imageFile = $image;
  145 + $media->upload();
  146 + $media_category->media_id = $media->media_id;
  147 + $ok = $media_category->save() && $ok;
  148 + unset($media_category);
  149 + }
  150 + return $ok;
  151 + } elseif(!empty($this->imageFile)) {
  152 + ArticleCategoryMedia::deleteAll(['category_id' => $this->article_category_id, 'type' => $this->type]);
  153 + $media = new Media();
  154 + $media->imageFile = $this->imageFile;
  155 + $media->upload();
  156 + $this->media_id = $media->media_id;
  157 + $this->setIsNewRecord(true);
  158 + return $this->save();
  159 + }
  160 + }
  161 +
  162 +}
... ...
common/modules/blog/models/ArticleLang.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\blog\models;
  4 +
  5 +use Yii;
  6 +use common\models\Language;
  7 +
  8 +/**
  9 + * This is the model class for table "article_lang".
  10 + *
  11 + * @property integer $article_language_id
  12 + * @property integer $language_id
  13 + * @property integer $article_id
  14 + * @property string $text
  15 + * @property string $seo_url
  16 + * @property string $name
  17 + * @property string $preview
  18 + * @property string $meta_title
  19 + * @property string $meta_descr
  20 + * @property string $meta_keyword
  21 + * @property string $h1_tag
  22 + * @property string $tag
  23 + *
  24 + * @property Article $article
  25 + * @property Language $lang
  26 + */
  27 +class ArticleLang extends \yii\db\ActiveRecord
  28 +{
  29 + /**
  30 + * @inheritdoc
  31 + */
  32 + public static function tableName()
  33 + {
  34 + return 'article_lang';
  35 + }
  36 +
  37 + /**
  38 + * @inheritdoc
  39 + */
  40 + public function rules()
  41 + {
  42 + return [
  43 + [['language_id', 'text', 'name'], 'required'],
  44 + [['language_id', 'article_id'], 'integer'],
  45 + [['text', 'seo_url', 'name', 'preview', 'meta_title', 'meta_descr', 'meta_keyword', 'h1_tag', 'tag'], 'string']
  46 + ];
  47 + }
  48 +
  49 + /**
  50 + * @inheritdoc
  51 + */
  52 + public function attributeLabels()
  53 + {
  54 + return [
  55 + 'article_language_id' => Yii::t('app', 'ID'),
  56 + 'language_id' => Yii::t('app', 'Lang ID'),
  57 + 'article_id' => Yii::t('app', 'Article ID'),
  58 + 'text' => Yii::t('app', 'Text'),
  59 + 'seo_url' => Yii::t('app', 'Seo Url'),
  60 + 'name' => Yii::t('app', 'Name'),
  61 + 'preview' => Yii::t('app', 'Preview'),
  62 + 'meta_title' => Yii::t('app', 'Meta Title'),
  63 + 'meta_descr' => Yii::t('app', 'Meta Descr'),
  64 + 'meta_keyword' => Yii::t('app', 'Meta Keywords'),
  65 + 'h1_tag' => Yii::t('app', 'H1 Tag'),
  66 + 'tag' => Yii::t('app', 'Tags'),
  67 + ];
  68 + }
  69 +
  70 + /**
  71 + * @return \yii\db\ActiveQuery
  72 + */
  73 + public function getArticle()
  74 + {
  75 + return $this->hasOne(Article::className(), ['article_id' => 'article_id']);
  76 + }
  77 +
  78 + /**
  79 + * @return \yii\db\ActiveQuery
  80 + */
  81 + public function getLang()
  82 + {
  83 + return $this->hasOne(Language::className(), ['language_id' => 'language_id']);
  84 + }
  85 +}
... ...
common/modules/blog/models/ArticleMedia.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\blog\models;
  4 +
  5 +use common\models\Media;
  6 +use Yii;
  7 +use yii\web\UploadedFile;
  8 +
  9 +/**
  10 + * This is the model class for table "article_media".
  11 + *
  12 + * @property integer $article_media_id
  13 + * @property integer $article_id
  14 + * @property integer $media_id
  15 + * @property string $type
  16 + * @property string $media_alt
  17 + * @property string $media_title
  18 + * @property string $media_caption
  19 + * @property integer $language_id
  20 + *
  21 + * @property Article $article
  22 + * @property Media $media
  23 + */
  24 +class ArticleMedia extends \yii\db\ActiveRecord
  25 +{
  26 + const SCENARIO_FULL = 'full';
  27 + const SCENARIO_PREVIEW = 'preview';
  28 + const SCENARIO_ADDITIONAL = 'additional';
  29 + public $imageFile;
  30 + /**
  31 + * @inheritdoc
  32 + */
  33 + public static function tableName()
  34 + {
  35 + return 'article_media';
  36 + }
  37 +
  38 + public function scenarios()
  39 + {
  40 + $scenarios = parent::scenarios();
  41 + $scenarios[self::SCENARIO_FULL] = ['article_media_id', 'article_id', 'media_id', 'type', 'media_alt', 'media_title', 'media_caption', 'imageFile', 'language_id'];
  42 + $scenarios[self::SCENARIO_PREVIEW] = ['article_media_id', 'article_id', 'media_id', 'type', 'media_alt', 'media_title', 'media_caption', 'imageFile', 'language_id'];
  43 + $scenarios[self::SCENARIO_ADDITIONAL] = ['article_media_id', 'article_id', 'media_id', 'type', 'imageFile', 'language_id'];
  44 + return $scenarios;
  45 + }
  46 +
  47 + /**
  48 + * @inheritdoc
  49 + */
  50 + public function rules()
  51 + {
  52 + return [
  53 + [['article_id', 'media_id'], 'required'],
  54 + [['article_id', 'media_id', 'language_id'], 'integer'],
  55 + [['media_alt', 'media_title', 'media_caption'], 'string'],
  56 + [['type'], 'string', 'max' => 10],
  57 + [['imageFile'], 'file', 'extensions' => 'png, gif, jpg, jpeg', 'skipOnEmpty' => true, 'on' => self::SCENARIO_FULL],
  58 + [['imageFile'], 'file', 'extensions' => 'png, gif, jpg, jpeg', 'skipOnEmpty' => true, 'on' => self::SCENARIO_PREVIEW],
  59 + [['imageFile'], 'file', 'extensions' => 'png, gif, jpg, jpeg', 'skipOnEmpty' => true, 'maxFiles' => 10, 'on' => self::SCENARIO_ADDITIONAL]
  60 + ];
  61 + }
  62 +
  63 + /**
  64 + * @inheritdoc
  65 + */
  66 + public function attributeLabels()
  67 + {
  68 + return [
  69 + 'article_media_id' => Yii::t('app', 'ID'),
  70 + 'article_id' => Yii::t('app', 'Article ID'),
  71 + 'media_id' => Yii::t('app', 'Media ID'),
  72 + 'type' => Yii::t('app', 'Type'),
  73 + 'media_alt' => Yii::t('app', 'Media Alt'),
  74 + 'media_title' => Yii::t('app', 'Media Title'),
  75 + 'media_caption' => Yii::t('app', 'Media Caption'),
  76 + 'imageFile' => Yii::t('app', 'Image File'),
  77 + ];
  78 + }
  79 +
  80 + /**
  81 + * @return \yii\db\ActiveQuery
  82 + */
  83 + public function getArticle()
  84 + {
  85 + return $this->hasOne(Article::className(), ['article_id' => 'article_id']);
  86 + }
  87 +
  88 + /**
  89 + * @return \yii\db\ActiveQuery
  90 + */
  91 + public function getMedia()
  92 + {
  93 + return $this->hasOne(Media::className(), ['media_id' => 'media_id']);
  94 + }
  95 +
  96 + public function upload($article_id)
  97 + {
  98 + $this->article_id = $article_id;
  99 + if(is_array($this->imageFile)) {
  100 + $ok = true;
  101 + foreach($this->imageFile as $image) {
  102 + $media_article = clone $this;
  103 + $media = new Media();
  104 + $media->imageFile = $image;
  105 + $media->upload();
  106 + $media_article->media_id = $media->media_id;
  107 + $ok = $media_article->save() && $ok;
  108 + unset($media_article);
  109 + }
  110 + return $ok;
  111 + } elseif(!empty($this->imageFile)) {
  112 + $media = new Media();
  113 + $media->imageFile = $this->imageFile;
  114 + $media->upload();
  115 + $this->media_id = $media->media_id;
  116 + return $this->save();
  117 + }
  118 + }
  119 +
  120 + public function replace($article_id, $removeMedia = false)
  121 + {
  122 + $this->article_id = $article_id;
  123 + if($removeMedia && !$this->getIsNewRecord()) {
  124 + $article_media = ArticleMedia::find()->select('media_id')->where(['article_id' => $this->article_id, 'type' => $this->type, 'language_id' => $this->language_id])->column();
  125 + $media = array();
  126 + foreach($article_media as $media_id) {
  127 + $media[] = Media::findOne(['media_id' => $media_id]);
  128 + }
  129 + $media = array_unique($media);
  130 + foreach($media as $one_media) {
  131 + if($one_media instanceof Media) {
  132 + $one_media->delete();
  133 + }
  134 + }
  135 + unset($media);
  136 + unset($article_media);
  137 + }
  138 + if(is_array($this->imageFile)) {
  139 + $ok = true;
  140 + foreach($this->imageFile as $image) {
  141 + $media_article = clone $this;
  142 + $media = new Media();
  143 + $media->imageFile = $image;
  144 + $media->upload();
  145 + $media_article->media_id = $media->media_id;
  146 + $ok = $media_article->save() && $ok;
  147 + unset($media_article);
  148 + }
  149 + return $ok;
  150 + } elseif(!empty($this->imageFile)) {
  151 + ArticleMedia::deleteAll(['article_id' => $this->article_id, 'type' => $this->type, 'language_id' => $this->language_id]);
  152 + $media = new Media();
  153 + $media->imageFile = $this->imageFile;
  154 + $media->upload();
  155 + $this->media_id = $media->media_id;
  156 + $this->setIsNewRecord(true);
  157 + return $this->save();
  158 + }
  159 + }
  160 +
  161 +}
... ...
common/modules/blog/models/ArticleToCategory.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\blog\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "article_to_category".
  9 + *
  10 + * @property integer $article_id
  11 + * @property integer $article_category_id
  12 + *
  13 + * @property Article $article
  14 + * @property ArticleCategory $category
  15 + */
  16 +class ArticleToCategory extends \yii\db\ActiveRecord
  17 +{
  18 + /**
  19 + * @inheritdoc
  20 + */
  21 + public static function tableName()
  22 + {
  23 + return 'article_to_category';
  24 + }
  25 +
  26 + /**
  27 + * @inheritdoc
  28 + */
  29 + public function rules()
  30 + {
  31 + return [
  32 + [['article_id', 'article_category_id'], 'integer']
  33 + ];
  34 + }
  35 +
  36 + /**
  37 + * @inheritdoc
  38 + */
  39 + public function attributeLabels()
  40 + {
  41 + return [
  42 + 'article_id' => Yii::t('app', 'Article ID'),
  43 + 'article_category_id' => Yii::t('app', 'Category ID'),
  44 + ];
  45 + }
  46 +
  47 + /**
  48 + * @return \yii\db\ActiveQuery
  49 + */
  50 + public function getArticle()
  51 + {
  52 + return $this->hasOne(Article::className(), ['article_id' => 'article_id']);
  53 + }
  54 +
  55 + /**
  56 + * @return \yii\db\ActiveQuery
  57 + */
  58 + public function getCategory()
  59 + {
  60 + return $this->hasOne(ArticleCategory::className(), ['article_category_id' => 'article_category_id']);
  61 + }
  62 +}
... ...
common/modules/blog/views/ajax/_article_form.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use yii\bootstrap\ActiveField;
  4 +use mihaildev\ckeditor\CKEditor;
  5 +
  6 +if(empty($form)) {
  7 + $new_form = true;
  8 + $form = \yii\bootstrap\ActiveForm::begin();
  9 +}
  10 +?>
  11 +<div role="" class="tab-pane active ajax-loaded" id="<?=$widget_id?>-<?=$model->language_id?>">
  12 +
  13 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]language_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?>
  14 +
  15 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]text", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?>
  16 +
  17 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]preview", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?>
  18 +
  19 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]seo_url"]))->textInput() ?>
  20 +
  21 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]name"]))->textInput() ?>
  22 +
  23 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]meta_title"]))->textInput() ?>
  24 +
  25 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]meta_descr"]))->textarea() ?>
  26 +
  27 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]meta_keyword"]))->textInput() ?>
  28 +
  29 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]h1_tag"]))->textInput() ?>
  30 +
  31 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]tag"]))->textInput() ?>
  32 +
  33 +</div>
  34 +<?php
  35 + if($new_form) {
  36 + $form->end();
  37 + }
  38 +?>
... ...
common/modules/blog/views/ajax/_article_form_test.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use yii\bootstrap\ActiveField;
  4 +use mihaildev\ckeditor\CKEditor;
  5 + //ะ•ัะปะธ ัั‚ะพ ะฝะต AJAX ะทะฐะฟั€ะพั, ั‚ะพ ะฟะตั€ะตะผะตะฝะฝะฐั $form ะฑัƒะดะตั‚ ะพะฟั€ะตะดะตะปะตะฝะฐ ะธ ะฝะฐะผ ะฝะต ะฟั€ะธะดะตั‚ัั ะณะตะฝะตั€ะธั€ะพะฒะฐั‚ัŒ ั„ะพั€ะผัƒ.
  6 +if(empty($form)) {
  7 + $new_form = true;
  8 + $form = \yii\bootstrap\ActiveForm::begin();
  9 +}
  10 +?>
  11 +<div role="" class="tab-pane active ajax-loaded" id="<?=$widget_id?>-<?=$model->language_id?>">
  12 +
  13 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]language_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?>
  14 +
  15 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]text", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?>
  16 +
  17 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]preview", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?>
  18 +
  19 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]seo_url"]))->textInput() ?>
  20 +
  21 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]name"]))->textInput() ?>
  22 +
  23 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]meta_title"]))->textInput() ?>
  24 +
  25 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]meta_descr"]))->textarea() ?>
  26 +
  27 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]meta_keyword"]))->textInput() ?>
  28 +
  29 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]h1_tag"]))->textInput() ?>
  30 +
  31 + <?= (new ActiveField(['model' => $model, 'attribute' => "[$model->language_id]tag"]))->textInput() ?>
  32 +
  33 +</div>
  34 +<?php
  35 + if($new_form) {
  36 + $form->end();
  37 + }
  38 +?>
... ...
common/modules/blog/views/ajax/_article_media_form.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use yii\bootstrap\ActiveField;
  4 +use mihaildev\ckeditor\CKEditor;
  5 +
  6 +$form = \yii\bootstrap\ActiveForm::begin();
  7 +?>
  8 +<div role="" class="tab-pane active ajax-loaded" id="<?=$widget_id?>-<?=$model->language_id?>">
  9 +
  10 + <?= (new ActiveField(['model' => $article_lang, 'attribute' => "[$model->language_id][$type]language_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?>
  11 +
  12 + <?= (new ActiveField(['model' => $article_lang, 'attribute' => "[$model->language_id][$type]imageFile"]))->fileInput(['class' => 'image_inputs_field']) ?>
  13 +
  14 +</div>
  15 +<?php
  16 +$form->end();
  17 +?>
... ...
common/modules/blog/views/ajax/_category_form.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use yii\bootstrap\ActiveField;
  4 +use mihaildev\ckeditor\CKEditor;
  5 +
  6 +$form = \yii\bootstrap\ActiveForm::begin();
  7 +?>
  8 +<div role="" class="tab-pane active ajax-loaded" id="<?=$widget_id?>-<?=$model->language_id?>">
  9 +
  10 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]language_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?>
  11 +
  12 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]text", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?>
  13 +
  14 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]preview", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?>
  15 +
  16 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]seo_url"]))->textInput() ?>
  17 +
  18 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]name"]))->textInput() ?>
  19 +
  20 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]meta_title"]))->textInput() ?>
  21 +
  22 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]meta_descr"]))->textarea() ?>
  23 +
  24 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]meta_keyword"]))->textInput() ?>
  25 +
  26 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]h1_tag"]))->textInput() ?>
  27 +
  28 + <?= (new ActiveField(['model' => $category_lang, 'attribute' => "[$model->language_id]tag"]))->textInput() ?>
  29 +
  30 +</div>
  31 +<?php
  32 +$form->end();
  33 +?>
... ...
common/modules/blog/views/article/_form.php 0 โ†’ 100644
  1 +<?php
  2 +use common\modules\blog\models\ArticleCategory;
  3 +use common\modules\blog\models\ArticleMedia;
  4 +use common\widgets\Multilang;
  5 + use common\widgets\Multilanguage;
  6 + use yii\bootstrap\ActiveForm;
  7 +use common\modules\blog\models\Article;
  8 +use yii\bootstrap\Html;
  9 +use mihaildev\ckeditor\CKEditor;
  10 +use yii\helpers\Json;
  11 +use yii\helpers\Url;
  12 +use yii\widgets\Pjax;
  13 +
  14 +$def_lang = array_keys($langs)[0];
  15 +$uploaddir = \Yii::getAlias('@saveImageDir');
  16 +?>
  17 +<div class="article-form">
  18 +
  19 + <?php $form = \yii\bootstrap\ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
  20 +
  21 + <?= $form->field($article, 'code')->hint(Yii::t('app', 'Insensitive latin non-space'))->textInput() ?>
  22 +
  23 + <?= $form->field($article, 'tag')->hint(Yii::t('app', 'Comma-separated'))->textInput() ?>
  24 +
  25 + <?= $form->field($article, 'sort')->input('number') ?>
  26 +
  27 + <?= $form->field($article, 'article_pid')
  28 + ->dropDownList(Article::findArticleDropdown($article->article_id), ['prompt' => Yii::t('app', 'Select parent')]) ?>
  29 +
  30 + <?= $form->field($article, 'articleCategoriesArray')
  31 + ->dropDownList(ArticleCategory::findArticleCategoryDropdown(NULL), ['multiple' => 'multiple'])->label(\Yii::t('app', 'Article Categories Array')); ?>
  32 +
  33 + <?= $form->field($article, 'status')->checkbox() ?>
  34 +
  35 + <ul class="nav nav-tabs" id="image-tabs" role="tablist">
  36 + <li role="image_inputs" class="active" data-type="full"><a href="#image-full" aria-controls="image-full" role="tab" data-toggle="tab"><span><?= \Yii::t('app', 'full')?></span></a></li>
  37 + <li role="image_inputs" class="" data-type="preview"><a href="#image-preview" aria-controls="image-preview" role="tab" data-toggle="tab"><span><?= \Yii::t('app', 'preview')?></span></a></li>
  38 + <li role="image_inputs" class="" data-type="additional"><a href="#image-additional" aria-controls="image-additional" role="tab" data-toggle="tab"><span><?= \Yii::t('app', 'additional')?></span></a></li>
  39 + </ul>
  40 + <div class="tab-content image-tab-content">
  41 + <div role="" class="tab-pane active main-tab" id="image-full">
  42 + <?php
  43 + $imagelang = Multilang::begin([
  44 + 'ajaxpath' => Url::to(['/blog/ajax/article-media-form?type=full']),
  45 + 'form' => $form,
  46 + 'data_langs' => $article->getIsNewRecord()?$images:ArticleMedia::find()->where(['article_id' => $article->article_id, 'type' => 'full'])->indexBy('language_id')->all()
  47 + ]);
  48 + $first = 1;
  49 + foreach($images as $lang => $value) {
  50 + if(!array_key_exists('full', $value)) continue;
  51 + ?>
  52 + <div role="" class="tab-pane <?php if($first) { echo 'active main-tab'; } ?>" id="<?=$imagelang->id?>-<?=$lang?>">
  53 + <?php
  54 + echo $form->field($images[$lang]['full'], "[{$lang}][full]language_id")->label(false)->hiddenInput(['value' => $lang]);
  55 + echo $form->field($images[$lang]['full'], "[{$lang}][full]imageFile")->fileInput(['class' => 'image_inputs_field']);
  56 + if(!empty($images[$lang]['full']->article_media_id)) {
  57 + echo "<img src='/images/upload/{$images[$lang]['full']->media->hash}/original.{$images[$lang]['full']->media->extension}' width='100' class='image_inputs_prev'>";
  58 + }
  59 + ?>
  60 + </div>
  61 + <?php
  62 + $first = 0;
  63 + }
  64 + $imagelang->end();
  65 + ?>
  66 + </div>
  67 + <div role="" class="tab-pane" id="image-preview">
  68 + <?php
  69 + $imagelang = Multilang::begin([
  70 + 'ajaxpath' => Url::to(['/blog/ajax/article-media-form?type=preview']),
  71 + 'form' => $form,
  72 + 'data_langs' => $article->getIsNewRecord()?$images:ArticleMedia::find()->where(['article_id' => $article->article_id, 'type' => 'preview'])->indexBy('language_id')->all()
  73 + ]);
  74 + $first = 1;
  75 + foreach($images as $lang => $value) {
  76 + if(!array_key_exists('preview', $value)) continue;
  77 + ?>
  78 + <div role="" class="tab-pane <?php if($first) { echo 'active main-tab'; } ?>" id="<?=$imagelang->id?>-<?=$lang?>">
  79 + <?php
  80 + echo $form->field($images[$lang]['preview'], "[{$lang}][preview]language_id")->label(false)->hiddenInput(['value' => $lang]);
  81 + echo $form->field($images[$lang]['preview'], "[{$lang}][preview]imageFile")->fileInput(['class' => 'image_inputs_field']);
  82 + if(!empty($images[$lang]['preview']->article_media_id)) {
  83 + echo "<img src='/images/upload/{$images[$lang]['preview']->media->hash}/original.{$images[$lang]['preview']->media->extension}' width='100' class='image_inputs_prev'>";
  84 + }
  85 + ?>
  86 + </div>
  87 + <?php
  88 + $first = 0;
  89 + }
  90 + $imagelang->end();
  91 + ?>
  92 + </div>
  93 + <div role="" class="tab-pane" id="image-additional">
  94 + <?php
  95 + echo $form->field(is_array($images[0]['additional'])?$images[0]['additional'][0]:$images[0]['additional'], "[0][additional]imageFile[]")->fileInput(['multiple' => 'multiple', 'class' => 'image_inputs_field']);
  96 + if(is_array($images[0]['additional']) && count($images[0]['additional']) > 1) {
  97 + foreach($images[0]['additional'] as $onefield => $oneimage) {
  98 + if($onefield) {
  99 + ?>
  100 + <div class="additional_image_container">
  101 + <img src='/images/upload/<?= $oneimage->media->hash ?>/original.<?= $oneimage->media->extension ?>' width='100'>
  102 + <a
  103 + href="<?= Url::to(['ajax/remove-image']) ?>"
  104 + class="remove_image glyphicon glyphicon-remove-circle"
  105 + data-params='<?= Json::encode(['article_media_id' => $oneimage->article_media_id, 'remove_media' => true]) ?>',
  106 + ></a>
  107 + </div>
  108 + <?php
  109 + }
  110 + }
  111 + }
  112 + ?>
  113 + </div>
  114 + </div>
  115 +
  116 + <hr>
  117 +
  118 + <?php
  119 + echo Multilanguage::widget([
  120 + 'data' => $article_langs,
  121 + 'form' => $form,
  122 + 'ajaxView' => '@common/modules/blog/views/ajax/_article_form',
  123 + ]);
  124 + /*
  125 + $multilang = Multilang::begin(['ajaxpath' => Url::to(['/blog/ajax/article-form']), 'form' => $form, 'data_langs' => $article_langs]);
  126 + ?>
  127 + <?php
  128 + $first = 1;
  129 + foreach($article_langs as $index => $article_lang) {
  130 + ?>
  131 + <div role="" class="tab-pane <?php if($first) { echo 'active main-tab'; } ?>" id="<?=$multilang->id?>-<?=$index?>">
  132 +
  133 + <?= $form->field($article_langs[$index], "[$index]language_id")->label(false)->hiddenInput(['value' => $index]) ?>
  134 +
  135 + <?= $form->field($article_langs[$index], "[$index]text")->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?>
  136 +
  137 + <?= $form->field($article_langs[$index], "[$index]preview")->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?>
  138 +
  139 + <?= $form->field($article_langs[$index], "[$index]seo_url")->textInput() ?>
  140 +
  141 + <?= $form->field($article_langs[$index], "[$index]name")->textInput() ?>
  142 +
  143 + <?= $form->field($article_langs[$index], "[$index]meta_title")->textInput() ?>
  144 +
  145 + <?= $form->field($article_langs[$index], "[$index]meta_descr")->textarea(); ?>
  146 +
  147 + <?= $form->field($article_langs[$index], "[$index]meta_keywords")->textInput() ?>
  148 +
  149 + <?= $form->field($article_langs[$index], "[$index]h1_tag")->textInput() ?>
  150 +
  151 + <?= $form->field($article_langs[$index], "[$index]tags")->textInput() ?>
  152 +
  153 + </div>
  154 + <?php
  155 + $first = 0;
  156 + }
  157 + ?>
  158 + <?php
  159 + $multilang->end();
  160 + */
  161 + ?>
  162 +
  163 + <div class="form-group">
  164 + <?= Html::submitButton($article->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $article->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  165 + </div>
  166 +
  167 + <?php ActiveForm::end(); ?>
  168 +
  169 +</div>
  170 +<script>
  171 + var confirm_message = '<?= \Yii::t('app', 'Remove image?') ?>';
  172 +</script>
0 173 \ No newline at end of file
... ...
common/modules/blog/views/article/create.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\helpers\Html;
  3 +
  4 +$this->title = Yii::t('app', 'Article create');
  5 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Articles'), 'url' => ['index']];
  6 +$this->params['breadcrumbs'][] = $this->title;
  7 +?>
  8 +<div class="article-create">
  9 +
  10 + <h1><?= Html::encode($this->title) ?></h1>
  11 +
  12 + <?= $this->render('_form', [
  13 + 'article_langs' => $article_langs,
  14 + 'article' => $article,
  15 + 'langs' => $langs,
  16 + 'images' => $images
  17 + ]) ?>
  18 +
  19 +</div>
... ...
common/modules/blog/views/article/index.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\grid\ActionColumn;
  3 +use yii\grid\Column;
  4 +use yii\grid\GridView;
  5 +use common\modules\blog\models\Article;
  6 +use common\models\Language;
  7 +
  8 +echo GridView::widget([
  9 + 'dataProvider' => $dataProvider,
  10 + 'columns' => [
  11 + 'article_id',
  12 + 'code',
  13 + 'date_add',
  14 + [
  15 + 'value' => function($data) {
  16 + return $data->user->firstname.' '.$data->user->lastname;
  17 + },
  18 + 'header' => Yii::t('app', 'Author')
  19 + ],
  20 + [
  21 + 'class' => Column::className(),
  22 + 'header' => Yii::t('app', 'Name'),
  23 + 'content' => function($model, $key, $index, $column) {
  24 + return $model->getArticleLangs()->where(['language_id' => Language::getDefaultLang()->language_id])->one()->name;
  25 + }
  26 + ],
  27 + [
  28 + 'class' => ActionColumn::className(),
  29 + 'template' => '{update} {delete}'
  30 + ]
  31 + ]
  32 +]);
0 33 \ No newline at end of file
... ...
common/modules/blog/views/article/update.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\helpers\Html;
  3 +
  4 +$this->title = Yii::t('app', 'Article update');
  5 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Articles'), 'url' => ['index']];
  6 +$this->params['breadcrumbs'][] = $this->title;
  7 +?>
  8 +<div class="article-create">
  9 +
  10 + <h1><?= Html::encode($this->title) ?></h1>
  11 + <?= $this->render('_form', [
  12 + 'article_langs' => $article_langs,
  13 + 'article' => $article,
  14 + 'langs' => $langs,
  15 + 'images' => $images
  16 + ]) ?>
  17 +
  18 +</div>
... ...
common/modules/blog/views/category/_form.php 0 โ†’ 100644
  1 +<?php
  2 +use common\modules\blog\models\ArticleCategoryMedia;
  3 +use common\widgets\Multilang;
  4 +use yii\bootstrap\ActiveForm;
  5 +use common\modules\blog\models\ArticleCategory;
  6 +use yii\bootstrap\Html;
  7 +use mihaildev\ckeditor\CKEditor;
  8 +use yii\helpers\Json;
  9 +use yii\helpers\Url;
  10 +
  11 +$def_lang = array_keys($langs)[0];
  12 +$uploaddir = \Yii::getAlias('@saveImageDir');
  13 +?>
  14 +<div class="category-form">
  15 +
  16 + <?php $form = \yii\bootstrap\ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
  17 +
  18 + <?= $form->field($category, 'code')->hint(Yii::t('app', 'Insensitive latin non-space'))->textInput() ?>
  19 +
  20 + <?= $form->field($category, 'tag')->hint(Yii::t('app', 'Comma-separated'))->textInput() ?>
  21 +
  22 + <?= $form->field($category, 'sort')->input('number') ?>
  23 +
  24 + <?= $form->field($category, 'article_category_pid')
  25 + ->dropDownList(ArticleCategory::findArticleCategoryDropdown($category->article_category_id), ['prompt' => Yii::t('app', 'Select parent')]) ?>
  26 +
  27 + <?= $form->field($category, 'status')->checkbox() ?>
  28 +
  29 + <ul class="nav nav-tabs" id="image-tabs" role="tablist">
  30 + <li role="image_inputs" class="active" data-type="full"><a href="#image-full" aria-controls="image-full" role="tab" data-toggle="tab"><span><?= \Yii::t('app', 'full')?></span></a></li>
  31 + <li role="image_inputs" class="" data-type="preview"><a href="#image-preview" aria-controls="image-preview" role="tab" data-toggle="tab"><span><?= \Yii::t('app', 'preview')?></span></a></li>
  32 + <li role="image_inputs" class="" data-type="additional"><a href="#image-additional" aria-controls="image-additional" role="tab" data-toggle="tab"><span><?= \Yii::t('app', 'additional')?></span></a></li>
  33 + </ul>
  34 + <div class="tab-content image-tab-content">
  35 + <div role="" class="tab-pane active main-tab" id="image-full">
  36 + <?php
  37 + $imagelang = Multilang::begin([
  38 + 'ajaxpath' => Url::to(['/blog/ajax/article-category-media-form?type=full']),
  39 + 'form' => $form,
  40 + 'data_langs' => $category->getIsNewRecord()?$images:ArticleCategoryMedia::find()->where(['article_category_id' => $category->article_category_id, 'type' => 'full'])->indexBy('language_id')->all()
  41 + ]);
  42 + $first = 1;
  43 + foreach($images as $lang => $value) {
  44 + if(!array_key_exists('full', $value)) continue;
  45 + ?>
  46 + <div role="" class="tab-pane <?php if($first) { echo 'active main-tab'; } ?>" id="<?=$imagelang->id?>-<?=$lang?>">
  47 + <?php
  48 + echo $form->field($images[$lang]['full'], "[{$lang}][full]language_id")->label(false)->hiddenInput(['value' => $lang]);
  49 + echo $form->field($images[$lang]['full'], "[{$lang}][full]imageFile")->fileInput(['class' => 'image_inputs_field']);
  50 + if(!empty($images[$lang]['full']->article_category_media_id)) {
  51 + echo "<img src='/images/upload/{$images[$lang]['full']->media->hash}/original.{$images[$lang]['full']->media->extension}' width='100' class='image_inputs_prev'>";
  52 + }
  53 + ?>
  54 + </div>
  55 + <?php
  56 + $first = 0;
  57 + }
  58 + $imagelang->end();
  59 + ?>
  60 + </div>
  61 + <div role="" class="tab-pane" id="image-preview">
  62 + <?php
  63 + $imagelang = Multilang::begin([
  64 + 'ajaxpath' => Url::to(['/blog/ajax/article-category-media-form?type=preview']),
  65 + 'form' => $form,
  66 + 'data_langs' => $category->getIsNewRecord()?$images:ArticleCategoryMedia::find()->where(['article_category_id' => $category->article_category_id, 'type' => 'preview'])->indexBy('language_id')->all()
  67 + ]);
  68 + $first = 1;
  69 + foreach($images as $lang => $value) {
  70 + if(!array_key_exists('preview', $value)) continue;
  71 + ?>
  72 + <div role="" class="tab-pane <?php if($first) { echo 'active main-tab'; } ?>" id="<?=$imagelang->id?>-<?=$lang?>">
  73 + <?php
  74 + echo $form->field($images[$lang]['preview'], "[{$lang}][preview]language_id")->label(false)->hiddenInput(['value' => $lang]);
  75 + echo $form->field($images[$lang]['preview'], "[{$lang}][preview]imageFile")->fileInput(['class' => 'image_inputs_field']);
  76 + if(!empty($images[$lang]['preview']->article_category_media_id)) {
  77 + echo "<img src='/images/upload/{$images[$lang]['preview']->media->hash}/original.{$images[$lang]['preview']->media->extension}' width='100' class='image_inputs_prev'>";
  78 + }
  79 + ?>
  80 + </div>
  81 + <?php
  82 + $first = 0;
  83 + }
  84 + $imagelang->end();
  85 + ?>
  86 + </div>
  87 + <div role="" class="tab-pane" id="image-additional">
  88 + <?php
  89 + echo $form->field(is_array($images[0]['additional'])?$images[0]['additional'][0]:$images[0]['additional'], "[0][additional]imageFile[]")->fileInput(['multiple' => 'multiple', 'class' => 'image_inputs_field']);
  90 + if(is_array($images[0]['additional']) && count($images[0]['additional']) > 1) {
  91 + foreach($images[0]['additional'] as $onefield => $oneimage) {
  92 + if($onefield) {
  93 + ?>
  94 + <div class="additional_image_container">
  95 + <img src='/images/upload/<?= $oneimage->media->hash ?>/original.<?= $oneimage->media->extension ?>' width='100'>
  96 + <a
  97 + href="<?= Url::to(['ajax/remove-image']) ?>"
  98 + class="remove_image glyphicon glyphicon-remove-circle"
  99 + data-params='<?= Json::encode(['article_category_media_id' => $oneimage->article_category_media_id, 'remove_media' => true]) ?>',
  100 + ></a>
  101 + </div>
  102 + <?php
  103 + }
  104 + }
  105 + }
  106 + ?>
  107 + </div>
  108 + </div>
  109 +
  110 + <hr>
  111 +
  112 + <?php
  113 + $multilang = Multilang::begin(['ajaxpath' => Url::to(['/blog/ajax/category-form']), 'form' => $form, 'data_langs' => $category_langs])
  114 + ?>
  115 + <?php
  116 + $first = 1;
  117 + foreach($category_langs as $index => $category_lang) {
  118 + ?>
  119 + <div role="" class="tab-pane <?php if($first) { echo 'active main-tab'; } ?>" id="lang-<?=$index?>">
  120 + <?= $form->field($category_langs[$index], "[$index]language_id")->label(false)->hiddenInput(['value' => $index]) ?>
  121 +
  122 + <?= $form->field($category_langs[$index], "[$index]text")->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?>
  123 +
  124 + <?= $form->field($category_langs[$index], "[$index]preview")->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?>
  125 +
  126 + <?= $form->field($category_langs[$index], "[$index]seo_url")->textInput() ?>
  127 +
  128 + <?= $form->field($category_langs[$index], "[$index]name")->textInput() ?>
  129 +
  130 + <?= $form->field($category_langs[$index], "[$index]meta_title")->textInput() ?>
  131 +
  132 + <?= $form->field($category_langs[$index], "[$index]meta_descr")->textarea(); ?>
  133 +
  134 + <?= $form->field($category_langs[$index], "[$index]meta_keyword")->textInput() ?>
  135 +
  136 + <?= $form->field($category_langs[$index], "[$index]h1_tag")->textInput() ?>
  137 +
  138 + <?= $form->field($category_langs[$index], "[$index]tag")->textInput() ?>
  139 +
  140 + </div>
  141 + <?php
  142 + $first = 0;
  143 + }
  144 + ?>
  145 + <?php
  146 + $multilang->end();
  147 + ?>
  148 +
  149 + <div class="form-group">
  150 + <?= Html::submitButton($category->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $category->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  151 + </div>
  152 +
  153 + <?php ActiveForm::end(); ?>
  154 +
  155 +</div>
  156 +<script>
  157 + var confirm_message = '<?= \Yii::t('app', 'Remove image?') ?>';
  158 +</script>
0 159 \ No newline at end of file
... ...
common/modules/blog/views/category/create.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\helpers\Html;
  3 +
  4 +$this->title = Yii::t('app', 'Category create');
  5 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Categories'), 'url' => ['index']];
  6 +$this->params['breadcrumbs'][] = $this->title;
  7 +?>
  8 +<div class="category-create">
  9 +
  10 + <h1><?= Html::encode($this->title) ?></h1>
  11 +
  12 + <?= $this->render('_form', [
  13 + 'category_langs' => $category_langs,
  14 + 'category' => $category,
  15 + 'langs' => $langs,
  16 + 'images' => $images
  17 + ]) ?>
  18 +
  19 +</div>
... ...
common/modules/blog/views/category/index.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\grid\ActionColumn;
  3 +use yii\grid\Column;
  4 +use yii\grid\GridView;
  5 +use common\modules\blog\models\Article;
  6 +use common\models\Language;
  7 +echo GridView::widget([
  8 + 'dataProvider' => $dataProvider,
  9 + 'columns' => [
  10 + 'article_category_id',
  11 + 'code',
  12 + 'date_add',
  13 + 'date_update',
  14 + [
  15 + 'class' => Column::className(),
  16 + 'header' => Yii::t('app', 'Name'),
  17 + 'content' => function($model, $key, $index, $column) {
  18 + return $model->getArticleCategoryLangs()->orderBy(['language_id' => 'ASC'])->one()->name;
  19 + }
  20 + ],
  21 + [
  22 + 'class' => ActionColumn::className(),
  23 + 'template' => '{update} {delete}'
  24 + ]
  25 + ]
  26 +]);
0 27 \ No newline at end of file
... ...
common/modules/blog/views/category/update.php 0 โ†’ 100644
  1 +<?php
  2 +use yii\helpers\Html;
  3 +
  4 +$this->title = Yii::t('app', 'Update category');
  5 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Categories'), 'url' => ['index']];
  6 +$this->params['breadcrumbs'][] = $this->title;
  7 +?>
  8 +<div class="category-create">
  9 +
  10 + <h1><?= Html::encode($this->title) ?></h1>
  11 + <?= $this->render('_form', [
  12 + 'category_langs' => $category_langs,
  13 + 'category' => $category,
  14 + 'langs' => $langs,
  15 + 'images' => $images
  16 + ]) ?>
  17 +
  18 +</div>
... ...
common/modules/blog/views/default/index.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use yii\behaviors\BlameableBehavior;
  4 +use yii\web\Application;
  5 +
  6 +$behavior = new BlameableBehavior();
  7 +var_dump($behavior->value);
0 8 \ No newline at end of file
... ...
common/modules/blog/views/media/index.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +use yii\bootstrap\ActiveForm;
  4 +use yii\bootstrap\Html;
  5 +
  6 +$form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]);
  7 +
  8 +echo $form->field($model, 'imageFile')->fileInput(['multiple' => 'multiple']);
  9 +
  10 +?>
  11 + <img id="blah" src="#" alt="your image">
  12 +<div class="form-group">
  13 + <?= Html::submitButton(Yii::t('app', 'Create'), ['class' => 'btn btn-success']) ?>
  14 +</div>
  15 +<?php
  16 +ActiveForm::end();
  17 +?>
  18 +<script>
  19 + function readURL(input) {
  20 + if (input.files && input.files[1]) {
  21 + var reader = new FileReader();
  22 +
  23 + reader.onload = function (e) {
  24 + $('#blah')
  25 + .attr('src', e.target.result)
  26 + .width(150);
  27 + };
  28 +
  29 + reader.readAsDataURL(input.files[1]);
  30 + }
  31 + }
  32 + $(function() {
  33 + $(document).on('change', 'input[type=file]', function() {
  34 + readURL(this);
  35 + });
  36 + });
  37 +</script>
... ...
common/modules/blog/views/test/index.php 0 โ†’ 100644
  1 +<?php
  2 + use common\widgets\Multilanguage;
  3 + use yii\bootstrap\ActiveForm;
  4 +
  5 +$form = ActiveForm::begin();
  6 +echo Multilanguage::widget([
  7 + 'data' => $model,
  8 + 'form' => $form,
  9 + 'ajaxView' => '@common/modules/blog/views/ajax/_article_form_test',
  10 +]);
  11 +$form->end();
0 12 \ No newline at end of file
... ...
common/modules/comment/Controller.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment;
  3 +
  4 + class Controller extends \yii\web\Controller
  5 + {
  6 + public function behaviors()
  7 + {
  8 + return [
  9 + 'verbs' => [
  10 + 'class' => \yii\filters\VerbFilter::className(),
  11 + 'actions' => [
  12 + '*' => ['post'],
  13 + ],
  14 + ],
  15 + ];
  16 + }
  17 +
  18 + public function actionDelete()
  19 + {
  20 + \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  21 + $post = \Yii::$app->request->post('Comment');
  22 + if(!empty($post['comment_id'])) {
  23 + if($model = \common\modules\comment\models\Comment::findOne($post['comment_id'])) {
  24 + /**
  25 + * @var \common\modules\comment\models\Comment $model
  26 + */
  27 + $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST;
  28 + if($model->deleteComment()) {
  29 + \Yii::$app->response->data = ['text' => 'Comment marked as deleted and will be check by administrators'];
  30 + } else {
  31 + \Yii::$app->response->data = ['error' => $model->hasErrors('comment_id')?$model->getFirstError('comment_id'):'Cannot delete message'];
  32 + }
  33 + }else {
  34 + \Yii::$app->response->data = ['error' => 'Comment not found'];
  35 + };
  36 + } else {
  37 + \Yii::$app->response->data = ['error' => 'Missing comment_id'];
  38 + }
  39 + \Yii::$app->response->send();
  40 + }
  41 +
  42 + public function actionUpdate()
  43 + {
  44 + \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  45 + $post = \Yii::$app->request->post();
  46 + if(!empty($post['Comment']['comment_id'])) {
  47 + if($model = \common\modules\comment\models\Comment::findOne($post['Comment']['comment_id'])) {
  48 + /**
  49 + * @var \common\modules\comment\models\Comment $model
  50 + */
  51 + $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST;
  52 + $model->load($post);
  53 + if(empty($post['Comment']['comment_pid'])) {
  54 + $model->comment_pid = null;
  55 + }
  56 + if($model->updateComment()) {
  57 + \Yii::$app->response->data = ['text' => 'Comment successfully updated'];
  58 + } else {
  59 + \Yii::$app->response->data = ['error' => $model->hasErrors()?$model->getFirstErrors():'Cannot update message'];
  60 + }
  61 + }else {
  62 + \Yii::$app->response->data = ['error' => 'Comment not found'];
  63 + };
  64 + } else {
  65 + \Yii::$app->response->data = ['error' => 'Missing comment_id'];
  66 + }
  67 + \Yii::$app->response->send();
  68 + }
  69 +
  70 + public function actionForm()
  71 + {
  72 + $post = \Yii::$app->request->post('Comment');
  73 + if(!empty($post['comment_id'])) {
  74 + $model = \common\modules\comment\models\Comment::find()->where(['comment_id' => $post['comment_id']])->with('parent', 'author')->one();
  75 + if($model) {
  76 + /**
  77 + * @var \common\modules\comment\models\Comment $model
  78 + */
  79 + $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST;
  80 + if($model->checkUpdate()) {
  81 + return $this->renderAjax('@common/modules/comment/views/comment_form', [
  82 + 'model' => $model,
  83 + ]);
  84 + } else {
  85 + \Yii::$app->response->data = ['error' => 'You are not able to update this comment'];
  86 + }
  87 + }else {
  88 + \Yii::$app->response->data = ['error' => 'Comment not found'];
  89 + };
  90 + } else {
  91 + \Yii::$app->response->data = ['error' => 'Missing comment_id'];
  92 + }
  93 + \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  94 + \Yii::$app->response->send();
  95 + }
  96 + }
0 97 \ No newline at end of file
... ...
common/modules/comment/Module.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment;
  3 +
  4 + /**
  5 + * Class Module
  6 + * @package common\modules\comment
  7 + */
  8 + class Module extends \yii\base\Module
  9 + {
  10 +
  11 + /**
  12 + * @var string Module name
  13 + */
  14 + public static $moduleName = 'artbox_comment';
  15 +
  16 + /**
  17 + * @var bool Wheather to use Rbac system
  18 + * @link http://www.yiiframework.com/doc-2.0/guide-security-authorization.html#rbac
  19 + * @see \yii\rbac\ManagerInterface
  20 + */
  21 + public $useRbac = false;
  22 +
  23 + /**
  24 + * Array of RBAC rules and permissions that can be used by install command.
  25 + *
  26 + * Currently supports associative array, of such view:
  27 + *
  28 + * <code>
  29 + * [
  30 + * 'rules' => [
  31 + * \full\namapaced\ClassName,
  32 + * \another\one\ClassName,
  33 + * ],
  34 + * 'permissions' => [
  35 + * [
  36 + * 'name' => stringName,
  37 + * 'description' => descriptionText,
  38 + * 'ruleName' => (new \full\namespaced\ClassName())->name (optional)
  39 + * ],
  40 + * [
  41 + * 'name' => stringName2,
  42 + * 'description' => descriptionText2,
  43 + * 'ruleName' => (new \another\one\ClassName())->name (optional)
  44 + * ],
  45 + * ]
  46 + * ]
  47 + * </code>
  48 + *
  49 + * @var array
  50 + * @see \common\modules\comment\commands\RbacController
  51 + */
  52 + public $rbac = [];
  53 +
  54 + /**
  55 + * @var \yii\db\Connection Connection to the db
  56 + */
  57 + public $db = null;
  58 +
  59 + /**
  60 + * @inheritdoc
  61 + */
  62 + public function init()
  63 + {
  64 + parent::init();
  65 + if(\Yii::$app instanceof \yii\console\Application) {
  66 + $this->controllerNamespace = 'common\modules\comment\commands';
  67 + }
  68 + if($this->db === null) {
  69 + $this->db = \Yii::$app->db;
  70 + } elseif(!$this->db instanceof \yii\db\Connection) {
  71 + throw new \yii\base\InvalidConfigException('ะšะพะฝั„ะธะณ db ะพะฑัะทะฐะฝ ะฝะฐัะปะตะดะพะฒะฐั‚ัŒัั ะพั‚'.\yii\db\Connection::className());
  72 + }
  73 + }
  74 + }
0 75 \ No newline at end of file
... ...
common/modules/comment/Permissions.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment;
  3 +
  4 + class Permissions
  5 + {
  6 +
  7 + const CREATE = 'artbox_comment.create';
  8 + const UPDATE = 'artbox_comment.update';
  9 + const DELETE = 'artbox_comment.delete';
  10 + const UPDATE_OWN = 'artbox_comment.update_own';
  11 + const DELETE_OWN = 'artbox_comment.delete_own';
  12 + }
0 13 \ No newline at end of file
... ...
common/modules/comment/assets/CommentAsset.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment\assets;
  3 +
  4 + class CommentAsset extends \yii\web\AssetBundle
  5 + {
  6 + public $sourcePath = '@common/modules/comment/resources';
  7 +
  8 + public $css = [
  9 + 'comment.css',
  10 + ];
  11 +
  12 + public $js = [
  13 + 'comment.js',
  14 + ];
  15 +
  16 + public $depends = [
  17 + '\yii\web\YiiAsset',
  18 + '\yii\web\JqueryAsset',
  19 + ];
  20 +
  21 + }
0 22 \ No newline at end of file
... ...
common/modules/comment/commands/RbacController.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment\commands;
  3 +
  4 + class RbacController extends \yii\console\Controller
  5 + {
  6 +
  7 + public function actionInstall()
  8 + {
  9 + /**
  10 + * @var \common\modules\comment\Module $module
  11 + */
  12 + $module = \Yii::$app->controller->module;
  13 + if(!$module->useRbac) {
  14 + throw new \yii\base\InvalidConfigException('Please set useRbac config to TRUE in your module configs');
  15 + }
  16 + $auth = \Yii::$app->getAuthManager();
  17 + if(!$auth instanceof \yii\rbac\ManagerInterface) {
  18 + throw new \yii\base\InvalidConfigException('ManagerInterface is not configured');
  19 + }
  20 + if(!empty($module->rbac['rules'])) {
  21 + foreach($module->rbac['rules'] as $rule) {
  22 + $rule_model = new $rule();
  23 + echo "Creating rule: ".$rule_model->name."\n";
  24 + if($auth->add($rule_model)) {
  25 + echo "Successful\n";
  26 + } else {
  27 + echo "Failed\n";
  28 + }
  29 + unset($rule_model);
  30 + }
  31 + }
  32 + if(!empty($module->rbac['permissions'])) {
  33 + foreach($module->rbac['permissions'] as $permission) {
  34 + echo "Creating permission: ".$permission['name']."\n";
  35 + if($auth->add(new \yii\rbac\Permission($permission))) {
  36 + echo "Successful\n";
  37 + } else {
  38 + echo "Failed\n";
  39 + }
  40 + }
  41 + }
  42 + }
  43 +
  44 + public function actionUninstall()
  45 + {
  46 + /**
  47 + * @var \common\modules\comment\Module $module
  48 + */
  49 + $module = \Yii::$app->controller->module;
  50 + if(!$module->useRbac) {
  51 + throw new \yii\base\InvalidConfigException('Please set useRbac config to TRUE in your module configs');
  52 + }
  53 + $auth = \Yii::$app->getAuthManager();
  54 + if(!$auth instanceof \yii\rbac\ManagerInterface) {
  55 + throw new \yii\base\InvalidConfigException('ManagerInterface is not configured');
  56 + }
  57 + if(!empty($module->rbac['rules'])) {
  58 + foreach($module->rbac['rules'] as $rule) {
  59 + $rule_model = new $rule();
  60 + echo "Removing rule: ".$rule_model->name."\n";
  61 + if($auth->remove($rule_model)) {
  62 + echo "Successful\n";
  63 + } else {
  64 + echo "Failed\n";
  65 + }
  66 + unset($rule_model);
  67 + }
  68 + }
  69 + if(!empty($module->rbac['permissions'])) {
  70 + foreach($module->rbac['permissions'] as $permission) {
  71 + echo "Removing permission: ".$permission['name']."\n";
  72 + if($auth->remove(new \yii\rbac\Permission($permission))) {
  73 + echo "Successful\n";
  74 + } else {
  75 + echo "Failed\n";
  76 + }
  77 + }
  78 + }
  79 + }
  80 +
  81 + }
0 82 \ No newline at end of file
... ...
common/modules/comment/interfaces/CommentInterface.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment\interfaces;
  3 +
  4 + interface CommentInterface {
  5 + public function load($data, $formName = null);
  6 + public function formName();
  7 + public function getComments($model, $model_id);
  8 + public function postComment();
  9 + public function deleteComment();
  10 + public function updateComment();
  11 + }
... ...
common/modules/comment/models/Comment.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment\models;
  3 +
  4 + use yii\db\ActiveQuery;
  5 +
  6 + /**
  7 + * Class Comment
  8 + * @property bool $guestComment
  9 + * @property integer $comment_id
  10 + * @property string $text
  11 + * @property int $user_id
  12 + * @property string $user_name
  13 + * @property string $user_email
  14 + * @property int $comment_pid
  15 + * @property int $status
  16 + * @property string $date_add
  17 + * @property string $date_update
  18 + * @property string $date_delete
  19 + * @property string $model
  20 + * @property int $model_id
  21 + * @package common\modules\comment\models
  22 + */
  23 + class Comment extends \yii\db\ActiveRecord
  24 + implements \common\modules\comment\interfaces\CommentInterface
  25 + {
  26 +
  27 + const STATUS_HIDDEN = 0;
  28 + const STATUS_DELETED = 2;
  29 + const STATUS_ACTIVE = 1;
  30 + const STATUS_PERSONAL = 3;
  31 +
  32 + const SCENARIO_USER = 'user';
  33 + const SCENARIO_GUEST = 'guest';
  34 +
  35 + /**
  36 + * @var bool
  37 + */
  38 + public $guestComment = true;
  39 +
  40 + public function rules()
  41 + {
  42 + return [
  43 + [
  44 + [
  45 + 'text',
  46 + 'user_name',
  47 + 'user_email',
  48 + ],
  49 + 'required',
  50 + ],
  51 + [
  52 + [
  53 + 'rating',
  54 + ],
  55 + 'safe',
  56 + ],
  57 + [
  58 + [ 'user_email' ],
  59 + 'email',
  60 + ],
  61 + [
  62 + [ 'user_name' ],
  63 + 'string',
  64 + ],
  65 + [
  66 + [
  67 + 'comment_id',
  68 + 'comment_pid',
  69 + ],
  70 + 'integer',
  71 + ],
  72 + [
  73 + [ 'status' ],
  74 + 'default',
  75 + 'value' => 1,
  76 + ],
  77 + [
  78 + [ 'comment_pid' ],
  79 + 'exist',
  80 + 'targetAttribute' => 'comment_id',
  81 + 'filter' => [
  82 + 'model' => $this->model,
  83 + 'model_id' => $this->model_id,
  84 + ],
  85 + ],
  86 + ];
  87 + }
  88 +
  89 + public function scenarios()
  90 + {
  91 + return [
  92 + self::SCENARIO_GUEST => [
  93 + 'user_name',
  94 + 'user_email',
  95 + 'text',
  96 + 'comment_pid',
  97 + ],
  98 + self::SCENARIO_USER => [
  99 + 'text',
  100 + 'comment_pid',
  101 + ],
  102 + ];
  103 + }
  104 +
  105 + /**
  106 + * @inheritdoc
  107 + */
  108 + public function behaviors()
  109 + {
  110 + return [
  111 + [
  112 + 'class' => \yii\behaviors\TimestampBehavior::className(),
  113 + 'createdAtAttribute' => 'date_add',
  114 + 'updatedAtAttribute' => 'date_update',
  115 + 'value' => new \yii\db\Expression('NOW()'),
  116 + ],
  117 + ];
  118 + }
  119 +
  120 + public static function tableName()
  121 + {
  122 + return '{{%comment}}';
  123 + }
  124 +
  125 + /**
  126 + * @inheritdoc
  127 + */
  128 + public function attributeLabels()
  129 + {
  130 + return [
  131 + 'text' => \Yii::t('app', 'ะšะพะผะผะตะฝั‚ะฐั€ะธะน'),
  132 + 'user_name' => \Yii::t('app', 'ะ˜ะผั'),
  133 + 'user_email' => \Yii::t('app', 'Email'),
  134 + ];
  135 + }
  136 +
  137 + public function getGuestComment()
  138 + {
  139 + return $this->guestComment;
  140 + }
  141 +
  142 + public function setGuestComment($value)
  143 + {
  144 + $this->guestComment = $value;
  145 + }
  146 +
  147 + /**
  148 + * @param string $model
  149 + * @param integer $model_id
  150 + *
  151 + * @return ActiveQuery
  152 + */
  153 + public function getComments($model, $model_id)
  154 + {
  155 + return $this->find()
  156 + ->where([
  157 + 'comment.model' => $model,
  158 + 'comment.model_id' => $model_id,
  159 + 'comment.status' => 1,
  160 + ]);
  161 + }
  162 +
  163 + public function postComment()
  164 + {
  165 + if($this->checkCreate()) {
  166 + if($this->insert()) {
  167 + $this->clearSafe();
  168 + return true;
  169 + } else {
  170 + return false;
  171 + }
  172 + } else {
  173 + $this->addError('comment_id', 'You can`t post comment here');
  174 + return false;
  175 + }
  176 + }
  177 +
  178 + public function updateComment()
  179 + {
  180 + if($this->checkUpdate()) {
  181 + if(empty( $this->comment_id )) {
  182 + $this->addError('comment_id', 'Comment ID not found');
  183 + return false;
  184 + } else {
  185 + if($this->update()) {
  186 + $this->clearSafe();
  187 + return true;
  188 + } else {
  189 + return false;
  190 + }
  191 + }
  192 + } else {
  193 + $this->addError('comment_id', 'You can`t update this post');
  194 + return false;
  195 + }
  196 + }
  197 +
  198 + public function deleteComment()
  199 + {
  200 + if($this->checkDelete()) {
  201 + if(empty( $this->comment_id )) {
  202 + $this->addError('comment_id', 'Comment ID not found');
  203 + return false;
  204 + } else {
  205 + if($this->status == self::STATUS_DELETED) {
  206 + return false;
  207 + }
  208 + $this->status = self::STATUS_DELETED;
  209 + if($this->update()) {
  210 + $this->clearSafe();
  211 + return true;
  212 + } else {
  213 + return false;
  214 + }
  215 + }
  216 + } else {
  217 + $this->addError('comment_id', 'You can`t delete this post');
  218 + return false;
  219 + }
  220 + }
  221 +
  222 + public function checkCreate()
  223 + {
  224 + if($this->getGuestComment()) {
  225 + return true;
  226 + } else {
  227 + return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, [
  228 + 'model' => $this->model,
  229 + 'model_id' => $this->model_id,
  230 + ]);
  231 + }
  232 + }
  233 +
  234 + public function checkUpdate()
  235 + {
  236 + if($this->scenario == self::SCENARIO_GUEST) {
  237 + return false;
  238 + } else {
  239 + return \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE, [
  240 + 'model' => $this->model,
  241 + 'model_id' => $this->model_id,
  242 + ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE_OWN, [
  243 + 'model' => $this->model,
  244 + 'model_id' => $this->model_id,
  245 + ]);
  246 + }
  247 + }
  248 +
  249 + public function checkDelete()
  250 + {
  251 + if($this->scenario == self::SCENARIO_GUEST) {
  252 + return false;
  253 + } else {
  254 + return \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE, [
  255 + 'model' => $this->model,
  256 + 'model_id' => $this->model_id,
  257 + ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE_OWN, [
  258 + 'model' => $this->model,
  259 + 'model_id' => $this->model_id,
  260 + ]);
  261 + }
  262 + }
  263 +
  264 + protected function clearSafe($setNew = true)
  265 + {
  266 + $safe = $this->safeAttributes();
  267 + $count = count($safe);
  268 + $values = array_fill(0, $count, NULL);
  269 + $result = array_combine($safe, $values);
  270 + $this->setAttributes($result);
  271 + $this->setIsNewRecord($setNew);
  272 + }
  273 +
  274 + public function getParent()
  275 + {
  276 + return $this->hasOne(self::className(), [ 'comment_id' => 'comment_pid' ]);
  277 + }
  278 +
  279 + public function getAuthor()
  280 + {
  281 + // if($this->user_id != NULL) {
  282 + return $this->hasOne(\common\models\User::className(), [ 'id' => 'user_id' ]);
  283 + // } else {
  284 + // return ['firstname' => $this->user_name, 'email' => $this->user_email];
  285 + // }
  286 + }
  287 +
  288 + public function checkRating()
  289 + {
  290 + $rating = $this->hasOne(\common\modules\comment\models\Rating::className(), [
  291 + 'model_id' => 'comment_id',
  292 + ])
  293 + ->andWhere([
  294 + 'model' => $this->className(),
  295 + ])
  296 + ->one();
  297 + if(!$rating instanceof \common\modules\comment\models\Rating) {
  298 + $rating = new \common\modules\comment\models\Rating([
  299 + 'model' => $this->className(),
  300 + 'model_id' => $this->comment_id,
  301 + 'user_id' => $this->user_id,
  302 + ]);
  303 + $rating->save();
  304 + }
  305 + }
  306 +
  307 + public function getRating()
  308 + {
  309 + $this->checkRating();
  310 + return $this->hasOne(\common\modules\comment\models\Rating::className(), [
  311 + 'model_id' => 'comment_id',
  312 + ])
  313 + ->andWhere([ 'model' => $this->className() ]);
  314 + }
  315 +
  316 + public function hasRating($return = true)
  317 + {
  318 + $rating = $this->hasOne(\common\modules\comment\models\Rating::className(), [
  319 + 'model_id' => 'comment_id',
  320 + ])
  321 + ->andWhere([ 'model' => $this->className() ])
  322 + ->andWhere([
  323 + 'not',
  324 + [ 'value' => NULL ],
  325 + ])
  326 + ->one();
  327 + if($return) {
  328 + return $rating;
  329 + } else {
  330 + return $rating ? true : false;
  331 + }
  332 + }
  333 +
  334 + }
... ...
common/modules/comment/models/CommentProject.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment\models;
  3 +
  4 + use common\models\Currency;
  5 + use common\models\File;
  6 + use yii\db\ActiveQuery;
  7 + use yii\web\UploadedFile;
  8 +
  9 + /**
  10 + * Class Comment
  11 + * @property bool $guestComment
  12 + * @property integer $comment_id
  13 + * @property string $text
  14 + * @property int $user_id
  15 + * @property int $status
  16 + * @property string $date_add
  17 + * @property string $date_update
  18 + * @property string $date_delete
  19 + * @property string $model
  20 + * @property int $model_id
  21 + * @property string $files
  22 + * @property float $budget_from
  23 + * @property float $budget_to
  24 + * @property int $term_from
  25 + * @property int $term_to
  26 + * @package common\modules\comment\models
  27 + */
  28 + class CommentProject extends \yii\db\ActiveRecord
  29 + implements \common\modules\comment\interfaces\CommentInterface
  30 + {
  31 +
  32 + const STATUS_HIDDEN = 0;
  33 + const STATUS_DELETED = 2;
  34 + const STATUS_ACTIVE = 1;
  35 + const STATUS_PERSONAL = 3;
  36 + const STATUS_ANONYMOUS = 4;
  37 +
  38 + const SCENARIO_USER = 'user';
  39 + const SCENARIO_GUEST = 'guest';
  40 +
  41 + /**
  42 + * @var bool
  43 + */
  44 + public $guestComment = false;
  45 + public $file;
  46 +
  47 + public function rules()
  48 + {
  49 + return [
  50 + [
  51 + [
  52 + 'text',
  53 + 'budget_from',
  54 + 'budget_to',
  55 + 'term_from',
  56 + 'term_to',
  57 + 'budget_currency',
  58 + ],
  59 + 'required',
  60 + ],
  61 + [
  62 + [
  63 + 'budget_currency',
  64 + ],
  65 + 'integer',
  66 + ],
  67 + [
  68 + [
  69 + 'budget_from',
  70 + 'budget_to',
  71 + 'term_from',
  72 + 'term_to',
  73 + ],
  74 + 'integer',
  75 + 'min' => 0,
  76 + ],
  77 + [
  78 + [
  79 + 'budget_currency',
  80 + ],
  81 + 'default',
  82 + 'value' => 3,
  83 + ],
  84 + [
  85 + [ 'budget_currency' ],
  86 + 'exist',
  87 + 'targetClass' => Currency::className(),
  88 + 'targetAttribute' => 'currency_id',
  89 + ],
  90 + [
  91 + [
  92 + 'files',
  93 + ],
  94 + 'string',
  95 + ],
  96 + [
  97 + [
  98 + 'file',
  99 + ],
  100 + 'safe',
  101 + ],
  102 + [
  103 + [ 'status' ],
  104 + 'default',
  105 + 'value' => 1,
  106 + ],
  107 + ];
  108 + }
  109 +
  110 + public function scenarios()
  111 + {
  112 + return [
  113 + self::SCENARIO_USER => [
  114 + 'text',
  115 + 'budget_from',
  116 + 'budget_to',
  117 + 'term_from',
  118 + 'term_to',
  119 + 'file',
  120 + ],
  121 + self::SCENARIO_GUEST => [
  122 +
  123 + ],
  124 + ];
  125 + }
  126 +
  127 + /**
  128 + * @inheritdoc
  129 + */
  130 + public function behaviors()
  131 + {
  132 + return [
  133 + [
  134 + 'class' => \yii\behaviors\TimestampBehavior::className(),
  135 + 'createdAtAttribute' => 'date_add',
  136 + 'updatedAtAttribute' => 'date_update',
  137 + 'value' => new \yii\db\Expression('NOW()'),
  138 + ],
  139 + ];
  140 + }
  141 +
  142 + public static function tableName()
  143 + {
  144 + return '{{%comment_project}}';
  145 + }
  146 +
  147 + /**
  148 + * @inheritdoc
  149 + */
  150 + public function attributeLabels()
  151 + {
  152 + return [
  153 + 'text' => \Yii::t('app', 'ะขะตะบัั‚ ะพั‚ะฒะตั‚ะฐ'),
  154 + 'budget_from' => \Yii::t('app', 'ะพั‚'),
  155 + 'budget_to' => \Yii::t('app', 'ะดะพ'),
  156 + 'term_from' => \Yii::t('app', 'ะพั‚'),
  157 + 'term_to' => \Yii::t('app', 'ะดะพ'),
  158 + ];
  159 + }
  160 +
  161 + public function getGuestComment()
  162 + {
  163 + return $this->guestComment;
  164 + }
  165 +
  166 +// public function setGuestComment($value)
  167 +// {
  168 +// $this->guestComment = $value;
  169 +// }
  170 +
  171 + /**
  172 + * @param string $model
  173 + * @param integer $model_id
  174 + *
  175 + * @return ActiveQuery
  176 + */
  177 + public function getComments($model, $model_id)
  178 + {
  179 + return $this->find()
  180 + ->where([
  181 + 'comment_project.model' => $model,
  182 + 'comment_project.model_id' => $model_id,
  183 + 'comment_project.status' => 1,
  184 + ]);
  185 + }
  186 +
  187 + public function postComment()
  188 + {
  189 + if($this->checkCreate()) {
  190 + if(!empty(\Yii::$app->request->post($this->formName())['anonymous'])) {
  191 + $this->status = self::STATUS_ANONYMOUS;
  192 + }
  193 + $this->file = UploadedFile::getInstances($this, 'file');
  194 + if(!empty($this->file)) {
  195 + $file_id = [];
  196 + if(is_array($this->file)){
  197 + foreach($this->file as $file){
  198 + if($file instanceof UploadedFile){
  199 + $file_model = new File();
  200 + $file_id[] = $file_model->saveFile($file);
  201 + }
  202 + }
  203 + } else {
  204 + if($this->file instanceof UploadedFile){
  205 + $file_model = new File();
  206 + $file_id[] = $file_model->saveFile($this->file);
  207 + }
  208 + }
  209 + $this->files = json_encode($file_id);
  210 + }
  211 + if($this->insert()) {
  212 + $this->clearSafe();
  213 + return true;
  214 + } else {
  215 + return false;
  216 + }
  217 + } else {
  218 + $this->addError('comment_id', 'You can`t post comment here');
  219 + return false;
  220 + }
  221 + }
  222 +
  223 + public function updateComment()
  224 + {
  225 + if($this->checkUpdate()) {
  226 + if(empty( $this->comment_id )) {
  227 + $this->addError('comment_id', 'Comment ID not found');
  228 + return false;
  229 + } else {
  230 + if($this->update()) {
  231 + $this->clearSafe();
  232 + return true;
  233 + } else {
  234 + return false;
  235 + }
  236 + }
  237 + } else {
  238 + $this->addError('comment_id', 'You can`t update this post');
  239 + return false;
  240 + }
  241 + }
  242 +
  243 + public function deleteComment()
  244 + {
  245 + if($this->checkDelete()) {
  246 + if(empty( $this->comment_id )) {
  247 + $this->addError('comment_id', 'Comment ID not found');
  248 + return false;
  249 + } else {
  250 + if($this->status == self::STATUS_DELETED) {
  251 + return false;
  252 + }
  253 + $this->status = self::STATUS_DELETED;
  254 + if($this->update()) {
  255 + $this->clearSafe();
  256 + return true;
  257 + } else {
  258 + return false;
  259 + }
  260 + }
  261 + } else {
  262 + $this->addError('comment_id', 'You can`t delete this post');
  263 + return false;
  264 + }
  265 + }
  266 +
  267 + public function checkCreate()
  268 + {
  269 + if($this->getGuestComment()) {
  270 + return true;
  271 + } else {
  272 + return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, [
  273 + 'model' => $this->model,
  274 + 'model_id' => $this->model_id,
  275 + ]);
  276 + }
  277 + }
  278 +
  279 + public function checkUpdate()
  280 + {
  281 + if($this->scenario == self::SCENARIO_GUEST) {
  282 + return false;
  283 + } else {
  284 + return \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE, [
  285 + 'model' => $this->model,
  286 + 'model_id' => $this->model_id,
  287 + ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE_OWN, [
  288 + 'model' => $this->model,
  289 + 'model_id' => $this->model_id,
  290 + ]);
  291 + }
  292 + }
  293 +
  294 + public function checkDelete()
  295 + {
  296 + if($this->scenario == self::SCENARIO_GUEST) {
  297 + return false;
  298 + } else {
  299 + return \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE, [
  300 + 'model' => $this->model,
  301 + 'model_id' => $this->model_id,
  302 + ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE_OWN, [
  303 + 'model' => $this->model,
  304 + 'model_id' => $this->model_id,
  305 + ]);
  306 + }
  307 + }
  308 +
  309 + protected function clearSafe($setNew = true)
  310 + {
  311 + $safe = $this->safeAttributes();
  312 + $count = count($safe);
  313 + $values = array_fill(0, $count, NULL);
  314 + $result = array_combine($safe, $values);
  315 + $this->setAttributes($result);
  316 + $this->setIsNewRecord($setNew);
  317 + }
  318 +
  319 + public function getAuthor()
  320 + {
  321 + // if($this->user_id != NULL) {
  322 + return $this->hasOne(\common\models\User::className(), [ 'id' => 'user_id' ]);
  323 + // } else {
  324 + // return ['firstname' => $this->user_name, 'email' => $this->user_email];
  325 + // }
  326 + }
  327 +
  328 + }
... ...
common/modules/comment/models/Rating.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +namespace common\modules\comment\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "rating".
  9 + *
  10 + * @property integer $rating_id
  11 + * @property string $date_add
  12 + * @property string $date_update
  13 + * @property integer $user_id
  14 + * @property integer $value
  15 + * @property string $model
  16 + * @property integer $model_id
  17 + *
  18 + * @property \common\models\User $user
  19 + */
  20 +class Rating extends \yii\db\ActiveRecord
  21 +{
  22 +
  23 + public $rating;
  24 + /**
  25 + * @inheritdoc
  26 + */
  27 + public static function tableName()
  28 + {
  29 + return 'rating';
  30 + }
  31 +
  32 + /**
  33 + * @inheritdoc
  34 + */
  35 + public function rules()
  36 + {
  37 + return [
  38 + [['value'], 'integer'],
  39 + ];
  40 + }
  41 +
  42 + /**
  43 + * @inheritdoc
  44 + */
  45 + public function attributeLabels()
  46 + {
  47 + return [
  48 + 'rating_id' => Yii::t('app', 'Rating ID'),
  49 + 'date_add' => Yii::t('app', 'Date Add'),
  50 + 'date_update' => Yii::t('app', 'Date Update'),
  51 + 'user_id' => Yii::t('app', 'User ID'),
  52 + 'entity' => Yii::t('app', 'Entity'),
  53 + 'value' => Yii::t('app', 'Value'),
  54 + ];
  55 + }
  56 +
  57 + /**
  58 + * @return \yii\db\ActiveQuery
  59 + */
  60 + public function getUser()
  61 + {
  62 + return $this->hasOne(\common\models\User::className(), ['id' => 'user_id']);
  63 + }
  64 +}
... ...
common/modules/comment/rbac/ArtboxCommentCreateRule.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace common\modules\comment\rbac;
  4 +
  5 + use yii\rbac\Rule;
  6 +
  7 + class ArtboxCommentCreateRule extends Rule
  8 + {
  9 +
  10 + public $name = 'canCommentCreateArtbox';
  11 +
  12 + public function execute($user, $item, $params)
  13 + {
  14 + return true;
  15 + }
  16 +
  17 + }
0 18 \ No newline at end of file
... ...
common/modules/comment/rbac/ArtboxCommentDeleteOwnRule.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace common\modules\comment\rbac;
  4 +
  5 + use yii\rbac\Rule;
  6 +
  7 + class ArtboxCommentDeleteOwnRule extends Rule
  8 + {
  9 +
  10 + public $name = 'canCommentDeleteOwnArtbox';
  11 +
  12 + public function execute($user, $item, $params)
  13 + {
  14 + return true;
  15 + }
  16 +
  17 + }
0 18 \ No newline at end of file
... ...
common/modules/comment/rbac/ArtboxCommentDeleteRule.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace common\modules\comment\rbac;
  4 +
  5 + use yii\rbac\Rule;
  6 +
  7 + class ArtboxCommentDeleteRule extends Rule
  8 + {
  9 +
  10 + public $name = 'canCommentDeleteArtbox';
  11 +
  12 + public function execute($user, $item, $params)
  13 + {
  14 + return true;
  15 + }
  16 +
  17 + }
0 18 \ No newline at end of file
... ...
common/modules/comment/rbac/ArtboxCommentUpdateOwnRule.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace common\modules\comment\rbac;
  4 +
  5 + use yii\rbac\Rule;
  6 +
  7 + class ArtboxCommentUpdateOwnRule extends Rule
  8 + {
  9 +
  10 + public $name = 'canCommentUpdateOwnArtbox';
  11 +
  12 + public function execute($user, $item, $params)
  13 + {
  14 + return true;
  15 + }
  16 +
  17 + }
0 18 \ No newline at end of file
... ...
common/modules/comment/rbac/ArtboxCommentUpdateRule.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 + namespace common\modules\comment\rbac;
  4 +
  5 + use yii\rbac\Rule;
  6 +
  7 + class ArtboxCommentUpdateRule extends Rule
  8 + {
  9 +
  10 + public $name = 'canCommentUpdateArtbox';
  11 +
  12 + public function execute($user, $item, $params)
  13 + {
  14 + return true;
  15 + }
  16 +
  17 + }
0 18 \ No newline at end of file
... ...
common/modules/comment/resources/comment.css 0 โ†’ 100644
  1 +.artbox_comment_reply_author, .artbox_comment_update_reply {
  2 + position: relative;
  3 + width: 25%;
  4 +}
  5 +.artbox_comment_update_reply {
  6 + width: 25%;
  7 + float: none;
  8 +}
  9 +.artbox_comment_reply_author:after, .artbox_comment_update_reply:after {
  10 + content: '';
  11 + background-image: url('delete-ico.png');
  12 + display: block;
  13 + position: absolute;
  14 + right: -13px;
  15 + width: 13px;
  16 + height: 13px;
  17 + top: 0;
  18 + cursor: pointer;
  19 +}
0 20 \ No newline at end of file
... ...
common/modules/comment/resources/comment.js 0 โ†’ 100644
  1 +$(function() {
  2 +
  3 + $(document).on('click', '.artbox_comment_delete', function() {
  4 + var container = $(this).parents('.artbox_comment_container');
  5 + var comment_id = $(container).data('comment_id');
  6 + var form_name = $(container).data('form_name');
  7 + if(confirm("ะฃะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ัƒะดะฐะปะธั‚ัŒ ะบะพะผะผะตะฝั‚ะฐั€ะธะน?")) {
  8 + $.post(
  9 + '/artbox-comment/delete',
  10 + {
  11 + Comment: {
  12 + comment_id: comment_id
  13 + }
  14 + },
  15 + function(data, textStatus, jqXHR) {
  16 + if(!data.error) {
  17 + $(container).after('<p class="removeable">'+data.text+'</p>');
  18 + $(container).remove();
  19 + } else {
  20 + $(container).prepend('<p class="removeable error_message">'+data.error+'</p>')
  21 + }
  22 + }
  23 + );
  24 + }
  25 + });
  26 +
  27 + $(document).on('click', '.artbox_comment_reply', function() {
  28 + var container = $(this).parents('.artbox_comment_container').first();
  29 + var comment_id = $(container).data('comment_id');
  30 + var form_name = $(container).data('form_name');
  31 + var author = $(container).find('.artbox_comment_author').first().text();
  32 + var comment_form = $('.artbox_comment_form').first();
  33 + var offset = $(comment_form).offset();
  34 + var reply_block = $(comment_form).find('.artbox_comment_reply_block').first();
  35 + $(reply_block).empty();
  36 + $(reply_block).append('<input type="hidden" name="'+form_name+'[comment_pid]" value="'+comment_id+'">');
  37 + $(reply_block).append('<p class="artbox_comment_reply_author">'+author+'</p>');
  38 + $('html, body').animate({
  39 + scrollTop: offset.top - 50,
  40 + });
  41 + });
  42 +
  43 + $(document).on('click', '.artbox_comment_reply_author', function() {
  44 + $(this).parents('.artbox_comment_reply_block').first().empty();
  45 + });
  46 +
  47 + $(document).on('click', '.artbox_comment_update', function() {
  48 + $(this).removeClass('artbox_comment_update');
  49 + $(this).text('ะกะพั…ั€ะฐะฝะธั‚ัŒ');
  50 + $(this).addClass('artbox_comment_update_submit');
  51 + var container = $(this).parents('.artbox_comment_container').first();
  52 + var comment_id = $(container).data('comment_id');
  53 + var form_name = $(container).data('form_name');
  54 + var text = $(container).find('.artbox_comment_text');
  55 + var object = {};
  56 + object[form_name] = {comment_id: comment_id};
  57 + $.post(
  58 + '/artbox-comment/form',
  59 + object,
  60 + function(data, textStatus, jqXHR) {
  61 + $(text).hide();
  62 + $(text).after(
  63 + '<div class="artbox_comment_text_edit new-portf-answer">'
  64 + + data
  65 + + '</div>'
  66 + );
  67 + }
  68 + );
  69 + });
  70 +
  71 + $(document).on('click', '.artbox_comment_update_reply', function() {
  72 + $(this).remove();
  73 + });
  74 +
  75 + $(document).on('click', '.artbox_comment_update_submit', function(e) {
  76 + e.preventDefault();
  77 + var container = $(this).parents('.artbox_comment_container').first();
  78 + var edit = $(container).find('.artbox_comment_text_edit').first();
  79 + $.post(
  80 + '/artbox-comment/update',
  81 + $(edit).find('form').serialize(),
  82 + function(data) {
  83 + if(!data.error) {
  84 + location.reload(true);
  85 + }
  86 + }
  87 + )
  88 + });
  89 +});
0 90 \ No newline at end of file
... ...
common/modules/comment/resources/delete-ico.png 0 โ†’ 100644

368 Bytes

common/modules/comment/views/comment_form.php 0 โ†’ 100644
  1 +<?php
  2 + /**
  3 + * @var \common\modules\comment\models\Comment $model
  4 + */
  5 + use yii\widgets\ActiveForm;
  6 +
  7 + $form = ActiveForm::begin();
  8 +
  9 +?>
  10 +<?php
  11 + echo $form->field($model, 'comment_id')
  12 + ->label(false)
  13 + ->hiddenInput();
  14 + if(!empty( $model->parent )) {
  15 + ?>
  16 + <div class="artbox_comment_update_reply">
  17 + <?php
  18 + echo "<span>";
  19 + if(!empty( $model->parent->author )) {
  20 + echo $model->parent->author->firstname . ' ' . $model->parent->author->lastname;
  21 + } else {
  22 + echo $model->parent->user_name;
  23 + }
  24 + echo "</span>";
  25 + echo $form->field($model, 'comment_pid')
  26 + ->label(false)
  27 + ->hiddenInput();
  28 + ?>
  29 + </div>
  30 + <?php
  31 + }
  32 + echo $form->field($model, 'text')
  33 + ->label(false)
  34 + ->textarea();
  35 +?>
  36 +<?php
  37 + $form->end();
  38 +?>
0 39 \ No newline at end of file
... ...
common/modules/comment/widgets/CommentWidget.php 0 โ†’ 100644
  1 +<?php
  2 + namespace common\modules\comment\widgets;
  3 +
  4 + use \yii\helpers\ArrayHelper;
  5 + use \yii\helpers\Html;
  6 +
  7 + class CommentWidget extends \yii\base\Widget
  8 + {
  9 +
  10 + /**
  11 + * @var null|\yii\web\View
  12 + */
  13 + public $context = NULL;
  14 +
  15 + /**
  16 + * @var array Parts of widgets that can be rendered
  17 + */
  18 + public $parts = [ ];
  19 +
  20 + public $rating_class = NULL;
  21 +
  22 + public $rating_options = [ ];
  23 +
  24 + /**
  25 + * @var string|\common\modules\comment\models\Comment
  26 + */
  27 + public $comment_class;
  28 +
  29 + /**
  30 + * @var array
  31 + */
  32 + public $class_options = [ ];
  33 +
  34 + /**
  35 + * @var bool Wheather to display comment list
  36 + */
  37 + public $display_comment_list = true;
  38 +
  39 + /**
  40 + * @var bool Whether to display comment form
  41 + */
  42 + public $display_comment_form = true;
  43 +
  44 + /**
  45 + * @var bool Whether to display success text
  46 + */
  47 + public $display_comment_success = true;
  48 +
  49 + /**
  50 + * @var bool Whether to allow one user post multiple comments
  51 + */
  52 + public $allow_multiple = true;
  53 +
  54 + /**
  55 + * @var array Options sent to list part
  56 + */
  57 + public $list_options = [
  58 + 'tag' => 'div',
  59 + 'view' => 'list-comment',
  60 + 'class' => 'test-class',
  61 + ];
  62 +
  63 + /**
  64 + * @var array Options sent to success part
  65 + */
  66 + public $success_options = [
  67 + 'tag' => 'div',
  68 + 'content' => NULL,
  69 + 'class' => 'test-class-success',
  70 + ];
  71 +
  72 + /**
  73 + * @var array Options sent to form part
  74 + */
  75 + public $form_options = [
  76 + 'tag' => 'div',
  77 + 'view' => 'form-comment',
  78 + 'class' => 'test-class-form',
  79 + ];
  80 +
  81 + /**
  82 + * @var bool Indicates whether any successful action happened
  83 + */
  84 + protected $isSuccess = false;
  85 +
  86 + public $success_text = 'Comment successfully added';
  87 +
  88 + /**
  89 + * @var string $model Model, to which comments attached
  90 + */
  91 + public $model;
  92 +
  93 + /**
  94 + * @var integer $model_id Model id, to which comments attached
  95 + */
  96 + public $model_id;
  97 +
  98 + /**
  99 + * @var string Template of the widget. You may use <code>{success}, {form}, {list}</code>
  100 + * to render particular parts. You are also able to use common HTML here.
  101 + */
  102 + public $template = "{success}\n{form}\n{list}";
  103 +
  104 + /**
  105 + * @var array Widget options
  106 + */
  107 + public $options = [ ];
  108 +
  109 + /**
  110 + * @var \yii\data\DataProviderInterface Data provider of comments
  111 + */
  112 + public $dataProvider;
  113 +
  114 + /**
  115 + * @inheritdoc
  116 + */
  117 + public function init()
  118 + {
  119 + parent::init();
  120 + \common\modules\comment\assets\CommentAsset::register($this->view);
  121 + if(is_string($this->comment_class)) {
  122 + $this->comment_class = new $this->comment_class($this->class_options);
  123 + } else {
  124 + throw new \yii\base\InvalidConfigException(__CLASS__ . '->comment_class must be defined as object full class name string.');
  125 + }
  126 + if(!empty( $this->rating_class ) && is_string($this->rating_class)) {
  127 + $this->rating_class = new $this->rating_class($this->rating_options);
  128 + } elseif(!empty( $this->rating_class )) {
  129 + throw new \yii\base\InvalidConfigException(__CLASS__ . '->rating_class must be defined as object full class name string.');
  130 + }
  131 + $this->comment_class->model = $this->model;
  132 + $this->comment_class->model_id = $this->model_id;
  133 + $this->createDataProvider();
  134 + $this->process();
  135 + ob_start();
  136 + }
  137 +
  138 + /**
  139 + * @inheritdoc
  140 + * @return string
  141 + */
  142 + public function run()
  143 + {
  144 + $content = ob_get_clean();
  145 + $this->createParts();
  146 + return $this->renderWidget();
  147 + }
  148 +
  149 + public function createParts()
  150 + {
  151 + if($this->display_comment_success && $this->isSuccess) {
  152 + $tag = ArrayHelper::remove($this->success_options, 'tag', 'div');
  153 + if(is_callable($this->success_options[ 'content' ])) {
  154 + $result = call_user_func(ArrayHelper::remove($this->success_options, 'content'), $this->success_text);
  155 + } elseif($this->success_options[ 'content' ] != NULL) {
  156 + $result = Html::encode(ArrayHelper::remove($this->success_options, 'content', $this->success_text));
  157 + } else {
  158 + $result = Html::encode($this->success_text);
  159 + }
  160 + $this->parts[ 'success' ] = Html::tag($tag, $result, $this->success_options);
  161 + unset( $tag, $result );
  162 + }
  163 +
  164 + if($this->display_comment_list) {
  165 + $tag = ArrayHelper::remove($this->list_options, 'tag', 'div');
  166 + $view = ArrayHelper::remove($this->list_options, 'view');
  167 + $this->parts[ 'list' ] = Html::tag($tag, $this->renderItems($view), $this->list_options);
  168 + }
  169 +
  170 + if($this->display_comment_form) {
  171 + $tag = ArrayHelper::remove($this->form_options, 'tag', 'div');
  172 + $view = ArrayHelper::remove($this->form_options, 'view');
  173 + $this->parts[ 'form' ] = Html::tag($tag, $this->renderForm($view), $this->form_options);
  174 + }
  175 + }
  176 +
  177 + public function createDataProvider()
  178 + {
  179 + $this->dataProvider = new \yii\data\ActiveDataProvider([
  180 + 'query' => $this->comment_class->getComments($this->model, $this->model_id),
  181 + 'pagination' => [
  182 + 'pageSize' => 10,
  183 + ],
  184 + ]);
  185 + }
  186 +
  187 + public function renderItems($view)
  188 + {
  189 + if(empty( $view )) {
  190 + throw new \yii\base\InvalidConfigException("list_options[view] must be set");
  191 + }
  192 + return $this->render($view, [ 'dataProvider' => $this->dataProvider ]);
  193 + }
  194 +
  195 + public function renderForm($view)
  196 + {
  197 + if(empty( $view )) {
  198 + throw new \yii\base\InvalidConfigException("form_options[view] must be set");
  199 + }
  200 + return $this->render($view, [
  201 + 'model' => $this->comment_class,
  202 + 'rating' => $this->rating_class,
  203 + 'user' => \Yii::$app->user->identity,
  204 + 'dataProvider' => $this->dataProvider,
  205 + ]);
  206 + }
  207 +
  208 + public function renderWidget()
  209 + {
  210 + $template = $this->template;
  211 + $parts = $this->parts;
  212 + $options = $this->options;
  213 + $template = preg_replace('/{success}/', ArrayHelper::remove($parts, 'success', ''), $template);
  214 + $template = preg_replace('/{list}/', ArrayHelper::remove($parts, 'list', ''), $template);
  215 + $template = preg_replace('/{form}/', ArrayHelper::remove($parts, 'form', ''), $template);
  216 + $tag = ArrayHelper::remove($options, 'tag', 'div');
  217 + return Html::tag($tag, $template, $options);
  218 + }
  219 +
  220 + public function process()
  221 + {
  222 + $data = \Yii::$app->request->post();
  223 + if($this->comment_class->load($data) && $this->comment_class->postComment()) {
  224 + if(is_object($this->rating_class) && $this->comment_class->rating->load($data) && $this->comment_class->rating->save()) {
  225 + $this->isSuccess = true;
  226 + }
  227 + }
  228 + }
  229 + }
0 230 \ No newline at end of file
... ...
common/modules/comment/widgets/views/_project_comment_view.php 0 โ†’ 100644
  1 +<?php
  2 + use common\models\User;
  3 + use yii\helpers\Html;
  4 +
  5 + /**
  6 + * @var \common\modules\comment\models\CommentProject $model Current comment model
  7 + * @var integer $key ID of current comment
  8 + * @var integer $index index of current element according
  9 + * to current page, starting from 0
  10 + * @var \yii\widgets\ListView $widget current ListView instance
  11 + * @var User $user
  12 + */
  13 + $user = NULL;
  14 + if(!empty( $model->user_id )) {
  15 + $user = User::find()
  16 + ->where([ 'id' => $model->user_id ])
  17 + ->with('userInfo')
  18 + ->one();
  19 + }
  20 +?>
  21 +<div class="performer-vacancy-sidebar-left-wr">
  22 + <div class="performer-vacancy-sidebar-left">
  23 + <div class="performer-vacancy-sidebar-img style">
  24 + <?= Html::img($user->userInfo->image) ?>
  25 + </div>
  26 + <div class="performer-vacancy-sidebar-all style">
  27 + <div class="performer-vacancy-sidebar-soc style">
  28 + <ul>
  29 + <?php
  30 + if(!empty( $user->userInfo->social_fb )) {
  31 + echo '<li>'.Html::a(Html::img('/images/ico-fb.png'), $user->userInfo->social_fb, ['target' => '_blank']).'</li>';
  32 + }
  33 + ?>
  34 + <?php
  35 + if(!empty( $user->userInfo->social_t )) {
  36 + echo '<li>'.Html::a(Html::img('/images/ico-tw.png'), $user->userInfo->social_t, ['target' => '_blank']).'</li>';
  37 + }
  38 + ?>
  39 + <?php
  40 + if(!empty( $user->userInfo->social_in )) {
  41 + echo '<li>'.Html::a(Html::img('/images/ico-in.png'), $user->userInfo->social_in, ['target' => '_blank']).'</li>';
  42 + }
  43 + ?>
  44 + <?php
  45 + if(!empty( $user->userInfo->social_vk )) {
  46 + echo '<li>'.Html::a(Html::img('/images/ico-vk.png'), $user->userInfo->social_vk, ['target' => '_blank']).'</li>';
  47 + }
  48 + ?>
  49 + </ul>
  50 + </div>
  51 + <div class="performer-vacancy-sidebar-views style">
  52 + <ul class="style">
  53 + <li><img src="/images/sidebar-ico/ico-1.png" alt="">
  54 + <div class="sidebarvievstxt"><?= $user->userInfo->view_count ?></div>
  55 + </li>
  56 + <li><img src="/images/sidebar-ico/ico-9.png" alt="">
  57 + <div class="sidebarvievstxt"><span class="sidebar-views-txt">ะกั‚ะฐั‚ัƒั: </span><?= (empty($user->userInfo->busy)?'ะกะฒะพะฑะพะดะตะฝ':'ะ—ะฐะฝัั‚') ?>
  58 + </div>
  59 + </li>
  60 + <li><img src="/images/sidebar-ico/ico-2.png" alt="">
  61 + <div class="sidebarvievstxt">
  62 + <span class="sidebar-views-txt">ะะฐ ัะฐะนั‚ะต: </span>1ะณ. 8 ะผะตั.
  63 + </div>
  64 + </li>
  65 + <li><img src="/images/sidebar-ico/ico-3.png" alt="">
  66 + <div class="sidebarvievstxt"><span class="sidebar-views-txt">ะŸะพัะปะตะดะฝะธะน ะฒะธะทะธั‚:<br></span>2 ะดะฝั ะฝะฐะทะฐะด
  67 + </div>
  68 + </li>
  69 + </ul>
  70 + <a href="#" class="tender-see-profile style">ะŸะพัะผะพั‚ั€ะตั‚ัŒ ะฟั€ะพั„ะธะปัŒ</a>
  71 + </div>
  72 + </div>
  73 + </div>
  74 +</div>
  75 +<div class="tender-offer-proj-block-right-wr">
  76 + <div class="tender-offer-proj-block-right">
  77 + <div class="tender-offer-proj-min-blocks"><span>2000 ะณั€ะฝ</span></div>
  78 + <div class="tender-offer-proj-min-blocks"><span>3 ะ”ะะฏ</span></div>
  79 + </div>
  80 + <div class="tender-offer-proj-block-left">
  81 + <div class="search-worker-blocks-title-wr">
  82 + <div class="search-worker-blocks-title-title">ะŸะตั‚ะตั€ ะฆัƒะผั‚ะพั€</div>
  83 + <div class="rating-new">
  84 + <!--ะพั†ะตะฝะบะฐ-->
  85 + <input type="hidden" class="val" value="4"/>
  86 + </div>
  87 + <a href="#" class="link-to-comm">30 ะพั‚ะทั‹ะฒะพะฒ</a>
  88 + </div>
  89 + <div class="tender-offer-proj-txt">
  90 + <p>1.1 ะกั‚ั€ะพะธั‚ะตะปัŒะฝะฐั ะฟะปะพั‰ะฐะดะบะฐ ั€ะฐัะฟะพะปะพะถะตะฝะฐ ะฟะพ ะฐะดั€ะตััƒ: ะณ. ะšะธะตะฒ.</p>
  91 + <p>1.2 ะกัƒั‰ะตัั‚ะฒัƒัŽั‰ะธะน ะพะฑัŠะตะบั‚ ะฟั€ะตะดัั‚ะฐะฒะปัะตั‚ ัะพะฑะพะน ะฟะพะผะตั‰ะตะฝะธะต ะพะฑั‰ะตะน ะฟะปะพั‰ะฐะดัŒัŽ ะพั€ะธะตะฝั‚ะธั€ะพะฒะพั‡ะฝะพ โ€“ 140 ะผ2.</p>
  92 + <p>1.3. ะฆะตะปัŒ ะฟั€ะพะตะบั‚ะฐ ัะพัั‚ะพะธั‚ ะฒ ะฟั€ะพะฒะตะดะตะฝะธะธ ะฒะฝัƒั‚ั€ะตะฝะฝะธั… ะพะฑั‰ะตัั‚ั€ะพะธั‚ะตะปัŒะฝั‹ั… ะธ ะพั‚ะดะตะปะพั‡ะฝั‹ั… ั€ะฐะฑะพั‚.</p>
  93 + <p>1.4. ะŸั€ะธ ั€ะฐะทั€ะฐะฑะพั‚ะบะต ะผะตั‚ะพะดะพะฒ ัั‚ั€ะพะธั‚ะตะปัŒัั‚ะฒะฐ ะธ ะฒั‹ะฑะพั€ะต ะผะฐั‚ะตั€ะธะฐะปะพะฒ, ะธัะฟะพะปัŒะทัƒะตะผั‹ั… ะฒ ะฝะฐัั‚ะพัั‰ะตะผ ะฟั€ะพะตะบั‚ะต, ะฝะตะพะฑั…ะพะดะธะผะพ ัƒั‡ะธั‚ั‹ะฒะฐั‚ัŒ ะบะปะธะผะฐั‚ะธั‡ะตัะบะธะต ัƒัะปะพะฒะธั, ั…ะฐั€ะฐะบั‚ะตั€ะฝั‹ะต ะดะปั ะณ. ะšะธะตะฒะฐ.</p>
  94 + <p>1.5. ะขั€ะตะฑะพะฒะฐะฝะธั ะบ ะฟั€ะพะตะบั‚ะธั€ะพะฒะฐะฝะธัŽ ะธ ะฟั€ะพะธะทะฒะพะดัั‚ะฒัƒ ั€ะฐะฑะพั‚ ะพะฟั€ะตะดะตะปััŽั‚ัั ัะปะตะดัƒัŽั‰ะธะผะธ ะดะพะบัƒะผะตะฝั‚ะฐะผะธ:</p>
  95 + <p>- ะขะตั…ะฝะธั‡ะตัะบะธะผ ะทะฐะดะฐะฝะธะตะผ.</p>
  96 + <p>- ะกั‚ั€ะพะธั‚ะตะปัŒะฝั‹ะผะธ ะฝะพั€ะผะฐะผะธ ะธ ะฟั€ะฐะฒะธะปะฐะผะธ.</p>
  97 + <p>ะ’ัะต ะฟั€ะพะตะบั‚ะฝั‹ะต ั€ะตัˆะตะฝะธั ะธ ะฒัะต ั€ะฐะทะดะตะปั‹ ั€ะฐะฑะพั‡ะตะณะพ ะฟั€ะพะตะบั‚ะฐ ะดะพะปะถะฝั‹ ะฑั‹ั‚ัŒ ัะพะณะปะฐัะพะฒะฐะฝั‹ ั ะ—ะฐะบะฐะทั‡ะธะบะพะผ ะฒ ะพะฑัŠะตะผะต, ะฝะตะพะฑั…ะพะดะธะผะพะผ ะดะปั ะฟะพัะปะตะดัƒัŽั‰ะตะน ัะดะฐั‡ะธ ะธะฝะถะตะฝะตั€ะฝั‹ั… ัะธัั‚ะตะผ ะธ ะบะพะผะผัƒะฝะธะบะฐั†ะธะน.</p>
  98 + </div>
  99 + <ul class="download-list-files">
  100 + <li>
  101 + <span></span><a href="#" class="download-link-file">ะšะŸ.doc</a><a href="#" class="download-link">ะกะบะฐั‡ะฐั‚ัŒ</a>
  102 + </li>
  103 + <li>
  104 + <span></span><a href="#" class="download-link-file">ะ ะตะทัŽะผะต.txt</a><a href="#" class="download-link">ะกะบะฐั‡ะฐั‚ัŒ</a>
  105 + </li>
  106 + </ul>
  107 + </div>
  108 + <div class="tender-more-buttons-wr">
  109 + <a class="get-project-new" href="#">ะŸะพั€ั‚ั„ะพะปะธะพ</a>
  110 + <a class="get-list-new" href="#">ะšะพะฝะฐั‚ะบั‚ั‹</a>
  111 + </div>
  112 +
  113 +</div>
... ...
common/modules/comment/widgets/views/form-comment.php 0 โ†’ 100644
  1 +<?php
  2 + /**
  3 + * @var \common\modules\comment\models\Comment $model
  4 + * @var \common\models\User $user
  5 + * @var \yii\data\ActiveDataProvider $dataProvider
  6 + * @var null|\common\modules\comment\models\Rating $rating
  7 + */
  8 + use yii\widgets\ActiveForm;
  9 + use yii\helpers\Html;
  10 +
  11 +?>
  12 +<div class="new-portf-comm-count">ะšะพะผะผะตะฝั‚ะฐั€ะธะธ: <?= $dataProvider->totalCount ?></div>
  13 +
  14 +<div class="new-portf-add-comm style">
  15 +
  16 + <?php
  17 + $form = ActiveForm::begin();
  18 +
  19 + echo $form->field($rating, 'value')
  20 + ->label(false)
  21 + ->radioList([
  22 + 1 => 1,
  23 + 2 => 2,
  24 + 3 => 3,
  25 + 4 => 4,
  26 + 5 => 5,
  27 + ]);
  28 +
  29 + if($model->scenario == $model::SCENARIO_GUEST) {
  30 + echo $form->field($model, 'user_name', [
  31 + 'options' => [
  32 + 'class' => 'input-blocks-comm',
  33 + ],
  34 + 'inputOptions' => [
  35 + 'class' => 'custom-input-4',
  36 + ],
  37 + ])
  38 + ->textInput();
  39 + echo $form->field($model, 'user_email', [
  40 + 'options' => [
  41 + 'class' => 'input-blocks-comm',
  42 + ],
  43 + 'inputOptions' => [
  44 + 'class' => 'custom-input-4',
  45 + ],
  46 + ])
  47 + ->textInput();
  48 + }
  49 +
  50 + ?>
  51 + <div class="artbox_comment_reply_block"></div>
  52 + <?php
  53 +
  54 + echo $form->field($model, 'text', [
  55 + 'options' => [
  56 + 'class' => 'input-blocks-comm area-comm',
  57 + ],
  58 + 'inputOptions' => [
  59 + 'class' => 'custom-area-4',
  60 + ],
  61 + ])
  62 + ->textarea();
  63 + ?>
  64 + <div class="input-blocks-comm-button style">
  65 + <?= Html::submitButton('ะ”ะพะฑะฐะฒะธั‚ัŒ ะบะพะผะผะตะฝั‚ะฐั€ะธะน') ?>
  66 + </div>
  67 + <?php
  68 + $form->end();
  69 + ?>
  70 +</div>
0 71 \ No newline at end of file
... ...
common/modules/comment/widgets/views/form-project-comment.php 0 โ†’ 100644
  1 +<?php
  2 + /**
  3 + * @var \common\modules\comment\models\CommentProject $model
  4 + * @var \common\models\User $user
  5 + * @var \yii\data\ActiveDataProvider $dataProvider
  6 + */
  7 + use common\models\Currency;
  8 + use yii\widgets\ActiveForm;
  9 + use yii\helpers\Html;
  10 +
  11 + $currencies = Currency::getCurrencyDropdown();
  12 +?>
  13 +
  14 +<div class="new-portf-add-comm style">
  15 + <div class="box-wr">
  16 + <div class="box-all">
  17 + <div class="tender-add-answer-title">ะ”ะพะฑะฐะฒะธั‚ัŒ ะพั‚ะฒะตั‚</div>
  18 + <div class="form-tender-answer style">
  19 + <?php
  20 + $form = ActiveForm::begin([ 'options' => [ 'class' => 'resformsfile MultiFile-intercepted', 'enctype' => 'multipart/form-data' ] ]);
  21 + ?>
  22 + <div class="form-value-wr style">
  23 + <div class="form-ico-ded-wr">
  24 + <div class="header-cabinet-foto">
  25 + <?= Html::img($user->userInfo->image) ?>
  26 + </div>
  27 + <div class="form-value-ded-name">
  28 + <?= $user->name ?>
  29 + </div>
  30 + </div>
  31 + <div class="form-value-price-wr">
  32 + <div class="form-value-price-title">ะกั‚ะพะธะผะพัั‚ัŒ</div>
  33 + <div class="form-price-wr">
  34 + <?= $form->field($model, 'budget_from', [
  35 + 'template' => "{input}\n{error}",
  36 + 'options' => [ 'tag' => 'span' ],
  37 + ])
  38 + ->input('number', [ 'placeholder' => $model->getAttributeLabel('budget_from') ]) ?>
  39 + <?= $form->field($model, 'budget_to', [
  40 + 'template' => "{input}\n{error}",
  41 + 'options' => [ 'tag' => 'span' ],
  42 + ])
  43 + ->input('number', [ 'placeholder' => $model->getAttributeLabel('budget_to') ]) ?>
  44 + <?= $form->field($model, 'budget_currency', [
  45 + 'template' => "{input}<div class='select-after'></div>\n{error}",
  46 + 'options' => [ 'class' => 'blocks-check-list-wrapp check-valuta' ],
  47 + ])
  48 + ->dropDownList($currencies) ?>
  49 + </div>
  50 + </div>
  51 + <div class="form-value-price-wr" style="float: right">
  52 + <div class="form-value-price-title">
  53 + ะกั€ะพะบะธ(<span style="font-weight: normal">ะฒ ะดะฝัั…</span>)
  54 + </div>
  55 + <div class="form-price-wr">
  56 + <?= $form->field($model, 'term_from', [
  57 + 'template' => "{input}\n{error}",
  58 + 'options' => [ 'tag' => 'span' ],
  59 + ])
  60 + ->input('number', [ 'placeholder' => $model->getAttributeLabel('term_from') ]) ?>
  61 + <?= $form->field($model, 'term_to', [
  62 + 'template' => "{input}\n{error}",
  63 + 'options' => [ 'tag' => 'span' ],
  64 + ])
  65 + ->input('number', [ 'placeholder' => $model->getAttributeLabel('term_to') ]) ?>
  66 + </div>
  67 + </div>
  68 + </div>
  69 + <?= $form->field($model, 'text', [
  70 + 'template' => "{input}\n{error}",
  71 + 'options' => [ 'class' => 'form-tender-txt style' ],
  72 + ])
  73 + ->textarea([ 'placeholder' => $model->getAttributeLabel('text') ]) ?>
  74 + <div class="tender-file-wr">
  75 + <?= $form->field($model, 'file[]')
  76 + ->fileInput([ 'class' => 'multi' ])
  77 + ->label(false) ?>
  78 + <a href="#" class="addfilemulti">ะŸั€ะธะบั€ะตะฟะธั‚ัŒ ั„ะฐะนะป</a>
  79 + <div class="max-size">ะœะฐะบัะธะผะฐะปัŒะฝั‹ะน ั€ะฐะทะผะตั€<br/>ั„ะฐะนะปะฐ 5 ะœะ‘</div>
  80 + </div>
  81 + <div class="tender-form-buttons-wr">
  82 + <?php
  83 + echo Html::submitInput('ะŸะพะดะฐั‚ัŒ ะทะฐัะฒะบัƒ', [ 'class' => 'get-project-new' ]);
  84 + echo Html::submitInput('ะพั‚ะฒะตั‚ะธั‚ัŒ ะฐะฝะพะฝะธะผะฝะพ', [
  85 + 'class' => 'get-list-new',
  86 + 'name' => 'CommentProject[anonymous]',
  87 + ]);
  88 + echo Html::a('ะžั‡ะธัั‚ะธั‚ัŒ', [
  89 + 'tender/view',
  90 + 'tender_id' => \Yii::$app->request->get('tender_id'),
  91 + '#' => 'w1',
  92 + ]);
  93 + ?>
  94 + </div>
  95 + <?php
  96 + $form->end();
  97 + ?>
  98 + </div>
  99 + </div>
  100 + </div>
  101 +</div>
0 102 \ No newline at end of file
... ...
common/modules/comment/widgets/views/list-comment.php 0 โ†’ 100644
  1 +<?php
  2 + /**
  3 + * @var \yii\data\DataProviderInterface $dataProvider
  4 + */
  5 +echo \yii\widgets\ListView::widget([
  6 + 'dataProvider' => $dataProvider,
  7 + 'itemView' => 'project_comment_view',
  8 + 'itemOptions' => [
  9 + 'tag' => false,
  10 + ],
  11 + 'summary' => '',
  12 +]);
0 13 \ No newline at end of file
... ...
common/modules/comment/widgets/views/list-project-comment.php 0 โ†’ 100644
  1 +<?php
  2 + /**
  3 + * @var \yii\data\DataProviderInterface $dataProvider
  4 + */
  5 +?>
  6 +<div class="box-wr">
  7 + <div class="box-all">
  8 + <div class="tender-offer-proj-title-all style">ะŸั€ะตะดะปะพะถะตะฝะธั ะฟั€ะพะตะบั‚ะฐะฝั‚ะพะฒ</div>
  9 + <div class="tender-offer-proj-blocks-wr style">
  10 + <?php
  11 + echo \yii\widgets\ListView::widget([
  12 + 'dataProvider' => $dataProvider,
  13 + 'itemView' => '_project_comment_view',
  14 + 'itemOptions' => [
  15 + 'class' => 'tender-offer-proj-blocks style',
  16 + ],
  17 + 'summary' => '',
  18 + ]);
  19 + ?>
  20 + </div>
  21 + </div>
  22 +</div>
0 23 \ No newline at end of file
... ...
common/modules/comment/widgets/views/project_comment_view.php 0 โ†’ 100644
  1 +<?php
  2 + use common\models\User;
  3 + use yii\helpers\Html;
  4 +
  5 + /**
  6 + * @var \common\modules\comment\models\Comment $model Current comment model
  7 + * @var integer $key ID of current comment
  8 + * @var integer $index index of current element according to
  9 + * current page, starting from 0
  10 + * @var \yii\widgets\ListView $widget current ListView instance
  11 + * @var User $user
  12 + */
  13 + $user = NULL;
  14 + if(!empty( $model->user_id )) {
  15 + $user = User::find()
  16 + ->where([ 'id' => $model->user_id ])
  17 + ->with('userInfo')
  18 + ->one();
  19 + }
  20 +?>
  21 +<div class="new-portf-comm-read artbox_comment_container" data-comment_id="<?= $model->comment_id ?>" data-form_name="<?= $model->formName() ?>">
  22 + <div class="style">
  23 + <div class="header-cabinet-foto">
  24 + <?php
  25 + if(!empty( $user ) && !empty( $user->userInfo->image )) {
  26 + echo "<img src='{$user->userInfo->image}' alt=''>";
  27 + } else {
  28 + echo "<img src='/images/ded-ico.png' alt=''>";
  29 + }
  30 + ?>
  31 + </div>
  32 + <div class="new-prof-wrapper-read">
  33 + <div class="new-portf-comm-read-title">
  34 + <?php
  35 + if(!empty( $user )) {
  36 + echo Html::a('<span class="artbox_comment_author">' . $user->firstname . ' ' . $user->lastname . '</span>', [
  37 + 'performer/common',
  38 + 'performer_id' => $user->id,
  39 + ]);
  40 + } else {
  41 + echo '<span class="artbox_comment_author">' . $model->user_name . '</span>' . '(ะ“ะพัั‚ัŒ)';
  42 + }
  43 + ?>
  44 + </div>
  45 + <div class="new-portf-comm-read-rating">
  46 + <?php
  47 + if($rating = $model->hasRating()) {
  48 + ?>
  49 + <div class="rating">
  50 + <!--ะพั†ะตะฝะบะฐ-->
  51 + <input type="hidden" class="val" value="<?= $rating->value ?>"/>
  52 + <!--ะบะพะปะธั‡ะตัั‚ะฒะพ ะณะพะปะพัะพะฒ-->
  53 + <input type="hidden" class="votes" value="1"/>
  54 + </div>
  55 + <?php
  56 + }
  57 + ?>
  58 + </div>
  59 + <div class="blog-post-date">
  60 + <span></span>
  61 + <p><?= date('d.m.Y', strtotime($model->date_add)) ?></p>
  62 + </div>
  63 + </div>
  64 +
  65 + <div class="new-portf-answer artbox_comment_text">
  66 + <?= Html::encode($model->text) ?>
  67 + </div>
  68 + <div style="clear:both"></div>
  69 + <?php
  70 + /*
  71 + ?>
  72 + <div class="action_panel">
  73 + <ul>
  74 + <li style="display:inline-block" class="artbox_comment_reply">ะžั‚ะฒะตั‚ะธั‚ัŒ</li>
  75 + <li style="display:inline-block" class="artbox_comment_update">ะ ะตะดะฐะบั‚ะธั€ะพะฒะฐั‚ัŒ</li>
  76 + <li style="display:inline-block" class="artbox_comment_delete">ะฃะดะฐะปะธั‚ัŒ</li>
  77 + </ul>
  78 + </div>
  79 + <?php
  80 + */
  81 + ?>
  82 + </div>
  83 + <div class="style"></div>
  84 +</div>
0 85 \ No newline at end of file
... ...
common/modules/file/FileUploadAsset.php 0 โ†’ 100644
  1 +<?php
  2 +/**
  3 + * @link http://www.yiiframework.com/
  4 + * @copyright Copyright (c) 2008 Yii Software LLC
  5 + * @license http://www.yiiframework.com/license/
  6 + */
  7 +
  8 +
  9 +namespace common\modules\file;
  10 +
  11 +use yii\helpers\Url;
  12 +use yii\web\AssetBundle;
  13 +
  14 +/**
  15 + * Asset bundle for the Twitter bootstrap javascript files.
  16 + *
  17 + * @author Qiang Xue <qiang.xue@gmail.com>
  18 + * @since 2.0
  19 + */
  20 +class FileUploadAsset extends AssetBundle
  21 +{
  22 +
  23 +
  24 + /**
  25 + * @inheritdoc
  26 + */
  27 + public function init()
  28 + {
  29 + parent::init();
  30 + $this->sourcePath = __DIR__.'/assets';
  31 + }
  32 +
  33 + public $css = [
  34 + 'css/jquery.fileupload.css',
  35 + 'css/fileupload/style.css'
  36 + ];
  37 +
  38 + public $js = [
  39 + 'js/vendor/jquery.ui.widget.js',
  40 + 'js/jquery.iframe-transport.js',
  41 + 'js/jquery.fileupload.js'
  42 + ];
  43 +}
... ...
common/modules/file/Module.php 0 โ†’ 100644
  1 +<?php
  2 +namespace common\modules\file;
  3 +
  4 +use yii\base\BootstrapInterface;
  5 +
  6 +class Module extends \yii\base\Module
  7 +{
  8 + public function init()
  9 + {
  10 + parent::init();
  11 +
  12 + \Yii::configure($this, require(__DIR__.'/config.php'));
  13 + }
  14 +
  15 +}
... ...
common/modules/file/assets/css/fileupload/style.css 0 โ†’ 100644
  1 +.remover_image {
  2 + position: absolute !important;
  3 + font-size: 20px;
  4 + right: 30px;
  5 + top:30px;
  6 + cursor:pointer;
  7 +}
... ...
common/modules/file/assets/css/jquery.fileupload-noscript.css 0 โ†’ 100644
  1 +@charset "UTF-8";
  2 +/*
  3 + * jQuery File Upload Plugin NoScript CSS
  4 + * https://github.com/blueimp/jQuery-File-Upload
  5 + *
  6 + * Copyright 2013, Sebastian Tschan
  7 + * https://blueimp.net
  8 + *
  9 + * Licensed under the MIT license:
  10 + * http://www.opensource.org/licenses/MIT
  11 + */
  12 +
  13 +.fileinput-button input {
  14 + position: static;
  15 + opacity: 1;
  16 + filter: none;
  17 + font-size: inherit;
  18 + direction: inherit;
  19 +}
  20 +.fileinput-button span {
  21 + display: none;
  22 +}
... ...