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