2017 © Pedro Peláez
 

library core

Front controller and other core libraries used by the Toadsuck project.

image

toadsuck/core

Front controller and other core libraries used by the Toadsuck project.

  • Tuesday, August 19, 2014
  • by joshmoody
  • Repository
  • 2 Watchers
  • 3 Stars
  • 168 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 2 Forks
  • 2 Open issues
  • 20 Versions
  • 1 % Grown

The README.md

Toadsuck.Core

Core libraries for the Toadsuck Project

Build Status Total Downloads Latest Stable Version, (*1)

Learn more at The Toadsuck Project or see Toadsuck.Skeleton for a reference implementation., (*2)

Installation

Installation of this package is easy with Composer. If you aren't familiar with the Composer Dependency Manager for PHP, you should read this first., (*3)

If you don't already have Composer installed (either globally or in your project), you can install it like this:, (*4)

``` bash $ curl -sS https://getcomposer.org/installer | php, (*5)


Create a file named composer.json someplace (usually in the root of your project) with the following content. ``` json { "require": { "toadsuck/core": "dev-master" } }

Suggested Directory Structure

  • Your application resides in src/ and has a base namespace of Example\Project
  • Your controllers are in src/controllers/ and have a namespace of Example\Project\Controllers
    • Your controllers extend Toadsuck\Core\Controller
src/
    config/
        local/
            config.php
        test/
        prod/
        config.php
        routes.php
    controllers/
        Home.php
    models/
    views/
        home/
            index.php
        layouts/
            default.php
vendor/
    Composer's installation directory
web/
    index.php
    composer.json

Front Controller

Your web/index.php serves as the front controller and contains the following content:, (*6)

``` php $app_dir, 'namespace' => __NAMESPACE__]; $app = new \Toadsuck\Core\Dispatcher($opts); // Dispatch the request. $app->dispatch(); ``` This will turn control of dispatching the request to the Toadsuck.Core dispatcher. ## Routing Routing is handled by the [Aura Router](https://github.com/auraphp/Aura.Router). Some sensible default routes are provided out of the box in the dispatcher. ``` php $router->add(null, null); $router->add(null, '/'); $router->add(null, '/{controller}'); $router->add(null, '/{controller}/{action}'); $router->add(null, '/{controller}/{action}/{id}'); ``` The following will all call the `index()` method of your `Home` controller. >- http://example.com/path/to/index.php >- http://example.com/path/to/index.php/home >- http://example.com/path/to/index.php/home/index This one will also call `index`, but will also pass the value "1" to the index method. >- http://example.com/path/to/index.php/home/index/1 Likewise, you can call the `bar()` method of the `Foo` controller like this: >- http://example.com/path/to/index.php/foo/bar If you want to supply different routes, just create a `config` directory under source with a file named `routes.php` that defines the routes you need. ``` src/ config/ routes.php ``` For more information on routing options, see . ## Configuration The configuration manger is built on [FuelPHP\Config](https://github.com/fuelphp/config) ### Basic Configuration Usage ``` php // Load our primary config file. $this->config->load('config'); $something = $this->config->get('something'); // You can load any configuration file... $this->config->load('database'); ``` ### Multiple Environment Configuration Support The configuration manager supports different configs for different environments (local, dev, test, prod, etc). To activate per-environment configs, create a sub-directory of `src/config` named the same as your environment. This directory should contain configuration files with any items from the main config you want to override in that environment. Example: src/config/test/database.php You can tell the app which environment you are running in by modifying the content of `src/config/environment` to contain the name of your active environment. Then load your config as you normally would. The configuration items will be merged between the default config environment-specific overrides. See the [FuelPHP Docs](https://github.com/fuelphp/config/blob/master/README.md) for more information on configuration management. ### Extra Configuration Helper Methods #### getBaseUrl() Returns the absolute url to the base of your application without the filename (ex. index.php). Accepts an optional path to append to the base url as an argument. ``` php var_dump($this->config->getBaseUrl()); // http://example.com/ var_dump($this->config->getBaseUrl('image.jpg')); // http://example.com/image.jpg var_dump($this->config->getBaseUrl('home/index')); // http://example.com/home/index ``` #### getSiteUrl() Returns the absolute url to the base of your application, including the filename (ex. index.php). Accepts an optional path to append to the site url as an argument. ``` php var_dump($this->config->getSiteUrl('home/index')); // http://example.com/index.php var_dump($this->config->getSiteUrl('home/index')); // http://example.com/index.php/home/index ``` ## Templates Templates are powered by the [Plates Project](http://platesphp.com/), which is part of [The League of Extraordinary Packages](http://thephpleague.com/). Within this project, all themes and layouts live in `src/views`. ### Basic Template Usage ``` php class Home extends Controller { public function __construct() { // Set our default template. $this->template->layout('layouts/default'); } public function index() { // Set some variables for all views. $this->template->page_title = 'Toadsuck Skeleton'; // Render and Display the home/index view, passing a variable named "heading". $this->template->output('home/index', ['heading' => 'Congratulations, it worked!']); // Same as above, but return the rendered content instead of displaying. // $content = $this->template->render('home/index', ['heading' => 'Congratulations, it worked!']); } } ``` I've extended the standard Template class from Plates in 2 important ways: - 1) I've added the `output()` method so you can display the rendered view without an `echo` if you like. - 2) All variables are escaped before rendering/displaying the content to prevent cross site scripting. If there are variables you don't want auto-escaped (example: pre-rendered HTML), you can prevent escaping by calling `unguard('param_name')`. ``` php $this->template->unguard('html'); $this->template->output('home/index', ['html' => '

Some markup., (*8)

']); ``` #### Prefill I've added some functionality to the Template class for easily getting default values in views when the variable doesn't exist. ``` php class Home extends Controller { public function __construct() { // Set our default template. $this->template->layout('layouts/default'); } public function index() { // Grab our prefill content from the request and mass assign. $this->template->setPrefill($this->input->get()); // Or we can pull the prefill content from session. $this->template->setPrefill($this->session->get('prefill')); // Render and Display the home/index view. $this->template->output('home/index'); } } ``` Then in our view: ```

, (*9)


See the [Plates Project documentation](http://platesphp.com/) for more information on template usage. ## HTTP Abstraction HTTP Abstraction is provided by [Symfony\HttpFoundation](https://github.com/symfony/HttpFoundation). This provides useful things like: - Object-Oriented access to `$_GET`, `$_POST`, `$_SESSION`, `$_COOKIE`, etc. - Internal/External Redirects - JSON/JSONP Responses ``` php namespace Example\Project\Controllers; use Illuminate\Database\Capsule\Manager as Model; use Toadsuck\Core\Controller; use Toadsuck\Core\Database as DB; use Toadsuck\Skeleton\Models\Widget; class Home extends Controller { // Internal Redirect (another resource in our app) public function internalRedirect() { $this->redirect('home/foo'); # Foo method of the Home Controller. } // External Redirect public function externalRedirect() { $this->redirect('http://www.google.com'); } // Output data json-encoded with proper headers. public function getJson() { $data = (object) ['items' => ['foo', 'bar']]; $this->json($data); } // Output data json-encoded with proper headers and callback. // Default callback name is 'callback' public function getJsonp() { $data = (object) ['items' => ['foo', 'bar']]; $this->jsonp($data, 'callback'); } }

$_GET and $_POST

The Core Controller has a reference to the httpFoundation Request object, but I find the syntax for accessing $_GET and $_POST attributes less than ideal. So, I've built a wrapper around the httpFoundation Request object to make the syntax friendlier., (*10)

Examples:, (*11)

``` php, (*12)

Symfony way to access an attribute from $_POST

$foo = $this->request->request->get('foo');, (*13)

Toadsuck way to access an attribute from $_POST

$foo = $this->input->post('foo');, (*14)

Symfony way to access an attribute from $_GET

$foo = $this->request->query->get('foo');, (*15)

Toadsuck way to access an attribute from $_GET

$foo = $this->input->get('foo');, (*16)

Symfony way to access the entire $_POST array

$post = $this->request->request->all();, (*17)

Toadsuck way to access the entire $_POST array

$post = $this->input->post();, (*18)

Symfony way to access the entire $_GET array

$get = $this->request->query->all();, (*19)

Toadsuck way to access the entire $_GET array

$get = $this->input->get();, (*20)


`null` is returned when trying to access a non-existent attribute from get/post. Pass a 2nd parameter to `$this->input->get()` or `$this->input->post()` to serve as the default value if you want something other than `null`. ``` php // Returns 'foo' $foo = $this->input->post('nonexistent', 'foo');

In the default Request object, you have to pass true as the 3rd argument to $this->request->query->get() in order to access "deep" array keys. This is defaulted to true in my override., (*21)

``` php $bar = $this->input->get('foo[bar]');, (*22)


See the [Symfony Docs](http://symfony.com/doc/current/components/http_foundation/introduction.html) for more information on the HttpFoundation component. ## Database Database abstraction is handled by [Illuminate\Database](https://github.com/illuminate/database) Your model: ``` php # File: src/models/Widget.php namespace Example\Project\Models; use Illuminate\Database\Eloquent\Model; class Widget extends Model { public $timestamps = false; # Aren't using the default timestamp columns }

Instead of extending Eloquent\Model directly, you can extend Toadsuck\Core\Model (which extends Eloquent) to get easier access to the query builder.

``` php, (*23)

File: src/models/Widget.php

namespace Example\Project\Models;, (*24)

use Toadsuck\Core\Model;, (*25)

class Widget extends Model { public $timestamps = false; # Aren't using the default timestamp columns, (*26)

public static function search($params = null)
{
    $query = self::queryBuilder();

    if (array_key_exists('firstname', $params))
    {
        $query->where('firstname', $params['firstname']); 
    }

    if (array_key_exists('lastname', $params))
    {
        $query->where('lastname', $params['lastname']); 
    }

    return $query->get();
}

}, (*27)


> See tests/resources/models/Captain for a working example. #### Initialize the database before you try to use it. ``` php use Toadsuck\Core\Database as DB; /* DSN can be pear-style DSN string: mysql://username:password@host/database OR an array of connection params $defaults = [ 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'mysql', 'username' => 'root', 'password' => null, 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => null ]; */ DB::init($dsn);

Once your database has been initialized, you can call your ORM models from anywhere.

``` php // Get all widgets: $widgets = \Example\Project\Models\Widget::all()->toArray();, (*28)

foreach ($widgets as $widget) { var_dump($widget['type']); var_dump($widget['size']); var_dump($widget['color']); }, (*29)

> See the [Laravel Eloquent Documentation](http://laravel.com/docs/eloquent) for more info on the ORM.

#### You also have access to the fluent query builder.

``` php
use Illuminate\Database\Capsule\Manager as QueryBuilder;

$result = QueryBuilder::table('captains')->where('lastname', 'Kirk')->get();

See the Laravel Database Documentation for more info on the fluent query builder., (*30)

Multiple Database Connection Support

To initialize Eloquent with multiple database connections, you can pass an array of connection params to DB::init()., (*31)

# DSN Strings
$dsn = ['default' => 'mysql://username:password@hostname/primarydb', 'otherdb' => 'mysql://username:password@hostname/otherdb'];

DB::init($dsn);
# Connection setting array
$dsn = [
    'default' => [
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'primarydb',
        'username'  => 'username',
        'password'  => 'password'
    ],
    'otherdb' => [
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'otherdb',
        'username'  => 'username',
        'password'  => 'password'
    ]
];

DB::init($dsn);     

Then in your model, specify the connection to use., (*32)

<?php
use Illuminate\Database\Eloquent\Model;
class Widget extends Model
{
    public $timestamps = false;
    public $connection = 'otherdb';
}
, (*7)

The Versions

27/01 2014
27/01 2014
27/01 2014
27/01 2014