Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optionally delete invisible or disabled nodes recursively #42

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,27 @@ class Module extends \yii\base\Module
*/
public $pageUseFallbackPage = true;

/**
* Whether Tree::getMenuItems() should remove all childs for all invisible nodes from menu tree
*
* @var bool
*/
public $menuRemoveInvisibleRecursive = false;

/**
* Whether Tree::getMenuItems() should return an empty array for invisible root nodes
*
* @var bool
*/
public $menuRemoveInvisibleRoot = false;

/**
* Whether Tree::getMenuItems() should remove all childs for all disabled nodes from menu tree
*
* @var bool
*/
public $menuRemoveDisabledRecursive = false;

/**
* @inheritdoc
*/
Expand Down
83 changes: 82 additions & 1 deletion models/Tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,33 @@ public static function optsIcon($html = false)
return $result;
}

/**
* get property from module config
* @return bool
*/
public static function menuRemoveInvisibleRecursive()
{
return \Yii::$app->getModule(PagesModule::NAME)->menuRemoveInvisibleRecursive;
}

/**
* get property from module config
* @return bool
*/
public static function menuRemoveInvisibleRoot()
{
return \Yii::$app->getModule(PagesModule::NAME)->menuRemoveInvisibleRoot;
}

/**
* get property from module config
* @return bool
*/
public static function menuRemoveDisabledRecursive()
{
return \Yii::$app->getModule(PagesModule::NAME)->menuRemoveDisabledRecursive;
}

/**
* @param array $additionalParams
*
Expand Down Expand Up @@ -297,6 +324,10 @@ public static function getMenuItems($domainId, $checkUserPermissions = false, ar
if ($rootNode->isDisabled() && !Yii::$app->user->can(self::PAGES_ACCESS_PERMISSION)) {
return [];
}
// return empty array if root is invisible and module menuRemoveInvisibleRoot flag is set to true
if (!$rootNode->isVisible() && self::menuRemoveInvisibleRoot()) {
return [];
}

/*
* @var $leaves Tree[]
Expand All @@ -310,6 +341,7 @@ public static function getMenuItems($domainId, $checkUserPermissions = false, ar
]
);
$leavesQuery->with('translationsMeta');
$leavesQuery->indexBy('id');
$leaves = $leavesQuery->all();

if ($leaves === null) {
Expand All @@ -319,16 +351,33 @@ public static function getMenuItems($domainId, $checkUserPermissions = false, ar
// filter out invisible models and disabled models (if needed)
// this is not done in the SQL query to reflect translation_meta values for "visible" and "disabled" attributes.
$canAccessPages = Yii::$app->user->can(self::PAGES_ACCESS_PERMISSION);
$leaves = array_filter($leaves, function (Tree $leave) use ($canAccessPages) {
// should invisible or disabled leaves be removed recursive?
$removeInvisible = self::menuRemoveInvisibleRecursive();
$removeDisabled = self::menuRemoveDisabledRecursive();
// arrays of child ids which should be "removed" afterwards
$invisibleByParent = [];
$disabledByParent = [];
$leaves = array_filter($leaves, function (Tree $leave) use ($canAccessPages, &$invisibleByParent, &$disabledByParent, &$removeInvisible, &$removeDisabled) {
if (!$leave->isVisible()) {
// get/remember Ids from leave childs to be able to "delete" these leave nodes afterwards
if ($removeInvisible) {
$invisibleByParent = array_merge($invisibleByParent, self::getChildIds($leave));
}
return false;
}
if (!$canAccessPages && $leave->isDisabled()) {
if ($removeDisabled) {
$disabledByParent = array_merge($disabledByParent, self::getChildIds($leave));
}
return false;
}
return true;
});

// remove invisible leaves recursive if set in module config
$removeInvisible && self::removeIdsFromLeavesArray($leaves, $invisibleByParent);
// remove disabled leaves recursive if set in module config
$removeDisabled && self::removeIdsFromLeavesArray($leaves, $disabledByParent);

// tree mapping and leave stack
$treeMap = [];
Expand Down Expand Up @@ -410,6 +459,38 @@ public static function getMenuItems($domainId, $checkUserPermissions = false, ar
return $data;
}

/**
* get array of child IDs from given $leave
*
* @param $leave
*
* @return array
*/
public static function getChildIds($leave)
{
$childs = $leave->children()->asArray()->select('id')->indexBy('id')->all();
if (empty($childs)) {
return [];
}
return array_keys($childs);
}

/**
* remove all items from leaves array by model-id (which is also the array key)
* Attention: this method work on a $leaves reference!
*
* @param $leaves
* @param $ids
*/
public static function removeIdsFromLeavesArray(&$leaves, array $ids)
{
foreach($ids as $id) {
if (isset($leaves[$id])) {
unset($leaves[$id]);
}
}
}

public function getMenuLabel()
{
return !empty($this->name) ? htmlentities($this->name) : "({$this->domain_id})";
Expand Down