paneric / module-resolver
Simple, yet still useful, static tool (meaning, based on configuration) for specifying module's folder name in case of modular project architecture, accompanied by settings collector.
Requires
- paneric/local: ^1.0
Requires (Dev)
- phpspec/phpspec: ^6.0
- dev-master
- v4.0.0
- v3.0.6
- v3.0.5
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v2.0.23
- v2.0.22
- v2.0.21
- v2.0.20
- v2.0.19
- v2.0.18
- v2.0.17
- v2.0.16
- v2.0.15
- v2.0.14
- v2.0.13
- v2.0.12
- v2.0.11
- v2.0.10
- v2.0.9
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.0.0
- dev-dev
- dev-ref/dynamic_files_loading
- dev-test/update
- dev-edit/readme
This package is auto-updated.
Last update: 2024-04-28 14:03:54 UTC
README
Simple, yet still useful, tool for specifying module's folder name in case of modular project architecture, accompanied by dynamic (no config required) definitions collector.
Required
- PHP 7.1+
File structure
- ModuleResolver.php
- DefinitionsCollector.php
- module-resolver-config.php (an example of required configuration)
Installation
composer
composer require paneric/module-resolver
Integration
Slim Framework/PHP-DI example (ver.4)
Module Resolver
The main role of the Module Resolver is to establish configuration folders. Both for an application itself and a current module that is called. This task is completed based on current route pattern first element.
In case of project's modular structure, it is highly possible to relay on "double scoped" definitions (the first, common for an application itself and the second, that is specific for an application module or installed package).
In order to fully profit all the features delivered by this package, there is one specific condition that is required to
be fulfilled. Each module/package has to be related to its proper routes patters first element.
These relations have to be written in config as an array under the module_map
key.
Application Module Example
In case of code exists as an application module
- application module folder: src/Book
- application module routes patterns: /book/... , /books/... , /bk/... (one or more)
src/config/module-resolver-config.php
'module_map' => [
'book' => ROOT_FOLDER . 'src/Book',
'books' => ROOT_FOLDER . 'src/Book',
'bk' => ROOT_FOLDER . 'src/Book',
...
],
Package Example
In case of code that is supposed to be used also as composer package
- package folder: src/Book
- package routes patterns: /book/... , /books/... , /bk/... (one or more)
src/config/module-resolver-config.php
'module_map_cross' => [
'book' => ROOT_PACKAGE . 'src/Book',
'books' => ROOT_PACKAGE . 'src/Book',
'bk' => ROOT_PACKAGE . 'src/Book',
...
],
Configuration
Application only with modules
src/config/module-resolver-config.php
<?php
declare(strict_types=1);
return [
'default_route_key' => 'lc',
'local_map' => ['en', 'pl'],
'dash_as_slash' => false,
'merge_module_cross_map' => false,
'module_map' => [
'lc' => ROOT_FOLDER . 'src/ListCountryApp',
'api-lc' => ROOT_FOLDER . 'src/ListCountryApi',
'api-lcs' => ROOT_FOLDER . 'src/ListCountryApi',
'apc-lc' => ROOT_FOLDER . 'src/ListCountryApc',
],
'module_map_cross' => [
'lc' => ROOT_FOLDER . 'vendor/paneric/e-commerce-list-country/src/ListCountryApp',
'api-lc' => ROOT_FOLDER . 'vendor/paneric/e-commerce-list-country/src/ListCountryApi',
'api-lcs' => ROOT_FOLDER . 'vendor/paneric/e-commerce-list-country/src/ListCountryApi',
'apc-lc' => ROOT_FOLDER . 'vendor/paneric/e-commerce-list-country/src/ListCountryApc',
],
];
Application with modules and packages
src/config/module-resolver-config.php
<?php
declare(strict_types=1);
use Paneric\ModuleResolver\ModuleMapper;
$moduleMapper = new ModuleMapper();
$moduleMapCrossPaths = [
'vendor/paneric/e-commerce-list-country',
'vendor/paneric/e-commerce-list-type-company',
];
$moduleMapPath = 'vendor/paneric/e-commerce-address';
$moduleMap = [
'adr' => ROOT_FOLDER . '%s/src/AddressApp',
'api-adr' => ROOT_FOLDER . '%s/src/AddressApi',
'api-adrs' => ROOT_FOLDER . '%s/src/AddressApi',
'apc-adr' => ROOT_FOLDER . '%s/src/AddressApc',
];
return [
'default_route_key' => 'adr',
'local_map' => ['en', 'pl'],
'dash_as_slash' => false,
'merge_module_cross_map' => true,
'module_map' => $moduleMapper->setModuleMap($moduleMap),
'module_map_cross' => $moduleMapper->setModuleMapCross(
$moduleMapCrossPaths,
$moduleMap,
$moduleMapPath,
__DIR__ !== ROOT_FOLDER . 'src/config'
),
];
Configuration details
- 'default_route_key' - default first element of a route pattern;
- 'local_map' - an array of language version markers intended to be recognized within your routes;
- 'dash_as_slash' - in case if you choose to use dashes instead of slashes as your route pattern elements separator;
- 'merge_module_cross_map' - in case of application consists of both its own modules and composer packages;
- 'module_map' - an array/mapper of application modules names related to the first segment of a route;
- 'module_map_cross' - an array/mapper prepared for a case if code is to be used as the composer package of a complex structure;
ProTip: as a consequence, above example of configuration: 'home' => 'Website', will establish Website/ as a module folder name for following examples of routes: /home, /home/fr or /home/sth/fr .
Definitions Collector
front controller
Let's consider an example of some modular project structure as follows:
- my_project
- public
- index.php
- src
- config
- module-resolver-config.php
- definitions
- di
- orm.php
- twig.php
- ...
- settings
- dev.php
- prod.php
- translation.en.php
- ...
- ...
- di
- Website
- definitions
- di
- controller.php
- repository.php
- service.php
- ...
- settings
- translation.en.php
- ...
- di
- Entity
- Controller
- Repository
- templates
- ...
- definitions
- Registration
- definitions
- di
- controller.php
- middleware.php
- package.php
- ...
- settings
- validation.php
- ...
- di
- ...
- definitions
- ...
- config
- public
In this case our practical integration of the module resolver may look this way:
use Paneric\ModuleResolver\ModuleResolver;
use Paneric\ModuleResolver\DefinitionsCollector;
use DI\ContainerBuilder;
use Slim\Factory\AppFactory;
define('ENV', 'dev');
define('ROOT_FOLDER', dirname(__DIR__) . '/');
define('APP_FOLDER', ROOT_FOLDER . 'src/');
require ROOT_FOLDER . 'vendor/autoload.php';
try{
$moduleResolverConfig = require_once APP_FOLDER . 'config/module_resolver_config.php';
$moduleResolver = new ModuleResolver();
$moduleFolderName = $moduleResolver->setModuleFolderName(
$_SERVER['REQUEST_URI'],
$moduleResolverConfig
);
$definitionsCollector = new DefinitionsCollector();
$definitions = $definitionsCollector->setDefinitions(
APP_FOLDER,
APP_FOLDER . $moduleFolderName,
'definitions'
);
$builder = new ContainerBuilder();
$builder->addDefinitions($definitions);
$container = $builder->build();
AppFactory::setContainer($container);
$app = AppFactory::create();
// ... (any other require) //
$app->run();
} catch (Exception $e) {
echo $e->getMessage();
}
ProTip: definitions** states for folder name of php-di definitions. Only its sub-folders (1 st level exclusively) are scanned for .php definitions files (returning array).
If you need some environment variables to include in your settings file, it has to be named according to your environment variable value (dev or prod) set in the front controller. The env value is passed to the definitions collector method as the last parameter (optional, default value is set to null).
It works the the same in case of translation settings related to "local" method parameter (also optional, default parameter value is set to null) under one condition however. Your translation settings file name has to follow a particular convention. Regardles of the location (application settings folder or module settings folder) it has to be for example "translation.en.php" where "en" is actual local value for "English". If you set translation files both in src/definitions/settings and src/Module/definitions/settings remember to merge appropriate arrays during translator instantiation.
To make a long story short it will be necessary to modify settings collector "setSettings" method call as:
$settingsCollector = new SettingsCollector();
$settings = $settingsCollector->setSettings(
APP_FOLDER,
APP_FOLDER . $moduleFolderName,
'definitions',
$local
);
if you need only some translation dictionary, or:
$settingsCollector = new SettingsCollector();
$settings = $settingsCollector->setSettings(
APP_FOLDER,
APP_FOLDER . $moduleFolderName,
'definitions',
$local,
ENV
);
if you need some translation dictionary along with some environmental settings, or:
$settingsCollector = new SettingsCollector();
$settings = $settingsCollector->setSettings(
APP_FOLDER,
APP_FOLDER . $moduleFolderName,
'definitions',
'',
ENV
);
if you need only some environmental settings.
ProTip: "... (any other require)" mentioned in the front controller code related to separated dependencies, routes etc can be realized by the following manner:
// twig, orm
require_once APP_FOLDER . 'definitions/dependencies.php';
// controllers, repositories, middlewares, extensions, etc;
require_once APP_FOLDER . $moduleFolderName . 'definitions/dependencies.php';
// and of course routes
require_once APP_FOLDER . $moduleFolderName . 'definitions/routes.php';