dszczer/minion

This package is abandoned and no longer maintained. No replacement package was suggested.

Powerful wrapper extending Silex, merging simplicity of Silex and usability of Symfony 2

v1.0.0 2016-01-23 10:47 UTC

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

  1. Main features
  2. Installation
  3. Usage
  4. API Documentation

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-specific propel.php configuration file path; ignored if option minion.usePropel is false

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 server
  • test 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 paths
  • MiscExtension - some miscellaneous functions thay may be useful
  • UrlExtension - 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 aliases bin/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.