4
* Fight: an extension to Flight, in the form of useful configuration changes
5
* and extra library code.
7
* @copyright Copyright (c) 2015, Tim Marston <tim@ed.am>
10
* FIGHT! ...brings the following changes to Flight:
12
* 1. Global $app object.
14
* 2. App directorties.
16
* It is expected that your app has the following layout, and class and view
17
* paths are set up to reflect this:
20
* +-- index.php (see note below)
26
* Note that index.php MUST go in the top-level directory, or autoloading
27
* breaks. If you want to keep it in the app/ directory, add a shim index.php
28
* that just requires app/bootstrap.php (or whatever you want to call it).
30
* 3. The route() method now accepts a class name and routes to class methods.
32
* The flight route() method now accepts a class name in an array (so, like a
33
* callable, except with no method specified) which indicates a class in which
34
* the part of the URL beyond the route specified should be looked up as a
35
* method and additional URL parts beyond those represented by the name of the
36
* method passed as arguments to the method.
38
* For example, you could configure routing to a class's methods like this:
40
* $app->route( '/some/path', array( 'MyClass' ) );
42
* Then, for example, /some/path/list will route to MyClass::action_list(),
45
* If MyClass::default_action() exists, then /some/path will route to it. If
46
* you don't require default functionality, you might still want to use this to
47
* call some other action method.
49
* If other URL parts are specified beyond the name of the matched method, for
50
* example /some/path/list/1/2, then these are passed as arguments to the
51
* action. You would define the action method as follows:
53
* public static function action_list( $foo = 0, $bar = 0 )
55
* NOTE: the use of default values for arguments is REQUIRED, or a PHP error
56
* would occur where if they were missing in the HTTP request.
58
* You can also specify either "special cases" of actions, or actions for a
59
* lower level of the URL path, by using a double-underscore to represent a path
60
* separator in your action method name. For example, using the above routing,
61
* /some/path/list/1 will route to MyClass::action_list__1(), if it exists,
62
* leaving URLs that have other values in the last part of their path (for
63
* example, /some/path/list/2) to still route to MyClass::action_list() as
64
* before (passing 2 as the first argument).
66
* Also note that hyphens in URLs are converted to underscores (or they wouldn't
67
* be usable as method names), and multiple underscores are contracred to a
68
* single underscore (so that the path separators can be represented as a
69
* double-underscode in method names)
72
// instantiate flight app
73
require 'flight/autoload.php';
74
$app = new flight\Engine();
76
// set fight class path
77
$app->path( __DIR__.'/classes' );
80
$app->set( 'flight.views.path', 'app/views' );
81
$app->path( 'app/controllers' );
84
$app->set( 'flight.log_errors', true );
86
// add class method router advice to route() method
87
$app->before( 'route',
88
function( &$params, &$output ) use( &$app )
90
// is the callback an array containing only a classname?
91
if( count( $params ) >= 2 &&
92
is_array( $params[ 1 ] ) &&
93
count( $params[ 1 ] ) == 1 )
95
$class = $params[ 1 ][ 0 ];
98
$params[ 0 ] = preg_replace( '/\/$/', '', $params[ 0 ] ).'/*';
100
// replace callback with method router
102
function( $route ) use( &$app, &$class )
105
$splat = preg_replace(
106
array( '/(.)\/$/', '/-/', '/_+/' ),
107
array( '\1', '_', '_' ), $route->splat );
110
if( $splat === '' ) {
111
if( method_exists( $class, 'default_action' ) ) {
113
return $obj->default_action();
118
$parts = explode( '/', $splat );
122
while( count( $parts ) )
124
// check to see if combined parts make a method name
125
$method = 'action_'.implode( '__', $parts );
126
if( method_exists( $class, $method ) ) {
128
return call_user_func_array(
129
array( $obj, $method ), $params );
132
// discard last part as a param and keep looking
133
array_unshift( $params, array_pop( $parts ) );
141
// pass route to callback
146
// add $app to view parameters
147
$app->view()->set( 'app', $app );