icanboogie / module
Provides module support to ICanBoogie.
Installs: 3 245
Dependents: 3
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: >=7.2
- icanboogie/errors: ^2.0
- icanboogie/event: ^4.0
- icanboogie/icanboogie: ^5.0
- icanboogie/operation: ^5.0
Requires (Dev)
- composer/composer: ^2.0
- icanboogie/bind-activerecord: ^5.0
- icanboogie/bind-event: ^5.0
- icanboogie/bind-facets: ^5.0
- icanboogie/bind-routing: ^5.0
- icanboogie/bind-symfony-dependency-injection: ^5.0
- icanboogie/bind-view: ^5.0
- icanboogie/i18n: ^3.0
- phpunit/phpunit: ^8.5
Suggests
- icanboogie/facets: In order to provide records fetchers to controllers.
- icanboogie/operation: Required to use the 'delete' and 'save' operations.
README
This package provides support for modules to the framework ICanBoogie.
A module is like a tiny application inside your application. It provides its own configurations, routes, operations, views, templates… it contains everything it needs to execute a desired functionality.
Installation
composer require icanboogie/module
Defining a module
It takes at least two files to define a module: a configuration fragment and a module class. The configuration fragment is a module.php
file located in the config
directory. The class is usually located in the file lib/Module.php
. The module directory is usually named with the identifier of the module.
The following directory structure demonstrates how a very basic nodes
module could be defined:
nodes
├─ config
│ └─ module.php
└─ lib
└─ Module.php
The following directory structure demonstrates a more advanced module:
nodes
├─ config
│ └─ module.php
| └─ <configuration files>
├─ lib
| ├─ Operation
| | └─ <operation classes>
| └─ Module.php
├─ locale
| └─ <message catalogs>
├─ public
| └─ <public assets>
├─ tests
| └─ <tests>
└─ templates
└─ <view templates>
The configuration fragment
The configuration fragment describes the module and its models. At the very least the identifier and the class of the module must be defined. The modules configuration takes care of verifying module relationships integrity, computing module weights, and sorting modules according to their weight.
The following code could be a configuration fragment for a "nodes" module.
<?php namespace Acme\Nodes; use ICanBoogie\Binding\Module\ConfigBuilder; return fn(ConfigBuilder $config) => $config ->add_module( id: 'nodes', class: Module::class );
Operations
Module operations are defined in the "lib/Operation" directory. For example a save
operation would be a class named SaveOperation
declared within the namespace <module namespace>\Operation
,
located in a "SaveOperation.php" file.
Operations are considered inherited. If the save
operation is requested on a News module,
the framework tries to locate the best matching operation class, according to the modules it
extends:
..\News\Operation\SaveOperation
..\Contents\Operation\SaveOperation
..\Nodes\Operation\SaveOperation
Working with modules
There's two ways to work with modules: a provider is good enough when all your need is load a module, a collection is better if you need to work on multiple modules such as installation.
Accessing a module
You can get a module using a module provider:
<?php /* @var \ICanBoogie\Module\ModuleProvider $provider */ $nodes = $provider->module_for_id('nodes');
You can check a module is defined with the has_module
method:
<?php /* @var \ICanBoogie\Module\ModuleProvider $provider */ $provider->has_module('nodes');
You can also iterate over the provider, and get modules:
<?php /* @var \ICanBoogie\Module\ModuleProvider $provider */ foreach ($provider as $module_id => $get) { $module = $get(); // … }
Installing and uninstalling modules
Modules are installed using the install()
method, and uninstalled using the uninstall()
method. The is_installed()
method returns the installation state of the module and also collects the reasons why the module is not installed.
<?php use ICanBoogie\ErrorCollection; use ICanBoogie\Module; /* @var Module $nodes */ $errors = new ErrorCollection(); if (!$nodes->is_installed($errors)) { # # $errors might contain messages about why the module is not installed # $errors->clear(); if (!$nodes->install($errors)) { # # $errors might contain the reasons why the module failed to install # } } $nodes->uninstall();
Modules can be installed all at once using a ModuleCollection instance. The ModuleCollectionInstallFailed exception is thrown with all the errors and exceptions collected in a ErrorCollection instance if the installation fails.
<?php use ICanBoogie\Module\ModuleCollection;use ICanBoogie\Module\ModuleInstaller\ModuleInstallFailed; /* @var ModuleCollection $modules */ try { $modules->install(); } catch (ModuleInstallFailed $e) { echo get_class($e->errors); // ICanBoogie\ErrorCollection }
Autoconfig
The package supports the autoconfig feature of ICanBoogie.
Template resolver decorator
A ModuleTemplateResolver instance is used to decorate the template resolver instance defined
when the ICanBoogie\Render\BasicTemplateResolver::alter
event of class
TemplateResolver\AlterEvent is fired, adding support for module defined templates. When the
path part of the template name matches an activated module identifier, the template pathname is
resolved using the module and its parents.
Event hooks
routing.collect_routes:before
: Alter routes defined by modules by adding amodule
key that holds the identifier of the module that defines the route.
Continuous Integration
The project is continuously tested by GitHub actions.
Code of Conduct
This project adheres to a Contributor Code of Conduct. By participating in this project and its community, you're expected to uphold this code.
Contributing
See CONTRIBUTING for details.