Powerful wrapper extending Silex, merging simplicity of Silex and usability of Symfony 2.
- Silex basic features (see more)
- Propel 2.x integration
- Twig 2.x integration
- More flexible services
- Controller classes with handy helpers
- Command line support
NOTE: Minion require PHP version 5.6.x or greater.
Type in console composer require dszczer/minion
.
- * 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)
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
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.
Avaliable environments:
prod
production - production environment which should be used in production servertest
testing - testing environment which disable handling error exceptions
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 map file is based on Symfony 2 routing files component.
# app/routing.yml
homepage:
path: /
defaults: { _controller: "DefaultController::indexAction" }
# ...
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 in Minion are something between Silex and Symfony 2. They are expandable, flexible and easy in use.
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.
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 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
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.
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.
Place Twig template under src/Resources/views/Static/<code>.html.twig
name, where <code>
is a status code generated by Application.
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.
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.
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');
}
}
Minion already has bootstrap file for CLI mode, so it should be accessible in your bin
directory, after installing dependencies with Composer.
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
.
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
.
Click here to see detailed API documentation.