diff --git a/meta/definitions/routes.php b/meta/definitions/routes.php index a167bce..083e7ed 100644 --- a/meta/definitions/routes.php +++ b/meta/definitions/routes.php @@ -11,7 +11,8 @@ use Psr\Http\Message\ResponseFactoryInterface, Psr\Http\Message\ResponseInterface, Psr\Http\Message\ServerRequestInterface, Psr\Http\Server\MiddlewareInterface, - Psr\Http\Server\RequestHandlerInterface; + Psr\Http\Server\RequestHandlerInterface, + Psr\SimpleCache\CacheInterface; use TheBugs\JavascriptMiddleware; @@ -21,6 +22,8 @@ use Tuupola\Middleware\HttpBasicAuthentication; use Notes\Route\RouteFetcher; +use Notes\Breadcrumb\Breadcrumb; + use Ulmus\User\Lib\Authenticate; use Storage\SessionMiddleware; @@ -29,7 +32,7 @@ return [ Lean\Routing::class => autowire(Lean\Routing::class), RouteFetcher::class => function($c) { - $fetcher = new RouteFetcher(); + $fetcher = new RouteFetcher(null, [], null, $c->get('routes.caching'), getenv('DEBUG')); $fetcher->setFolderList(array_map(function($item) { return $item; @@ -38,6 +41,16 @@ return [ return $fetcher; }, + Breadcrumb::class => function($c) { + $breadcrumb = new Breadcrumb(null, [], null, $c->get('breadcrumbs.caching'), getenv('DEBUG')); + + $breadcrumb->setFolderList(array_map(function($item) { + return $item; + }, $c->get(Lean\Lean::class)->getRoutable())); + + return $breadcrumb; + }, + ApplicationStrategy::class => function($c) { return new class($c->get(Picea\Picea::class)) extends ApplicationStrategy { diff --git a/meta/definitions/software.php b/meta/definitions/software.php index 32da575..fac69ab 100644 --- a/meta/definitions/software.php +++ b/meta/definitions/software.php @@ -110,4 +110,6 @@ return [ return "gitless-project"; }, + + Kash\CacheInvalidator::class => create(Kash\CacheInvalidator::class)->constructor(getenv('CACHE_PATH')."/version.cache", (bool) getenv('DEBUG')), ]; diff --git a/meta/definitions/template.php b/meta/definitions/template.php index 8bf5c89..285ad40 100644 --- a/meta/definitions/template.php +++ b/meta/definitions/template.php @@ -4,28 +4,13 @@ use function DI\autowire, DI\create, DI\get; use Zend\Diactoros\Response\HtmlResponse; -use Picea\Picea, - Picea\Caching\Cache, - Picea\Caching\Opcache, - Picea\Compiler, - Picea\Compiler\Context, - Picea\Compiler\BaseContext, - Picea\Extension\LanguageHandler, - Picea\Extension\LanguageExtension, - Picea\Extension\TitleExtension, - Picea\Extension\MoneyExtension, - Picea\Extension\UrlExtension, - Picea\FileFetcher, - Picea\Language\DefaultRegistrations, - Picea\Method\Request, - Picea\Ui\Method, - Picea\Ui\Ui; +use Picea\{ Picea, Caching\Cache, Caching\Opcache, Compiler, Compiler\Context, Compiler\BaseContext, FileFetcher, Language\DefaultRegistrations, Method\Request }; +use Picea\Extension\{ LanguageHandler, LanguageExtension, TitleExtension, MoneyExtension, UrlExtension }; +use Picea\Ui\{ Method, Ui }; return [ Picea::class => function($c) { - return new Picea(function($html) { - return new HtmlResponse( $html ); - }, $c->get(Context::class), $c->get(Cache::class), $c->get(Compiler::class), null, $c->get(FileFetcher::class), null, getenv("DEBUG")); + return new Picea($c->get(Context::class), $c->get(Cache::class), $c->get(Compiler::class), null, $c->get(FileFetcher::class), null, getenv("DEBUG")); }, Context::class => function($c) { @@ -80,7 +65,7 @@ return [ MoneyExtension::class => autowire(MoneyExtension::class), - UrlExtension::class => create(UrlExtension::class)->constructor(get(Context::class), getenv("URL_BASE"), get('git.commit')), + UrlExtension::class => create(UrlExtension::class)->constructor(getenv("URL_BASE"), get('git.commit')), Cache::class => create(Opcache::class)->constructor(getenv("CACHE_PATH"), get(Context::class)), diff --git a/skeleton/meta/definitions/env/dev.php b/skeleton/meta/definitions/env/dev.php index 7859e15..aebac13 100644 --- a/skeleton/meta/definitions/env/dev.php +++ b/skeleton/meta/definitions/env/dev.php @@ -11,4 +11,8 @@ if ($_GET['sql'] ?? false) { return [ "dump" => create(DumpMiddleware::class), "errorHandler" => create(Middlewares\Whoops::class), + 'routes.caching' => create(Kash\ArrayCache::class)->constructor(get(Kash\CacheInvalidator::class), "lean.routes", 30), + 'breadcrumbs.caching' => create(Kash\ArrayCache::class)->constructor( get(Kash\CacheInvalidator::class), "lean.breadcrumbs", 30), + 'ulmus.caching' => create(Kash\ArrayCache::class)->constructor( get(Kash\CacheInvalidator::class), "ulmus.entities", 30), + ]; diff --git a/skeleton/meta/definitions/env/prod.php b/skeleton/meta/definitions/env/prod.php index 28da8e9..8b6d3bc 100644 --- a/skeleton/meta/definitions/env/prod.php +++ b/skeleton/meta/definitions/env/prod.php @@ -39,4 +39,8 @@ return [ ])); }; }, -]; + + 'routes.caching' => create(Kash\ApcuCache::class)->constructor(get(Kash\CacheInvalidator::class), "lean.routes", random_int(3600, 7200)), + 'breadcrumbs.caching' => create(Kash\ApcuCache::class)->constructor(get(Kash\CacheInvalidator::class), "lean.breadcrumbs", random_int(3600, 7200)), + 'ulmus.caching' => create(Kash\ApcuCache::class)->constructor( get(Kash\CacheInvalidator::class), "ulmus.entities", random_int(3600, 7200)), +]; \ No newline at end of file diff --git a/src/Application.php b/src/Application.php index 4df16b7..e256f1c 100644 --- a/src/Application.php +++ b/src/Application.php @@ -8,7 +8,7 @@ class Application { public string $name; - public string $piceaContext; + public /*string|array*/ $piceaContext; public array $piceaExtensions; diff --git a/src/Composer.php b/src/Composer.php index a4a0e22..c5f2fef 100644 --- a/src/Composer.php +++ b/src/Composer.php @@ -55,6 +55,18 @@ class Composer } } + public static function postUpdate(Event $event) : void + { + $event->getIO()->write("post-update script executing ..."); + + $path = static::createPath('var/cache/version.cache'); + + if ( file_exists($path) ) { + $event->getIO()->write("removing cache file version to force a '$path'"); + unlink($path); + } + } + protected static function readComposerJson(Event $event) : ? array { $path = static::createPath('composer.json'); diff --git a/src/ControllerTrait.php b/src/ControllerTrait.php index ac47def..31232d2 100644 --- a/src/ControllerTrait.php +++ b/src/ControllerTrait.php @@ -18,6 +18,7 @@ use Psr\Http\Message\ResponseInterface; use TheBugs\Email\MailerInterface; use Notes\Cronard\Annotation\Method\Cronard, + Notes\Breadcrumb\Annotation\Method\Breadcrumb, Notes\Route\Annotation\Object\Route as RouteParam, Notes\Route\Annotation\Method\Route, Notes\Security\Annotation\Security, @@ -26,11 +27,11 @@ use Notes\Cronard\Annotation\Method\Cronard, use function file_get_contents; -/** - * @Security("locked" => true) - * @RouteParam("methods" => [ "GET", "POST", "DELETE" ]) - */ +#[\Notes\Security\Attribute\Security(locked: true)] +#[\Notes\Route\Attribute\Object\Route(method: [ "GET", "POST", "DELETE" ])] trait ControllerTrait { + public ? \Notes\Breadcrumb\Breadcrumb $breadcrumb; + public ? Session $session; public ? Picea\Picea $picea; @@ -149,7 +150,8 @@ trait ControllerTrait { return $this->picea->compiler->getExtensionFromToken('route')->buildRouteUrl($name, $parameters); } - public function json($data, int $flags = 0) { + public function json($data, int $flags = 0) : string + { return htmlentities(json_encode($data, $flags), ENT_QUOTES, 'UTF-8'); } @@ -164,4 +166,15 @@ trait ControllerTrait { { return $name ? $this->contextList[$name] : array_values($this->contextList)[0] ?? null; } + + public function isRoute(mixed $name, ServerRequestInterface $request) : bool + { + foreach((array) $name as $item) { + if ( fnmatch($item, $request->getAttribute('lean.route')->name) ) { + return true; + } + } + + return false; + } } diff --git a/src/Kernel.php b/src/Kernel.php index 9893efa..84096da 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -11,9 +11,11 @@ use League\Route\Strategy\ApplicationStrategy; use Psr\Http\Message\ServerRequestInterface; +use Psr\SimpleCache\CacheInterface; use Tell\I18n; use Ulmus\Container\AdapterProxy; +use Ulmus\Ulmus; use Zend\Diactoros\ServerRequestFactory, Zend\HttpHandlerRunner\Emitter\EmitterInterface; @@ -127,6 +129,7 @@ class Kernel { protected function serviceContainer() : self { $this->container->has(AdapterProxy::class) and $this->container->get(AdapterProxy::class); + $this->container->has('ulmus.caching') and ( Ulmus::$cache = $this->container->get('ulmus.caching') ); $this->container->has(Lean::class) and $this->container->get(Lean::class); if ($this->container->has(I18n::class)) { diff --git a/src/Lean.php b/src/Lean.php index 26bde6b..85ad5c5 100644 --- a/src/Lean.php +++ b/src/Lean.php @@ -49,7 +49,7 @@ class Lean return null; } - public function getPiceaContext() : string + public function getPiceaContext() /*: string|array */ { foreach(array_reverse($this->applications) as $apps) { if ( $apps->piceaContext ?? null ) { diff --git a/src/Routing.php b/src/Routing.php index 88851ca..ac759d0 100644 --- a/src/Routing.php +++ b/src/Routing.php @@ -2,6 +2,7 @@ namespace Lean; +use Notes\Annotation; use Taxus\Taxus; use League\Route\RouteGroup, @@ -27,6 +28,8 @@ use function DI\autowire, DI\create; class Routing { + public Annotation $selectedRoute; + protected Session $session; protected Cookie $cookie; @@ -106,7 +109,13 @@ class Routing { $container->get(Picea::class)->globalVariables['route'] = $annotation; } - return $object->$method($request->withAttribute('lean.route', $annotation), $arguments); + $request = $request->withAttribute('lean.route', $annotation); + + $this->session->set("lean.route", $annotation); + + $container->set(ServerRequestInterface::class, $request); + + return $object->$method($request, $arguments); }); } } diff --git a/view/lean/widget/calendar.phtml b/view/lean/widget/calendar.phtml index 634cebd..0b46a94 100644 --- a/view/lean/widget/calendar.phtml +++ b/view/lean/widget/calendar.phtml @@ -32,9 +32,7 @@