Compare commits
22
Commits
ffe66e522c
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
583580e068 | ||
|
|
5b7da3237f | ||
|
|
2bc0c9e56f | ||
|
|
cebb213830 | ||
|
|
8e29b0513a | ||
|
|
7f549a377a | ||
|
|
f87bccb3ab | ||
|
|
212dbd17c0 | ||
|
|
f462fcc597 | ||
|
|
13d306aec9 | ||
|
|
07613bf1cb | ||
|
|
4e28917b96 | ||
|
|
163df3f4ba | ||
|
|
3320dc47c1 | ||
|
|
4484dc8985 | ||
|
|
1d61ff87e4 | ||
|
|
0cc9a8a893 | ||
|
|
fd8fa7695e | ||
|
|
0581f378a5 | ||
|
|
708af80fa2 | ||
|
|
1f828eb022 | ||
|
|
959a182d16 |
No files matched your search
@@ -29,8 +29,8 @@ return [
|
|||||||
return function(array $errorData) {
|
return function(array $errorData) {
|
||||||
return HttpFactory::createJsonResponse($errorData + [
|
return HttpFactory::createJsonResponse($errorData + [
|
||||||
'api.error' => "Authorization failed",
|
'api.error' => "Authorization failed",
|
||||||
'api.datetime' => (new \DateTime)->format(\DateTime::ATOM),
|
'api.datetime' => (new \DateTime)->format(\DateTime::ISO8601),
|
||||||
], 401);
|
], 403);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -60,12 +60,11 @@ return [
|
|||||||
}
|
}
|
||||||
|
|
||||||
$routing->response = $redirect;
|
$routing->response = $redirect;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $securityHandler->isLocked($class, $method) && $container->has(Taxus::class) ) {
|
if ( $securityHandler->isLocked($class, $method) && $container->has(Taxus::class) && $container->has(SecurityHandler::class) ) {
|
||||||
if ( $forbidden = $container->get(SecurityHandler::class)->taxus($class, $method, $object->user ?? null) ) {
|
if ( $forbidden = $container->get(SecurityHandler::class)->taxus($class, $method, $object->user ?? null) ) {
|
||||||
$routing->response = $forbidden;
|
$routing->response = $forbidden;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Ulmus\Container\AdapterProxy;
|
use Ulmus\Container\AdapterProxy;
|
||||||
|
use Ulmus\ConnectionAdapter;
|
||||||
|
|
||||||
use function DI\autowire, DI\create, DI\get, DI\add;
|
use function DI\autowire, DI\create, DI\get, DI\add;
|
||||||
|
|
||||||
@@ -9,9 +10,8 @@ return [
|
|||||||
AdapterProxy::class,
|
AdapterProxy::class,
|
||||||
]),
|
]),
|
||||||
|
|
||||||
AdapterProxy::class => function (ContainerInterface $c) {
|
AdapterProxy::class => function (Psr\Container\ContainerInterface $c) {
|
||||||
return new AdapterProxy(
|
return new AdapterProxy(
|
||||||
$c->get('lean:adapter.sqlite'),
|
|
||||||
$c->get(ConnectionAdapter::class),
|
$c->get(ConnectionAdapter::class),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use function DI\autowire, DI\create, DI\get;
|
use function DI\autowire, DI\create, DI\get, DI\add;
|
||||||
|
|
||||||
use League\Route\Strategy\ApplicationStrategy,
|
use League\Route\Strategy\ApplicationStrategy,
|
||||||
League\Route\Router;
|
League\Route\Router;
|
||||||
@@ -49,10 +49,10 @@ return [
|
|||||||
"dump", "errorHandler", SessionMiddleware::class, CronardMiddleware::class, Mcnd\Event\EventMiddleware::class, Mcnd\CLI\CliMiddleware::class,
|
"dump", "errorHandler", SessionMiddleware::class, CronardMiddleware::class, Mcnd\Event\EventMiddleware::class, Mcnd\CLI\CliMiddleware::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
'app.middlewares' => [
|
'app.middlewares' => add([
|
||||||
# HeaderAuthenticationMiddleware::class,
|
# HeaderAuthenticationMiddleware::class,
|
||||||
# PostRequestAuthenticationMiddleware::class,
|
# PostRequestAuthenticationMiddleware::class,
|
||||||
],
|
]),
|
||||||
|
|
||||||
Lean\Routing\RouteDefinitionInterface::class => function($c) {
|
Lean\Routing\RouteDefinitionInterface::class => function($c) {
|
||||||
return function (ContainerInterface $container) {
|
return function (ContainerInterface $container) {
|
||||||
@@ -68,6 +68,8 @@ return [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$router->addPatternMatcher('email', '[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+');
|
||||||
|
|
||||||
$routing = $container->get(Lean\Routing::class);
|
$routing = $container->get(Lean\Routing::class);
|
||||||
$routing->registerRoute($container, getenv('URL_BASE'));
|
$routing->registerRoute($container, getenv('URL_BASE'));
|
||||||
|
|
||||||
|
|||||||
@@ -2,62 +2,48 @@
|
|||||||
|
|
||||||
use Taxus\Privilege;
|
use Taxus\Privilege;
|
||||||
|
|
||||||
use function DI\autowire, DI\create, DI\get;
|
use function DI\{ autowire, add, create, get };
|
||||||
|
|
||||||
$dir = getenv("META_PATH") . "/definitions";
|
$dir = dirname(__DIR__, 2);
|
||||||
|
|
||||||
return array_merge(
|
return [
|
||||||
Lean\Lean::autoloadDefinitionsFromComposerExtra(),
|
'%APPKEY%' => [
|
||||||
|
'picea' => [
|
||||||
[
|
'context' => "%ESCAPED_NAMESPACE%\\View",
|
||||||
'%APPKEY%' => [
|
'asset' => [],
|
||||||
'picea' => [
|
'extensions' => [],
|
||||||
'context' => "%ESCAPED_NAMESPACE%\\View",
|
|
||||||
'asset' => [],
|
|
||||||
'extensions' => [],
|
|
||||||
],
|
|
||||||
|
|
||||||
'ulmus' => [
|
|
||||||
'entities' => [ '%ESCAPED_NAMESPACE%\\Entity' => getenv("PROJECT_PATH") . '/src/Entity/' ],
|
|
||||||
],
|
|
||||||
|
|
||||||
'routes' => [
|
|
||||||
'%ESCAPED_NAMESPACE%\\Controller' => getenv("PROJECT_PATH") . '/src/Controller/',
|
|
||||||
],
|
|
||||||
|
|
||||||
'events' => [
|
|
||||||
'%ESCAPED_NAMESPACE%\\Controller' => implode(DIRECTORY_SEPARATOR, [ getenv("PROJECT_PATH"), 'src', 'Controller', '' ]),
|
|
||||||
],
|
|
||||||
|
|
||||||
'cronard' => [
|
|
||||||
'%ESCAPED_NAMESPACE%\\Controller' => implode(DIRECTORY_SEPARATOR, [ getenv("PROJECT_PATH"), 'src', 'Controller', '' ]),
|
|
||||||
],
|
|
||||||
|
|
||||||
'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' => [],
|
'ulmus' => [
|
||||||
|
'entities' => [ '%ESCAPED_NAMESPACE%\\Entity' => implode(DIRECTORY_SEPARATOR, [ $dir, 'src', 'Entity', '' ]) ],
|
||||||
|
],
|
||||||
|
|
||||||
|
'routes' => [
|
||||||
|
'%ESCAPED_NAMESPACE%\\Controller' => implode(DIRECTORY_SEPARATOR, [ $dir, 'src', 'Controller', '' ]),
|
||||||
|
],
|
||||||
|
|
||||||
|
'events' => [
|
||||||
|
'%ESCAPED_NAMESPACE%\\Controller' => implode(DIRECTORY_SEPARATOR, [ $dir, 'src', 'Controller', '' ]),
|
||||||
|
],
|
||||||
|
|
||||||
|
'cronard' => [
|
||||||
|
'%ESCAPED_NAMESPACE%\\Controller' => implode(DIRECTORY_SEPARATOR, [ $dir, 'src', 'Controller', '' ]),
|
||||||
|
],
|
||||||
|
|
||||||
|
'cli' => [
|
||||||
|
'%ESCAPED_NAMESPACE%\\Controller' => implode(DIRECTORY_SEPARATOR, [ $dir, 'src', 'Controller', '' ]),
|
||||||
|
],
|
||||||
|
|
||||||
|
'taxus' => [
|
||||||
|
'is_dev' => [ 'dev' => "Can manage almost everything in this application."],
|
||||||
|
'is_admin' => [ 'admin' => "Can manage almost everything in this application."],
|
||||||
|
'is_moderator' => [ 'moderator' => "Can moderate this application."],
|
||||||
|
'is_user' => [ 'user' => "Is an authenticated user."],
|
||||||
|
'is_anonymous' => [ 'anonymous' => "Is an anonymous (unauthenticated) user."],
|
||||||
|
]
|
||||||
],
|
],
|
||||||
|
|
||||||
require("$dir/auth.php"),
|
'app.middlewares' => \DI\add([
|
||||||
require("$dir/storage.php"),
|
Ulmus\User\Middleware\RememberMeMiddleware::class,
|
||||||
require("$dir/security.php"),
|
]),
|
||||||
require("$dir/env/" . getenv('APP_ENV') . ".php"),
|
];
|
||||||
[
|
|
||||||
'config' => function () {
|
|
||||||
return array_merge_recursive(
|
|
||||||
Lean\Lean::autoloadConfigFromComposerExtra(),
|
|
||||||
require(getenv("META_PATH")."/config.php")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
]
|
|
||||||
);
|
|
||||||
@@ -16,11 +16,4 @@ return [
|
|||||||
|
|
||||||
return $adapter;
|
return $adapter;
|
||||||
},
|
},
|
||||||
|
|
||||||
AdapterProxy::class => function (ContainerInterface $c) {
|
|
||||||
return new AdapterProxy(
|
|
||||||
$c->get('lean:adapter.sqlite'),
|
|
||||||
$c->get(ConnectionAdapter::class)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
@@ -23,8 +23,6 @@ new class(dirname(__DIR__)) extends \Lean\Kernel {
|
|||||||
{
|
{
|
||||||
$this->errorLogPath = getenv("LOGS_PATH") . DIRECTORY_SEPARATOR. date("Y-m").".log";
|
$this->errorLogPath = getenv("LOGS_PATH") . DIRECTORY_SEPARATOR. date("Y-m").".log";
|
||||||
|
|
||||||
$this->definitionFilePaths = Lean::getDefinitionsPathsFromComposer();
|
|
||||||
|
|
||||||
return parent::initializeEngine();
|
return parent::initializeEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,21 +11,25 @@ use Notes\Security\Attribute\Security;
|
|||||||
use %NAMESPACE%\{ Entity, Lib, Form };
|
use %NAMESPACE%\{ Entity, Lib, Form };
|
||||||
|
|
||||||
use Mcnd\Event\EventManager;
|
use Mcnd\Event\EventManager;
|
||||||
use Ulmus\User\Entity\UserInterface;
|
use Notes\Attribute\Ignore;use Ulmus\User\Entity\UserInterface;
|
||||||
|
|
||||||
#[Security(locked: false)]
|
#[Security(locked: false)]
|
||||||
#[Route(method: ['GET', 'POST', ])]
|
#[Route(method: ['GET', 'POST', ])]
|
||||||
trait ControllerTrait {
|
trait ControllerTrait {
|
||||||
use \Lean\ControllerTrait;
|
use \Lean\ControllerTrait;
|
||||||
|
|
||||||
|
#[Ignore]
|
||||||
public ? UserInterface $user;
|
public ? UserInterface $user;
|
||||||
|
|
||||||
|
#[Ignore]
|
||||||
protected EventManager $eventManager;
|
protected EventManager $eventManager;
|
||||||
|
|
||||||
|
#[Ignore]
|
||||||
public function __construct(Picea $picea, Session $session, UserInterface $user, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) {
|
public function __construct(Picea $picea, Session $session, UserInterface $user, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) {
|
||||||
$this->initializeController($picea, $session, $user, $breadcrumb, $eventManager);
|
$this->initializeController($picea, $session, $user, $breadcrumb, $eventManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Ignore]
|
||||||
public function initializeController(Picea $picea, Session $session, UserInterface $user, \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->picea = $picea;
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ class ApplicationStrategy extends Strategy\ApplicationStrategy {
|
|||||||
|
|
||||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
{
|
{
|
||||||
return $this->throw404($request);
|
if (php_sapi_name() !== 'cli' and ! defined('STDIN')) {
|
||||||
|
return $this->throw404($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handler->handle($request);;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function throw404(ServerRequestInterface $request) : ResponseInterface
|
public function throw404(ServerRequestInterface $request) : ResponseInterface
|
||||||
|
|||||||
+16
-13
@@ -2,29 +2,38 @@
|
|||||||
|
|
||||||
namespace Lean;
|
namespace Lean;
|
||||||
|
|
||||||
|
use DI\Attribute\Inject;
|
||||||
use Lean\Factory\HttpFactory;
|
use Lean\Factory\HttpFactory;
|
||||||
use Notes\Attribute\Ignore;
|
use Notes\Attribute\Ignore;
|
||||||
use Notes\Route\Attribute\Object\Route;
|
use Notes\Route\Attribute\Object\Route;
|
||||||
use Notes\Security\Attribute\Security;
|
use Notes\Security\Attribute\Security;
|
||||||
use Picea, Picea\Ui\Method\FormContext;
|
use Picea, Picea\Ui\Method\FormContext;
|
||||||
use TheBugs\Email\MailerInterface;
|
use TheBugs\Email\MailerInterface;
|
||||||
use Storage\Session;
|
use Storage\{ Cookie, Session };
|
||||||
use League\CommonMark\CommonMarkConverter;
|
use League\CommonMark\CommonMarkConverter;
|
||||||
|
|
||||||
use Psr\Http\Message\{ ServerRequestInterface, ResponseInterface };
|
use Psr\Http\Message\{ ServerRequestInterface, ResponseInterface };
|
||||||
|
|
||||||
use function file_get_contents;
|
use function file_get_contents;
|
||||||
|
|
||||||
#[Security(locked: true, realm: "Protected Area")]
|
#[Security(locked: false, realm: "Protected Area")]
|
||||||
#[Route(method: [ "GET", "POST" ])]
|
#[Route(method: [ "GET", "POST" ])]
|
||||||
trait ControllerTrait {
|
trait ControllerTrait {
|
||||||
public ? \Notes\Breadcrumb\Breadcrumb $breadcrumb;
|
|
||||||
|
|
||||||
public ? Session $session;
|
#[Inject]
|
||||||
|
public \Notes\Breadcrumb\Breadcrumb $breadcrumb;
|
||||||
|
|
||||||
public ? Picea\Picea $picea;
|
#[Inject]
|
||||||
|
public Session $session;
|
||||||
|
|
||||||
public ? MailerInterface $mailer;
|
#[Inject]
|
||||||
|
public Cookie $cookie;
|
||||||
|
|
||||||
|
#[Inject]
|
||||||
|
public Picea\Picea $picea;
|
||||||
|
|
||||||
|
#[Inject]
|
||||||
|
public MailerInterface $mailer;
|
||||||
|
|
||||||
public array $contextList = [];
|
public array $contextList = [];
|
||||||
|
|
||||||
@@ -217,12 +226,6 @@ trait ControllerTrait {
|
|||||||
#[Ignore]
|
#[Ignore]
|
||||||
public function isRoute(mixed $name, ServerRequestInterface $request) : bool
|
public function isRoute(mixed $name, ServerRequestInterface $request) : bool
|
||||||
{
|
{
|
||||||
foreach((array) $name as $item) {
|
return $request->getAttribute('lean.route')->match($name);
|
||||||
if ( fnmatch($item, $request->getAttribute('lean.route')->name) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+17
-6
@@ -29,7 +29,7 @@ class Kernel {
|
|||||||
|
|
||||||
public int $errorReporting = E_ALL & ~E_USER_DEPRECATED & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE;
|
public int $errorReporting = E_ALL & ~E_USER_DEPRECATED & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE;
|
||||||
|
|
||||||
public string $definitionFilePath;
|
public array $definitionFilePaths;
|
||||||
|
|
||||||
public string $errorLogPath;
|
public string $errorLogPath;
|
||||||
|
|
||||||
@@ -106,6 +106,8 @@ class Kernel {
|
|||||||
{
|
{
|
||||||
$containerBuilder = new ContainerBuilder();
|
$containerBuilder = new ContainerBuilder();
|
||||||
|
|
||||||
|
$containerBuilder->useAttributes(true);
|
||||||
|
|
||||||
if (getenv("APP_ENV") === "prod") {
|
if (getenv("APP_ENV") === "prod") {
|
||||||
if (getenv("CACHE_PATH")) {
|
if (getenv("CACHE_PATH")) {
|
||||||
# check if ACPU is there first, $containerBuilder->enableDefinitionCache();
|
# check if ACPU is there first, $containerBuilder->enableDefinitionCache();
|
||||||
@@ -122,13 +124,22 @@ class Kernel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# $containerBuilder->useAnnotations(false);
|
foreach(Lean::getDefinitionsPathsFromComposer() as $path) {
|
||||||
|
$containerBuilder->addDefinitions($path);
|
||||||
if ($this->definitionFilePath ?? false) {
|
|
||||||
$containerBuilder->addDefinitions(Lean::autoloadDefinitionsFromComposerExtra());
|
|
||||||
$containerBuilder->addDefinitions(require($this->definitionFilePath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach($this->definitionFilePaths ?? [] as $path) {
|
||||||
|
$containerBuilder->addDefinitions($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
$containerBuilder->addDefinitions([
|
||||||
|
'config' => function () {
|
||||||
|
return array_merge_recursive(
|
||||||
|
Lean::autoloadConfigFromComposerExtra(), []
|
||||||
|
);
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
$this->container = $containerBuilder->build();
|
$this->container = $containerBuilder->build();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
+43
-20
@@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Lean;
|
namespace Lean;
|
||||||
|
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
@@ -22,13 +21,16 @@ class Lean
|
|||||||
|
|
||||||
protected function loadApplications() : void
|
protected function loadApplications() : void
|
||||||
{
|
{
|
||||||
$list = $this->container->get('config')['lean']['autoload'] ?? [];
|
$list = array_filter($this->container->get('config')['lean']['autoload'] ?? []);
|
||||||
|
|
||||||
if (! $list ) {
|
if (! $list ) {
|
||||||
throw new \Exception("You must provide at least one application to autoload within your config file ( 'lean' => 'autoload' => [] )");
|
throw new \Exception("You must provide at least one application to autoload within your config file ( 'lean' => 'autoload' => [] )");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(array_filter($list) as $application) {
|
# Allows 'lean.default' and [ 'lean.default', 100 ] which allows ordering of apps loading.
|
||||||
|
usort($list, fn($e1, $e2) => ( is_array($e1) ? $e1[1] : 0 ) <=> ( is_array($e2) ? $e2[1] : 0 ));
|
||||||
|
|
||||||
|
foreach(array_map(fn($item) => is_array($item) ? $item[0] : $item, $list) as $application) {
|
||||||
if ( $this->container->has($application) ) {
|
if ( $this->container->has($application) ) {
|
||||||
$this->applications[] = ( new Application($application) )->fromArray($this->container->get($application));
|
$this->applications[] = ( new Application($application) )->fromArray($this->container->get($application));
|
||||||
}
|
}
|
||||||
@@ -139,11 +141,11 @@ class Lean
|
|||||||
switch($reader) {
|
switch($reader) {
|
||||||
case "php":
|
case "php":
|
||||||
$list = array_merge(...array_map(fn($app) => $app->tellPhp ?? [], $this->applications));
|
$list = array_merge(...array_map(fn($app) => $app->tellPhp ?? [], $this->applications));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "json":
|
case "json":
|
||||||
$list = array_merge(...array_map(fn($app) => $app->tellJson ?? [], $this->applications));
|
$list = array_merge(...array_map(fn($app) => $app->tellJson ?? [], $this->applications));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $list ?? false ) {
|
if ( $list ?? false ) {
|
||||||
@@ -161,21 +163,28 @@ class Lean
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function autoloadDefinitionsFromComposerExtra() : array
|
public static function getDefinitionsPathsFromComposer() : array
|
||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
|
|
||||||
foreach(Composer::readComposerLock()['packages'] as $package) {
|
foreach(Composer::readComposerLock()['packages'] as $package) {
|
||||||
|
$order = $package['extra']['lean']['autoload']['order'] ?? 0;
|
||||||
|
|
||||||
foreach($package['extra']['lean']['autoload']['definitions'] ?? [] as $autoload) {
|
foreach($package['extra']['lean']['autoload']['definitions'] ?? [] as $autoload) {
|
||||||
$list = array_replace($list, static::loadFromPackage($package, $autoload, getenv('VENDOR_DIR') ?: dirname(__DIR__, 3)));
|
$list[] = [ static::pathFromPackage($package, $autoload), $order ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Composer::readComposerJson()['extra']['lean']['autoload']['definitions'] ?? [] as $autoload) {
|
foreach(Composer::readComposerJson()['extra']['lean']['autoload']['definitions'] ?? [] as $autoload) {
|
||||||
$list = array_replace($list, static::loadFromPackage(null, $autoload, getenv('PROJECT_PATH') ?: dirname(__DIR__, 5)));
|
$order = $package['extra']['lean']['autoload']['order'] ?? 1000;
|
||||||
|
|
||||||
|
$list[] = [ getenv('PROJECT_PATH') . DIRECTORY_SEPARATOR . $autoload, $order ];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $list;
|
# Allows 'lean.default' and [ 'lean.default', 100 ] which allows ordering of apps loading.
|
||||||
|
usort($list, fn($e1, $e2) => $e1[1] <=> $e2[1]);
|
||||||
|
|
||||||
|
return array_column($list, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function autoloadConfigFromComposerExtra() : array
|
public static function autoloadConfigFromComposerExtra() : array
|
||||||
@@ -184,36 +193,50 @@ class Lean
|
|||||||
|
|
||||||
foreach(Composer::readComposerLock()['packages'] as $package) {
|
foreach(Composer::readComposerLock()['packages'] as $package) {
|
||||||
foreach($package['extra']['lean']['autoload']['config'] ?? [] as $autoload) {
|
foreach($package['extra']['lean']['autoload']['config'] ?? [] as $autoload) {
|
||||||
$list = array_merge_recursive($list, static::loadFromPackage($package, $autoload, getenv('VENDOR_DIR') ?: dirname(__DIR__, 3)));
|
$list = array_merge_recursive($list, static::loadFromPackage($package, $autoload));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Composer::readComposerJson()['extra']['lean']['autoload']['config'] ?? [] as $autoload) {
|
foreach(Composer::readComposerJson()['extra']['lean']['autoload']['config'] ?? [] as $autoload) {
|
||||||
$list = array_merge_recursive($list, static::loadFromPackage(null, $autoload, getenv('PROJECT_PATH') ?: dirname(__DIR__, 5)));
|
$list = array_merge_recursive($list, static::loadFromPackage(null, $autoload));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function loadFromPackage(?array $package, array|string $autoload, string $path) : false|array
|
protected static function pathFromPackage(?array $package, array|string $autoload) : string
|
||||||
|
{
|
||||||
|
if ($package === null) {
|
||||||
|
$filepath = getenv('PROJECT_PATH') . DIRECTORY_SEPARATOR . $autoload;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$vendor = getenv('VENDOR_DIR') ? getenv('VENDOR_PATH') : dirname(__DIR__, 3);
|
||||||
|
$filepath = $vendor . DIRECTORY_SEPARATOR . $package['name'] . DIRECTORY_SEPARATOR . $autoload;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! file_exists($filepath)) {
|
||||||
|
throw new \InvalidArgumentException("Given definition filepath do not exists '$filepath'");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function loadFromPackage(? array $package, array|string $autoload) : false|array
|
||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
|
|
||||||
if (is_string($autoload)) {
|
if (is_string($autoload)) {
|
||||||
$file = $path . DIRECTORY_SEPARATOR . ($package ? $package['name'] . DIRECTORY_SEPARATOR : "") . $autoload;
|
$file = static::pathFromPackage($package, $autoload);
|
||||||
|
|
||||||
if ( ! file_exists($file) ) {
|
if ( ! file_exists($file) ) {
|
||||||
throw new \InvalidArgumentException(sprintf("Given autoload file `%s` from package `%s` was not found or is unreachable", $file, $package['name']));
|
throw new \InvalidArgumentException(sprintf("Given autoload file `%s` from package `%s` was not found or is unreachable", $autoload, $package['name']));
|
||||||
}
|
}
|
||||||
|
|
||||||
return require($file);
|
return require($file);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$func = implode('::', array_merge([ key($autoload) ], $autoload));
|
|
||||||
|
|
||||||
return call_user_func($func);
|
$func = implode('::', array_merge([ key($autoload) ], $autoload));
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return call_user_func($func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+42
-3
@@ -5,6 +5,7 @@ namespace Lean;
|
|||||||
use League\Route\RouteGroup,
|
use League\Route\RouteGroup,
|
||||||
League\Route\Router;
|
League\Route\Router;
|
||||||
|
|
||||||
|
use Notes\Route\Attribute\Method\Route;
|
||||||
use Psr\Http\Message\ServerRequestInterface,
|
use Psr\Http\Message\ServerRequestInterface,
|
||||||
Psr\Http\Message\ResponseInterface,
|
Psr\Http\Message\ResponseInterface,
|
||||||
Psr\Container\ContainerInterface;
|
Psr\Container\ContainerInterface;
|
||||||
@@ -17,6 +18,8 @@ class Routing {
|
|||||||
|
|
||||||
public ResponseInterface $response;
|
public ResponseInterface $response;
|
||||||
|
|
||||||
|
public array $overriddenRoutes = [];
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public Router $router,
|
public Router $router,
|
||||||
public RouteFetcher $fetcher,
|
public RouteFetcher $fetcher,
|
||||||
@@ -25,15 +28,15 @@ class Routing {
|
|||||||
|
|
||||||
public function registerRoute(ContainerInterface $container, string $urlBase) {
|
public function registerRoute(ContainerInterface $container, string $urlBase) {
|
||||||
$this->router->group(rtrim($urlBase, "/"), function (RouteGroup $route) use ($container) {
|
$this->router->group(rtrim($urlBase, "/"), function (RouteGroup $route) use ($container) {
|
||||||
foreach($this->fetcher->compile() as $attribute) {
|
foreach($this->fetchRoutesAttributes() as $attribute) {
|
||||||
$this->eventManager->execute(Event\RoutingCompileRoutes::class, $this, $attribute);
|
$this->eventManager->execute(Event\RoutingCompileRoutes::class, $this, $attribute);
|
||||||
|
|
||||||
# Mapping every URLs from attributes in searched folders (Api, Controller, etc...)
|
# Mapping every URLs from attributes in searched folders (Api, Controller, etc...)
|
||||||
foreach((array) $attribute->method as $method) {
|
foreach((array) $attribute->method as $method) {
|
||||||
$route->map(strtoupper($method), $attribute->getRoute(), function (ServerRequestInterface $request, array $arguments) use (
|
$route->map(strtoupper($method), $attribute->getRegistrableRoute(), function (ServerRequestInterface $request, array $arguments) use (
|
||||||
$container, $route, $attribute
|
$container, $route, $attribute
|
||||||
) : ResponseInterface {
|
) : ResponseInterface {
|
||||||
$class = $attribute->class;
|
$class = $attribute->class;
|
||||||
$method = $attribute->classMethod;
|
$method = $attribute->classMethod;
|
||||||
$object = $container->get($class);
|
$object = $container->get($class);
|
||||||
|
|
||||||
@@ -47,4 +50,40 @@ class Routing {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fetchRoutesAttributes() : iterable
|
||||||
|
{
|
||||||
|
static $list = [];
|
||||||
|
|
||||||
|
if ($list) {
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($this->fetcher->compile() as $routeAttribute) {
|
||||||
|
# Routes with differents methods can have the same name
|
||||||
|
$key = sprintf('{%s}~{%s}', $routeAttribute->name, $this->serializeMethods((array) $routeAttribute->method));
|
||||||
|
|
||||||
|
if ( isset($list[$key]) ) {
|
||||||
|
$this->overriddenRoutes[$key] = $list[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$list[$key] = $routeAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findOverriddenRoute(Route $route) : false|iterable
|
||||||
|
{
|
||||||
|
return array_filter($this->overriddenRoutes, fn($e) => $route->name === $e->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function serializeMethods(array $methods) : string
|
||||||
|
{
|
||||||
|
$methods = array_map('strtolower', $methods);
|
||||||
|
|
||||||
|
sort($methods);
|
||||||
|
|
||||||
|
return implode(':', $methods);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
<svg id="e7dedc5b-fca6-4313-b5a0-e6297481e8ae" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1022.7" height="785.81" viewBox="0 0 1022.7 785.81"><defs><linearGradient id="af83dc26-9572-4816-b7a1-1af4f72ff554" x1="678.2" y1="821.79" x2="678.2" y2="493.4" gradientTransform="translate(-20.24 29.65) rotate(-2.31)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="gray" stop-opacity="0.25"/><stop offset="0.54" stop-color="gray" stop-opacity="0.12"/><stop offset="1" stop-color="gray" stop-opacity="0.1"/></linearGradient></defs><title>bug fixing</title><ellipse cx="468.63" cy="660.88" rx="425" ry="33" fill="#6c63ff" opacity="0.1"/><g opacity="0.1"><path d="M933.7,529.93c-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46a22.42,22.42,0,0,0,.63-6.79A24.6,24.6,0,0,0,916,495.12a24.63,24.63,0,0,0,10.86-21.47,23.76,23.76,0,0,0,8.23-9.32c4.9-9.7,2.87-20.6-4.54-24.35s-17.4,1.08-22.3,10.78a23.69,23.69,0,0,0-2.63,12.15,24.63,24.63,0,0,0-10.86,21.47,24.63,24.63,0,0,0-10.86,21.47A24.64,24.64,0,0,0,873,527.33a23.76,23.76,0,0,0-8.23,9.32,25.46,25.46,0,0,0-2.08,5.74,21.18,21.18,0,0,0-4.44-4.73,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83s-11.26,12.83-7.92,23a23.07,23.07,0,0,0,7.56,11.08,25.38,25.38,0,0,0,1,4.5c1.94,5.9,5.77,10.46,10.15,12.75a23.23,23.23,0,0,0-.83,3.9,25.29,25.29,0,0,0-7.54,14.91,25.27,25.27,0,0,0-7.54,14.92,24.63,24.63,0,0,0-5,6.81c-4.91,9.7-2.88,20.61,4.53,24.35s17.4-1.07,22.31-10.78a24.62,24.62,0,0,0,2.5-8.09,25.29,25.29,0,0,0,7.54-14.91,25.27,25.27,0,0,0,7.54-14.92A25.21,25.21,0,0,0,879,571.94,25.21,25.21,0,0,0,886.56,557a24.11,24.11,0,0,0,3.39-4,23.46,23.46,0,0,0,12.27-.77,24.76,24.76,0,0,0,4.23-1.83,23.2,23.2,0,0,0,13.42-.48C930,546.61,936.23,537.65,933.7,529.93Z" transform="translate(-88.65 -57.09)" fill="#3f3d56"/><g opacity="0.1"><path d="M915.77,499.53a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,26.18,26.18,0,0,0,2.1-3.43A24.64,24.64,0,0,0,915.77,499.53Z" transform="translate(-88.65 -57.09)"/><path d="M926.63,478.06a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,25.65,25.65,0,0,0,2.1-3.44A24.85,24.85,0,0,0,926.63,478.06Z" transform="translate(-88.65 -57.09)"/><path d="M902,470.07a21.91,21.91,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,902,470.07Z" transform="translate(-88.65 -57.09)"/><path d="M833.07,600a23.59,23.59,0,0,1,2.95-3.38,22.92,22.92,0,0,1,.87-4,25.09,25.09,0,0,0-2.29,3.71A25.59,25.59,0,0,0,833.07,600Z" transform="translate(-88.65 -57.09)"/><path d="M840.61,585.1a23.59,23.59,0,0,1,2.95-3.38,23,23,0,0,1,.83-3.9l0,0a25.68,25.68,0,0,0-2.2,3.59A26.76,26.76,0,0,0,840.61,585.1Z" transform="translate(-88.65 -57.09)"/><path d="M904.9,521a20.82,20.82,0,0,1-3.43,2.74,22.45,22.45,0,0,1-.63,6.79,18.75,18.75,0,0,1,2,.46,24.76,24.76,0,0,1,4.23-1.83c10.18-3.34,20.47.21,23,7.92a11.68,11.68,0,0,1,.32,6c3.35-3.94,4.74-8.74,3.3-13.14-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46C904.65,522.59,904.79,521.8,904.9,521Z" transform="translate(-88.65 -57.09)"/><path d="M829.35,607.49a25.09,25.09,0,0,0-2.29,3.71,26.56,26.56,0,0,0-1.54,3.74,24.48,24.48,0,0,1,3-3.4A22.92,22.92,0,0,1,829.35,607.49Z" transform="translate(-88.65 -57.09)"/><path d="M891.09,491.54a22,22,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,891.09,491.54Z" transform="translate(-88.65 -57.09)"/><path d="M875.4,579.1a24.29,24.29,0,0,1-1,4.38,26.67,26.67,0,0,0,2.09-3.44,25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,875.4,579.1Z" transform="translate(-88.65 -57.09)"/><path d="M860.32,608.92a24.15,24.15,0,0,1-1,4.38,25.65,25.65,0,0,0,2.1-3.44,26.47,26.47,0,0,0,1.63-4A23.57,23.57,0,0,1,860.32,608.92Z" transform="translate(-88.65 -57.09)"/><path d="M867.86,594a24.11,24.11,0,0,1-1,4.38A26.67,26.67,0,0,0,869,595a25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,867.86,594Z" transform="translate(-88.65 -57.09)"/><path d="M882.94,564.19a24,24,0,0,1-1,4.37,25.89,25.89,0,0,0,2.09-3.43,25.48,25.48,0,0,0,1.64-4.07A23.22,23.22,0,0,1,882.94,564.19Z" transform="translate(-88.65 -57.09)"/><path d="M833.57,526.48c7.72-2.53,16.68,3.66,20,13.83a25.68,25.68,0,0,1,1,4.51,21.18,21.18,0,0,1,4.44,4.73,25.53,25.53,0,0,1,2.08-5.75c.35-.68.73-1.33,1.12-2a21.07,21.07,0,0,0-4-4.18,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83-4.4,1.44-7.44,5.41-8.62,10.43A11.69,11.69,0,0,1,833.57,526.48Z" transform="translate(-88.65 -57.09)"/><path d="M869.37,534.48a21.85,21.85,0,0,1,.18-4.4,24.73,24.73,0,0,0-4.79,6.57,25.07,25.07,0,0,0-1.52,3.72A23,23,0,0,1,869.37,534.48Z" transform="translate(-88.65 -57.09)"/><path d="M880.23,513a21.85,21.85,0,0,1,.18-4.4,24.52,24.52,0,0,0-4.79,6.56,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,880.23,513Z" transform="translate(-88.65 -57.09)"/><path d="M852.78,623.83a24.25,24.25,0,0,1-1,4.39,25.73,25.73,0,0,0,3.73-7.49A23.57,23.57,0,0,1,852.78,623.83Z" transform="translate(-88.65 -57.09)"/></g><path d="M948.52,430.71a23.68,23Line truncated
|
<svg id="e7dedc5b-fca6-4313-b5a0-e6297481e8ae" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1022.7" height="785.81" viewBox="0 0 1022.7 785.81"><defs><linearGradient id="af83dc26-9572-4816-b7a1-1af4f72ff554" x1="678.2" y1="821.79" x2="678.2" y2="493.4" gradientTransform="translate(-20.24 29.65) rotate(-2.31)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="gray" stop-opacity="0.25"/><stop offset="0.54" stop-color="gray" stop-opacity="0.12"/><stop offset="1" stop-color="gray" stop-opacity="0.1"/></linearGradient></defs><title>bug fixing</title><ellipse cx="468.63" cy="660.88" rx="425" ry="33" fill="#6c63ff" opacity="0.1"/><g opacity="0.1"><path d="M933.7,529.93c-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46a22.42,22.42,0,0,0,.63-6.79A24.6,24.6,0,0,0,916,495.12a24.63,24.63,0,0,0,10.86-21.47,23.76,23.76,0,0,0,8.23-9.32c4.9-9.7,2.87-20.6-4.54-24.35s-17.4,1.08-22.3,10.78a23.69,23.69,0,0,0-2.63,12.15,24.63,24.63,0,0,0-10.86,21.47,24.63,24.63,0,0,0-10.86,21.47A24.64,24.64,0,0,0,873,527.33a23.76,23.76,0,0,0-8.23,9.32,25.46,25.46,0,0,0-2.08,5.74,21.18,21.18,0,0,0-4.44-4.73,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83s-11.26,12.83-7.92,23a23.07,23.07,0,0,0,7.56,11.08,25.38,25.38,0,0,0,1,4.5c1.94,5.9,5.77,10.46,10.15,12.75a23.23,23.23,0,0,0-.83,3.9,25.29,25.29,0,0,0-7.54,14.91,25.27,25.27,0,0,0-7.54,14.92,24.63,24.63,0,0,0-5,6.81c-4.91,9.7-2.88,20.61,4.53,24.35s17.4-1.07,22.31-10.78a24.62,24.62,0,0,0,2.5-8.09,25.29,25.29,0,0,0,7.54-14.91,25.27,25.27,0,0,0,7.54-14.92A25.21,25.21,0,0,0,879,571.94,25.21,25.21,0,0,0,886.56,557a24.11,24.11,0,0,0,3.39-4,23.46,23.46,0,0,0,12.27-.77,24.76,24.76,0,0,0,4.23-1.83,23.2,23.2,0,0,0,13.42-.48C930,546.61,936.23,537.65,933.7,529.93Z" transform="translate(-88.65 -57.09)" fill="#3f3d56"/><g opacity="0.1"><path d="M915.77,499.53a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,26.18,26.18,0,0,0,2.1-3.43A24.64,24.64,0,0,0,915.77,499.53Z" transform="translate(-88.65 -57.09)"/><path d="M926.63,478.06a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,25.65,25.65,0,0,0,2.1-3.44A24.85,24.85,0,0,0,926.63,478.06Z" transform="translate(-88.65 -57.09)"/><path d="M902,470.07a21.91,21.91,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,902,470.07Z" transform="translate(-88.65 -57.09)"/><path d="M833.07,600a23.59,23.59,0,0,1,2.95-3.38,22.92,22.92,0,0,1,.87-4,25.09,25.09,0,0,0-2.29,3.71A25.59,25.59,0,0,0,833.07,600Z" transform="translate(-88.65 -57.09)"/><path d="M840.61,585.1a23.59,23.59,0,0,1,2.95-3.38,23,23,0,0,1,.83-3.9l0,0a25.68,25.68,0,0,0-2.2,3.59A26.76,26.76,0,0,0,840.61,585.1Z" transform="translate(-88.65 -57.09)"/><path d="M904.9,521a20.82,20.82,0,0,1-3.43,2.74,22.45,22.45,0,0,1-.63,6.79,18.75,18.75,0,0,1,2,.46,24.76,24.76,0,0,1,4.23-1.83c10.18-3.34,20.47.21,23,7.92a11.68,11.68,0,0,1,.32,6c3.35-3.94,4.74-8.74,3.3-13.14-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46C904.65,522.59,904.79,521.8,904.9,521Z" transform="translate(-88.65 -57.09)"/><path d="M829.35,607.49a25.09,25.09,0,0,0-2.29,3.71,26.56,26.56,0,0,0-1.54,3.74,24.48,24.48,0,0,1,3-3.4A22.92,22.92,0,0,1,829.35,607.49Z" transform="translate(-88.65 -57.09)"/><path d="M891.09,491.54a22,22,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,891.09,491.54Z" transform="translate(-88.65 -57.09)"/><path d="M875.4,579.1a24.29,24.29,0,0,1-1,4.38,26.67,26.67,0,0,0,2.09-3.44,25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,875.4,579.1Z" transform="translate(-88.65 -57.09)"/><path d="M860.32,608.92a24.15,24.15,0,0,1-1,4.38,25.65,25.65,0,0,0,2.1-3.44,26.47,26.47,0,0,0,1.63-4A23.57,23.57,0,0,1,860.32,608.92Z" transform="translate(-88.65 -57.09)"/><path d="M867.86,594a24.11,24.11,0,0,1-1,4.38A26.67,26.67,0,0,0,869,595a25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,867.86,594Z" transform="translate(-88.65 -57.09)"/><path d="M882.94,564.19a24,24,0,0,1-1,4.37,25.89,25.89,0,0,0,2.09-3.43,25.48,25.48,0,0,0,1.64-4.07A23.22,23.22,0,0,1,882.94,564.19Z" transform="translate(-88.65 -57.09)"/><path d="M833.57,526.48c7.72-2.53,16.68,3.66,20,13.83a25.68,25.68,0,0,1,1,4.51,21.18,21.18,0,0,1,4.44,4.73,25.53,25.53,0,0,1,2.08-5.75c.35-.68.73-1.33,1.12-2a21.07,21.07,0,0,0-4-4.18,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83-4.4,1.44-7.44,5.41-8.62,10.43A11.69,11.69,0,0,1,833.57,526.48Z" transform="translate(-88.65 -57.09)"/><path d="M869.37,534.48a21.85,21.85,0,0,1,.18-4.4,24.73,24.73,0,0,0-4.79,6.57,25.07,25.07,0,0,0-1.52,3.72A23,23,0,0,1,869.37,534.48Z" transform="translate(-88.65 -57.09)"/><path d="M880.23,513a21.85,21.85,0,0,1,.18-4.4,24.52,24.52,0,0,0-4.79,6.56,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,880.23,513Z" transform="translate(-88.65 -57.09)"/><path d="M852.78,623.83a24.25,24.25,0,0,1-1,4.39,25.73,25.73,0,0,0,3.73-7.49A23.57,23.57,0,0,1,852.78,623.83Z" transform="translate(-88.65 -57.09)"/></g><path d="M948.52,430.71a23.68,23Line truncated
|
||||||
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 32 KiB |
@@ -31,15 +31,17 @@
|
|||||||
{% foreach range(0, 5) as $week %}
|
{% foreach range(0, 5) as $week %}
|
||||||
<div class="week">
|
<div class="week">
|
||||||
{% foreach range(0, 6) as $day %}
|
{% foreach range(0, 6) as $day %}
|
||||||
|
{% php $dayType = in_array($day, [0, 6]) ? 'week-end' : 'week-day' %}
|
||||||
|
|
||||||
{% if ( $week * 6 + $day >= $index ) && ( $currentDay < $dayCount ) %}
|
{% if ( $week * 6 + $day >= $index ) && ( $currentDay < $dayCount ) %}
|
||||||
{% php $currentDay++; %}
|
{% php $currentDay++; %}
|
||||||
|
|
||||||
{% slot "day.content", new \DateTime("$year-$month-$currentDay"), date("$year-$month-$currentDay") === date('Y-n-j') %}
|
{% slot "day.content", new \DateTime("$year-$month-$currentDay"), date("$year-$month-$currentDay") === date('Y-n-j') %}
|
||||||
<div class="day-box {{ $today ? 'today' : '' }}">{{ $date->format('d') }}</div>
|
<div class="day-box {{ $today ? 'today' : '' }} {{ $dayType }}">{{ $date->format('d') }}</div>
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% slot "day.empty", $day, $month, $year %}
|
{% slot "day.empty", $day, $month, $year %}
|
||||||
<div class="day-box"></div>
|
<div class="day-box {{ $dayType }}"></div>
|
||||||
{% endslot %}
|
{% endslot %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endforeach %}
|
{% endforeach %}
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
<li class="page-item {{ $page === 1 ? 'active' : '' }}"><a class="page-link" href="{% url.parameters $url, [ 'page' => 1 ] + get() %}">1</a></li>
|
<li class="page-item {{ $page === 1 ? 'active' : '' }}"><a class="page-link" href="{% url.parameters $url, [ 'page' => 1 ] + get() %}">1</a></li>
|
||||||
|
|
||||||
{% foreach range(2, $pageCount < $maxPage ? $pageCount : $maxPage) as $pageIndex %}
|
{% if $pageCount > 1%}
|
||||||
<li class="page-item {{ $page === $pageIndex ? 'active' : '' }}"><a class="page-link" href="{% url.parameters $url, [ 'page' => $pageIndex ] + get() %}">{{ $pageIndex }}</a></li>
|
{% foreach range(2, $pageCount < $maxPage ? $pageCount : $maxPage) as $pageIndex %}
|
||||||
{% endforeach %}
|
<li class="page-item {{ $page === $pageIndex ? 'active' : '' }}"><a class="page-link" href="{% url.parameters $url, [ 'page' => $pageIndex ] + get() %}">{{ $pageIndex }}</a></li>
|
||||||
|
{% endforeach %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<li class="page-item {{ $page === $pageCount ? 'disabled' : '' }}"><a class="page-link" href="{% url.parameters $url, [ 'page' => $page + 1 ] + get() %}">{% lang "lean.widget.pagination.next" %}</a></li>
|
<li class="page-item {{ $page === $pageCount ? 'disabled' : '' }}"><a class="page-link" href="{% url.parameters $url, [ 'page' => $page + 1 ] + get() %}">{% lang "lean.widget.pagination.next" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in new issue
Block a user