/** * Returns a tree of menu-items that belong to the menu * * @param array $settings A settings array that holds the parent-id and level * @return array */ public function getTree($settings = ['subMenu' => true, 'parentId' => 0, 'level' => 0, 'includeLanguage' => true, 'convertBr' => false]) { $items = []; $menuItems = $this->getItems($settings)->all(); foreach ($menuItems as $menuItem) { // First we need to check if the item has a non-public page attached // If so, and no user is logged in, the item is skipped if ($menuItem->entity == Page::className() && Yii::$app->user->isGuest) { $menuItemEntity = $menuItem->entityModel; if (isset($menuItemEntity->public) && $menuItemEntity->public == false) { continue; } } $item = ['label' => isset($settings['convertBr']) ? str_replace("\n", '<br>', $menuItem->name) : str_replace("\n", ' ', $menuItem->name), 'url' => $menuItem->getUrl($settings['includeLanguage']), 'entity' => $menuItem->entity, 'entity_id' => $menuItem->entity_id, 'active' => in_array($menuItem->entity == MenuItem::className() ? $menuItem->entity_id : $menuItem->id, Yii::$app->page->linkedMenuItemsIds), 'options' => ['class' => "menu-item-{$menuItem->id}"]]; if (isset($settings['includeObject']) && $settings['includeObject'] == true) { $item['object'] = $menuItem; } // A menu-item that links to an url has to open in a new window if ($menuItem->entity == MenuItem::ENTITY_URL) { $item['linkOptions'] = ['target' => '_blank']; } if ($settings['subMenu'] == true) { // Get the item's children $children = $this->getTree(['parentId' => $menuItem->id, 'level' => $menuItem->level + 1, 'includeLanguage' => $settings['includeLanguage'], 'subMenu' => $settings['subMenu'], 'convertBr' => isset($settings['convertBr'])]); if ($children) { $item['items'] = $children; } } $items[$menuItem->id] = $item; } return $items; }
public function checkValue($event) { $homepage = $this->owner->homepage; // Not set as homepage if ($homepage == 0) { // If no other pages are set as homepage, the owner is automatically // set as homepage $homepageExists = (bool) Page::find()->where(['homepage' => 1])->count(); if (!$homepageExists) { $this->owner->homepage = 1; // The homepage is always a public page $this->owner->public = 1; } } else { // The flag for the current homepage has to be unset only if the // 'homepage' attribute of the owner changed (meaning that the // owner was not already the current homepage) if (in_array('homepage', array_keys($this->owner->getDirtyAttributes()))) { $currentHomepage = Page::findOne(['homepage' => 1]); if ($currentHomepage) { $currentHomepage->homepage = 0; $currentHomepage->save(); } } // The homepage is always a public page if ($this->owner->public != 1) { $this->owner->public = 1; } } }
public function init() { parent::init(); // Merge the linkable entities with default values $this->linkableEntities = ArrayHelper::merge([MenuItem::className() => ['label' => 'Menu item', 'i18nGroup' => 'infoweb/menu', 'createEntity' => false, 'createEntityUrl' => ''], Page::className() => ['label' => 'Page', 'i18nGroup' => 'infoweb/pages', 'createEntity' => true, 'createEntityUrl' => '/pages/page/create']], $this->linkableEntities); // Set eventhandlers $this->setEventHandlers(); // Content duplication is only possible if there is more than 1 app language if (isset(Yii::$app->params['languages']) && count(Yii::$app->params['languages']) == 1) { $this->allowContentDuplication = false; } }
protected function setEventHandlers() { // Set eventhandlers for the 'Page' model Event::on(Page::className(), ActiveRecord::EVENT_BEFORE_DELETE, function ($event) { // Check if the page is the homepage if ($event->sender->homepage == 1) { throw new \yii\base\Exception(Yii::t('infoweb/pages', 'The page can not be deleted because it is the homepage')); } // Check if the page is not used in a menu if ($event->sender->isUsedInMenu()) { throw new \yii\base\Exception(Yii::t('infoweb/pages', 'The page can not be deleted because it is used in a menu')); } }); }
/** * @inheritdoc */ public function rules() { return [[['entity', 'language', 'url'], 'required'], ['entity_id', 'required', 'when' => function ($model) { return !$this->isNewRecord; }], [['created_at', 'updated_at'], 'integer'], [['type'], 'string'], ['type', 'in', 'range' => [self::TYPE_SYSTEM, self::TYPE_USER_DEFINED]], ['type', 'default', 'value' => self::TYPE_USER_DEFINED], [['url'], 'trim'], [['entity_id'], 'integer'], [['language'], 'string', 'max' => 10], [['url', 'entity'], 'string', 'max' => 255], [['entity', 'language', 'url'], 'unique', 'targetAttribute' => ['entity', 'language', 'url'], 'message' => Yii::t('infoweb/alias', 'This url is already used')], ['url', function ($attribute, $params) { // Check if the url is not a reserved url when: // - Inserting a new record // - Updating an existing record that is not part of a system alias // - The record is an instance of \infoweb\pages\models\Page if (in_array($this->url, Yii::$app->getModule('alias')->reservedUrls) && ($this->isNewRecord || !$this->isNewRecord && $this->type != Alias::TYPE_SYSTEM) && $this->entity == \infoweb\pages\models\Page::className()) { $this->addError($attribute, Yii::t('infoweb/alias', 'This is a reserved url and can not be used')); } }]]; }
/** * Creates data provider instance with search query applied * @return ActiveDataProvider */ public function search($params) { $query = Page::find(); $query->andFilterWhere(['language' => Yii::$app->language]); $dataProvider = new ActiveDataProvider(['query' => $query, 'sort' => ['defaultOrder' => ['name' => SORT_ASC]], 'pagination' => ['pageSize' => 50]]); // Join the entity model as a relation $query->joinWith(['translations']); // enable sorting for the related column $dataProvider->sort->attributes['name'] = ['asc' => ['name' => SORT_ASC], 'desc' => ['name' => SORT_DESC]]; if (!($this->load($params) && $this->validate())) { return $dataProvider; } $query->andFilterWhere(['id' => $this->id, 'active' => $this->active, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at]); if (Yii::$app->getModule('pages')->enablePrivatePages) { $query->andFilterWhere(['public' => $this->public]); } $query->andFilterWhere(['like', 'name', $this->name]); return $dataProvider; }
public function setEventHandlers() { /** * Update menuitem active state */ Event::on(Page::className(), Page::EVENT_BEFORE_ACTIVE, function ($event) { $menuItem = MenuItem::find()->where(['entity' => Page::className(), 'entity_id' => $event->sender->id])->one(); if ($menuItem) { $menuItem->active = $event->sender->active == 1 ? 0 : 1; $menuItem->save(); } }); // Set eventhandlers for the 'Menu' model Event::on(Page::className(), ActiveRecord::EVENT_BEFORE_DELETE, function ($event) { $menuItem = MenuItem::find()->where(['entity' => Page::className(), 'entity_id' => $event->sender->id])->one(); if ($menuItem) { throw new \yii\base\Exception(Yii::t('app', "Deze pagina is gekoppeld aan menu item '{$menuItem->name}', verwijder eerst het menu item")); } }); }
/** * Returns the url for the item * * @param boolean A flag to determine if the language parameter should * be added to the url * @param boolean A flag to determine if the url should be prefixed with * the webpath * @return string */ public function getUrl($includeLanguage = true, $excludeWebPath = false) { // Url if ($this->entity == self::ENTITY_NONE) { return null; } elseif ($this->entity == self::ENTITY_URL) { return $this->url; } else { $prefix = !$excludeWebPath ? '@web/' : ''; $prefix .= $includeLanguage ? Yii::$app->language . '/' : ''; // Page if ($this->entity == Page::className()) { $page = $this->getEntityModel(); // In the frontend application, the alias for the homepage is ommited // and '/' is used if (Yii::$app->id == 'app-frontend' && $page->homepage == true) { return Url::to($prefix); } $url = "{$prefix}{$page->alias->url}"; // Params are set, append to the url if (!empty($this->params)) { $url = $url . $this->params; } // An anchor is set, append it to the url if (!empty($this->anchor)) { return Url::to("{$url}#{$this->anchor}"); } return Url::to($url); // Everything else } else { // Second parameter is language $url = $this->getEntityModel()->getUrl($includeLanguage, null, $excludeWebPath); // Params are set, append to the url if (!empty($this->params)) { $url = $url . $this->params; } return $url; } } }
/** * Performs validation on the provided model and $_POST data * * @param \infoweb\pages\models\Page $model The page model * @param array $post The $_POST data * @return array */ protected function validateModel($model, $post) { $languages = Yii::$app->params['languages']; // Populate the model with the POST data $model->load($post); // Create an array of translation models and populate them $translationModels = []; // Insert if ($model->isNewRecord) { foreach ($languages as $languageId => $languageName) { $translationModels[$languageId] = new Lang(['language' => $languageId]); } // Update } else { $translationModels = ArrayHelper::index($model->getTranslations()->all(), 'language'); } Model::loadMultiple($translationModels, $post); // Validate the model and translation $response = array_merge(ActiveForm::validate($model), ActiveForm::validateMultiple($translationModels)); // Return validation in JSON format Yii::$app->response->format = Response::FORMAT_JSON; return $response; }
/** * Sets the page model. * If not null, it also loads all the linked menu-items. * * @param infoweb\pages\models\Page | null */ public function setModel($value = null) { $this->model = $value; // Set the entity and (re)load the linked menu items each time the model is set if ($this->model !== null) { $this->entity = ['id' => $value->id, 'type' => PageModel::className()]; $this->loadLinkedMenuItems(); } }
/** * Performs validation on the provided model and $_POST data * * @param \infoweb\pages\models\Page $model The page model * @param array $post The $_POST data * @return array */ protected function validateModel($model, $post) { $languages = Yii::$app->params['languages']; // Populate the model with the POST data $model->load($post); // Parent is root if (empty($post[StringHelper::basename(MenuItem::className())]['parent_id'])) { $model->parent_id = 0; $model->level = 0; } else { $parent = MenuItem::findOne($post[StringHelper::basename(MenuItem::className())]['parent_id']); $model->parent_id = $parent->id; $model->level = $parent->level + 1; } // Create an array of translation models and populate them $translationModels = []; // Insert if ($model->isNewRecord) { foreach ($languages as $languageId => $languageName) { $translationModels[$languageId] = new MenuItemLang(['language' => $languageId]); } // Update } else { $translationModels = ArrayHelper::index($model->getTranslations()->all(), 'language'); } Model::loadMultiple($translationModels, $post); // Validate the model and translation $response = array_merge(ActiveForm::validate($model), ActiveForm::validateMultiple($translationModels)); // Return validation in JSON format Yii::$app->response->format = Response::FORMAT_JSON; return $response; }
/** * @return \yii\db\ActiveQuery */ public function getPage() { return $this->hasOne(Page::className(), ['id' => 'page_id']); }
?> <div class="help-block"></div> </div> <?php // None ?> <?php echo Html::hiddenInput('MenuItem[entity_id]', 0, ['class' => 'attribute none-attribute', 'style' => $model->entity != $model::ENTITY_NONE ? 'display: none;' : '', 'disabled' => $model->entity != $model::ENTITY_NONE ? 'true' : '']); ?> <?php // Page anchors ?> <?php echo $form->field($model, 'anchor', ['options' => ['class' => 'menu-item-anchor-container', 'style' => $model->entity != Page::className() || !isset($model->entityModel) || $model->entity == Page::className() && !count($model->entityModel->htmlAnchors) ? 'display: none;' : '']])->dropDownList(array_merge(['' => Yii::t('app', '-- Choose an {item} --', ['item' => Yii::t('infoweb/menu', 'anchor')])], $model->entity == Page::className() && isset($model->entityModel) ? $model->entityModel->htmlAnchors : []), ['readonly' => $model->type == $model::TYPE_SYSTEM && !Yii::$app->user->can('Superadmin') ? true : false]); ?> <?php if (Yii::$app->getModule('menu')->enablePrivateMenuItems) { ?> <?php echo $form->field($model, 'public')->widget(SwitchInput::classname(), ['inlineLabel' => false, 'pluginOptions' => ['onColor' => 'success', 'offColor' => 'danger', 'onText' => Yii::t('app', 'Yes'), 'offText' => Yii::t('app', 'No')], 'readonly' => $model->type == $model::TYPE_SYSTEM && !Yii::$app->user->can('Superadmin') ? true : false]); ?> <?php } ?> <?php echo $form->field($model, 'active')->widget(SwitchInput::classname(), ['pluginOptions' => ['onColor' => 'success', 'offColor' => 'danger', 'onText' => Yii::t('app', 'Yes'), 'offText' => Yii::t('app', 'No')], 'readonly' => $model->type == $model::TYPE_SYSTEM && !Yii::$app->user->can('Superadmin') ? true : false]); ?>