Merge branch 'master' of https://git.mcnd.ca/mcndave/lean
This commit is contained in:
		
						commit
						70e7b54c65
					
				| @ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "mcnd/lean", | ||||
|     "description": "A more-than-micro framework for basic apps", | ||||
|     "description": "A micro framework for rapid application development (RAD)", | ||||
|     "type": "library", | ||||
|     "license": "MIT", | ||||
|     "authors": [ | ||||
| @ -24,7 +24,6 @@ | ||||
|         "ralouphie/getallheaders": "dev-master", | ||||
|         "swiftmailer/swiftmailer": "^6.2@dev", | ||||
|         "mcnd/storage": "dev-master", | ||||
|         "mcnd/lean": "dev-master", | ||||
|         "mcnd/lean-console": "dev-master", | ||||
|         "mcnd/ulmus": "dev-master", | ||||
|         "mcnd/tell": "dev-master", | ||||
| @ -109,5 +108,26 @@ | ||||
|         "post-update-cmd": [ | ||||
|             "Lean\\Composer::postUpdate" | ||||
|         ] | ||||
|     }, | ||||
|     "extra" : { | ||||
|         "lean" : { | ||||
|             "autoload": { | ||||
|                 "definitions" : [ | ||||
|                     "meta/definitions/software.php", | ||||
|                     "meta/definitions/authorize.php", | ||||
|                     "meta/definitions/email.php", | ||||
|                     "meta/definitions/event.php", | ||||
|                     "meta/definitions/http.php", | ||||
|                     "meta/definitions/language.php", | ||||
|                     "meta/definitions/routes.php", | ||||
|                     "meta/definitions/software.php", | ||||
|                     "meta/definitions/storage.php", | ||||
|                     "meta/definitions/template.php" | ||||
|                 ], | ||||
|                 "config": [ | ||||
|                     "meta/config.php" | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								meta/config.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								meta/config.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| <?php | ||||
| 
 | ||||
| return [ | ||||
|     'ulmus' => [ | ||||
|         'connections' => [ | ||||
|             'lean' => [ | ||||
|                 'adapter'  => 'SQLite', | ||||
|                 'path'     => getenv('PROJECT_PATH') . DIRECTORY_SEPARATOR . "var/lean.sqlite3", | ||||
|                 'pragma_begin' => "journal_mode=WAL", | ||||
|                 'pragma_close' => "analysis_limit=500,optimize", | ||||
|             ], | ||||
|         ], | ||||
|     ], | ||||
| ]; | ||||
							
								
								
									
										46
									
								
								meta/definitions/authorize.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								meta/definitions/authorize.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| <?php | ||||
| 
 | ||||
| use Lean\Factory\HttpFactory; | ||||
| 
 | ||||
| use Ulmus\User\{Entity, | ||||
|     Lib\Authenticate, | ||||
|     Middleware\HeaderAuthenticationMiddleware, | ||||
|     Middleware\PostRequestAuthenticationMiddleware, | ||||
|     Authorize\PostRequestAuthentication}; | ||||
| 
 | ||||
| use Picea\Picea; | ||||
| 
 | ||||
| use Storage\{ Cookie, Session }; | ||||
| 
 | ||||
| use function DI\{get, autowire, create}; | ||||
| 
 | ||||
| return [ | ||||
|     Authenticate::class => create(Authenticate::class)->constructor(get(Entity\UserInterface::class), get(Session::class), get(Cookie::class), get('authentication.method')), | ||||
| 
 | ||||
|     HeaderAuthenticationMiddleware::class => create(HeaderAuthenticationMiddleware::class)->constructor(get(Entity\UserInterface::class), get('authorize.error')), | ||||
| 
 | ||||
|     PostRequestAuthentication::class => create(PostRequestAuthentication::class)->constructor(get(\Ulmus\User\Lib\Authenticate::class), "email", "email", "password"), | ||||
| 
 | ||||
|     PostRequestAuthenticationMiddleware::class => create(PostRequestAuthenticationMiddleware::class)->constructor(get(Entity\UserInterface::class), get('authentication.error'), get(PostRequestAuthentication::class)), | ||||
| 
 | ||||
|     'authentication.method' => null, | ||||
| 
 | ||||
|     'authorize.error' => function($c) { | ||||
|         return function(array $errorData) { | ||||
|             return HttpFactory::createJsonResponse($errorData + [ | ||||
|                 'api.error' => "Authorization failed", | ||||
|                 'api.datetime' => (new \DateTime)->format(\DateTime::ATOM), | ||||
|             ]); | ||||
|         }; | ||||
|     }, | ||||
| 
 | ||||
|     'authentication.error' => function($c, Picea $picea) { | ||||
|         return function($message) use ($picea) { | ||||
|             return HttpFactory::createHtmlResponse($picea->renderHtml('lean/error/500', [ | ||||
|                 'title' => "Authentication failed", | ||||
|                 'subtitle' => "", | ||||
|                 'message' => $message, | ||||
|             ])); | ||||
|         }; | ||||
|     }, | ||||
| ]; | ||||
| @ -1,33 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use Psr\Http\Message\ResponseInterface; | ||||
| 
 | ||||
| use Mcnd\CLI\CliMiddleware; | ||||
| 
 | ||||
| use Notes\CLI\CommandFetcher; | ||||
| 
 | ||||
| use Lean\Lean; | ||||
| 
 | ||||
| return [ | ||||
|     CommandFetcher::class => function($c) { | ||||
|         $fetcher = new CommandFetcher(null, null, $c->get('cli.caching')); | ||||
| 
 | ||||
|         $fetcher->setFolderList(array_map(function($item) { | ||||
|             return $item; | ||||
|         }, $c->get(Lean::class)->getCli())); | ||||
| 
 | ||||
|         return $fetcher; | ||||
|     }, | ||||
| 
 | ||||
|     CliMiddleware::class => function($c) { | ||||
|         return new CliMiddleware($c, $c->get('cli.response:default'), $c->get(CommandFetcher::class)); | ||||
|     }, | ||||
| 
 | ||||
|     'cli.response:default' => function($c) { | ||||
|         return function() { | ||||
|             return new \Laminas\Diactoros\Response\TextResponse("This is the default response from CLI middleware which indicates that no command were registered for this application.\n"); | ||||
|         }; | ||||
|     }, | ||||
| ]; | ||||
| @ -1,32 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use Laminas\Diactoros\Response\HtmlResponse; | ||||
| 
 | ||||
| use Cronard\CronardMiddleware, | ||||
|     Notes\Cronard\TaskFetcher; | ||||
| 
 | ||||
| use Psr\Http\Message\ResponseInterface; | ||||
| 
 | ||||
| use Lean\Lean; | ||||
| 
 | ||||
| return [ | ||||
|     CronardMiddleware::class => function($c) { | ||||
|         $cronardMiddleware = new CronardMiddleware($c, getenv('CRON_KEY'), function() : ResponseInterface { | ||||
|             return new HtmlResponse(sprintf("%s - cron task begin...", date('Y-m-d H:i:s'))); | ||||
|         }, [], $c->get(TaskFetcher::class)); | ||||
| 
 | ||||
|         return $cronardMiddleware->fromFile(getenv("META_PATH")."/crontab.php")->fromAnnotations($c->get(TaskFetcher::class)); | ||||
|     }, | ||||
| 
 | ||||
|     TaskFetcher::class => function($c) { | ||||
|         $fetcher = new TaskFetcher(null, null, $c->get('cronard.caching')); | ||||
| 
 | ||||
|         $fetcher->setFolderList(array_map(function($item) { | ||||
|             return $item; | ||||
|         }, $c->get(Lean::class)->getCronard())); | ||||
| 
 | ||||
|         return $fetcher; | ||||
|     }, | ||||
| ]; | ||||
| @ -26,7 +26,7 @@ return [ | ||||
|     Event\EventDefinition::class => function($c) { | ||||
|         return new Event\EventDefinition([ | ||||
|             new class() implements RoutingCompileRoutes { | ||||
|                 public function execute(Routing $routing, Route|\Notes\Route\Annotation\Method\Route $attribute) : void | ||||
|                 public function execute(Routing $routing, Route $attribute) : void | ||||
|                 { | ||||
|                     if (null !== ($name = $attribute->name ?? null)) { | ||||
|                         $routing->extension->registerRoute($name, $attribute->getRoute(), $attribute->class, $attribute->classMethod, $attribute->methods ?? (array)$attribute->method); | ||||
| @ -35,7 +35,7 @@ return [ | ||||
|             }, | ||||
| 
 | ||||
|             new class() implements RoutingMapRoutes { | ||||
|                 public function execute(Routing $routing, ContainerInterface $container, ServerRequestInterface & $request, Route|\Notes\Route\Annotation\Method\Route $attribute) : void | ||||
|                 public function execute(Routing $routing, ContainerInterface $container, ServerRequestInterface & $request, Route $attribute) : void | ||||
|                 { | ||||
|                     $class = $attribute->class; | ||||
|                     $method = $attribute->classMethod; | ||||
|  | ||||
| @ -19,7 +19,6 @@ return [ | ||||
|         return $i18n; | ||||
|     }, | ||||
| 
 | ||||
|     # TODO -- accept folders from Lean Apps
 | ||||
|     Tell\Reader\PhpReader::class => function($c) { | ||||
|         return new Tell\Reader\PhpReader($c->get(Lean\Lean::class)->getI18n('php'), false); | ||||
|     }, | ||||
|  | ||||
| @ -1,12 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use Negundo\Client\{ SoftwareConfig, Dump, Task, NegundoMiddleware }; | ||||
| 
 | ||||
| return [ | ||||
|     SoftwareConfig::class => create(SoftwareConfig::class)->constructor(getenv('NEGUNDO_HASH'), getenv('NEGUNDO_SERVER')), | ||||
|     # NegundoMiddleware::class => create(NegundoMiddleware::class)->constructor(get(SoftwareConfig::class)),
 | ||||
|     Dump::class => create(Dump::class)->constructor(get(SoftwareConfig::class)), | ||||
|     Task::class => create(Task::class)->constructor(get(SoftwareConfig::class)), | ||||
| ]; | ||||
| @ -3,31 +3,23 @@ | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use League\Route\Strategy\ApplicationStrategy, | ||||
|     League\Route\Http\Exception\NotFoundException, | ||||
|     League\Route\Router; | ||||
| 
 | ||||
| use Psr\Http\Message\ResponseFactoryInterface, | ||||
|     Psr\Container\ContainerInterface, | ||||
|     Psr\Http\Message\ResponseInterface, | ||||
|     Psr\Http\Message\ServerRequestInterface, | ||||
|     Psr\Http\Server\MiddlewareInterface, | ||||
|     Psr\Http\Server\RequestHandlerInterface, | ||||
|     Psr\SimpleCache\CacheInterface; | ||||
| 
 | ||||
| use TheBugs\JavascriptMiddleware; | ||||
| use Psr\Container\ContainerInterface; | ||||
| 
 | ||||
| use Cronard\CronardMiddleware; | ||||
| 
 | ||||
| use Tuupola\Middleware\HttpBasicAuthentication; | ||||
| 
 | ||||
| use Notes\Route\RouteFetcher; | ||||
| 
 | ||||
| use Notes\Breadcrumb\Breadcrumb; | ||||
| 
 | ||||
| use Ulmus\User\Lib\Authenticate; | ||||
| 
 | ||||
| use Storage\SessionMiddleware; | ||||
| 
 | ||||
| use Ulmus\User\Middleware\{ | ||||
|     HeaderAuthenticationMiddleware, | ||||
|     PostRequestAuthenticationMiddleware | ||||
| }; | ||||
| 
 | ||||
| return [ | ||||
|     Lean\Routing::class => autowire(Lean\Routing::class), | ||||
| 
 | ||||
| @ -53,17 +45,28 @@ return [ | ||||
| 
 | ||||
|     ApplicationStrategy::class => autowire(\Lean\ApplicationStrategy::class), | ||||
| 
 | ||||
|     'routes.middlewares'  => [ "dump", "errorHandler", SessionMiddleware::class, CronardMiddleware::class, Mcnd\Event\EventMiddleware::class, Mcnd\CLI\CliMiddleware::class,  ], | ||||
|     'routes.middlewares'  => [ | ||||
|         "dump", "errorHandler", SessionMiddleware::class, CronardMiddleware::class, Mcnd\Event\EventMiddleware::class, Mcnd\CLI\CliMiddleware::class, | ||||
|     ], | ||||
| 
 | ||||
|     'app.middlewares' => [ | ||||
|         HeaderAuthenticationMiddleware::class, | ||||
|         PostRequestAuthenticationMiddleware::class, | ||||
|     ], | ||||
| 
 | ||||
|     'routes.list' => function($c) { | ||||
|         return function (ContainerInterface $container) { | ||||
|             $router = $container->get(Router::class); | ||||
| 
 | ||||
|             foreach($container->get('routes.middlewares') as $i => $middleware) { | ||||
|                 if ( $container->has($middleware) ) { | ||||
|             foreach([ 'routes.middlewares', 'app.middlewares' ] as $key) { | ||||
|                 if ( $container->has($key) ) { | ||||
|                     foreach ($container->get($key) as $i => $middleware) { | ||||
|                         if ($container->has($middleware)) { | ||||
|                             $router->middleware($container->get($middleware)); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             $routing = $container->get(Lean\Routing::class); | ||||
|             $routing->registerRoute($container, getenv('URL_BASE')); | ||||
|  | ||||
| @ -2,18 +2,10 @@ | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use Laminas\Diactoros\Response\HtmlResponse; | ||||
| 
 | ||||
| use TheBugs\JavascriptMiddleware; | ||||
| 
 | ||||
| 
 | ||||
| use Cronard\CronardMiddleware, | ||||
|     Notes\Cronard\TaskFetcher; | ||||
| 
 | ||||
| use Lean\Lean; | ||||
| 
 | ||||
| use Psr\Http\Message\ResponseInterface; | ||||
| 
 | ||||
| use Storage\Cookie, | ||||
|     Storage\Session, | ||||
|     Storage\SessionMiddleware; | ||||
| @ -72,6 +64,8 @@ return [ | ||||
|         'routes' => [], | ||||
| 
 | ||||
|         'cronard' => [], | ||||
| 
 | ||||
|         'taxus' => [], | ||||
|     ], | ||||
| 
 | ||||
|     Lean::class => autowire(Lean::class), | ||||
|  | ||||
							
								
								
									
										19
									
								
								meta/definitions/storage.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								meta/definitions/storage.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <?php | ||||
| 
 | ||||
| use Psr\Container\ContainerInterface; | ||||
| 
 | ||||
| use Ulmus\ConnectionAdapter, | ||||
|     Ulmus\Container\AdapterProxy; | ||||
| 
 | ||||
| use Storage\Session; | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| return [ | ||||
|     'lean:adapter.sqlite' => function($c) { | ||||
|         $adapter = new ConnectionAdapter('sqlite', $c->get('config')['ulmus'], true); | ||||
|         $adapter->resolveConfiguration(); | ||||
| 
 | ||||
|         return $adapter; | ||||
|     } | ||||
| ]; | ||||
| @ -2,68 +2,13 @@ | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use Picea\{ | ||||
|     Language\LanguageRegistration, | ||||
|     Caching\Cache, | ||||
|     Caching\Opcache, | ||||
|     Compiler, | ||||
|     Compiler\Context, | ||||
|     Compiler\BaseContext, | ||||
|     FileFetcher, | ||||
|     Method\Request}; | ||||
| use Picea\{ Language\LanguageRegistration, }; | ||||
| 
 | ||||
| use Picea\Extension\{ LanguageHandlerInterface, LanguageExtension, TitleExtension, NumberExtension, UrlExtension }; | ||||
| use Picea\Extension\{ LanguageHandlerInterface, }; | ||||
| 
 | ||||
| use Picea\Ui\{ Method, Ui }; | ||||
| use Picea\Ui\{ Ui }; | ||||
| 
 | ||||
| return [ | ||||
|     Picea\Picea::class => function($c) { | ||||
|         return new Picea\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) { | ||||
|         return new BaseContext($c->get(Lean\Lean::class)->getPiceaContext()); | ||||
|     }, | ||||
| 
 | ||||
|     Ui::class => autowire(Ui::class), | ||||
| 
 | ||||
|     Compiler::class => autowire(Compiler::class), | ||||
| 
 | ||||
|     Request::class => autowire(Request::class), | ||||
| 
 | ||||
|     Method\Form::class => autowire(Method\Form::class), | ||||
| 
 | ||||
|     Method\Pagination::class => autowire(Method\Pagination::class), | ||||
| 
 | ||||
|     LanguageExtension::class => create(LanguageExtension::class)->constructor(get(LanguageHandlerInterface::class)), | ||||
| 
 | ||||
|     LanguageHandlerInterface::class => autowire(\Lean\LanguageHandler::class), | ||||
| 
 | ||||
|     LanguageRegistration::class => create(\Lean\PiceaDefaultRegistration::class)->constructor(get('picea.extensions'), [], [], get(Ui::class), null), | ||||
| 
 | ||||
|     'picea.extensions' => function(\Psr\Container\ContainerInterface $c) { | ||||
|         return array_merge([ | ||||
|             $c->get(LanguageExtension::class), | ||||
|             $c->get(TitleExtension::class), | ||||
|             $c->get(NumberExtension::class), | ||||
|             $c->get(UrlExtension::class), | ||||
|             $c->get(Method\Form::class), | ||||
|             $c->get(Method\Pagination::class), | ||||
|             $c->get(Request::class), | ||||
|         ], class_exists(\Taxus\Picea\Extension::class) ? [ $c->get(\Taxus\Picea\Extension::class) ] : [], | ||||
|             array_map(fn($class) => $c->get($class), $c->get(Lean\Lean::class)->getPiceaExtensions()) | ||||
|         ); | ||||
|     }, | ||||
| 
 | ||||
|     TitleExtension::class => autowire(TitleExtension::class), | ||||
| 
 | ||||
|     NumberExtension::class => autowire(NumberExtension::class), | ||||
| 
 | ||||
|     UrlExtension::class => create(UrlExtension::class)->constructor(getenv("URL_BASE"), get('git.commit'), explode(',', getenv('APP_URL')), (bool) getenv('FORCE_SSL')), | ||||
| 
 | ||||
|     Cache::class => create(Opcache::class)->constructor(getenv("CACHE_PATH"), get(Context::class)), | ||||
| 
 | ||||
|     FileFetcher::class => function($c) { | ||||
|         return new FileFetcher($c->get(Lean\Lean::class)->getViewPaths()); | ||||
|     }, | ||||
| ]; | ||||
| @ -31,11 +31,17 @@ return [ | ||||
|                 ], | ||||
|             ], | ||||
| 
 | ||||
|             #'sqlite' => [
 | ||||
|             #    'adapter'  => getenv("SQLITE_ADAPTER"),
 | ||||
|             #    'path'     => getenv('PROJECT_PATH') . DIRECTORY_SEPARATOR . getenv("SQLITE_PATH"),
 | ||||
|             #    'pragma'   => explode(',', getenv("SQLITE_PRAGMA")),
 | ||||
|             #],
 | ||||
|             'sqlite' => [ | ||||
|                 'adapter'  => getenv("SQLITE_ADAPTER"), | ||||
|                 'path'     => getenv('PROJECT_PATH') . DIRECTORY_SEPARATOR . getenv("SQLITE_PATH"), | ||||
|                 'pragma'   => explode(',', getenv("SQLITE_PRAGMA")), | ||||
|                 'pragma_begin' => array_merge( | ||||
|                      explode(',', getenv("SQLITE_PRAGMA_BEGIN")), explode(',', getenv('DEBUG') ? getenv("SQLITE_PRAGMA_DEBUG_BEGIN") : "") | ||||
|                  ), | ||||
|                  'pragma_close' => array_merge( | ||||
|                      explode(',', getenv("SQLITE_PRAGMA_CLOSE")), explode(',', getenv('DEBUG') ? getenv("SQLITE_PRAGMA_DEBUG_CLOSE") : "") | ||||
|                  ), | ||||
|             ], | ||||
|         ] | ||||
|     ] | ||||
| ]; | ||||
|  | ||||
| @ -22,29 +22,15 @@ use TheBugs\Email\{ EmailConfiguration, MailerInterface, SwiftMailer }; | ||||
| use Taxus\{ Taxus, PermissionGrantInterface }; | ||||
| 
 | ||||
| return [ | ||||
|     Entity\User::class => autowire(Entity\User::class), | ||||
| 
 | ||||
|     Authenticate::class => create(Authenticate::class)->constructor(get(Session::class), get(Cookie::class), get('authentication.method')), | ||||
|     \Ulmus\User\Entity\UserInterface::class => autowire(Entity\User::class), | ||||
| 
 | ||||
|     SecurityHandler::class => create(SecurityHandler::class)->constructor(function() { | ||||
|         return new RedirectResponse(getenv("URL_BASE")."/login"); | ||||
|         return Lean\Factory\HttpFactory::createRedirectResponse(getenv("URL_BASE")."/login"); | ||||
|     }, get('authentication.unauthorize'), get(Taxus::class)), | ||||
| 
 | ||||
|     'authentication.method' => null, | ||||
| 
 | ||||
|     'authentication.error' => function($c, Picea $picea) { | ||||
|         return function($message) use ($picea) { | ||||
|             return new HtmlResponse($picea->renderHtml('lean/error/500', [ | ||||
|                 'title' => "", | ||||
|                 'subtitle' => "", | ||||
|                 'message' => $message, | ||||
|             ])); | ||||
|         }; | ||||
|     }, | ||||
| 
 | ||||
|     'authentication.unauthorize' => function($c, Picea $picea) { | ||||
|         return function($message) use ($picea) { | ||||
|             return new HtmlResponse($picea->renderHtml('lean/error/401', [ | ||||
|             return Lean\Factory\HttpFactory::createHtmlResponse($picea->renderHtml('lean/error/401', [ | ||||
|                 'title' => "", | ||||
|                 'subtitle' => "", | ||||
|                 'message' => $message, | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| <?php | ||||
| 
 | ||||
| use Taxus\Privilege; | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| $dir = getenv("META_PATH") . "/definitions"; | ||||
| 
 | ||||
| return array_merge( | ||||
|     Lean\Lean::definitions(), | ||||
| 
 | ||||
|     Lean\Console\Lean::definitions(), | ||||
|     Lean\Lean::autoloadDefinitionsFromComposerExtra(), | ||||
| 
 | ||||
|     [ | ||||
|         '%APPKEY%' => [ | ||||
| @ -15,7 +15,6 @@ return array_merge( | ||||
|                 'context' => "%ESCAPED_NAMESPACE%\\View", | ||||
|                 'asset' => [], | ||||
|                 'extensions' => [], | ||||
| 
 | ||||
|             ], | ||||
| 
 | ||||
|             'ulmus' => [ | ||||
| @ -37,12 +36,28 @@ return array_merge( | ||||
|             'cli' => [ | ||||
|                 '%ESCAPED_NAMESPACE%\\Controller' => implode(DIRECTORY_SEPARATOR, [ getenv("PROJECT_PATH"), 'src', 'Controller', '' ]), | ||||
|             ], | ||||
| 
 | ||||
|             'taxus' => [ | ||||
|                 [ new Privilege("dev", "Is a developper of this application."), "is_dev" ], | ||||
|                 [ new Privilege("admin", "Can manage mostly everything from this application."), "is_admin" ], | ||||
|                 [ new Privilege("user", "Is an authenticated user."), "is_user" ], | ||||
|                 [ new Privilege("anonymous", "Is an anonymous (unauthenticated) user."), "is_anonymous" ], | ||||
|             ] | ||||
|         ], | ||||
| 
 | ||||
|         'app.middlewares' => [], | ||||
|     ], | ||||
| 
 | ||||
|     require("$dir/auth.php"), | ||||
|     require("$dir/storage.php"), | ||||
|     require("$dir/security.php"), | ||||
|     require("$dir/env/" . getenv('APP_ENV') . ".php"), | ||||
|     [ 'config' => function () { return require(getenv("META_PATH")."/config.php"); } ] | ||||
|     [ | ||||
|         'config' => function () { | ||||
|             return array_merge_recursive( | ||||
|                 Lean\Lean::autoloadConfigFromComposerExtra(), | ||||
|                 require(getenv("META_PATH")."/config.php") | ||||
|             ); | ||||
|         } | ||||
|     ] | ||||
| ); | ||||
|  | ||||
| @ -1,20 +1,17 @@ | ||||
| <?php | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use Storage\Session; | ||||
| 
 | ||||
| use Taxus\{ Privilege, Taxus, PermissionGrantInterface, DefaultPermissionGrant }; | ||||
| 
 | ||||
| use Psr\Http\Message\ServerRequestInterface; | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| return [ | ||||
|     Taxus::class => function ($c) { | ||||
|         return ( new Taxus( $c->get(PermissionGrantInterface::class) ) )->add( | ||||
|             [ new Privilege("dev", "Is a developper of this application."), "is_dev" ], | ||||
|             [ new Privilege("admin", "Can manage mostly everything from this application."), "is_admin" ], | ||||
|             [ new Privilege("user", "Is an authenticated user."), "is_user" ], | ||||
|             [ new Privilege("anonymous", "Is an anonymous (unauthenticated) user."), "is_anonymous" ], | ||||
|             $c->get(Lean\Lean::class)->getTaxusPrivileges() | ||||
|         ); | ||||
|     }, | ||||
| 
 | ||||
|  | ||||
| @ -19,6 +19,7 @@ return [ | ||||
| 
 | ||||
|     AdapterProxy::class => function (ContainerInterface $c) { | ||||
|         return new AdapterProxy( | ||||
|             $c->get('lean:adapter.sqlite'), | ||||
|             $c->get(ConnectionAdapter::class) | ||||
|         ); | ||||
|     }, | ||||
|  | ||||
| @ -5,36 +5,33 @@ namespace %NAMESPACE%\Lib; | ||||
| use Picea\Picea; | ||||
| use Storage\Session; | ||||
| use Ulmus\User\Entity\User; | ||||
| use Ulmus\User\Lib\Authenticate; | ||||
| use Notes\Route\Attribute\Object\Route; | ||||
| use Notes\Security\Attribute\Security; | ||||
| 
 | ||||
| use %NAMESPACE%\{ Entity, Lib, Form }; | ||||
| 
 | ||||
| use Mcnd\Event\EventManager; | ||||
| use Ulmus\User\Entity\UserInterface; | ||||
| 
 | ||||
| #[Security(locked: false)]
 | ||||
| #[Route(method: ['GET', 'POST', ])]
 | ||||
| trait ControllerTrait { | ||||
|     use \Lean\ControllerTrait; | ||||
| 
 | ||||
|     public ? \Ulmus\User\Entity\User $user; | ||||
| 
 | ||||
|     protected Authenticate $authenticate; | ||||
|     public ? UserInterface $user; | ||||
| 
 | ||||
|     protected EventManager $eventManager; | ||||
| 
 | ||||
|     public function __construct(Picea $picea, Session $session, Authenticate $authenticate, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) { | ||||
|         $this->initializeController($picea, $session, $authenticate, $breadcrumb, $eventManager); | ||||
|     public function __construct(Picea $picea, Session $session, UserInterface $user, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) { | ||||
|         $this->initializeController($picea, $session, $user, $breadcrumb, $eventManager); | ||||
|     } | ||||
| 
 | ||||
|     public function initializeController(Picea $picea, Session $session, Authenticate $authenticate, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) { | ||||
|     public function initializeController(Picea $picea, Session $session, UserInterface $user, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) { | ||||
|         $this->picea = $picea; | ||||
|         $this->authenticate = $authenticate; | ||||
|         $this->session = $session; | ||||
|         $this->eventManager = $eventManager; | ||||
|         $this->breadcrumb = $breadcrumb; | ||||
|         $this->user = $authenticate->rememberMe( Entity\User::repository() ) ?: new Entity\User(); | ||||
|         $this->user = $user; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,9 +1,7 @@ | ||||
| <?php | ||||
| 
 | ||||
| 
 | ||||
| namespace Lean; | ||||
| 
 | ||||
| 
 | ||||
| class Application | ||||
| { | ||||
|     public string $name; | ||||
| @ -30,6 +28,8 @@ class Application | ||||
| 
 | ||||
|     public array $tellPhp; | ||||
| 
 | ||||
|     public array $taxus; | ||||
| 
 | ||||
|     public array $data = []; | ||||
| 
 | ||||
|     public function __construct(string $name) { | ||||
| @ -40,7 +40,14 @@ class Application | ||||
|     { | ||||
|         $this->data = array_replace($this->data, $data); | ||||
| 
 | ||||
|         if (is_array($picea = $data['picea'] ?? false)) { | ||||
|         $this->loadData(); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| 
 | ||||
|     public function loadData() : static | ||||
|     { | ||||
|         if (is_array($picea = $this->data['picea'] ?? false)) { | ||||
|             if ($picea['context'] ?? false ) { | ||||
|                 $this->piceaContext = $picea['context']; | ||||
|             } | ||||
| @ -58,13 +65,13 @@ class Application | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (is_array($ulmus = $data['ulmus'] ?? false)) { | ||||
|         if (is_array($ulmus = $this->data['ulmus'] ?? false)) { | ||||
|             if ($ulmus['entities'] ?? false) { | ||||
|                 $this->entities = $ulmus['entities']; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (is_array($tell = $data['tell'] ?? false)) { | ||||
|         if (is_array($tell = $this->data['tell'] ?? false)) { | ||||
|             if ($tell['json'] ?? false) { | ||||
|                 $this->tellJson = $tell['json']; | ||||
|             } | ||||
| @ -74,20 +81,24 @@ class Application | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (is_array($data['routes'] ?? false)) { | ||||
|             $this->routes = $data['routes']; | ||||
|         if (is_array($this->data['routes'] ?? false)) { | ||||
|             $this->routes = $this->data['routes']; | ||||
|         } | ||||
| 
 | ||||
|         if (is_array($data['cronard'] ?? false)) { | ||||
|             $this->cronard = $data['cronard']; | ||||
|         if (is_array($this->data['cronard'] ?? false)) { | ||||
|             $this->cronard = $this->data['cronard']; | ||||
|         } | ||||
| 
 | ||||
|         if (is_array($data['events'] ?? false)) { | ||||
|             $this->events = $data['events']; | ||||
|         if (is_array($this->data['events'] ?? false)) { | ||||
|             $this->events = $this->data['events']; | ||||
|         } | ||||
| 
 | ||||
|         if (is_array($data['cli'] ?? false)) { | ||||
|             $this->cli = $data['cli']; | ||||
|         if (is_array($this->data['cli'] ?? false)) { | ||||
|             $this->cli = $this->data['cli']; | ||||
|         } | ||||
| 
 | ||||
|         if (is_array($this->data['taxus'] ?? false)) { | ||||
|             $this->taxus = $this->data['taxus']; | ||||
|         } | ||||
| 
 | ||||
|         return $this; | ||||
|  | ||||
| @ -2,33 +2,19 @@ | ||||
| 
 | ||||
| namespace Lean; | ||||
| 
 | ||||
| use Lean\Response\{FileDownloadResponse, PdfResponse, ImageResponse, DownloadResponse}; | ||||
| 
 | ||||
| use Picea, | ||||
|     Picea\Ui\Method\FormContext; | ||||
| 
 | ||||
| use Psr\Http\Message\ServerRequestInterface; | ||||
| use Storage\Session; | ||||
| use Laminas\Diactoros\Response\{EmptyResponse, HtmlResponse, TextResponse, RedirectResponse, JsonResponse}; | ||||
| 
 | ||||
| use Ulmus\EntityCollection; | ||||
| 
 | ||||
| use Psr\Http\Message\ResponseInterface; | ||||
| 
 | ||||
| use Lean\Factory\HttpFactory; | ||||
| use Notes\Route\Attribute\Object\Route; | ||||
| use Notes\Security\Attribute\Security; | ||||
| use Picea, Picea\Ui\Method\FormContext; | ||||
| use TheBugs\Email\MailerInterface; | ||||
| use Storage\Session; | ||||
| 
 | ||||
| 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, | ||||
|     Notes\Security\Annotation\Taxus, | ||||
|     Notes\Tell\Annotation\Language; | ||||
| use Psr\Http\Message\{ ServerRequestInterface, ResponseInterface }; | ||||
| 
 | ||||
| use function file_get_contents; | ||||
| 
 | ||||
| #[\Notes\Security\Attribute\Security(locked: true)]
 | ||||
| #[\Notes\Route\Attribute\Object\Route(method: [ "GET", "POST", "DELETE" ])]
 | ||||
| #[Security(locked: true)]
 | ||||
| #[Route(method: [ "GET", "POST", "DELETE" ])]
 | ||||
| trait ControllerTrait { | ||||
|     public ? \Notes\Breadcrumb\Breadcrumb $breadcrumb; | ||||
| 
 | ||||
| @ -52,7 +38,7 @@ trait ControllerTrait { | ||||
|     public function renderRawView(string $view, ?array $variables = null) : string | ||||
|     { | ||||
|         if ( null === $content = $this->picea->renderHtml($view, $variables ?? [], $this) ) { | ||||
|             throw new \RuntimeException("Picea's renderHtml() returned NULL as result ; an error occured within your template `$view`."); | ||||
|             throw new \RuntimeException("Picea's renderHtml() returned NULL as result ; an error occurred within your template `$view`."); | ||||
|         } | ||||
| 
 | ||||
|         return $content; | ||||
| @ -78,47 +64,58 @@ trait ControllerTrait { | ||||
|     } | ||||
| 
 | ||||
|     protected function redirect(string $url, int $code = 302, array $headers = []) { | ||||
|         return new RedirectResponse($url, $code, $headers); | ||||
|         return HttpFactory::createRedirectResponse($url, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function renderNothing(int $code = 204, array $headers = []) : ResponseInterface | ||||
|     { | ||||
| 	    return new EmptyResponse($code, $headers); | ||||
| 	    return HttpFactory::createEmptyResponse($code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function renderText(string $html, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     public static function renderText(string $text, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new TextResponse($html, $code, $headers); | ||||
|         return HttpFactory::createTextResponse($text, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function renderHtml(string $html, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new HtmlResponse($html, $code, $headers); | ||||
|         return HttpFactory::createHtmlResponse($html, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function renderJson(mixed $data, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new JsonResponse($data, $code, $headers); | ||||
|         return HttpFactory::createJsonResponse($data, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public function renderPdf($rawdata, int $status = 200, array $headers = []) : PdfResponse | ||||
|     public function renderPdf($rawdata, int $status = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new PdfResponse($rawdata, $status, $headers); | ||||
|         return HttpFactory::createPdfResponse($rawdata, $status, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function renderDownloadable(string $data, string $filename, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new DownloadResponse($data, $filename, $code, $headers); | ||||
|         return HttpFactory::createDownloadableResponse($data, $filename, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function renderImage(string $data, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new ImageResponse($data, $code, $headers); | ||||
|         return HttpFactory::createImageResponse($data, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function renderAsset(string $path, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new FileDownloadResponse($path, $code, $headers); | ||||
|         return HttpFactory::createFileDownloadResponse($path, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public function renderMarkdown(string $filepath, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         if ( ! class_exists(CommonMarkConverter::class)) { | ||||
|             throw new \BadFunctionCallException("League\CommonMark seems to be missing, please install dependency before trying to render Markdown content"); | ||||
|         } | ||||
| 
 | ||||
|         $markdown = ( new CommonMarkConverter() )->convertToHtml(file_get_contents($filepath)); | ||||
| 
 | ||||
|         return $this->renderView("docs", get_defined_vars()); | ||||
|     } | ||||
| 
 | ||||
|     public function renderCLI(ServerRequestInterface $request, mixed $data) : ResponseInterface | ||||
|  | ||||
| @ -6,5 +6,5 @@ use Lean\Routing; | ||||
| use Notes\Route\Attribute\Method\Route; | ||||
| 
 | ||||
| interface RoutingCompileRoutes { | ||||
|     public function execute(Routing $routing, Route|\Notes\Route\Annotation\Method\Route $attribute) : void; | ||||
|     public function execute(Routing $routing, Route $attribute) : void; | ||||
| } | ||||
|  | ||||
| @ -8,5 +8,5 @@ use Psr\Container\ContainerInterface; | ||||
| use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface }; | ||||
| 
 | ||||
| interface RoutingMapRoutes { | ||||
|     public function execute(Routing $routing, ContainerInterface $container, ServerRequestInterface & $request, Route|\Notes\Route\Annotation\Method\Route $attribute) : void; | ||||
|     public function execute(Routing $routing, ContainerInterface $container, ServerRequestInterface & $request, Route $attribute) : void; | ||||
| } | ||||
|  | ||||
							
								
								
									
										55
									
								
								src/Factory/HttpFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/Factory/HttpFactory.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Lean\Factory; | ||||
| 
 | ||||
| use Laminas\Diactoros\Response\{EmptyResponse, HtmlResponse, JsonResponse, RedirectResponse, TextResponse}; | ||||
| use Lean\Response\{ DownloadResponse, ImageResponse, FileDownloadResponse, PdfResponse }; | ||||
| use Psr\Http\Message\ResponseInterface; | ||||
| 
 | ||||
| class HttpFactory | ||||
| { | ||||
|     public static function createRedirectResponse(string $url, int $code = 302, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new RedirectResponse($url, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createHtmlResponse(string $html, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new HtmlResponse($html, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createTextResponse(string $text, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new TextResponse($text, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createJsonResponse(mixed $data, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new JsonResponse($data, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createEmptyResponse(int $code = 204, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new EmptyResponse($code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createPdfResponse(\Stringable $binary, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new PdfResponse((string) $binary, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createDownloadableResponse(string $data, string $filename, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new DownloadResponse($data, $filename, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createImageResponse(string $data, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new ImageResponse($data, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     public static function createFileDownloadResponse(string $path, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return new FileDownloadResponse($path, $code, $headers); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								src/Lean.php
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/Lean.php
									
									
									
									
									
								
							| @ -93,6 +93,11 @@ class Lean | ||||
|         return array_merge(...array_map(fn($app) => $app->events ?? [], $this->applications)); | ||||
|     } | ||||
| 
 | ||||
|     public function getTaxusPrivileges() : array | ||||
|     { | ||||
|         return array_merge(...array_map(fn($app) => $app->taxus ?? [], $this->applications)); | ||||
|     } | ||||
| 
 | ||||
|     public function getEntities() : array | ||||
|     { | ||||
|         return array_merge(...array_map(fn($app) => $app->entities ?? [], $this->applications)); | ||||
| @ -150,23 +155,10 @@ class Lean | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     #[\Deprecated("Definitions are now loaded automatically from composer extra array.")]
 | ||||
|     public static function definitions() : array | ||||
|     { | ||||
|         $path = dirname(__DIR__) . "/meta/definitions/"; | ||||
| 
 | ||||
|         return array_replace( | ||||
|             class_exists(\Mcnd\CLI\CliMiddleware::class) ? require($path . "cli.php") : [], | ||||
|             class_exists(\Cronard\CronardMiddleware::class) ? require($path . "cronard.php") : [], | ||||
|             require($path . "email.php"), | ||||
|             require($path . "event.php"), | ||||
|             require($path . "http.php"), | ||||
|             require($path . "language.php"), | ||||
|             class_exists(\Negundo\Client\NegundoMiddleware::class) ? require($path . "negundo.php") : [], | ||||
|             require($path . "routes.php"), | ||||
|             # require($path . "security.php"),
 | ||||
|             require($path . "software.php"), | ||||
|             class_exists(\Picea\Picea::class) ?  require($path . "template.php") : [], | ||||
|         ); | ||||
|         return []; | ||||
|     } | ||||
| 
 | ||||
|     public static function autoloadDefinitionsFromComposerExtra() : array | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user