• M5: Add ServiceProviderInterface and ProviderRepository; integrate providers into Kernel (register before container build, boot after); add RouteRegistry with clear(); add default core providers (Routing, Template, ORM, Flags, Testing) and AppServiceProvider; add contracts and default drivers (Template/Eyrie, Orm/Pairity, Flags/Flagpole, Testing/Codeception) • Routing: allow providers to contribute routes; add ProviderRouteTest • Config: add config/providers.php; extend config/app.php with driver keys; document env keys • M6: Introduce MVC bases: Controller, APIController (JSON helpers), ViewController (html + renderView helpers), View (transformData + renderer); add ViewWithDefaultTemplate and default-template flow; adjust method signatures to data-first and delegate template override to View • HTTP: Add UrlExtensionNegotiationMiddleware (opt-in via URL_EXTENSION_NEGOTIATION, whitelist via URL_EXTENSION_WHITELIST with default json|php|none); wire before ContentNegotiationMiddleware • Tests: add UrlExtensionNegotiationTest and MvcViewTest; ensure RouteRegistry::clear prevents duplicate routes in tests • Docs: Update README with M5 provider usage, M6 MVC examples and template selection conventions, and URL extension negotiation; mark M5 complete in MILESTONES; add M12 task to provide XML support and enable xml in whitelist by default
43 lines
1.4 KiB
PHP
43 lines
1.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Phred\Mvc;
|
|
|
|
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
abstract class ViewController extends Controller
|
|
{
|
|
private Psr17Factory $psr17;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->psr17 = new Psr17Factory();
|
|
}
|
|
|
|
/**
|
|
* Return an HTML response with the provided content.
|
|
*/
|
|
protected function html(string $content, int $status = 200, array $headers = []): ResponseInterface
|
|
{
|
|
$response = $this->psr17->createResponse($status)->withHeader('Content-Type', 'text/html; charset=utf-8');
|
|
foreach ($headers as $k => $v) {
|
|
$response = $response->withHeader((string) $k, (string) $v);
|
|
}
|
|
$response->getBody()->write($content);
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Convenience to render a module View and return an HTML response.
|
|
* The `$template` is optional; when omitted (null), the view should use its default template.
|
|
*/
|
|
protected function renderView(View $view, array $data = [], ?string $template = null, int $status = 200, array $headers = []): ResponseInterface
|
|
{
|
|
// Delegate template selection to the View; when $template is null,
|
|
// the View may use its default template.
|
|
$markup = $view->render($data, $template);
|
|
return $this->html($markup, $status, $headers);
|
|
}
|
|
}
|