matiasnamendola/slimpower-slim

Dynamically instantiated controller classes for Slim Framework

v0.0.1-alpha 2016-12-06 16:58 UTC

This package is not auto-updated.

Last update: 2024-04-13 17:27:52 UTC


README

Latest version Total Downloads

Latest Stable Version Latest Unstable Version Total Downloads Monthly Downloads Daily Downloads composer.lock available

An extension to Slim Framework that allows you use to dynamically instantiated controllers with action methods wherever you would use a closure or callback when routing.

The controller can optionally be loaded from Slim's DI container, allowing you to inject dependencies as required.

Additionally, this extension implements Json Middleware & View with great ease.

Installation

Look at Installation File

Usage - Dynamic controller instantiation

Use the string format {controller class name}:{action method name} wherever you would usually use a closure:

e.g.

require 'vendor/autoload.php';

$app = new \SlimPower\Slim\Slim();

$app->get('/hello:name', 'App\IndexController:home');

You can also register the controller with Slim's DI container:

<?php

require 'vendor/autoload.php';

$app = new \SlimPower\Slim\Slim();

$app->container->singleton('App\IndexController', function ($container) {
    // Retrieve any required dependencies from the container and
    // inject into the constructor of the controller.

    return new \App\IndexController();
});

$app->get('/', 'App\IndexController:index');

Example controller

SlimPower - Slim Controller will call the controller's setApp(), setRequest() and setResponse() methods if they exist and populate appropriately. It will then call the controller's `init()`` method.

Hence, a typical controller may look like:

<?php

namespace App;

class IndexController {
    // Optional properties.
    protected $app;
    protected $request;
    protected $response;

    public function index() {
        echo "This is the home page";
    }

    public function hello($name) {
        echo "Hello, $name";
    }

    // Optional setters.
    public function setApp($app) {
        $this->app = $app;
    }

    public function setRequest($request) {
        $this->request = $request;
    }

    public function setResponse($response) {
        $this->response = $response;
    }

    // Init
    public function init() {
        // Do things now that app, request and response are set.
    }
}

Usage - Json Middleware

To include the middleware and view you just have to load them using the default Slim way. Read more about Slim Here (https://github.com/codeguy/Slim#getting-started)

require 'vendor/autoload.php';

$app = new \SlimPower\Slim\Slim();

$app->view(new \SlimPower\Slim\Middleware\Json\JsonView());
$app->add(new \SlimPower\Slim\Middleware\Json\JsonMiddleware());

Example method

All your requests will be returning a JSON output. the usage will be $app->render( (int)$HTTP_CODE, (array)$DATA);

Example code

    $app->get('/', function() use ($app) {
        $app->render(200, array(
            'msg' => 'welcome to my API!',
        ));
    });

Example output

{
    "msg":"welcome to my API!",
    "error":false,
    "status":200
}

Errors

To display an error just set the error => true in your data array. All requests will have an error param that defaults to false.

$app->get('/user/:id', function($id) use ($app) {

    // Your code here.

    $app->render(404, array(
        'error' => TRUE,
        'msg'   => 'user not found',
    ));
});
{
    "msg":"user not found",
    "error":true,
    "status":404
}

You can optionally throw exceptions, the middleware will catch all exceptions and display error messages.

$app->get('/user/:id', function($id) use ($app) {

    // Your code here.

    if(...) {
        throw new \Exception("Something wrong with your request!");
    }
});
{
    "error": true,
    "msg": "ERROR: Something wrong with your request!",
    "status": 500
}

Embedding response data and metadata in separate containers

It is possible to separate response metadata and business information in separate containers.

To make it possible just init JsonView with containers names

require 'vendor/autoload.php';

$app = new \SlimPower\Slim\Slim();

$app->view(new \SlimPower\Slim\Middleware\Json\JsonView("resource", "meta"));
$app->add(new \SlimPower\Slim\Middleware\Json\JsonMiddleware());

Response

{
    "resource":{
        "msg":"welcome to my API!"
    },
    "meta":{
        "error":false,
        "status":200
    }
}

Routing specific requests to the API

If your site is using regular HTML responses and you just want to expose an API point on a specific route, you can use Slim router middlewares to define this.

function jsonResponse(){
    $app = \SlimPower\Slim\Slim::getInstance();
    $app->view(new \SlimPower\Slim\Middleware\Json\JsonView());
    $app->add(new \SlimPower\Slim\Middleware\Json\JsonMiddleware());
}

$app->get('/home',function() use($app){
    // Regular HTML response.
    $app->render("template.tpl");
});

$app->get('/api','jsonResponse',function() use($app){
    // This request will have full JSON responses.

    $app->render(200, array(
        'msg' => 'welcome to my API!',
    ));
});

Middleware

The middleware will set some static routes for default requests. if you dont want to use it, you can copy its content code into your bootstrap file.

IMPORTANT: remember to use $app->config('debug', false); or errors will still be printed in HTML

Credits

License

The MIT License (MIT). Please see License File for more information.

Example project

Look at slimpower-slim-example.