Merge branch 'master' of https://git.mcnd.ca/mcndave/lean
This commit is contained in:
		
						commit
						ffe66e522c
					
				| @ -87,6 +87,7 @@ | ||||
|                     "meta/definitions/email.php", | ||||
|                     "meta/definitions/event.php", | ||||
|                     "meta/definitions/http.php", | ||||
|                     "meta/definitions/orm.php", | ||||
|                     "meta/definitions/language.php", | ||||
|                     "meta/definitions/routes.php", | ||||
|                     "meta/definitions/software.php", | ||||
|  | ||||
| @ -35,7 +35,7 @@ return [ | ||||
|                 public function execute(Routing $routing, Route $attribute) : void | ||||
|                 { | ||||
|                     if (null !== ($name = $attribute->name ?? null)) { | ||||
|                         $this->extension->registerRoute($name, $attribute->getRoute(), $attribute->class, $attribute->classMethod, $attribute->methods ?? (array)$attribute->method); | ||||
|                         $this->extension->registerRoute($name, $attribute->getRoute(), $attribute->class, $attribute->classMethod, (array) ( $attribute->method ?? $attribute->methods )); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
| @ -1,29 +1,37 @@ | ||||
| <?php | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| 
 | ||||
| use Tell\I18n; | ||||
| use Psr\Container\ContainerInterface; | ||||
| use Notes\Tell\LanguageHandler; | ||||
| 
 | ||||
| return [ | ||||
|     Tell\I18n::class => create( Tell\I18n::class ) ->constructor( | ||||
|         get(Tell\Reader\JsonReader::class), | ||||
|         get(Tell\Reader\PhpReader::class), | ||||
|         get('tell.fallback') /* getenv("DEBUG") ? create(Tell\PrintMissingKey::class) : get('tell.fallback') */ | ||||
|     ), | ||||
| use function DI\autowire, DI\create, DI\get, DI\add; | ||||
| 
 | ||||
|     'tell.fallback' => function($c) { | ||||
|         $i18n = new Tell\I18n( $c->get(Tell\Reader\JsonReader::class), $c->get(Tell\Reader\PhpReader::class), new Tell\PrintMissingKey() ); | ||||
| return [ | ||||
|     I18n::class => function(ContainerInterface $container) { | ||||
|         $i18n = new I18n($container->get(Tell\Reader\JsonReader::class), $container->get(Tell\Reader\PhpReader::class), $container->get('tell.fallback')); | ||||
|         $i18n->locale(getenv('DEFAULT_LOCAL')); | ||||
|         $i18n->initialize(! getenv("DEBUG")); | ||||
| 
 | ||||
|         return $i18n; | ||||
|     }, | ||||
| 
 | ||||
|     'tell.fallback' => function(ContainerInterface $container) { | ||||
|         $i18n = new Tell\I18n( $container->get(Tell\Reader\JsonReader::class), $container->get(Tell\Reader\PhpReader::class), new Tell\PrintMissingKey() ); | ||||
|         $i18n->locale(getenv('DEFAULT_LOCAL_FALLBACK') ?: "en_US"); | ||||
|         $i18n->initialize(true); | ||||
| 
 | ||||
|         return $i18n; | ||||
|     }, | ||||
| 
 | ||||
|     Tell\Reader\PhpReader::class => function($c) { | ||||
|         return new Tell\Reader\PhpReader($c->get(Lean\Lean::class)->getI18n('php'), false); | ||||
|     Tell\Reader\PhpReader::class => function(ContainerInterface $container) { | ||||
|         return new Tell\Reader\PhpReader($container->get(Lean\Lean::class)->getI18n('php'), false); | ||||
|     }, | ||||
| 
 | ||||
|     Tell\Reader\JsonReader::class => function($c) { | ||||
|         return new Tell\Reader\JsonReader($c->get(Lean\Lean::class)->getI18n('json'), true, \JSON_PRETTY_PRINT); | ||||
|     Tell\Reader\JsonReader::class => function(ContainerInterface $container) { | ||||
|         return new Tell\Reader\JsonReader($container->get(Lean\Lean::class)->getI18n('json'), true, \JSON_PRETTY_PRINT); | ||||
|     }, | ||||
| 
 | ||||
|     'lean.autoload' => add([ | ||||
|         I18n::class, | ||||
|     ]), | ||||
| ]; | ||||
|  | ||||
							
								
								
									
										18
									
								
								meta/definitions/orm.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								meta/definitions/orm.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| <?php | ||||
| 
 | ||||
| use Ulmus\Container\AdapterProxy; | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get, DI\add; | ||||
| 
 | ||||
| return [ | ||||
|     'lean.autoload' => add([ | ||||
|         AdapterProxy::class, | ||||
|     ]), | ||||
| 
 | ||||
|     AdapterProxy::class => function (ContainerInterface $c) { | ||||
|         return new AdapterProxy( | ||||
|             $c->get('lean:adapter.sqlite'), | ||||
|             $c->get(ConnectionAdapter::class), | ||||
|         ); | ||||
|     }, | ||||
| ]; | ||||
| @ -54,7 +54,7 @@ return [ | ||||
|         # PostRequestAuthenticationMiddleware::class,
 | ||||
|     ], | ||||
| 
 | ||||
|     'routes.list' => function($c) { | ||||
|     Lean\Routing\RouteDefinitionInterface::class => function($c) { | ||||
|         return function (ContainerInterface $container) { | ||||
|             $router = $container->get(Router::class); | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| <?php | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| use Tell\I18n; | ||||
| 
 | ||||
| use TheBugs\JavascriptMiddleware; | ||||
| 
 | ||||
| @ -10,12 +10,14 @@ use Storage\Cookie, | ||||
|     Storage\Session, | ||||
|     Storage\SessionMiddleware; | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get, DI\add; | ||||
| 
 | ||||
| $dir = dirname(__DIR__, 2); | ||||
| 
 | ||||
| return [ | ||||
|     'lean.default' => [ | ||||
|         'picea' => [ | ||||
|             'context' => "Lean\\View", | ||||
|             'context' => \Lean\View::class, | ||||
| 
 | ||||
|             'view' => [ | ||||
|                 [ | ||||
| @ -74,6 +76,10 @@ return [ | ||||
|         ], | ||||
|     ], | ||||
| 
 | ||||
|     'lean.autoload' => add([ | ||||
|         Lean::class, | ||||
|     ]), | ||||
| 
 | ||||
|     Lean::class => autowire(Lean::class), | ||||
| 
 | ||||
|     JavascriptMiddleware::class => create(JavascriptMiddleware::class), | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| <?php | ||||
| 
 | ||||
| use Ulmus\ConnectionAdapter; | ||||
| use Ulmus\{ ConnectionAdapter, Container\AdapterProxy }; | ||||
| use Lean\Lean; | ||||
| 
 | ||||
| return [ | ||||
|     'lean:adapter.sqlite' => function($c) { | ||||
|  | ||||
							
								
								
									
										8
									
								
								skeleton/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								skeleton/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| .idea | ||||
| .env | ||||
| composer.lock | ||||
| /private/ | ||||
| /public/static/ | ||||
| /public/.htaccess | ||||
| /vendor/ | ||||
| /var/ | ||||
							
								
								
									
										152
									
								
								skeleton/composer.json.dist
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								skeleton/composer.json.dist
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,152 @@ | ||||
| { | ||||
|     "name": "my_namespace/my_project", | ||||
|     "description": "", | ||||
|     "type": "app", | ||||
|     "license": "MIT", | ||||
|     "authors": [ | ||||
| 
 | ||||
|     ], | ||||
|     "minimum-stability": "dev", | ||||
|     "require": { | ||||
|         "php": "^8.2", | ||||
|         "ext-apcu": "*", | ||||
|         "ext-json": "*", | ||||
|         "league/route": "^5.0.0-dev", | ||||
|         "laminas/laminas-diactoros": "2.24.x-dev", | ||||
|         "laminas/laminas-httphandlerrunner": "2.5.x-dev", | ||||
|         "vlucas/phpdotenv": "^3.4@dev", | ||||
|         "middlewares/whoops": "dev-master", | ||||
|         "ralouphie/getallheaders": "dev-master", | ||||
|         "mcnd/dump": "dev-master", | ||||
|         "mcnd/storage": "dev-master", | ||||
|         "mcnd/event": "dev-master", | ||||
|         "mcnd/ulmus": "dev-master", | ||||
|         "mcnd/ulmus-api": "dev-master", | ||||
|         "mcnd/ulmus-user": "dev-master", | ||||
|         "mcnd/picea": "dev-master", | ||||
|         "mcnd/picea-ui": "dev-master", | ||||
|         "mcnd/picea-asset": "dev-master", | ||||
|         "mcnd/cronard": "dev-master", | ||||
|         "mcnd/lean-console": "dev-master", | ||||
|         "mcnd/kash": "dev-master", | ||||
|         "mcnd/taxus": "dev-master", | ||||
|         "mcnd/notes": "dev-master", | ||||
|         "mcnd/thebugs": "dev-master", | ||||
|         "mcnd/negundo-client": "dev-master" | ||||
|     }, | ||||
|     "repositories": [ | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/cronard.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/dump.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/storage.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/lean.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/lean-console.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/ulmus.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/ulmus-api.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/ulmus-user.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/ulmus-api-gitea.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/picea.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/storage.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/picea-ui.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/picea-asset.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/notes.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/the-bugs.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/tell.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/taxus.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/dump.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/kash.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/event.git" | ||||
|         }, | ||||
|         { | ||||
|             "type": "vcs", | ||||
|             "url": "https://git.mcnd.ca/mcndave/negundo-client.git" | ||||
|         } | ||||
|     ], | ||||
|     "autoload": { | ||||
|         "psr-4": { | ||||
|             "MyProject\\Namespace": "src/" | ||||
|         } | ||||
|     }, | ||||
|     "scripts": { | ||||
|         "post-install-cmd": [ | ||||
|             "Lean\\Composer::postInstall" | ||||
|         ], | ||||
|         "post-update-cmd": [ | ||||
|             "Lean\\Composer::postUpdate" | ||||
|         ] | ||||
|     }, | ||||
|     "extra" : { | ||||
|         "lean" : { | ||||
|             "autoload": { | ||||
|                 "definitions" : [ | ||||
|                     "meta/definitions/definitions.php", | ||||
|                     "meta/definitions/storage.php", | ||||
|                     "meta/definitions/security.php", | ||||
|                     "meta/definitions/auth.php", | ||||
|                     "meta/definitions/env.php" | ||||
|                 ], | ||||
|                 "config" : [ | ||||
|                     "meta/config.php" | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										3
									
								
								skeleton/meta/definitions/env.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								skeleton/meta/definitions/env.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| <?php | ||||
| 
 | ||||
| return require("env/" . ( getenv('APP_ENV') ?? 'prod' ) . ".php"); | ||||
							
								
								
									
										4
									
								
								skeleton/meta/definitions/env/prod.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								skeleton/meta/definitions/env/prod.php
									
									
									
									
										vendored
									
									
								
							| @ -4,7 +4,7 @@ use Picea\Picea; | ||||
| 
 | ||||
| use Negundo\Client\{ NegundoMiddleware, SoftwareConfig }; | ||||
| 
 | ||||
| use Laminas\Diactoros\Response\HtmlResponse; | ||||
| use Lean\Factory\HttpFactory; | ||||
| 
 | ||||
| use Psr\Http\Server\MiddlewareInterface, | ||||
|     Psr\Http\Message\ServerRequestInterface, | ||||
| @ -35,7 +35,7 @@ return [ | ||||
|         return function(\Throwable $exception) use ($picea) { | ||||
|             error_log($exception->getMessage()); | ||||
| 
 | ||||
|             return new HtmlResponse($picea->renderHtml('lean/error/500', [ | ||||
|             return HttpFactory::createHtmlResponse($picea->renderHtml('lean/error/500', [ | ||||
|                 'title' => "Une erreur s'est produite lors de l'exécution du script.", | ||||
|                 'subtitle' => "Êtes-vous connecté avec le bon compte ?", | ||||
|                 'message' => $exception->getMessage(), | ||||
|  | ||||
| @ -6,14 +6,28 @@ use Taxus\{ Privilege, Taxus, PermissionGrantInterface, DefaultPermissionGrant } | ||||
| 
 | ||||
| use Psr\Http\Message\ServerRequestInterface; | ||||
| 
 | ||||
| use function DI\autowire, DI\create, DI\get; | ||||
| use function DI\{ create, get, add }; | ||||
| 
 | ||||
| return [ | ||||
|     Taxus::class => function ($c) { | ||||
|         return ( new Taxus( $c->get(PermissionGrantInterface::class) ) )->add( | ||||
|             $c->get(Lean\Lean::class)->getTaxusPrivileges() | ||||
|         ); | ||||
|         $taxus = new Taxus( ... $c->get('taxus.gates') ); | ||||
| 
 | ||||
|         $list = []; | ||||
| 
 | ||||
|         foreach($c->get(Lean\Lean::class)->getTaxusPrivileges() as $key => $privilege) { | ||||
|             foreach($privilege as $name => $description) { | ||||
|                 $list[] = [ new Privilege($name, $description), $key ]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         $taxus->add(... $list); | ||||
| 
 | ||||
|         return $taxus; | ||||
|     }, | ||||
| 
 | ||||
|     'taxus.gates' => add([ | ||||
|         get(PermissionGrantInterface::class), | ||||
|     ]), | ||||
| 
 | ||||
|     PermissionGrantInterface::class => create(%NAMESPACE%\PrivilegeGrantAccess::class)->constructor(get(ServerRequestInterface::class), get(Session::class)), | ||||
| ]; | ||||
|  | ||||
| @ -1,12 +1,22 @@ | ||||
| <IfModule mod_rewrite.c> | ||||
|     RewriteEngine On | ||||
|     # RewriteBase / | ||||
| 
 | ||||
|     # Force HTTPS (disabled by default) | ||||
|     # RewriteCond %{HTTPS} off | ||||
|     # RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] | ||||
| 
 | ||||
|     # Reverse Proxy ; Force HTTPS (disabled by default) | ||||
|     # RewriteCond %{HTTP:X-Forwarded-SSL} off | ||||
|     # RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] | ||||
| 
 | ||||
|     # Remove trailing slashes from request URL | ||||
|     #RewriteCond %{REQUEST_FILENAME} !-d | ||||
|     #RewriteCond %{REQUEST_URI} (.+)/$ | ||||
|     #RewriteRule ^ %1 [R=301,L] | ||||
| 
 | ||||
|     # Redirect everything into app | ||||
|     RewriteCond %{REQUEST_FILENAME} !-f | ||||
|     RewriteCond %{REQUEST_FILENAME} !-d | ||||
|     RewriteCond %{REQUEST_URI} (.+)/$ | ||||
|     RewriteRule ^ %1 [R=301,L] | ||||
|     RewriteRule ^([^?]*)$ %1 [NC,L,QSA] | ||||
| </IfModule> | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| <?php | ||||
| 
 | ||||
| try { | ||||
|     require_once("../src/Kernel.php"); | ||||
|     require_once(dirname(__DIR__)."/src/Kernel.php"); | ||||
| } | ||||
| catch(\Throwable $t) { | ||||
|     echo $t->getMessage(); | ||||
|     echo sprintf("%s in <strong>%s</strong> <pre>%s</pre>", $t->getMessage(), $t->getFile() . ":" . $t->getLine(), $t->getTraceAsString()); | ||||
| } | ||||
| @ -1,45 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <configuration> | ||||
|     <system.webServer> | ||||
|         <rewrite> | ||||
|             <rules> | ||||
|                 <rule name="Remove trailing slash" stopProcessing="true"> | ||||
|                     <match url="(.*)/$" /> | ||||
|                     <conditions> | ||||
|                         <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> | ||||
|                         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> | ||||
|                     </conditions> | ||||
|                     <action type="Redirect" redirectType="Permanent" url="{R:1}" /> | ||||
|                 </rule> | ||||
|                 <rule name="Framework Routing" stopProcessing="true"> | ||||
|                     <match url="." ignoreCase="false" /> | ||||
|                     <conditions logicalGrouping="MatchAll"> | ||||
|                         <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" /> | ||||
|                         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" /> | ||||
|                     </conditions> | ||||
|                     <action type="Rewrite" url="index.php" /> | ||||
|                 </rule> | ||||
|             </rules> | ||||
|         </rewrite> | ||||
|         <staticContent> | ||||
|             <remove fileExtension=".js" /> | ||||
|             <mimeMap fileExtension=".js" mimeType="application/x-javascript; charset=UTF-8" /> | ||||
|             <remove fileExtension=".css" /> | ||||
|             <mimeMap fileExtension=".css" mimeType="text/css; charset=UTF-8" /> | ||||
|             <remove fileExtension=".woff" /> | ||||
|             <remove fileExtension=".eot" /> | ||||
|             <remove fileExtension=".ttf" /> | ||||
|             <remove fileExtension=".svg" /> | ||||
| 
 | ||||
|             <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" /> | ||||
|             <mimeMap fileExtension=".ttf" mimeType="application/font-sfnt" /> | ||||
|             <mimeMap fileExtension=".svg" mimeType="image/svg+xml" /> | ||||
|             <mimeMap fileExtension=".woff" mimeType="application/font-woff" /> | ||||
|         </staticContent> | ||||
|         <handlers> | ||||
|             <remove name="PHP7.3" /> | ||||
|             <add name="PHP7.3" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\php\7.4.0\php-cgi.exe" resourceType="File" requireAccess="Script" /> | ||||
|         </handlers> | ||||
|         <httpErrors errorMode="Detailed" /> | ||||
|     </system.webServer> | ||||
| </configuration> | ||||
| @ -3,11 +3,13 @@ | ||||
| namespace Lean; | ||||
| 
 | ||||
| use Lean\Factory\HttpFactory; | ||||
| use Notes\Attribute\Ignore; | ||||
| 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 League\CommonMark\CommonMarkConverter; | ||||
| 
 | ||||
| use Psr\Http\Message\{ ServerRequestInterface, ResponseInterface }; | ||||
| 
 | ||||
| @ -26,6 +28,7 @@ trait ControllerTrait { | ||||
| 
 | ||||
|     public array $contextList = []; | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function exportJson(ServerRequestInterface $request, string $entityClass, bool $includeRelations = true, ? callable $callback = null) : ResponseInterface | ||||
|     { | ||||
|         foreach($entityClass::repository()->filterServerRequest( $entityClass::searchRequest()->fromRequest($request->withQueryParams($request->getQueryParams() + ['limit' => PHP_INT_MAX,])) )->loadAll() as $entity) { | ||||
| @ -35,6 +38,7 @@ trait ControllerTrait { | ||||
|         return $this->renderJson( array_filter($data ?? [], function($row) { return $row !== null; })); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function renderRawView(string $view, ?array $variables = null) : string | ||||
|     { | ||||
|         if ( null === $content = $this->picea->renderHtml($view, $variables ?? [], $this) ) { | ||||
| @ -44,6 +48,7 @@ trait ControllerTrait { | ||||
|         return $content; | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function renderView(string $view, ?array $variables = null) : ResponseInterface | ||||
|     { | ||||
|         return static::renderHtml( | ||||
| @ -51,6 +56,7 @@ trait ControllerTrait { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function renderError(string $errorCode, ?array $variables = null) : ResponseInterface | ||||
|     { | ||||
|         return static::renderHtml( | ||||
| @ -58,66 +64,78 @@ trait ControllerTrait { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function renderDocumentation(string $filename) : ResponseInterface | ||||
|     { | ||||
|         return $this->renderMarkdown( file_get_contents(getenv("PROJECT_PATH") . "/meta/doc/$filename.md") ); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     protected function redirect(string $url, int $code = 302, array $headers = []) { | ||||
|         return HttpFactory::createRedirectResponse($url, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public static function renderNothing(int $code = 204, array $headers = []) : ResponseInterface | ||||
|     { | ||||
| 	    return HttpFactory::createEmptyResponse($code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public static function renderText(string $text, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return HttpFactory::createTextResponse($text, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public static function renderHtml(string $html, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return HttpFactory::createHtmlResponse($html, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public static function renderJson(mixed $data, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return HttpFactory::createJsonResponse($data, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function renderPdf($rawdata, int $status = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return HttpFactory::createPdfResponse($rawdata, $status, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public static function renderDownloadable(string $data, string $filename, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return HttpFactory::createDownloadableResponse($data, $filename, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public static function renderImage(string $data, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return HttpFactory::createImageResponse($data, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public static function renderAsset(string $path, int $code = 200, array $headers = []) : ResponseInterface | ||||
|     { | ||||
|         return HttpFactory::createFileDownloadResponse($path, $code, $headers); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     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)); | ||||
|         $markdown = ( new CommonMarkConverter() )->convert(file_get_contents($filepath)); | ||||
| 
 | ||||
|         return $this->renderView("docs", get_defined_vars()); | ||||
|         return $this->renderView("lean/layout/docs", get_defined_vars()); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function renderCLI(ServerRequestInterface $request, mixed $data) : ResponseInterface | ||||
|     { | ||||
|         if ($data instanceof \JsonSerializable ) { | ||||
| @ -134,6 +152,7 @@ trait ControllerTrait { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function fromResponse(ResponseInterface $response) | ||||
|     { | ||||
|         if ( $response->getStatusCode() === 200 ) { | ||||
| @ -145,6 +164,7 @@ trait ControllerTrait { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function asset(string $url, array $parameters = []) : string | ||||
|     { | ||||
|         if (! $this->picea ) { | ||||
| @ -154,6 +174,7 @@ trait ControllerTrait { | ||||
|         return $this->picea->compiler->getExtensionFromToken('asset')->buildAssetUrl($url, $parameters); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function url(string $url, array $parameters = []) : string | ||||
|     { | ||||
|         if (! $this->picea ) { | ||||
| @ -163,6 +184,7 @@ trait ControllerTrait { | ||||
|         return $this->picea->compiler->getExtensionFromToken('url')->buildUrl($url, $parameters); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function route(string $name, array $parameters = []) : string | ||||
|     { | ||||
|         if (! $this->picea ) { | ||||
| @ -172,11 +194,13 @@ trait ControllerTrait { | ||||
|         return $this->picea->compiler->getExtensionFromToken('route')->buildRouteUrl($name, $parameters); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function json($data, int $flags = 0) : string | ||||
|     { | ||||
|         return htmlentities(json_encode($data, $flags), ENT_QUOTES, 'UTF-8'); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function pushContext(FormContext $context) : FormContext | ||||
|     { | ||||
|         $this->contextList[$context->formName ?? uniqid("context_")] = $context; | ||||
| @ -184,11 +208,13 @@ trait ControllerTrait { | ||||
|         return $context; | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function context(? string $name = null) : ? FormContext | ||||
|     { | ||||
|         return $name ? $this->contextList[$name] : array_values($this->contextList)[0] ?? null; | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|     public function isRoute(mixed $name, ServerRequestInterface $request) : bool | ||||
|     { | ||||
|         foreach((array) $name as $item) { | ||||
|  | ||||
| @ -35,8 +35,6 @@ class Kernel { | ||||
| 
 | ||||
|     public string $projectPath; | ||||
| 
 | ||||
|     public string $routeDefinitionList = 'routes.list'; | ||||
| 
 | ||||
|     public function __construct(string $projectPath) | ||||
|     { | ||||
|         $this->projectPath = $projectPath; | ||||
| @ -138,16 +136,15 @@ 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)) { | ||||
|             $i18n = $this->container->get(I18n::class); | ||||
|             $i18n->locale($this->locale); | ||||
|             $i18n->initialize(!getenv("DEBUG")); | ||||
|         if ($this->container->has('lean.autoload')) { | ||||
|             foreach($this->container->get('lean.autoload') as $class) { | ||||
|                 $this->container->get($class); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         # Must be removed from KERNEL !
 | ||||
|         $this->container->has('ulmus.caching') and ( Ulmus::$cache = $this->container->get('ulmus.caching') ); | ||||
| 
 | ||||
|         return $this; | ||||
|     } | ||||
| 
 | ||||
| @ -155,8 +152,7 @@ class Kernel { | ||||
|     { | ||||
|         ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); | ||||
| 
 | ||||
|         // Router
 | ||||
|         $routeFactory = $this->container->get($this->routeDefinitionList); | ||||
|         $routeFactory = $this->container->get(Routing\RouteDefinitionInterface::class); | ||||
| 
 | ||||
|         $router = $routeFactory($this->container); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/Routing/RouteDefinitionInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/Routing/RouteDefinitionInterface.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Lean\Routing; | ||||
| 
 | ||||
| interface RouteDefinitionInterface {} | ||||
							
								
								
									
										53
									
								
								view/lean/layout/docs.phtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								view/lean/layout/docs.phtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| {% title "Documentation" %} | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| <html lang="fr"> | ||||
|     {% section "head" %} | ||||
|         <head> | ||||
|             <meta charset="UTF-8" /> | ||||
|             <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | ||||
|             <title>{% section "head.title" %}{{ title() }}{% endsection %}</title> | ||||
| 
 | ||||
|             <link rel="apple-touch-icon" sizes="180x180" href="{% asset 'static/favicon/apple-touch-icon.png' %}"> | ||||
|             <link rel="icon" type="image/png" sizes="32x32" href="{% asset 'static/favicon/favicon-32x32.png' %}"> | ||||
|             <link rel="icon" type="image/png" sizes="16x16" href="{% asset 'static/favicon/favicon-16x16.png' %}"> | ||||
|             <link rel="manifest" href="{% asset 'static/favicon/site.webmanifest' %}"> | ||||
|             <link rel="mask-icon" href="{% asset 'static/favicon/safari-pinned-tab.svg' %}" color="#5bbad5"> | ||||
|             <meta name="msapplication-TileColor" content="#2d89ef"> | ||||
|             <meta name="theme-color" content="#ffffff"> | ||||
| 
 | ||||
|             <style> | ||||
|                 a{color:#e44a00}h3{background:#e1e1e1;padding:6px 12px}ul{background:#e9e9fd;padding-top:20px;padding-bottom:20px;border:1px solid #e3e3ec}ul li + li{margin-top:8px}li > em{font-size:0.75rem;color:gray}body{font-family:Helvetica, 'Helvetica Neuve', Arial, Tahoma, sans-serif;font-size:17px;color:#333}h1,h2,h3,h4,h5,h6{color:#222;margin:0 0 20px}dl,ol,p,pre,table,ul{margin:0 0 20px}h1,h2,h3{line-height:1.1}h1{font-size:20px;text-align:right;color:#387eea;font-weight:bold}h2{color:#393939}h3,h4,h5,h6{color:#494949}h3{display:flex}h3 > code{margin-right:5px;color:#b52dac}h3 > strong{margin-left:auto}a{color:#39c;font-weight:400;text-decoration:none}a small{font-size:11px;color:#777;margin-top:-0.6em;display:block}.wrapper{width:860px;margin:0 auto}blockquote{border-left:1px solid #e5e5e5;margin:0;padding:0 0 0 20px;font-style:italic}code,pre{font-size:12px}pre{padding:8px 15px;background:#f8f8f8;border-radius:5px;border:1px solid #e5e5e5;overflow-x:auto}table{width:100%;border-collapse:collapse}td,th{text-align:left;padding:5px 10px;border-bottom:1px solid #e5e5e5}dt{color:#444;font-weight:700}th{color:#444}img{max-width:100%}header{width:270px;float:left;position:fixed}header ul{list-style:none;height:40px;padding:0;background:#eee;background:-moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));background:-webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);background:-o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);background:-ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);background:linear-gradient(top, #f8f8f8 0%,#dddddd 100%);border-radius:5px;border:1px solid #d2d2d2;box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0;width:270px}header li{width:89px;float:left;border-right:1px solid #d2d2d2;height:40px}header ul a{line-height:1;font-size:11px;color:#999;display:block;text-align:center;padding-top:6px;height:40px}strong{color:#222;font-weight:700}header ul li + li{width:88px;border-left:1px solid #fff}header ul li + li + li{border-right:none;width:89px}header ul a strong{font-size:14px;display:block;color:#222}section{width:500px;float:right;padding-bottom:50px}small{font-size:11px}hr{border:0;background:#e5e5e5;height:1px;margin:0 0 20px}footer{width:270px;float:left;position:fixed;bottom:50px}@media print, screen and (max-width: 960px){div.wrapper{width:auto;margin:0}footer,header,section{float:none;position:static;width:auto}header{padding-right:320px}section{border:1px solid #e5e5e5;border-width:1px 0;padding:20px 0;margin:0 0 20px}header a small{display:inline}header ul{position:absolute;right:50px;top:52px}}@media print, screen and (max-width: 720px){body{word-wrap:break-word}header{padding:0}header p.view,header ul{position:static}code,pre{word-wrap:normal}}@media print, screen and (max-width: 480px){body{padding:15px}header ul{display:none}}@media print{body{padding:0.4in;font-size:12pt;color:#444}}#wrapper{margin-left:auto;margin-right:auto;background-color:white}.ca-menu{list-style:none;padding:0;margin:20px auto}#navi{padding-top:15px;padding-right:15px;float:right;width:420px}#title{padding-left:15px;width:460px;float:left}div.clear{clear:both}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.2em}h5{font-size:1em;font-weight:bold}h6{font-size:1em;font-weight:bold}h1,h2,h3,h4,h5,h6{font-weight:normal;line-height:2.5rem;margin:1rem 0}.post p{max-width:580px}ol.list,ul.list{padding-left:3.333em;max-width:580px}.post h2{border-bottom:1px solid #EDEDED}h1:nth-child(1),h2:nth-child(1),h3:nth-child(1),h4:nth-child(1),h5:nth-child(1),h6:nth-child(1){margin-top:0}body{padding:1em}#wrapper{padding:1em}@media (min-width: 43.75em){body{padding:2em}#wrapper{padding:2em}}@media (min-width: 62em){body{padding:3em}#wrapper{max-width:740px;padding:3em}} | ||||
|                 ol{background: #eff4f2;padding-top:20px;padding-bottom:20px;border:1px solid #e3e3ec} | ||||
|                 h4{background:#e0f7ed;padding:6px 12px; font-weight: bold!important;font-size:100%;margin-top:0} | ||||
|                 h5{text-decoration: underline} | ||||
|                 li.odd-even{border-top:1px solid #ccc;margin:10px 0;padding:15px 15px 10px 5px} | ||||
|                 li.odd-even:first-child{border:0} | ||||
|                 input, button {padding:5px; font-size:1em;margin-top:10px} | ||||
|                 ul ul {margin: 0;border: 0;padding: 5px 30px;} | ||||
|             </style> | ||||
|         </head> | ||||
|     {% endsection %} | ||||
| 
 | ||||
|     {% section "body" %} | ||||
|         <body> | ||||
|             {% section "body.header" %}{% endsection %} | ||||
| 
 | ||||
|             {% section "header" %}{% endsection %} | ||||
| 
 | ||||
|             {% section "message" %} | ||||
|                 {% view "lean/widget/message" %} | ||||
|             {% endsection %} | ||||
| 
 | ||||
|             <main role="main" class="content"> | ||||
|                 {% section "main" %} | ||||
|                     <div>{{= $markdown }}</div> | ||||
|                 {% endsection %} | ||||
|             </main> | ||||
| 
 | ||||
|             <footer>{% section "footer" %}{% endsection %}</footer> | ||||
| 
 | ||||
|             {% section "body.footer" %}{% endsection %} | ||||
|         </body> | ||||
|     {% endsection %} | ||||
| </html> | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user