diff --git a/app/Bootstrap/ConfigComposer.php b/app/Bootstrap/ConfigComposer.php new file mode 100644 index 0000000..96b3fc9 --- /dev/null +++ b/app/Bootstrap/ConfigComposer.php @@ -0,0 +1,32 @@ +container = $container; + } + + /** + * Set up the Config component. + * + * @return void + */ + public function __invoke(): void + { + $this->container->set(Config::class, new Config('app/config')); + } +} diff --git a/app/Bootstrap/FilesComposer.php b/app/Bootstrap/FinderComposer.php similarity index 65% rename from app/Bootstrap/FilesComposer.php rename to app/Bootstrap/FinderComposer.php index ae92eb1..c3a2ba1 100644 --- a/app/Bootstrap/FilesComposer.php +++ b/app/Bootstrap/FinderComposer.php @@ -3,13 +3,14 @@ namespace App\Bootstrap; use Closure; +use DI\Container; use PHLAK\Config\Config; use RuntimeException; use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\SplFileInfo; use Tightenco\Collect\Support\Collection; -class FilesComposer +class FinderComposer { /** @const Application paths to be hidden */ protected const APP_FILES = ['app', 'vendor', 'index.php']; @@ -17,16 +18,22 @@ class FilesComposer /** @var Config Application config */ protected $config; - /** @var Finder Symfony finder component */ - protected $finder; + /** @var Container The application container */ + protected $container; /** @var Collection Collection of hidden file paths */ protected $hiddenFiles; - public function __construct(Config $config, Finder $finder) + /** + * Create a new FilesComposer object. + * + * @param \PHLAK\Config\Config $config + * @param \Symfony\Component\Finder\Finder $finder + */ + public function __construct(Container $container, Config $config) { + $this->container = $container; $this->config = $config; - $this->finder = $finder; $this->hiddenFiles = Collection::make( $this->config->get('hidden_files', []) @@ -46,34 +53,34 @@ class FilesComposer */ public function __invoke(): void { - $this->finder->depth(0)->followLinks(); - $this->finder->ignoreVCS($this->config->get('ignore_vcs_files', false)); - $this->finder->filter(function (SplFileInfo $file) { + $finder = Finder::create()->depth(0)->followLinks(); + $finder->ignoreVCS($this->config->get('ignore_vcs_files', false)); + $finder->filter(function (SplFileInfo $file) { return ! $this->hiddenFiles->contains($file->getRealPath()); }); $sortOrder = $this->config->get('sort_order', 'name'); if ($sortOrder instanceof Closure) { - $this->finder->sort($sortOrder); + $finder->sort($sortOrder); } else { switch ($sortOrder) { case 'accessed': - $this->finder->sortByAccessedTime(); + $finder->sortByAccessedTime(); break; case 'changed': - $this->finder->sortByChangedTime(); + $finder->sortByChangedTime(); break; case 'modified': - $this->finder->sortByModifiedTime(); + $finder->sortByModifiedTime(); break; case 'name': - $this->finder->sortByName(); + $finder->sortByName(); break; case 'natural': - $this->finder->sortByName(true); + $finder->sortByName(true); break; case 'type': - $this->finder->sortByType(); + $finder->sortByType(); break; default: throw new RuntimeException("Invalid sort option '{$sortOrder}'"); @@ -81,7 +88,9 @@ class FilesComposer } if ($this->config->get('reverse_sort', false)) { - $this->finder->reverseSorting(); + $finder->reverseSorting(); } + + $this->container->set(Finder::class, $finder); } } diff --git a/app/Bootstrap/ViewComposer.php b/app/Bootstrap/ViewComposer.php index 0a52d20..e618f9c 100644 --- a/app/Bootstrap/ViewComposer.php +++ b/app/Bootstrap/ViewComposer.php @@ -2,6 +2,7 @@ namespace App\Bootstrap; +use DI\Container; use PHLAK\Config\Config; use Slim\Views\Twig; use Twig\Extension\CoreExtension; @@ -9,26 +10,22 @@ use Twig\TwigFunction; class ViewComposer { + /** @var Container The application container */ + protected $container; + /** @var Config Application config */ protected $config; - /** @var Twig Twig instance */ - protected $twig; - - /** @var string Path to theme */ - protected $themePath; - /** * Create a new ViewComposer object. * + * @param \DI\Container $container * @param \PHLAK\Config\Config $config - * @param \Slim\Views\Twig $twig */ - public function __construct(Config $config, Twig $twig) + public function __construct(Container $container, Config $config) { + $this->container = $container; $this->config = $config; - $this->twig = $twig; - $this->themePath = $twig->getLoader()->getPaths()[0]; } /** @@ -38,32 +35,38 @@ class ViewComposer */ public function __invoke(): void { - $this->twig->getEnvironment()->setCache( + $twig = new Twig("app/themes/{$this->config->get('theme', 'default')}"); + + $twig->getEnvironment()->setCache( $this->config->get('view_cache', 'app/cache/views') ); - $this->twig->getEnvironment()->getExtension(CoreExtension::class)->setDateFormat( + $twig->getEnvironment()->getExtension(CoreExtension::class)->setDateFormat( $this->config->get('date_format', 'Y-m-d H:i:s'), '%d days' ); - $this->registerGlobalFunctions(); - $this->registerThemeFunctions(); + $this->registerGlobalFunctions($twig); + $this->registerThemeFunctions($twig); + + $this->container->set(Twig::class, $twig); } /** * Register global Twig functions. * + * @param \Slim\Views\Twig $twig + * * @return void */ - public function registerGlobalFunctions(): void + public function registerGlobalFunctions(Twig $twig): void { - $this->twig->getEnvironment()->addFunction( - new TwigFunction('asset', function (string $path) { - return "/{$this->themePath}/{$path}"; + $twig->getEnvironment()->addFunction( + new TwigFunction('asset', function (string $path) use ($twig) { + return "/{$twig->getLoader()->getPaths()[0]}/{$path}"; }) ); - $this->twig->getEnvironment()->addFunction( + $twig->getEnvironment()->addFunction( new TwigFunction('sizeForHumans', function (int $bytes) { $sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; $factor = (int) floor((strlen((string) $bytes) - 1) / 3); @@ -76,18 +79,20 @@ class ViewComposer /** * Register theme specific Twig functions. * + * @param \Slim\Views\Twig $twig + * * @return void */ - public function registerThemeFunctions(): void + public function registerThemeFunctions(Twig $twig): void { - $themeFunctionsFile = "{$this->themePath}/functions.php"; + $themeFunctionsFile = "{$twig->getLoader()->getPaths()[0]}/functions.php"; if (file_exists($themeFunctionsFile)) { $themeConfig = include $themeFunctionsFile; } foreach ($themeConfig['functions'] ?? [] as $function) { - $this->twig->getEnvironment()->addFunction($function); + $twig->getEnvironment()->addFunction($function); } } } diff --git a/app/Controllers/DirectoryController.php b/app/Controllers/DirectoryController.php index a213036..8a0d53b 100644 --- a/app/Controllers/DirectoryController.php +++ b/app/Controllers/DirectoryController.php @@ -2,6 +2,7 @@ namespace App\Controllers; +use DI\Container; use PHLAK\Config\Config; use Slim\Psr7\Response; use Slim\Views\Twig; @@ -13,17 +14,22 @@ class DirectoryController /** @var Config App configuration component */ protected $config; + /** @var Container Application container */ + protected $container; + /** @var Twig Twig templating component */ protected $view; /** * Create a new DirectoryController object. * + * @param \DI\Container $container * @param \PHLAK\Config\Config $config * @param \Slim\Views\Twig $view */ - public function __construct(Config $config, Twig $view) + public function __construct(Container $container, Config $config, Twig $view) { + $this->container = $container; $this->config = $config; $this->view = $view; } @@ -67,7 +73,7 @@ class DirectoryController } /** - * Undocumented function. + * Determine if a provided path is the root path. * * @param string $path * @@ -75,6 +81,6 @@ class DirectoryController */ protected function isRoot(string $path): bool { - return realpath($path) === realpath($this->config->get('app.root')); + return realpath($path) === realpath($this->container->get('app.root')); } } diff --git a/index.php b/index.php index fc02cca..8a1206f 100644 --- a/index.php +++ b/index.php @@ -1,45 +1,35 @@ load(); -/** Create the container */ +// Initialize the container $container = new Container(); +$container->set('app.root', __DIR__); -/** Register dependencies */ -$container->set(Config::class, new Config('app/config')); -$container->set(Finder::class, new Finder()); -$container->set(Twig::class, function (Config $config) { - return new Twig("app/themes/{$config->get('theme', 'default')}"); -}); - -/** Configure the application components */ -$container->call(function (Config $config) { - $config->set('app.root', __DIR__); -}); -$container->call(FilesComposer::class); +// Configure the application componentes +$container->call(ConfigComposer::class); +$container->call(FinderComposer::class); $container->call(ViewComposer::class); -/** Create the application */ +// Create the application $app = Bridge::create($container); -/** Register routes */ +// Register routes $app->get('/[{path:.*}]', Controllers\DirectoryController::class); -/** Enagage! */ +// Enagage! $app->run();