dszczer / minion
Powerful wrapper extending Silex, merging simplicity of Silex and usability of Symfony 2
Requires
- php: >=5.6 || ~7.0
- knplabs/console-service-provider: ~1.0
- monolog/monolog: 1.*
- propel/propel: 2.*@dev
- propel/propel-service-provider: 2.*@dev
- silex/silex: 1.3.*
- symfony/console: 2.8.*
- symfony/twig-bridge: 3.*
- twig/twig: ~2.0-dev
Requires (Dev)
- phpunit/phpunit: 4.8.*
This package is not auto-updated.
Last update: 2022-02-01 12:54:56 UTC
README
Powerful wrapper extending Silex, merging simplicity of Silex and usability of Symfony 2.
Table of Contents
Main features
- Silex basic features (see more)
- Propel 2.x integration
- Twig 2.x integration
- More flexible services
- Controller classes with handy helpers
- Command line support
Installation
NOTE: Minion require PHP version 5.6.x or greater.
Using Composer
Type in console composer require dszczer/minion
.
Usage
Project directory tree
Legend:
- * required
- [name] directory
. (root directory)
+-- [app]*
| +-- config.yml*
| +-- parameters.yml*
| +-- routing.yml*
|
+-- [bin] (autogenerated by Composer)
|
+-- [src]* (project source code)
| +-- [Controller]*
| +-- [Resources] (required if using Twig)
| +-- [views]*
|
+-- [var]*
| +-- [cache] (must have write permission)
| +-- [log] (must have write permission)
|
+-- [vendor]* (Composer dependencies)
|
+-- [web]* (public access directory - server document root)
+-- assets (any directory structure)
+-- index.php (entry point)
Custom project directory structure
If you want to use other directory structure or you have no choice (e.g. shared hosting), you can define custom paths as third __construct
Application's method:
- string
rootDir
- project root directory - string
packageDir
- Minion vendor's directory root - string
configPath
- configuration files path, default is/app/
- string
propelConfigPath
- Propel sensitive-data and project-specificpropel.php
configuration file path; ignored if optionminion.usePropel
isfalse
Bootstrap
All you need to bootstrap Minion is include Composer autoloader, provide application namespace (not required, but recommended), instantiate Minion\Application
and call run()
method on it.
// web/index.php require_once __DIR__ . '/../vendor/autoload.php'; // it is recommended to provide ./src/ namespace, but Minion will try to guess this value $namespace = 'Project\\'; $app = new Minion\Application($namespace, ['debug' => false, 'environment' => 'prod']); $app->run();
You will need to configure your server to point ./web
directory as the only one with public access, and index.php
as directory index. Look here for more information.
Application environments
Avaliable environments:
prod
production - production environment which should be used in production servertest
testing - testing environment which disable handling error exceptions
Initial configuration
You can pass several options into second __construct()
argument Application's method:
- bool
debug
- debugging mode, true to enable, false to disable - string
environment
['prod'|'test']
- working application's environment - bool
minion.usePropel
- true to use Propel ORM, false to don't - bool
minion.useTwig
- true to use Twig templating, false to don't
Routing
Routing map
Routing map file is based on Symfony 2 routing files component.
# app/routing.yml homepage: path: / defaults: { _controller: "DefaultController::indexAction" } # ...
Controllers
Minion provides helpful controller basic class. To extend this class and use actions, write your controller like this:
// src/Controller/DefaultController.php namespace Project\Controller; use Minion\Controller; use Minion\Application; use Symfony\HttpFoundation\Request; // ... class DefaultController extends Controller { public function indexAction(Request $request, Application $app) { // ... // if you're using Twig, path is relative to src/Resources/views/ return $this->render('index.html.twig'); // if you're not using Twig, path is relative to src/ return $this->render('template_index.html.php'); } }
IMPORTANT: action shall always return an Symfony\HttpFoundation\Response
object (exactly like in Symfony 2).
For more information about avaliable methods, look into API documentation.
Services
Services in Minion are something between Silex and Symfony 2. They are expandable, flexible and easy in use.
Writing own service
First, you must write a new Service class:
// src/Service/MyService.php namespace Project\Service; class MyService { public function foo() { return 'bar'; } }
Then, you should write provider class:
// src/Service/CustomServiceProvider.php namespace Project\Service; use \Minion\Service\ServiceProvider; use \Silex\Application as SilexApp; class CustomServiceProvider extends ServiceProvider { public function register(SilexApp $app) { $config = $this->getServiceConfig(); $app[ $config->getId() ] = $app->share(function(SilexApp $app) { return new MyService(); }); } public function boot(SilexApp $app) {} }
CustomServiceProvider
shall extend Minion\Service\ServiceProvider
basic class or implement Minion\Service\ServiceProviderInterface
interface.
Of course, instead of sharing a new service, you are fully able to extend an exisitng one. Example below is extending Twig with Twig_Extension
class:
// src/Service/CustomServiceProvider.php namespace Project\Service; use \Minion\Service\ServiceProvider; use \Silex\Application as SilexApp; class CustomServiceProvider extends ServiceProvider { public function register(SilexApp $app) { $app['twig'] = $app->share($app->extend('twig', function (\Twig_Environment $twig, SilexApp $app) { $class = $this->getServiceConfig()->getOption('twig.extension.class'); // is \Project\Util\MyTwigExtension $twig->addExtension(new $class); return $twig; })); } public function boot(SilexApp $app) {} }
Finally, you can define your custom service in app/config.yml
file:
# app/config.yml services: my_custom_service_id: # unique service id class: "Project\\Service\\CustomServiceProvider" # service provider's fully qualified class name options: # options accesible inside service provider twig.extension.class: "\\Project\\Util\\MyTwigExtension"
And Voile'a! You have registered your new service. You can use it for e.g. inside controller's action:
// ... class DefaultController extends Controller { public function defaultAction(Request $request, Application $app) { $myServiceName = $app['my_custom_service']->foo(); // should return 'bar' } }
HINT: Minion has it's own Twig extension service provider expander, so you don't have to write your own one. Read more below.
Service configuration
Inside service provider's register
method you have full access to service configuration, thanks to Minion\Service\ServiceConfigInterface
:
// ... class CustomServiceProvider extends ServiceProvider { public function register(SilexApp $app) { $serviceConfiguration = $this->getServiceConfig(); } // ... }
Service tags
Service tags are marks for Minion to use build-in service provider and are special case use. Avaliable tags:
twig.extension
Tag twig.extension
is defined in app/config.yml
like below:
# app/config.yml services: my_custom_twig_extension_id: class: "\\Project\\Twig\\MyCustomTwigExtension" #options: # optional tags: - twig.extension
Build-in Twig extensions, ready to use
List of build-in twig extensions:
AssetExtension
- assets for web use, helps to define web side or server side related pathsMiscExtension
- some miscellaneous functions thay may be usefulUrlExtension
- generating links in templates with this is easy For more information about avaliable methods, see API documentation.
Error pages
Minion allows you to customize error pages for 403
, 404
and 500
HTTP status codes. Inside your template scope only thrown exception would be avaliable under (Twig) exception
or (PHP) $exception
variable name.
Template file can be standalone or extending other template file.
Twig template
Place Twig template under src/Resources/views/Static/<code>.html.twig
name, where <code>
is a status code generated by Application.
PHP template
If you are not using Twig, place your PHP template under src/Static/<code>.html.php
name, where <code>
is a status code generated by Application.
Console
Minion provides easy in use CLI mode. All project specific commands should be stored in src/Command
directory and should extend Knp\Command\Command
class.
More about Knp Command avaliable here.
Naming conventions
Command file must have name with suffix Command.php
. Class name also must contain Command
suffix. Files that do not fulfill those conditions are ignored.
Example command:
// src/Command/ProjectCommand.php namespace Project\Command; use Knp\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class ProjectCommand extends Command { // Configure command protected function configure() { $this ->setName('project') ->setDescription('project command') ; } // Execute command public function execute(InputInterface $input, OutputInterface $output) { $output->write('project command in practice'); } }
Bootstrap
Minion already has bootstrap file for CLI mode, so it should be accessible in your bin
directory, after installing dependencies with Composer.
Usage
To run Minion in CLI mode, go to your project directory (bash, windows command, etc.) and type bin/console command:name
.
Minion provides autoloader for Propel commands. If you want to use propel commands, type in project root directory
bin/console propel:namespace:command
, for e.g.bin/console propel:model:build
, or just use aliasesbin/console build
.
Registering
Minion has command autoloader, so you just need to place Command
class in the right directory src/Command
. That's all! Of course, you can load commands from anywhere, just call $app->loadCommands($path, $prefix)
before $app->run()
.
Required $path
argument is an absolute path to directory containing command files. Optional $prefix
argument is a namespace for them. So, if you enter prefix, your command for e.g. command:exec
will be avaliable under prefix:command:exec
.
API Documentation
Click here to see detailed API documentation.