Browse Source
LanguageBehavior, LanguageDynamicModel Set all tables unicode collate Remove Meta object from pages UrlManager fromtend /en/... /ru/... Backend top select language for control panelmaster
Egorka
6 years ago
71 changed files with 1967 additions and 340 deletions
@ -0,0 +1,25 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 24.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* @var $this \yii\web\View |
||||||
|
* @var $form \yii\widgets\ActiveForm |
||||||
|
* @var $model \core\forms\menu\MenuItemForm |
||||||
|
* @var $language string |
||||||
|
*/ |
||||||
|
|
||||||
|
$postfix = $language == Yii::$app->params['defaultLanguage'] ? '' : '_' . $language; |
||||||
|
?> |
||||||
|
|
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-6"> |
||||||
|
<?= $form->field($model, 'name' . $postfix)->textInput(['maxlength' => true]) ?> |
||||||
|
</div> |
||||||
|
<div class="col-md-6"> |
||||||
|
<?= $form->field($model, 'title_attr' . $postfix)->textInput(['maxlength' => true]) ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
@ -0,0 +1,17 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 24.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* @var $this \yii\web\View |
||||||
|
* @var $form \yii\widgets\ActiveForm |
||||||
|
* @var $model \core\forms\menu\MenuForm |
||||||
|
* @var $language string |
||||||
|
*/ |
||||||
|
|
||||||
|
$postfix = $language == Yii::$app->params['defaultLanguage'] ? '' : '_' . $language; |
||||||
|
?> |
||||||
|
|
||||||
|
<?= $form->field($model, 'name' . $postfix)->textInput(['maxlength' => true]) ?> |
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180827_195932_set_blog_unicode_collate |
||||||
|
*/ |
||||||
|
class m180827_195932_set_blog_unicode_collate extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$tables = ['blog_tag_assignments']; |
||||||
|
$db = Yii::$app->getDb(); |
||||||
|
$db->createCommand('SET FOREIGN_KEY_CHECKS=0;')->execute(); |
||||||
|
|
||||||
|
foreach ($tables as $table) { |
||||||
|
$db->createCommand( "ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci" )->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
$db->createCommand('SET FOREIGN_KEY_CHECKS=1;')->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Handles the creation of table `pages_lng`. |
||||||
|
*/ |
||||||
|
class m180824_202316_create_pages_lng_table extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$tableOptions = null; |
||||||
|
if ($this->db->driverName === 'mysql') { |
||||||
|
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; |
||||||
|
} |
||||||
|
|
||||||
|
$this->createTable('{{%pages_lng}}', [ |
||||||
|
'id' => $this->primaryKey(), |
||||||
|
'page_id' => $this->integer()->notNull(), |
||||||
|
'language' => $this->string(6)->notNull(), |
||||||
|
'title' => $this->string(255), |
||||||
|
'content' => 'MEDIUMTEXT', |
||||||
|
], $tableOptions); |
||||||
|
|
||||||
|
$this->createIndex('idx_pages_lng_language', '{{%pages_lng}}', 'language'); |
||||||
|
$this->createIndex('idx_pages_lng_page_id', '{{%pages_lng}}', 'page_id'); |
||||||
|
$this->addForeignKey('frg_pages_lng_pages_page_id_id', '{{%pages_lng}}', 'page_id', '{{%pages}}', 'id', 'CASCADE', 'CASCADE'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->dropForeignKey('frg_pages_lng_pages_page_id_id', '{{%pages_lng}}'); |
||||||
|
$this->dropColumn('idx_pages_lng_page_id', '{{%pages_lng}}'); |
||||||
|
$this->dropColumn('idx_pages_lng_language', '{{%pages_lng}}'); |
||||||
|
$this->dropTable('{{%pages_lng}}'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180825_155812_add_pages_lng_meta_json_field |
||||||
|
*/ |
||||||
|
class m180825_155812_add_pages_lng_meta_json_field extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$this->addColumn('{{%pages_lng}}', 'meta_json', $this->text()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->dropColumn('{{%pages_lng}}', 'meta_json'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180825_183752_add_pages_pages_lng_meta_fields |
||||||
|
*/ |
||||||
|
class m180825_183752_add_pages_pages_lng_meta_fields extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$this->addColumn('{{%pages_lng}}', 'meta_title', $this->string()); |
||||||
|
$this->addColumn('{{%pages_lng}}', 'meta_description', $this->text()); |
||||||
|
$this->addColumn('{{%pages_lng}}', 'meta_keywords', $this->string()); |
||||||
|
|
||||||
|
$this->dropColumn('{{%pages}}', 'meta_json'); |
||||||
|
$this->dropColumn('{{%pages_lng}}', 'meta_json'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->dropColumn('{{%pages_lng}}', 'meta_title'); |
||||||
|
$this->dropColumn('{{%pages_lng}}', 'meta_description'); |
||||||
|
$this->dropColumn('{{%pages_lng}}', 'meta_keywords'); |
||||||
|
|
||||||
|
$this->addColumn('{{%pages}}', 'meta_json', $this->text()); |
||||||
|
$this->addColumn('{{%pages_lng}}', 'meta_json', $this->text()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180826_083923_remove_pages_title_content_fields |
||||||
|
*/ |
||||||
|
class m180826_083923_remove_pages_title_content_fields extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$this->dropColumn('{{%pages}}', 'title'); |
||||||
|
$this->dropColumn('{{%pages}}', 'content'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->addColumn('{{%pages}}', 'title', $this->string(255)->notNull()); |
||||||
|
$this->addColumn('{{%pages}}', 'title', 'MEDIUMTEXT'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180827_195748_set_pages_unicode_collate |
||||||
|
*/ |
||||||
|
class m180827_195748_set_pages_unicode_collate extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$tables = ['pages_lng']; |
||||||
|
$db = Yii::$app->getDb(); |
||||||
|
$db->createCommand('SET FOREIGN_KEY_CHECKS=0;')->execute(); |
||||||
|
|
||||||
|
foreach ($tables as $table) { |
||||||
|
$db->createCommand( "ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci" )->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
$db->createCommand('SET FOREIGN_KEY_CHECKS=1;')->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 24.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
use zertex\ckeditor\CKEditor; |
||||||
|
|
||||||
|
/** |
||||||
|
* @var $this \yii\web\View |
||||||
|
* @var $form \yii\widgets\ActiveForm |
||||||
|
* @var $model \common\modules\pages\forms\PageForm |
||||||
|
* @var $language string |
||||||
|
*/ |
||||||
|
|
||||||
|
$postfix = $language == Yii::$app->params['defaultLanguage'] ? '' : '_' . $language; |
||||||
|
?> |
||||||
|
|
||||||
|
<?= $form->field($model, 'title' . $postfix)->textInput(['maxlength' => true]) ?> |
||||||
|
<?= $form->field($model, 'content' . $postfix)->widget(CKEditor::class) ?> |
||||||
|
|
||||||
|
<div class="box box-default"> |
||||||
|
<div class="box-header with-border"><?= Yii::t('pages', 'SEO') ?></div>
|
||||||
|
<div class="box-body"> |
||||||
|
<?= $form->field($model, 'meta_title' . $postfix)->textInput() ?> |
||||||
|
<?= $form->field($model, 'meta_description' . $postfix)->textarea(['rows' => 2]) ?> |
||||||
|
<?= $form->field($model, 'meta_keywords' . $postfix)->textInput() ?> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,71 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 25.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
use yii\widgets\DetailView; |
||||||
|
use common\modules\pages\entities\Page; |
||||||
|
|
||||||
|
/** |
||||||
|
* @var $this \yii\web\View |
||||||
|
* @var $page \common\modules\pages\entities\Page |
||||||
|
* @var $language string |
||||||
|
*/ |
||||||
|
|
||||||
|
?> |
||||||
|
|
||||||
|
<?= DetailView::widget([ |
||||||
|
'model' => $page, |
||||||
|
'attributes' => [ |
||||||
|
[ |
||||||
|
'label' => Yii::t('pages', 'Title'), |
||||||
|
'value' => function(Page $entity) use ($language) { |
||||||
|
return $entity->findTranslation($language)->title; |
||||||
|
} |
||||||
|
], |
||||||
|
], |
||||||
|
]) ?> |
||||||
|
|
||||||
|
<div class="box"> |
||||||
|
<div class="box-header with-border"><?= Yii::t('pages', 'SEO') ?></div>
|
||||||
|
<div class="box-body"> |
||||||
|
|
||||||
|
<?= DetailView::widget([ |
||||||
|
'model' => $page, |
||||||
|
'attributes' => [ |
||||||
|
[ |
||||||
|
'label' => Yii::t('pages', 'META Title'), |
||||||
|
'value' => function(Page $entity) use ($language) { |
||||||
|
return $entity->findTranslation($language)->meta_title; |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
'label' => Yii::t('pages', 'META Description'), |
||||||
|
'value' => function(Page $entity) use ($language) { |
||||||
|
return $entity->findTranslation($language)->meta_description; |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
'label' => Yii::t('pages', 'META Keywords'), |
||||||
|
'value' => function(Page $entity) use ($language) { |
||||||
|
return $entity->findTranslation($language)->meta_keywords; |
||||||
|
} |
||||||
|
], |
||||||
|
], |
||||||
|
]) ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="box"> |
||||||
|
<div class="box-header with-border"><?= Yii::t('pages', 'Content') ?></div>
|
||||||
|
<div class="box-body"> |
||||||
|
<?= Yii::$app->formatter->asHtml($page->findTranslation($language)->content, [ |
||||||
|
'Attr.AllowedRel' => array('nofollow'), |
||||||
|
'HTML.SafeObject' => true, |
||||||
|
'Output.FlashCompat' => true, |
||||||
|
'HTML.SafeIframe' => true, |
||||||
|
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%', |
||||||
|
]) ?> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,42 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Handles the creation of table `menu_lng`. |
||||||
|
*/ |
||||||
|
class m180824_081717_create_menu_lng_table extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$tableOptions = null; |
||||||
|
if ($this->db->driverName === 'mysql') { |
||||||
|
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; |
||||||
|
} |
||||||
|
|
||||||
|
$this->createTable('{{%menu_lng}}', [ |
||||||
|
'id' => $this->primaryKey(), |
||||||
|
'menu_id' => $this->integer()->notNull(), |
||||||
|
'language' => $this->string(6)->notNull(), |
||||||
|
'name' => $this->string(255)->notNull(), |
||||||
|
], $tableOptions); |
||||||
|
|
||||||
|
$this->createIndex('idx_menu_lng_language', '{{%menu_lng}}', 'language'); |
||||||
|
$this->createIndex('idx_menu_lng_menu_id', '{{%menu_lng}}', 'menu_id'); |
||||||
|
$this->addForeignKey('frg_menu_lng_menu_menu_id_id', '{{%menu_lng}}', 'menu_id', '{{%menu}}', 'id', 'CASCADE', 'CASCADE'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->dropForeignKey('frg_menu_lng_menu_menu_id_id', '{{%menu_lng}}'); |
||||||
|
$this->dropColumn('idx_menu_lng_menu_id', '{{%menu_lng}}'); |
||||||
|
$this->dropColumn('idx_menu_lng_language', '{{%menu_lng}}'); |
||||||
|
$this->dropTable('{{%menu_lng}}'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180826_171901_remove_menu_name_field |
||||||
|
*/ |
||||||
|
class m180826_171901_remove_menu_name_field extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$this->dropColumn('{{%menu}}', 'name'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->addColumn('{{%menu}}', 'name', $this->string(255)->notNull()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Handles the creation of table `menu_items_lng_lng`. |
||||||
|
*/ |
||||||
|
class m180826_204039_create_menu_items_lng_lng_table extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$tableOptions = null; |
||||||
|
if ($this->db->driverName === 'mysql') { |
||||||
|
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; |
||||||
|
} |
||||||
|
|
||||||
|
$this->createTable('{{%menu_items_lng}}', [ |
||||||
|
'id' => $this->primaryKey(), |
||||||
|
'menu_item_id' => $this->integer()->notNull(), |
||||||
|
'language' => $this->string(6)->notNull(), |
||||||
|
'name' => $this->string(255)->notNull(), |
||||||
|
'title_attr' => $this->string(255), |
||||||
|
], $tableOptions); |
||||||
|
|
||||||
|
$this->createIndex('idx_menu_items_lng_language', '{{%menu_items_lng}}', 'language'); |
||||||
|
$this->createIndex('idx_menu_items_lng_page_id', '{{%menu_items_lng}}', 'menu_item_id'); |
||||||
|
$this->addForeignKey('frg_menu_items_lng_menu_items_menu_item_id_id', '{{%menu_items_lng}}', 'menu_item_id', '{{%menu_items}}', 'id', 'CASCADE', 'CASCADE'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->dropForeignKey('frg_menu_items_lng_menu_items_menu_item_id_id', '{{%menu_items_lng}}'); |
||||||
|
$this->dropColumn('idx_menu_items_lng_page_id', '{{%menu_items_lng}}'); |
||||||
|
$this->dropColumn('idx_menu_items_lng_language', '{{%menu_items_lng}}'); |
||||||
|
$this->dropTable('{{%menu_items_lng}}'); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180826_215830_remove_menu_items_name_title_attr_fields |
||||||
|
*/ |
||||||
|
class m180826_215830_remove_menu_items_name_title_attr_fields extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$this->dropColumn('{{%menu_items}}', 'name'); |
||||||
|
$this->dropColumn('{{%menu_items}}', 'title_attr'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
$this->addColumn('{{%menu_items}}', 'name', $this->string(255)->notNull()); |
||||||
|
$this->addColumn('{{%menu_items}}', 'title_attr', $this->string(255)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use yii\db\Migration; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class m180827_194913_set_core_tables_unicode_oollate |
||||||
|
*/ |
||||||
|
class m180827_194913_set_core_tables_unicode_oollate extends Migration |
||||||
|
{ |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeUp() |
||||||
|
{ |
||||||
|
$tables = ['user_networks', 'settings', 'modules', 'menu', 'menu_items', 'menu_lng', 'menu_items_lng']; |
||||||
|
$db = Yii::$app->getDb(); |
||||||
|
$db->createCommand('SET FOREIGN_KEY_CHECKS=0;')->execute(); |
||||||
|
|
||||||
|
foreach ($tables as $table) { |
||||||
|
$db->createCommand( "ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci" )->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
$db->createCommand('SET FOREIGN_KEY_CHECKS=1;')->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function safeDown() |
||||||
|
{ |
||||||
|
true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,351 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 24.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace core\behaviors; |
||||||
|
|
||||||
|
use yii\base\Behavior; |
||||||
|
use yii\base\InvalidConfigException; |
||||||
|
use yii\db\ActiveRecord; |
||||||
|
use yii\db\ActiveQuery; |
||||||
|
|
||||||
|
class LanguageBehavior extends Behavior |
||||||
|
{ |
||||||
|
/** |
||||||
|
* Attributes for translate, ex.: ['name', 'content'] |
||||||
|
* @var array |
||||||
|
*/ |
||||||
|
public $attributes; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class name for language active record entity |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
public $virtualClassName = 'VirtualTranslate'; |
||||||
|
|
||||||
|
/** |
||||||
|
* Field name for language in translate table |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
public $languageField = 'language'; |
||||||
|
|
||||||
|
/** |
||||||
|
* Field name for tables relative, ex.: 'post_id' |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
public $relativeField; |
||||||
|
|
||||||
|
/** |
||||||
|
* Available languages, ex.: ['en', 'ru'] |
||||||
|
* @var array |
||||||
|
*/ |
||||||
|
public $translatedLanguages; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default language, ex.: 'en' |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
public $defaultLanguage; |
||||||
|
|
||||||
|
/** |
||||||
|
* Translate table name, ex.: 'post_lng' |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
public $tableName; |
||||||
|
|
||||||
|
/** |
||||||
|
* Abridge the language ID. |
||||||
|
* @var boolean whether to abridge the language ID. |
||||||
|
*/ |
||||||
|
public $abridge = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* Delete relative if foreign key not set on delete: cascade |
||||||
|
* @var bool |
||||||
|
*/ |
||||||
|
public $forceDelete = false; |
||||||
|
|
||||||
|
private $ownerClassName; |
||||||
|
private $ownerClassShortName; |
||||||
|
private $ownerPrimaryKey; |
||||||
|
private $languageAttributes = []; |
||||||
|
|
||||||
|
/** |
||||||
|
* Control events firing |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function events() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
ActiveRecord::EVENT_AFTER_FIND => 'afterFind', |
||||||
|
ActiveRecord::EVENT_AFTER_UPDATE => 'afterUpdate', |
||||||
|
ActiveRecord::EVENT_AFTER_INSERT => 'afterInsert', |
||||||
|
ActiveRecord::EVENT_AFTER_DELETE => 'afterDelete', |
||||||
|
//ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate', |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
public function attach( $owner ) { |
||||||
|
/** @var ActiveRecord $owner */ |
||||||
|
parent::attach($owner); |
||||||
|
if (empty($this->translatedLanguages) || !is_array($this->translatedLanguages)) { |
||||||
|
throw new InvalidConfigException('Please specify array of available languages for the ' . get_class($this) . ' in the ' |
||||||
|
. get_class($this->owner) . ' or in the application parameters', 101); |
||||||
|
} |
||||||
|
|
||||||
|
if (array_values($this->translatedLanguages) !== $this->translatedLanguages) { //associative array |
||||||
|
$this->translatedLanguages = array_keys($this->translatedLanguages); |
||||||
|
} |
||||||
|
|
||||||
|
if (!$this->defaultLanguage) { |
||||||
|
throw new InvalidConfigException('Please specify default language for the ' . get_class($this)); |
||||||
|
} |
||||||
|
|
||||||
|
if (empty($this->attributes) || !is_array($this->attributes)) { |
||||||
|
throw new InvalidConfigException('Please specify translated attributes for the ' . get_class($this) . ' in the ' |
||||||
|
. get_class($this->owner), 103); |
||||||
|
} |
||||||
|
|
||||||
|
$this->ownerClassName = get_class($this->owner); |
||||||
|
$this->ownerClassShortName = $this->getShortClassName($this->ownerClassName); |
||||||
|
|
||||||
|
/** @var ActiveRecord $className */ |
||||||
|
$className = $this->ownerClassName; |
||||||
|
$this->ownerPrimaryKey = $className::primaryKey()[0]; |
||||||
|
|
||||||
|
if (!isset($this->relativeField)) { |
||||||
|
throw new InvalidConfigException('Please specify relativeField for the ' . get_class($this) . ' in the ' |
||||||
|
. get_class($this->owner), 105); |
||||||
|
} |
||||||
|
|
||||||
|
//$rules = $owner->rules(); |
||||||
|
//$validators = $owner->getValidators(); |
||||||
|
/*foreach ($rules as $rule) { |
||||||
|
if (in_array($rule[1], $this->excludedValidators)) |
||||||
|
continue; |
||||||
|
$rule_attributes = is_array($rule[0]) ? $rule[0] : [$rule[0]]; |
||||||
|
$attributes = array_intersect($this->attributes, $rule_attributes); |
||||||
|
if (empty($attributes)) |
||||||
|
continue; |
||||||
|
$rule_attributes = []; |
||||||
|
foreach ($attributes as $key => $attribute) { |
||||||
|
foreach ($this->languages as $language) |
||||||
|
if ($language != $this->defaultLanguage) |
||||||
|
$rule_attributes[] = $this->getAttributeName($attribute, $language); |
||||||
|
} |
||||||
|
if (isset($rule['skipOnEmpty']) && !$rule['skipOnEmpty']) |
||||||
|
$rule['skipOnEmpty'] = !$this->requireTranslations; |
||||||
|
$params = array_slice($rule, 2); |
||||||
|
if ($rule[1] !== 'required' || $this->requireTranslations) { |
||||||
|
$validators[] = Validator::createValidator($rule[1], $owner, $rule_attributes, $params); |
||||||
|
} elseif ($rule[1] === 'required') { |
||||||
|
$validators[] = Validator::createValidator('safe', $owner, $rule_attributes, $params); |
||||||
|
} |
||||||
|
}*/ |
||||||
|
|
||||||
|
$this->createLanguageClass(); |
||||||
|
$translation = new $this->virtualClassName; |
||||||
|
|
||||||
|
foreach ($this->translatedLanguages as $language) { |
||||||
|
foreach ($this->attributes as $attribute) { |
||||||
|
$attributeName = $attribute; |
||||||
|
$this->setLanguageAttribute($attribute . '_' . $language, $translation->{$attributeName}); |
||||||
|
|
||||||
|
//$this->owner->__set($attribute . '_' . $language, $translation->{$attributeName}); |
||||||
|
//$this->owner->{$attribute . '_' . $language} = $translation->{$attributeName}; |
||||||
|
//$this->owner->createProperty($attribute . '_' . $language, $translation->{$attributeName}); |
||||||
|
|
||||||
|
if ($language == $this->defaultLanguage) { |
||||||
|
$this->setLanguageAttribute($attribute, $translation->{$attributeName}); |
||||||
|
//$this->owner->__set($attribute, $translation->{$attributeName}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Insert event |
||||||
|
*/ |
||||||
|
public function afterInsert() |
||||||
|
{ |
||||||
|
$this->saveTranslations(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Update event |
||||||
|
*/ |
||||||
|
public function afterUpdate() |
||||||
|
{ |
||||||
|
/** @var ActiveRecord $owner */ |
||||||
|
$owner = $this->owner; |
||||||
|
if ($owner->isRelationPopulated('translations')) { |
||||||
|
$translations = $this->indexByLanguage($owner->getRelatedRecords()['translations']); |
||||||
|
$this->saveTranslations($translations); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Find event |
||||||
|
*/ |
||||||
|
public function afterFind() |
||||||
|
{ |
||||||
|
/** @var ActiveRecord $owner */ |
||||||
|
$owner = $this->owner; |
||||||
|
if ($owner->isRelationPopulated('translations') && $related = $owner->getRelatedRecords()['translations']) { |
||||||
|
$translations = $this->indexByLanguage($related); |
||||||
|
foreach ($this->translatedLanguages as $language) { |
||||||
|
foreach ($this->attributes as $attribute) { |
||||||
|
foreach ($translations as $translation) { |
||||||
|
if ($translation->{$this->languageField} == $language) { |
||||||
|
$attributeName = $attribute; |
||||||
|
$this->setLanguageAttribute($attribute . '_' . $language, $translation->{$attributeName}); |
||||||
|
if ($language == $this->defaultLanguage) { |
||||||
|
$this->setLanguageAttribute($attribute, $translation->{$attributeName}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (!$owner->isRelationPopulated('translation')) { |
||||||
|
$owner->translation; |
||||||
|
} |
||||||
|
$translation = $owner->getRelatedRecords()['translation']; |
||||||
|
if ($translation) { |
||||||
|
foreach ($this->attributes as $attribute) { |
||||||
|
$attribute_name = $attribute; |
||||||
|
$owner->setLanguageAttribute($attribute, $translation->$attribute_name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
foreach ($this->attributes as $attribute) { |
||||||
|
if ($owner->hasAttribute($attribute) && $this->getLangAttribute($attribute)) { |
||||||
|
$owner->setAttribute($attribute, $this->getLangAttribute($attribute)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function afterDelete() |
||||||
|
{ |
||||||
|
if ($this->forceDelete) { |
||||||
|
/** @var ActiveRecord $owner */ |
||||||
|
$owner = $this->owner; |
||||||
|
$owner->unlinkAll('translations', true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function createLanguageClass() |
||||||
|
{ |
||||||
|
if (!class_exists($this->virtualClassName, false)) { |
||||||
|
eval(' |
||||||
|
use yii\db\ActiveRecord; |
||||||
|
class ' . $this->virtualClassName . ' extends ActiveRecord |
||||||
|
{ |
||||||
|
public static function tableName() |
||||||
|
{ |
||||||
|
return \'' . $this->tableName . '\'; |
||||||
|
} |
||||||
|
}'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function saveTranslations($translations = []) |
||||||
|
{ |
||||||
|
/** @var ActiveRecord $owner */ |
||||||
|
$owner = $this->owner; |
||||||
|
foreach ($this->translatedLanguages as $language) { |
||||||
|
$isDefaultLanguage = $language == $this->defaultLanguage; |
||||||
|
if (!isset($translations[$language])) { |
||||||
|
/** @var ActiveRecord $translation */ |
||||||
|
$translation = new $this->virtualClassName; |
||||||
|
$translation->{$this->languageField} = $language; |
||||||
|
$translation->{$this->relativeField} = $owner->getPrimaryKey(); |
||||||
|
} else { |
||||||
|
$translation = $translations[$language]; |
||||||
|
} |
||||||
|
$save = false; |
||||||
|
foreach ($this->attributes as $attribute) { |
||||||
|
//$value = $isDefaultLanguage ? $owner->$attribute : $owner->{$attribute . '_' . $language}; |
||||||
|
$value = $isDefaultLanguage ? $owner->_form->$attribute : $owner->_form->{$attribute . '_' . $language}; |
||||||
|
if ($value !== null) { |
||||||
|
//$field = $isDefaultLanguage ? $attribute : $attribute . '_' . $language; |
||||||
|
$field = $attribute; |
||||||
|
$translation->$field = $value; |
||||||
|
$save = true; |
||||||
|
} |
||||||
|
} |
||||||
|
if ($translation->isNewRecord && !$save) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
$translation->save(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function getShortClassName($className) |
||||||
|
{ |
||||||
|
return substr($className, strrpos($className, '\\') + 1); |
||||||
|
} |
||||||
|
|
||||||
|
public function setLanguageAttribute($name, $value) |
||||||
|
{ |
||||||
|
$this->languageAttributes[$name] = $value; |
||||||
|
} |
||||||
|
|
||||||
|
protected function indexByLanguage(array $records) |
||||||
|
{ |
||||||
|
$sorted = []; |
||||||
|
foreach ($records as $record) { |
||||||
|
$sorted[$record->{$this->languageField}] = $record; |
||||||
|
} |
||||||
|
unset($records); |
||||||
|
return $sorted; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Relation to model translations |
||||||
|
* @return ActiveQuery |
||||||
|
*/ |
||||||
|
public function getTranslations() |
||||||
|
{ |
||||||
|
/** @var ActiveRecord */ |
||||||
|
return $this->owner->hasMany($this->virtualClassName, [$this->relativeField => $this->ownerPrimaryKey]); |
||||||
|
} |
||||||
|
|
||||||
|
public function getTranslation($language = null) |
||||||
|
{ |
||||||
|
$language = $language ?: \Yii::$app->language; |
||||||
|
// if translate exists |
||||||
|
$translate = $this->virtualClassName::find() |
||||||
|
->andWhere([$this->relativeField => $this->owner->id]) |
||||||
|
->andWhere([$this->languageField => $language]) |
||||||
|
->one(); |
||||||
|
|
||||||
|
$language = $translate ? $language : \Yii::$app->params['defaultLanguage']; |
||||||
|
|
||||||
|
return $this->owner->hasOne($this->virtualClassName, [$this->relativeField => $this->ownerPrimaryKey]) |
||||||
|
->where([$this->languageField => $language]); |
||||||
|
} |
||||||
|
|
||||||
|
public function findTranslation($language = null) |
||||||
|
{ |
||||||
|
$language = $language ?: \Yii::$app->language; |
||||||
|
//$class = call_user_func(array($this->virtualClassName, 'getInstance')); |
||||||
|
return $this->virtualClassName::find() |
||||||
|
->andWhere([$this->relativeField => $this->owner->id]) |
||||||
|
->andWhere([$this->languageField => $language]) |
||||||
|
->one(); |
||||||
|
} |
||||||
|
|
||||||
|
public function hasLangAttribute($name) |
||||||
|
{ |
||||||
|
return array_key_exists($name, $this->languageAttributes); |
||||||
|
} |
||||||
|
|
||||||
|
public function getLangAttribute($name) |
||||||
|
{ |
||||||
|
return $this->hasLangAttribute($name) ? $this->languageAttributes[$name] : null; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 24.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace core\components; |
||||||
|
|
||||||
|
|
||||||
|
use yii\base\DynamicModel; |
||||||
|
use Yii; |
||||||
|
|
||||||
|
class LanguageDynamicModel extends DynamicModel |
||||||
|
{ |
||||||
|
private $new_labels = []; |
||||||
|
private $new_hints = []; |
||||||
|
private $new_rules = []; |
||||||
|
|
||||||
|
public function __construct( array $attributes = [], array $config = [] ) |
||||||
|
{ |
||||||
|
parent::__construct( array_merge($this->getPublicAttributes(), $this->prepareLanguageAttributes()), $config ); |
||||||
|
} |
||||||
|
|
||||||
|
private function prepareLanguageAttributes() |
||||||
|
{ |
||||||
|
$language_attributes = []; |
||||||
|
$labels = $this->attributeLabels(); |
||||||
|
$hints = $this->attributeHints(); |
||||||
|
foreach ($this->rules() as $rule) { |
||||||
|
$attributes = is_array($rule[0]) ? $rule[0] : [$rule[0]]; |
||||||
|
$type = $rule[1]; |
||||||
|
if ($type == 'string') { |
||||||
|
foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) { |
||||||
|
$rule_attributes = []; |
||||||
|
foreach ($attributes as $attribute) { |
||||||
|
// add attribute |
||||||
|
$language_attributes[] = $attribute . '_' . $language; |
||||||
|
$this->new_labels[$attribute . '_' . $language] = isset($labels[$attribute]) ? $labels[$attribute] : null; |
||||||
|
$this->new_hints[$attribute . '_' . $language] = isset($hints[$attribute]) ? $hints[$attribute] : null; |
||||||
|
$rule_attributes[] = $attribute . '_' . $language; |
||||||
|
} |
||||||
|
// add rule |
||||||
|
if (!empty($rule_attributes)) { |
||||||
|
$this->new_rules[] = [ $rule_attributes, $rule[1] ]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return $language_attributes; |
||||||
|
} |
||||||
|
|
||||||
|
public function attributeLabels(){ |
||||||
|
return $this->new_labels; |
||||||
|
} |
||||||
|
|
||||||
|
public function rules() { |
||||||
|
return $this->new_rules; |
||||||
|
} |
||||||
|
|
||||||
|
public function getPublicAttributes () { |
||||||
|
return call_user_func('get_object_vars', $this); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 26.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace core\components; |
||||||
|
|
||||||
|
|
||||||
|
use yii\db\ActiveQuery; |
||||||
|
|
||||||
|
class LanguageTranslateQuery extends ActiveQuery |
||||||
|
{ |
||||||
|
use LanguageTranslateTrait; |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 26.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace core\components; |
||||||
|
|
||||||
|
use yii\db\ActiveQuery; |
||||||
|
use Yii; |
||||||
|
|
||||||
|
/** |
||||||
|
* Translate trait. |
||||||
|
* Modify ActiveRecord query for translate support |
||||||
|
* |
||||||
|
* @mixin ActiveQuery |
||||||
|
*/ |
||||||
|
trait LanguageTranslateTrait |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var string the name of the lang field of the translation table. Default to 'language'. |
||||||
|
*/ |
||||||
|
public $languageField = 'language'; |
||||||
|
/** |
||||||
|
* Scope for querying by languages |
||||||
|
* |
||||||
|
* @param string $language |
||||||
|
* @param bool $abridge |
||||||
|
* |
||||||
|
* @return $this |
||||||
|
*/ |
||||||
|
public function localized($language = null, $abridge = true) |
||||||
|
{ |
||||||
|
$language = $language ?: Yii::$app->language; |
||||||
|
if (!isset($this->with['translations'])) { |
||||||
|
$this->with(['translation' => function ($query) use ($language, $abridge) { |
||||||
|
/** @var ActiveQuery $query */ |
||||||
|
$query->where([$this->languageField => $abridge ? substr($language, 0, 2) : $language]); |
||||||
|
}]); |
||||||
|
} |
||||||
|
return $this; |
||||||
|
} |
||||||
|
/** |
||||||
|
* Scope for querying by all languages |
||||||
|
* @return $this |
||||||
|
*/ |
||||||
|
public function multilingual() |
||||||
|
{ |
||||||
|
if (isset($this->with['translation'])) { |
||||||
|
unset($this->with['translation']); |
||||||
|
} |
||||||
|
$this->with('translations'); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 24.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace core\components; |
||||||
|
|
||||||
|
|
||||||
|
class TestForm extends LanguageDynamicModel |
||||||
|
{ |
||||||
|
public $name; |
||||||
|
public $content; |
||||||
|
public $number; |
||||||
|
|
||||||
|
public function rules() { |
||||||
|
return array_merge( |
||||||
|
parent::rules(), |
||||||
|
[ |
||||||
|
[['name', 'content'], 'required'], |
||||||
|
['name', 'string', 'max' => 50], |
||||||
|
['content', 'string'], |
||||||
|
['number', 'integer'], |
||||||
|
] |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
public function attributeLabels() { |
||||||
|
return array_merge( |
||||||
|
parent::attributeLabels(), |
||||||
|
[ |
||||||
|
'name' => \Yii::t('main', 'Name'), |
||||||
|
'content' => \Yii::t('main', 'Key'), |
||||||
|
'number' => \Yii::t('main', 'Value'), |
||||||
|
] |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace core\forms; |
||||||
|
|
||||||
|
use core\components\LanguageDynamicModel; |
||||||
|
use yii\base\Model; |
||||||
|
use yii\helpers\ArrayHelper; |
||||||
|
|
||||||
|
abstract class CompositeLanguageForm extends LanguageDynamicModel |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @var Model[]|array[] |
||||||
|
*/ |
||||||
|
private $forms = []; |
||||||
|
|
||||||
|
abstract protected function internalForms(): array; |
||||||
|
|
||||||
|
public function load($data, $formName = null): bool |
||||||
|
{ |
||||||
|
$success = parent::load($data, $formName); |
||||||
|
foreach ($this->forms as $name => $form) { |
||||||
|
if (is_array($form)) { |
||||||
|
$success = Model::loadMultiple($form, $data, $formName === null ? null : $name) && $success; |
||||||
|
} else { |
||||||
|
$success = $form->load($data, $formName !== '' ? null : $name) && $success; |
||||||
|
} |
||||||
|
} |
||||||
|
return $success; |
||||||
|
} |
||||||
|
|
||||||
|
public function validate($attributeNames = null, $clearErrors = true): bool |
||||||
|
{ |
||||||
|
$parentNames = $attributeNames !== null ? array_filter((array)$attributeNames, 'is_string') : null; |
||||||
|
$success = parent::validate($parentNames, $clearErrors); |
||||||
|
foreach ($this->forms as $name => $form) { |
||||||
|
if (is_array($form)) { |
||||||
|
$success = Model::validateMultiple($form) && $success; |
||||||
|
} else { |
||||||
|
$innerNames = $attributeNames !== null ? ArrayHelper::getValue($attributeNames, $name) : null; |
||||||
|
$success = $form->validate($innerNames ?: null, $clearErrors) && $success; |
||||||
|
} |
||||||
|
} |
||||||
|
return $success; |
||||||
|
} |
||||||
|
|
||||||
|
public function hasErrors($attribute = null): bool |
||||||
|
{ |
||||||
|
if ($attribute !== null) { |
||||||
|
return parent::hasErrors($attribute); |
||||||
|
} |
||||||
|
if (parent::hasErrors($attribute)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
foreach ($this->forms as $name => $form) { |
||||||
|
if (is_array($form)) { |
||||||
|
foreach ($form as $i => $item) { |
||||||
|
if ($item->hasErrors()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
if ($form->hasErrors()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public function getFirstErrors(): array |
||||||
|
{ |
||||||
|
$errors = parent::getFirstErrors(); |
||||||
|
foreach ($this->forms as $name => $form) { |
||||||
|
if (is_array($form)) { |
||||||
|
foreach ($form as $i => $item) { |
||||||
|
foreach ($item->getFirstErrors() as $attribute => $error) { |
||||||
|
$errors[$name . '.' . $i . '.' . $attribute] = $error; |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
foreach ($form->getFirstErrors() as $attribute => $error) { |
||||||
|
$errors[$name . '.' . $attribute] = $error; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return $errors; |
||||||
|
} |
||||||
|
|
||||||
|
public function __get($name) |
||||||
|
{ |
||||||
|
if (isset($this->forms[$name])) { |
||||||
|
return $this->forms[$name]; |
||||||
|
} |
||||||
|
return parent::__get($name); |
||||||
|
} |
||||||
|
|
||||||
|
public function __set($name, $value) |
||||||
|
{ |
||||||
|
if (in_array($name, $this->internalForms(), true)) { |
||||||
|
$this->forms[$name] = $value; |
||||||
|
} else { |
||||||
|
parent::__set($name, $value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function __isset($name) |
||||||
|
{ |
||||||
|
return isset($this->forms[$name]) || parent::__isset($name); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace core\forms; |
||||||
|
|
||||||
|
use core\entities\Meta; |
||||||
|
use yii\base\Model; |
||||||
|
use Yii; |
||||||
|
|
||||||
|
class MetaFormOrg extends Model |
||||||
|
{ |
||||||
|
public $title; |
||||||
|
public $description; |
||||||
|
public $keywords; |
||||||
|
|
||||||
|
public function __construct(Meta $meta = null, $config = []) |
||||||
|
{ |
||||||
|
if ($meta) { |
||||||
|
$this->title = $meta->title; |
||||||
|
$this->description = $meta->description; |
||||||
|
$this->keywords = $meta->keywords; |
||||||
|
} |
||||||
|
parent::__construct($config); |
||||||
|
} |
||||||
|
|
||||||
|
public function rules(): array |
||||||
|
{ |
||||||
|
return [ |
||||||
|
[['title'], 'string', 'max' => 255], |
||||||
|
[['description', 'keywords'], 'string'], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
public function attributeLabels() { |
||||||
|
return [ |
||||||
|
'title' => Yii::t('main', 'Title'), |
||||||
|
'description' => Yii::t('main', 'Description'), |
||||||
|
'keywords' => Yii::t('main', 'Keywords'), |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,119 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 23.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace core\helpers; |
||||||
|
|
||||||
|
use common\modules\pages\forms\PageForm; |
||||||
|
use Yii; |
||||||
|
use yii\base\DynamicModel; |
||||||
|
|
||||||
|
class LanguageHelper |
||||||
|
{ |
||||||
|
public static function enabled() |
||||||
|
{ |
||||||
|
return count(Yii::$app->params['translatedLanguages']) > 1; |
||||||
|
} |
||||||
|
|
||||||
|
public static function suffixList() |
||||||
|
{ |
||||||
|
$list = array(); |
||||||
|
$enabled = self::enabled(); |
||||||
|
|
||||||
|
foreach (Yii::$app->params['translatedLanguages'] as $lang => $name) { |
||||||
|
if ($lang === Yii::$app->params['defaultLanguage']) { |
||||||
|
$suffix = ''; |
||||||
|
$list[$suffix] = $enabled ? $name : ''; |
||||||
|
} else { |
||||||
|
$suffix = '_' . $lang; |
||||||
|
$list[$suffix] = $name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $list; |
||||||
|
} |
||||||
|
|
||||||
|
public static function isLangExists($url): bool |
||||||
|
{ |
||||||
|
$index = self::_getLangIndex(); |
||||||
|
$domains = explode('/', ltrim($url, '/')); |
||||||
|
return in_array($domains[$index], array_keys(Yii::$app->params['translatedLanguages'])); |
||||||
|
} |
||||||
|
|
||||||
|
public static function setLanguage($url) |
||||||
|
{ |
||||||
|
$index = self::_getLangIndex(); |
||||||
|
$domains = explode('/', ltrim($url, '/')); |
||||||
|
$isLangExists = in_array($domains[$index], array_keys(Yii::$app->params['translatedLanguages'])); |
||||||
|
if ($isLangExists) { |
||||||
|
Yii::$app->language = $domains[$index]; |
||||||
|
} |
||||||
|
else { |
||||||
|
Yii::$app->language = Yii::$app->params['defaultLanguage']; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static function processLangInUrl($url): string |
||||||
|
{ |
||||||
|
if (self::enabled()) { |
||||||
|
$index = self::_getLangIndex(); |
||||||
|
$domains = explode('/', ltrim($url, '/')); |
||||||
|
$isLangExists = in_array($domains[$index], array_keys(Yii::$app->params['translatedLanguages'])); |
||||||
|
$isDefaultLang = $domains[$index] == Yii::$app->params['defaultLanguage']; |
||||||
|
|
||||||
|
if ($isLangExists && !$isDefaultLang) { |
||||||
|
array_splice($domains, $index, 1); |
||||||
|
} |
||||||
|
$url = '/' . implode('/', $domains); |
||||||
|
} |
||||||
|
return $url; |
||||||
|
} |
||||||
|
|
||||||
|
public static function addLangToUrl($url, $language = null): string |
||||||
|
{ |
||||||
|
if (self::enabled()) { |
||||||
|
$index = self::_getLangIndex(); |
||||||
|
$domains = explode('/', ltrim($url, '/')); |
||||||
|
$isHasLang = in_array($language ?: $domains[$index], array_keys(Yii::$app->params['translatedLanguages'])); |
||||||
|
$isDefaultLang = $language ? $language == Yii::$app->params['defaultLanguage'] : Yii::$app->language == Yii::$app->params['defaultLanguage']; |
||||||
|
|
||||||
|
if ($isHasLang && $isDefaultLang) { |
||||||
|
array_splice($domains, $index, 1); |
||||||
|
} |
||||||
|
|
||||||
|
if (!$isHasLang && !$isDefaultLang) { |
||||||
|
array_splice($domains, $index, 0, Yii::$app->language); |
||||||
|
} |
||||||
|
|
||||||
|
$domains = array_filter($domains); |
||||||
|
$url = '/' . implode('/', $domains); |
||||||
|
} |
||||||
|
return $url; |
||||||
|
} |
||||||
|
|
||||||
|
public static function getName($language) |
||||||
|
{ |
||||||
|
return isset(Yii::$app->params['translatedLanguages'][$language]) ? Yii::$app->params['translatedLanguages'][$language] : $language; |
||||||
|
} |
||||||
|
|
||||||
|
public static function getBackendName($language) |
||||||
|
{ |
||||||
|
return isset(Yii::$app->params['backendTranslatedLanguages'][$language]) ? Yii::$app->params['backendTranslatedLanguages'][$language] : Yii::$app->params['backendTranslatedLanguages'][Yii::$app->params['backendDefaultLanguage']]; |
||||||
|
} |
||||||
|
|
||||||
|
private static function _getLangIndex(): int |
||||||
|
{ |
||||||
|
$index = 0; |
||||||
|
$baseUrl = ltrim(Yii::$app->request->baseUrl, '/'); |
||||||
|
|
||||||
|
if (strlen($baseUrl)) { |
||||||
|
$baseUrlChunks = explode('/', $baseUrl); |
||||||
|
if (count($baseUrlChunks) > 0) { |
||||||
|
$index = count( $baseUrlChunks ); |
||||||
|
} |
||||||
|
} |
||||||
|
return $index; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Created by Error202 |
||||||
|
* Date: 23.08.2018 |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace frontend\config; |
||||||
|
|
||||||
|
|
||||||
|
use core\helpers\LanguageHelper; |
||||||
|
use yii\web\UrlManager; |
||||||
|
use Yii; |
||||||
|
|
||||||
|
class LanguageUrlManager extends UrlManager |
||||||
|
{ |
||||||
|
public function init() |
||||||
|
{ |
||||||
|
LanguageHelper::setLanguage(Yii::$app->request->getUrl()); |
||||||
|
$langPrefix = Yii::$app->language . '/'; |
||||||
|
$finalRules[$langPrefix] = ''; |
||||||
|
|
||||||
|
foreach ($this->rules as $rule => $path) { |
||||||
|
if ( is_array($path) && isset($path['pattern']) && isset($path[0]) ) { |
||||||
|
$finalRules[$langPrefix . ltrim($path['pattern'], '/')] = $path[0]; |
||||||
|
} |
||||||
|
else { |
||||||
|
$finalRules[$langPrefix . ltrim($rule, '/')] = $path; |
||||||
|
} |
||||||
|
} |
||||||
|
$this->rules = array_merge_recursive($finalRules, $this->rules); |
||||||
|
return parent::init(); |
||||||
|
} |
||||||
|
|
||||||
|
public function createUrl( $params ) |
||||||
|
{ |
||||||
|
$url = parent::createUrl( $params ); |
||||||
|
return LanguageHelper::addLangToUrl($url, isset($params['language']) ? $params['language'] : null); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
<?php $this->beginContent('@frontend/web/themes/start/layouts/main.php') ?> |
||||||
|
|
||||||
|
<!-- Page Content --> |
||||||
|
<div class="container"> |
||||||
|
|
||||||
|
<?= \yii\widgets\Breadcrumbs::widget([ |
||||||
|
'tag' => 'ul', |
||||||
|
'itemTemplate' => '<li class="breadcrumb-item">{link}</li>' . "\n", |
||||||
|
'activeItemTemplate' => '<li class="breadcrumb-item active">{link}</li>' . "\n", |
||||||
|
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], |
||||||
|
]) ?> |
||||||
|
|
||||||
|
<div class="row"> |
||||||
|
|
||||||
|
<!-- Page Content --> |
||||||
|
<div class="col-md-12"> |
||||||
|
|
||||||
|
<?= $content ?> |
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
<!-- /.row --> |
||||||
|
|
||||||
|
</div> |
||||||
|
<!-- /.container --> |
||||||
|
<?php $this->endContent() ?> |
||||||
|
|
Loading…
Reference in new issue