243 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace Lean;
 | |
| 
 | |
| use Psr\Container\ContainerInterface;
 | |
| 
 | |
| class Lean
 | |
| {
 | |
|     const DEFAULT_PICEA_CONTEXT  = __NAMESPACE__;
 | |
| 
 | |
|     protected ContainerInterface $container;
 | |
| 
 | |
|     public array $applications = [];
 | |
| 
 | |
|     public function __construct(ContainerInterface $container)
 | |
|     {
 | |
|         $this->container = $container;
 | |
| 
 | |
|         $this->loadApplications();
 | |
|     }
 | |
| 
 | |
|     protected function loadApplications() : void
 | |
|     {
 | |
|         $list = array_filter($this->container->get('config')['lean']['autoload'] ?? []);
 | |
| 
 | |
|         if (! $list ) {
 | |
|             throw new \Exception("You must provide at least one application to autoload within your config file ( 'lean' => 'autoload' => [] )");
 | |
|         }
 | |
| 
 | |
|         # 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) ) {
 | |
|                 $this->applications[] = ( new Application($application) )->fromArray($this->container->get($application));
 | |
|             }
 | |
|             else {
 | |
|                 throw new \RuntimeException("Trying to load an application '$application' which have not been configured yet");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function getApplication(string $name) : ? Application
 | |
|     {
 | |
|         foreach($this->applications as $app) {
 | |
|             if ($app->name === $name) {
 | |
|                 return $app;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return null;
 | |
|     }
 | |
| 
 | |
|     public function getPiceaContext() /*: string|array */
 | |
|     {
 | |
|         foreach(array_reverse($this->applications) as $apps) {
 | |
|             if ( $apps->piceaContext ?? null ) {
 | |
|                 return $apps->piceaContext;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return static::DEFAULT_PICEA_CONTEXT;
 | |
|     }
 | |
| 
 | |
|     public function getPiceaExtensions() : array
 | |
|     {
 | |
|         $list = [];
 | |
| 
 | |
|         foreach(array_reverse($this->applications) as $apps) {
 | |
|             if ( $apps->piceaExtensions ?? null ) {
 | |
|                 $list = array_merge($list, $apps->piceaExtensions);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $list;
 | |
|     }
 | |
| 
 | |
|     public function getRoutable() : array
 | |
|     {
 | |
|         return array_merge(...array_map(fn($app) => $app->routes ?? [], $this->applications));
 | |
|     }
 | |
| 
 | |
|     public function getCronard() : array
 | |
|     {
 | |
|         return array_merge(...array_map(fn($app) => $app->cronard ?? [], $this->applications));
 | |
|     }
 | |
| 
 | |
|     public function getCLI() : array
 | |
|     {
 | |
|         return array_merge(...array_map(fn($app) => $app->cli ?? [], $this->applications));
 | |
|     }
 | |
| 
 | |
|     public function getEvents() : array
 | |
|     {
 | |
|         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));
 | |
|     }
 | |
| 
 | |
|     public function getViewPaths() : array
 | |
|     {
 | |
|         $list = array_merge(...array_map(fn($app) => $app->views ?? [], $this->applications));
 | |
| 
 | |
|         $this->verifyPathList($list);
 | |
| 
 | |
|         uasort($list, fn($i1, $i2) => $i1['order'] <=> $i2['order'] );
 | |
| 
 | |
|         return $list;
 | |
|     }
 | |
| 
 | |
|     public function getAssetPaths() : array
 | |
|     {
 | |
|         $list = array_merge(...array_map(fn($app) => $app->piceaAssets ?? [], $this->applications));
 | |
| 
 | |
|         $this->verifyPathList($list);
 | |
| 
 | |
|         uasort($list, fn($i1, $i2) => $i1['order'] <=> $i2['order'] );
 | |
| 
 | |
|         return $list;
 | |
|     }
 | |
| 
 | |
|     protected function verifyPathList(array $list) : void
 | |
|     {
 | |
|         foreach($list as $item) {
 | |
|             if (! isset($item['order']) ) {
 | |
|                 throw new \RuntimeException(sprintf("An error occured while verifying a path list (%s)", json_encode($item, \JSON_PRETTY_PRINT)));
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function getI18n(string $reader) : ? array
 | |
|     {
 | |
|         switch($reader) {
 | |
|             case "php":
 | |
|                 $list = array_merge(...array_map(fn($app) => $app->tellPhp ?? [], $this->applications));
 | |
|                 break;
 | |
| 
 | |
|             case "json":
 | |
|                 $list = array_merge(...array_map(fn($app) => $app->tellJson ?? [], $this->applications));
 | |
|                 break;
 | |
|         }
 | |
| 
 | |
|         if ( $list ?? false ) {
 | |
|             uasort($list, fn($i1, $i2) => $i2['order'] <=> $i1['order']);
 | |
| 
 | |
|             return array_map(fn($item) => $item['path'], $list);
 | |
|         }
 | |
| 
 | |
|         return null;
 | |
|     }
 | |
| 
 | |
|     #[\Deprecated("Definitions are now loaded automatically from composer extra array.")]
 | |
|     public static function definitions() : array
 | |
|     {
 | |
|         return [];
 | |
|     }
 | |
| 
 | |
|     public static function getDefinitionsPathsFromComposer() : array
 | |
|     {
 | |
|         $list = [];
 | |
| 
 | |
|         foreach(Composer::readComposerLock()['packages'] as $package) {
 | |
|             $order = $package['extra']['lean']['autoload']['order'] ?? 0;
 | |
| 
 | |
|             foreach($package['extra']['lean']['autoload']['definitions'] ?? [] as $autoload) {
 | |
|                 $list[] = [ static::pathFromPackage($package, $autoload), $order ];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         foreach(Composer::readComposerJson()['extra']['lean']['autoload']['definitions'] ?? [] as $autoload) {
 | |
|             $order = $package['extra']['lean']['autoload']['order'] ?? 1000;
 | |
| 
 | |
|             $list[] = [ getenv('PROJECT_PATH') . DIRECTORY_SEPARATOR . $autoload, $order ];
 | |
|         }
 | |
| 
 | |
|         # 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
 | |
|     {
 | |
|         $list = [];
 | |
| 
 | |
|         foreach(Composer::readComposerLock()['packages'] as $package) {
 | |
|             foreach($package['extra']['lean']['autoload']['config'] ?? [] as $autoload) {
 | |
|                 $list = array_merge_recursive($list, static::loadFromPackage($package, $autoload));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         foreach(Composer::readComposerJson()['extra']['lean']['autoload']['config'] ?? [] as $autoload) {
 | |
|             $list = array_merge_recursive($list, static::loadFromPackage(null, $autoload));
 | |
|         }
 | |
| 
 | |
|         return $list;
 | |
|     }
 | |
| 
 | |
|     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 = [];
 | |
| 
 | |
|         if (is_string($autoload)) {
 | |
|             $file = static::pathFromPackage($package, $autoload);
 | |
| 
 | |
|             if ( ! file_exists($file) ) {
 | |
|                 throw new \InvalidArgumentException(sprintf("Given autoload file `%s` from package `%s` was not found or is unreachable", $autoload, $package['name']));
 | |
|             }
 | |
| 
 | |
|             return require($file);
 | |
|         }
 | |
| 
 | |
|         $func = implode('::', array_merge([ key($autoload) ], $autoload));
 | |
| 
 | |
|         return call_user_func($func);
 | |
|     }
 | |
| }
 |