Skip to content

Commit

Permalink
Merge pull request #14 from tattersoftware/discovery
Browse files Browse the repository at this point in the history
Active discovery
  • Loading branch information
MGatner authored May 5, 2021
2 parents 2937bed + ff3b88b commit 8589d57
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 20 deletions.
44 changes: 40 additions & 4 deletions src/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ abstract class Menu
*/
public function __construct(BaseMenu $builder = null)
{
$this->builder = $builder ?? BaseMenu::new()->setActive(
current_url(),
(new URI(base_url()))->getPath() ?? '/'
);
$current = $this->detectCurrent();
$root = (new URI(site_url()))->getPath() ?? '/';

$this->builder = $builder ?? BaseMenu::new()->setActive($current, $root);

foreach (class_uses_recursive($this) as $trait)
{
Expand Down Expand Up @@ -59,4 +59,40 @@ public function builder(): BaseMenu
* @return string
*/
abstract public function __toString(): string;

/**
* Returns the current URL to use for determining
* which menu items should be active.
* Due to this bug:
* - https://github.com/codeigniter4/CodeIgniter4/issues/4116
* ...we cannot use current_url(). This method can be
* replaced if that bug is fixed or if we get this:
* - https://github.com/codeigniter4/CodeIgniter4/pull/4647
*
* @return string
* @internal
*/
protected function detectCurrent(): string
{
// Force path discovery in a new IncomingRequest
$request = service('request', null, false);
$path = ltrim($request->detectPath($request->config->uriProtocol), '/');

// Build the full URL based on the config and path
$url = rtrim($request->config->baseURL, '/ ') . '/';

// Check for an index page
if ($request->config->indexPage !== '')
{
$url .= $request->config->indexPage;

// If there is a path then we need a separator
if ($path !== '')
{
$url .= '/';
}
}

return (string) (new URI($url . $path));
}
}
5 changes: 2 additions & 3 deletions tests/_support/MenusTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ protected function setUp(): void
Factories::injectMock('config', 'App', $config);

// Set a current URL for checking "active" links
$request = Services::request();
$request->uri = new URI(site_url('current'));
Services::injectMock('request', $request);
$_SERVER['REQUEST_URI'] = '/current';
Services::injectMock('request', null);

// Create some Menu aliases for testing
$config = new MenusConfig();
Expand Down
34 changes: 21 additions & 13 deletions tests/menu/MenuTest.php
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
<?php namespace Tests\Support;

use Config\Services;
use Spatie\Menu\Menu as BaseMenu;
use Tatter\Menus\Menu;
use Tests\Support\MenusTestCase;

class MenuTest extends MenusTestCase
{
/**
* @var Menu
* Generates a test Menu on-the-fly
*
* @return Menu
*/
private $menu;

/**
* Creates a basic Menu to use for testing.
*/
protected function setUp(): void
private function menu(): Menu
{
parent::setUp();

$this->menu = new class extends Menu {
return new class extends Menu {

public function __toString(): string
{
return $this->builder
->link(site_url('/'), 'Home')
->link(site_url(''), 'Home')
->link(site_url('/current'), 'Grain')
->render();
}
Expand All @@ -32,7 +28,7 @@ public function __toString(): string

public function testGetBuilder()
{
$result = $this->menu->builder();
$result = $this->menu()->builder();

$this->assertInstanceOf(BaseMenu::class, $result);
}
Expand All @@ -55,7 +51,19 @@ public function __toString(): string
public function testGetUsesCurrentUrl()
{
$expected = '<ul><li><a href="http://example.com/">Home</a></li><li class="active exact-active"><a href="http://example.com/current">Grain</a></li></ul>';
$result = $this->menu->__toString();
$result = $this->menu()->__toString();

$this->assertSame($expected, $result);
}

public function testGetUsesIndexPage()
{
$config = config('App');
$config->indexPage = 'index.php';
Services::injectMock('request', null);

$expected = '<ul><li><a href="http://example.com/index.php">Home</a></li><li class="active exact-active"><a href="http://example.com/index.php/current">Grain</a></li></ul>';
$result = $this->menu()->__toString();

$this->assertSame($expected, $result);
}
Expand Down

0 comments on commit 8589d57

Please sign in to comment.