/**
  * 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]);
?>