Skip to content
Merged
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
14 changes: 10 additions & 4 deletions src/CP/Navigation/NavBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ public function build($preferences = true)
->resolveChildrenClosures()
->validateNesting()
->validateViews()
->authorizeItems()
->authorizeChildren()
->syncOriginal()
->trackCoreSections()
->trackOriginalSectionItems()
->trackUrls()
->applyPreferenceOverrides($preferences)
->authorizeItems()
->authorizeChildren()
->buildSections()
->blinkUrls()
->get();
Expand Down Expand Up @@ -156,7 +156,10 @@ protected function authorizeChildren()
{
collect($this->items)
->reject(fn ($item) => is_callable($item->children()))
->each(fn ($item) => $item->children($this->filterAuthorizedNavItems($item->children())));
->each(fn ($item) => $item->children(
items: $this->filterAuthorizedNavItems($item->children()),
generateNewIds: false,
));

return $this;
}
Expand Down Expand Up @@ -707,7 +710,10 @@ protected function userModifyItemChildren($item, $childrenOverrides, $section, $

$newChildren->each(fn ($item, $index) => $item->order($index + 1));

$item->children($newChildren, false);
$item->children(
items: $newChildren,
generateNewIds: false,
);

return $newChildren;
}
Expand Down
55 changes: 53 additions & 2 deletions tests/CP/Navigation/NavPreferencesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
use Illuminate\Support\Facades\Request;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades;
use Tests\FakesRoles;
use Tests\PreventSavingStacheItemsToDisk;
use Tests\TestCase;

class NavPreferencesTest extends TestCase
{
use Concerns\HashedIdAssertions;
use FakesRoles;
use PreventSavingStacheItemsToDisk;

protected $shouldPreventNavBeingBuilt = false;
Expand Down Expand Up @@ -1694,9 +1696,58 @@ public function it_checks_active_status_on_moved_items()
$this->assertTrue($tags->isActive());
}

private function buildNavWithPreferences($preferences, $withHidden = false)
#[Test]
public function it_can_hide_items_the_user_does_not_have_permission_to_see()
{
$this->actingAs(tap(Facades\User::make()->makeSuper())->save());
$preferences = [
'favourites' => [
'display' => 'Favourites',
'items' => [
'content::collections::articles' => '@alias',
'content::collections::pages' => '@alias',
],
],
'author_section' => [
'display' => 'Authors',
'items' => [
'content::collections::articles' => '@move',
],
],
'webmaster_section' => [
'display' => 'Webmasters',
'items' => [
'content::collections::pages' => '@move',
],
],
];

// A super user can see these items...
$nav = $this->buildNavWithPreferences($preferences);
$this->assertCount(2, $nav->get('Favourites'));
$this->assertTrue($nav->get('Favourites')->keyBy->display()->has('Articles'));
$this->assertTrue($nav->get('Favourites')->keyBy->display()->has('Pages'));
$this->assertCount(1, $nav->get('Authors'));
$this->assertTrue($nav->get('Authors')->keyBy->display()->has('Articles'));
$this->assertCount(1, $nav->get('Webmasters'));
$this->assertTrue($nav->get('Webmasters')->keyBy->display()->has('Pages'));

// But an author with permissions to only view articles...
$this->setTestRoles(['author' => ['view articles entries']]);
$user = Facades\User::make()->assignRole('author');

// Should not see pages related section and/or items...
$nav = $this->buildNavWithPreferences($preferences, user: $user);
$this->assertCount(1, $nav->get('Favourites'));
$this->assertTrue($nav->get('Favourites')->keyBy->display()->has('Articles'));
$this->assertFalse($nav->get('Favourites')->keyBy->display()->has('Pages'));
$this->assertCount(1, $nav->get('Authors'));
$this->assertTrue($nav->get('Authors')->keyBy->display()->has('Articles'));
$this->assertFalse($nav->has('Webmasters'));
}

private function buildNavWithPreferences($preferences, $withHidden = false, $user = null)
{
$this->actingAs(tap($user ?? Facades\User::make()->makeSuper())->save());

return Facades\CP\Nav::build($preferences, $withHidden)->pluck('items', 'display');
}
Expand Down