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
1 change: 0 additions & 1 deletion packages/admin-panel/config/admin-panel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@

return [
'page_title' => 'Marko Admin',
'items_per_page' => 20,
];
5 changes: 0 additions & 5 deletions packages/admin-panel/src/Config/AdminPanelConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,4 @@ public function getPageTitle(): string
{
return $this->config->getString('admin-panel.page_title');
}

public function getItemsPerPage(): int
{
return $this->config->getInt('admin-panel.items_per_page');
}
}
2 changes: 0 additions & 2 deletions packages/admin-panel/src/Config/AdminPanelConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,4 @@
interface AdminPanelConfigInterface
{
public function getPageTitle(): string;

public function getItemsPerPage(): int;
}
3 changes: 3 additions & 0 deletions packages/admin-panel/src/Controller/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Marko\AdminAuth\AdminGuardResolver;
use Marko\AdminAuth\Entity\AdminUserInterface;
use Marko\AdminAuth\Middleware\AdminAuthMiddleware;
use Marko\AdminPanel\Config\AdminPanelConfigInterface;
use Marko\AdminPanel\Menu\AdminMenuBuilderInterface;
use Marko\Routing\Attributes\Get;
use Marko\Routing\Attributes\Middleware;
Expand All @@ -20,6 +21,7 @@ public function __construct(
private readonly ViewInterface $view,
private readonly AdminMenuBuilderInterface $menuBuilder,
private readonly AdminGuardResolver $adminGuard,
private readonly AdminPanelConfigInterface $config,
) {}

/**
Expand All @@ -41,6 +43,7 @@ public function index(
return $this->view->render('admin-panel::dashboard/index', [
'sections' => $sections,
'currentUser' => $user,
'pageTitle' => $this->config->getPageTitle(),
]);
}
}
31 changes: 4 additions & 27 deletions packages/admin-panel/tests/Unit/Config/AdminPanelConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,22 @@
use Marko\AdminPanel\Config\AdminPanelConfigInterface;
use Marko\Testing\Fake\FakeConfigRepository;

it('creates AdminPanelConfig with pageTitle and itemsPerPage settings', function (): void {
it('reads the page title from admin-panel.page_title', function (): void {
$config = new AdminPanelConfig(new FakeConfigRepository([
'admin-panel.page_title' => 'My Custom Admin',
'admin-panel.items_per_page' => 50,
]));

expect($config)->toBeInstanceOf(AdminPanelConfigInterface::class)
->and($config->getPageTitle())->toBe('My Custom Admin')
->and($config->getItemsPerPage())->toBe(50);
->and($config->getPageTitle())->toBe('My Custom Admin');
});

it('provides default page title of Marko Admin', function (): void {
$config = new AdminPanelConfig(new FakeConfigRepository([
'admin-panel.page_title' => 'Marko Admin',
'admin-panel.items_per_page' => 20,
]));

expect($config->getPageTitle())->toBe('Marko Admin');
});

it('provides default items per page of 20', function (): void {
$config = new AdminPanelConfig(new FakeConfigRepository([
'admin-panel.page_title' => 'Marko Admin',
'admin-panel.items_per_page' => 20,
]));

expect($config->getItemsPerPage())->toBe(20);
});

it('has valid config/admin-panel.php with default values', function (): void {
it('ships config/admin-panel.php with only the page title default', function (): void {
$configPath = dirname(__DIR__, 3) . '/config/admin-panel.php';
$configData = require $configPath;

expect(file_exists($configPath))->toBeTrue()
->and($configData)->toBeArray()
->and($configData)->toHaveKey('page_title')
->and($configData)->toHaveKey('items_per_page')
->and($configData['page_title'])->toBe('Marko Admin')
->and($configData['items_per_page'])->toBe(20);
->and($configData)->toBe(['page_title' => 'Marko Admin']);
});

it('binds AdminPanelConfigInterface to AdminPanelConfig in module.php', function (): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
use Marko\AdminAuth\Entity\AdminUser;
use Marko\AdminAuth\Entity\Role;
use Marko\AdminAuth\Middleware\AdminAuthMiddleware;
use Marko\AdminPanel\Config\AdminPanelConfig;
use Marko\AdminPanel\Controller\DashboardController;
use Marko\AdminPanel\Menu\AdminMenuBuilder;
use Marko\AdminPanel\Tests\Fixtures\FixedAdminGuardResolver;
use Marko\Routing\Attributes\Middleware;
use Marko\Routing\Http\Request;
use Marko\Routing\Http\Response;
use Marko\Testing\Fake\FakeAuthenticatable;
use Marko\Testing\Fake\FakeConfigRepository;
use Marko\Testing\Fake\FakeGuard;
use Marko\View\ViewInterface;
use ReflectionMethod;
Expand Down Expand Up @@ -167,11 +169,15 @@ function createDashboardController(
StubView $view,
StubSectionRegistry $registry,
FakeGuard $guard,
string $pageTitle = 'Marko Admin',
): DashboardController {
return new DashboardController(
view: $view,
menuBuilder: new AdminMenuBuilder($registry),
adminGuard: new FixedAdminGuardResolver($guard),
config: new AdminPanelConfig(new FakeConfigRepository([
'admin-panel.page_title' => $pageTitle,
])),
);
}

Expand Down Expand Up @@ -269,3 +275,16 @@ function createDashboardController(
->and($view->lastData['currentUser'])->toBe($user)
->and($view->lastData['currentUser']->getAuthIdentifier())->toBe(5);
});

it('passes the configured admin-panel.page_title to the template as pageTitle', function (): void {
$view = new StubView();
$registry = new StubSectionRegistry();
$guard = new FakeGuard(name: 'admin', attemptResult: false);

$guard->setUser(createDashboardAdminUser(superAdmin: true));

createDashboardController($view, $registry, $guard, pageTitle: 'Acme Back Office')->index(new Request());

expect($view->lastData)->toHaveKey('pageTitle')
->and($view->lastData['pageTitle'])->toBe('Acme Back Office');
});
11 changes: 10 additions & 1 deletion packages/docs-markdown/docs/packages/admin-panel.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ mymodule/
index.latte # Overrides the default dashboard
```

### Configuration

`config/admin-panel.php` sets the browser title of the dashboard. `DashboardController` passes it to the template as `pageTitle`:

```php title="config/admin-panel.php"
return [
'page_title' => 'Marko Admin',
];
```

## Customization

Replace the menu builder via Preferences to customize navigation behavior:
Expand Down Expand Up @@ -153,6 +163,5 @@ use Marko\AdminAuth\Middleware\AdminAuthMiddleware;
interface AdminPanelConfigInterface
{
public function getPageTitle(): string;
public function getItemsPerPage(): int;
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ return [
];
```

Create the admin panel configuration:
Set the title the dashboard shows in the browser tab:

```php title="config/admin-panel.php"
<?php
Expand All @@ -59,7 +59,6 @@ declare(strict_types=1);

return [
'page_title' => 'My App Admin',
'items_per_page' => 25,
];
```

Expand Down
8 changes: 0 additions & 8 deletions packages/layout/config/layout.php

This file was deleted.

10 changes: 2 additions & 8 deletions packages/layout/tests/PackageStructureTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,8 @@
->and($module['bindings'][ComponentCollectorInterface::class])->toBe(DiscoveringComponentCollector::class);
});

it('has a config/layout.php that returns a configuration array', function (): void {
$configPath = dirname(__DIR__) . '/config/layout.php';

expect(file_exists($configPath))->toBeTrue();

$config = require $configPath;

expect($config)->toBeArray();
it('ships no config file, since layouts and components are discovered from attributes', function (): void {
expect(is_dir(dirname(__DIR__) . '/config'))->toBeFalse();
});

it('module.php declares LayoutMiddleware as globalMiddleware', function (): void {
Expand Down
16 changes: 2 additions & 14 deletions packages/mail/config/mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
| Mail Driver
|--------------------------------------------------------------------------
|
| The default mail driver used for sending emails. Supported drivers
| include: "smtp", "sendmail", "log", "array"
| The default mail driver used for sending emails. Drivers ship as
| separate packages: "smtp" (marko/mail-smtp), "log" (marko/mail-log).
|
*/
'driver' => 'smtp',
Expand Down Expand Up @@ -44,16 +44,4 @@
'timeout' => 30,
'auth_mode' => 'login',
],

/*
|--------------------------------------------------------------------------
| Sendmail Configuration
|--------------------------------------------------------------------------
|
| Configuration for the sendmail driver.
|
*/
'sendmail' => [
'path' => '/usr/sbin/sendmail -bs',
],
];
5 changes: 0 additions & 5 deletions tests/config-readers-allowlist.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,8 @@
'discovery.cache_path' => 'Mirrors the boot gate for introspection; boot reads the env through DiscoveryEnvironment (marko/core cannot depend on marko/config).',
'http-guzzle.timeout' => 'Read through the composed key "http-guzzle.$name" in GuzzleHttpClient::timeoutFromConfig().',
'http-guzzle.connect_timeout' => 'Read through the composed key "http-guzzle.$name" in GuzzleHttpClient::timeoutFromConfig().',
'layout.components' => 'Pre-existing: no reader yet; components are discovered from #[Component] attributes. Not security-relevant.',
'layout.layouts' => 'Pre-existing: no reader yet; layouts are discovered from attributes. Not security-relevant.',
'mail.sendmail' => 'Pre-existing: no sendmail driver ships yet. Not security-relevant.',
],
'accessors' => [
'Marko\AdminPanel\Config\AdminPanelConfig::getPageTitle' => 'Pre-existing: documented accessor for app templates; the panel itself does not read it yet. Not security-relevant.',
'Marko\AdminPanel\Config\AdminPanelConfig::getItemsPerPage' => 'Pre-existing: documented accessor for app code; the panel itself does not paginate yet. Not security-relevant.',
'Marko\Authentication\Config\AuthConfig::providers' => 'Whole-section accessor for app code; the framework reads providersOrNull().',
'Marko\Authentication\Config\AuthConfig::passwordConfig' => 'Whole-section accessor for app code; the framework reads bcryptCost().',
'Marko\Authentication\Config\AuthConfig::rememberConfig' => 'Whole-section accessor for app code; the framework reads the remember* accessors.',
Expand Down
Loading