class Session
That will be loaded from app/classes/session.php
.Class Session_Driver
app/classes/session/driver.php
// global namespace, fully underscored class name
class Core_System_Messages {}
// combine a namespace and underscores
namespace Core;
class System_Messages {}
// or fully namespaced
namespace Core\System;
class Messages {}
__construct()
does for instances of a class. You do this by adding a public static _init()
method to the class.class Example {
public static function _init()
{
// this is called upon loading the class
}
}
own _init()
method and a parent must be loaded alongside it, that parent's init method isn't called unless you call it using parent::_init();
class MyConfig extends Config {}
fuel/app/classes/lang.php
":class Lang extends Fuel\Core\Lang {}
Autoloader::add_core_namespace('Example');
Autoloader::add_classes(array(
'Example\\View' => __DIR__.'/classes/view.php',
));
Package::load('mypackagename');
just before the Fuel::init()
call. If you do, your package can only not extend:Autoloader
and have it used. After extending it you have to require it manually in the app/bootstrap.php file after the original Fuel\Core\Autoloader
, don't forget to remove the line that aliases the core class to global. public/index.php
.index.php
to direct fuel to the right paths./path/to/fuel/app
). This is where your application directories and code reside./path/to/fuel/core
). This is where all the Fuel classes live./path/to/public
). This is where index.php
resides. Everything accessible to user lives and is accessible via the browser. For oil command, path to where oil command resides./path/to/fuel/packages
). This is where your packages are installed (when installed through oil)./path/to/fuel/vendor
). This is where your composer installs the libraries downloaded from packagist.org.APPPATH/classes/controller
APPPATH/classes/model
APPPATH/views
APPPATH/classes/presenter
APPPATH/classes
. All main application classes are defined in the global namespace (they do not have a namespace set), and use the cascading file system to create unique classnames.APPPATH/classes/controller
folder, and are prefixed with Controller_
. This prefix is defined in your APPPATH/config/config.php
configuration file (and if not this is the default), but can be changed if you want to namespace your controllers, or if you want to move them to a different folder structure.controller_prefix
from 'Controller_
' to 'Controller\\
' in your app's config.php
file.namespace Controller;
class Example extends \Controller
{
public function action_index()
{
// some code here
}
}
namespace Mymodule\Controller;
class Example extends \Controller
{
public function action_index()
{
// some code here
}
}
fuel/app/config/routes.php.
_root_
: The default route when no URI is specified._403_
: The route used when the application throws an HttpNoAccessException
that isn't caught._404_
: The route used when the application throws an HttpNotFoundException
that isn't caught._500_
: The route used when the application throws an HttpServerErrorException
that isn't caught.return array(
'_root_' => 'welcome/index',
'_404_' => 'welcome/404',
);
return array(
'about' => 'site/about',
'contact' => 'contact/form',
'admin' => 'admin/login',
);
:any
: This matches anything from that point on in the URI, does not match "nothing":everything
: Like :any, but also matches "nothing":segment
: This matches only 1 segment in the URI, but that segment can be anything:num
: This matches any numbers:alpha
: This matches any alpha characters, including UTF-8:alnum
: This matches any alphanumeric characters, including UTF-8return array(
'blog/(:any)' => 'blog/entry/$1', // Routes /blog/entry_name to /blog/entry/entry_name
// matches /blog/, does not match /blogging and /blog
'blog(:any)' => 'blog/entry$1', // Routes /blog/entry_name to /blog/entry/entry_name
// matches /blog/ and /blogging, does not match /blog
'blog(:everything)' => 'blog/entry$1', // Routes /blog/entry_name to /blog/entry/entry_name
// matches /blog/, /blogging and /blog
'(:segment)/about' => 'site/about/$1', // Routes /en/about to /site/about/en
'(\d{2})/about' => 'site/about/$1', // Routes /12/about to /site/about/12
);
return array(
'blog/:year/:month/:id' => 'blog/entry', // Routes /blog/2010/11/entry_name to /blog/entry
);
/blog/2010/11/entry_name
. It would then route that request to your 'entry' action in your 'blog' controller. There, the named params will be available like this :$this->param('year');
$this->param('month');
$this->param('id');
return array(
// Routes GET /blog to /blog/all and POST /blog to /blog/create
'blog' => array(array('GET', new Route('blog/all')), array('POST', new Route('blog/create'))),
);
return array(
'blog/(:any)' => array(array('GET', new Route('blog/show/$1'))),
);
// route only valid if this is an https request
return array(
'blog/(:any)' => array(array('GET', new Route('blog/show/$1'), true)),
);
admin/start/overview
'. Now you decide to move stuff around and end up moving that specific page to 'admin/overview
'. As a result of this now you need to update the links in all your views...return array(
'admin/start/overview' => array('admin/overview', 'name' => 'admin_overview'), // add a named route for the admin/overview page
);
// produces <a href="http://your_base_url/admin/start/overview">Overview</a>
echo Html::anchor(Router::get('admin_overview'), 'Overview');
return array(
'secret/mystuff' => function () {
// this route only works in development
if (\Fuel::$env == \Fuel::DEVELOPMENT)
{
return \Request::forge('secret/mystuff/keepout', false)->execute();
}
else
{
throw new HttpNotFoundException('This page is only accessable in development.');
}
};
__toString()
method on which the encoding can take place, add your object class to the class whitelist in the security configuration (don't forget the namespace!), or pass it to the view with the $encode flag set to false. You can also use the auto_encode method to temporary disable automatic output encoding on a per-view basis.config/config.php
file.// in plain HTML
<input type="hidden" name="<?php echo \Config::get('security.csrf_token_key');?>" value="<?php echo \Security::fetch_token();?>" />
// using the Form class
echo \Form::csrf();
// using a form instance, will also add a validation rule to forms fieldset
$form = \Form::forge();
$form->add_csrf();
// check if a form was submitted
if ($_POST)
{
// check for a valid CSRF token
if ( ! \Security::check_token())
{
// CSRF attack or expired CSRF token
}
else
{
// token is valid, you can process the form input
}
}
$_GET, $_POST
and $_COOKIE
) on every page request. To do so, configure the functions or methods to be used to filter them in the application's config/config.php
file./**
* Security settings
*/
'security' => array(
'input_filter' => array(),
)
htmlentities
', static class methods like '\\Security::xss_clean
' or even object methods which are defined as array($object
, 'method
'). If you use an object method, make sure the object is available before Fuel is initialized, as input filtering happens very early in the request process.modules_path
' setting in your applications config.php
file to define your module path. You can also define multiple paths. If you do, they will be searched in the sequence you have defined them./**
* To enable you to split up your application into modules which can be
* routed by the first uri segment you have to define their basepaths
* here.
*/
'module_paths' => array(
APPPATH.'modules'.DS, // path to application modules
APPPATH.'..'.DS.'globalmods'.DS // path to our global modules
),
<?php
/**
* Module controller in the Mymodule module
*/
namespace Mymodule;
class Controller_Widget
{
// put your controller code here, just like for an application controller
}
/packages
/package
/bootstrap.php
/classes
/your.php
/classes.php
/here.php
/config
/packageconfig.php
/and_so_on
// Add namespace, necessary if you want the autoloader to be able to find classes
Autoloader::add_namespace('Mypackage', __DIR__.'/classes/');
// Add as core namespace
Autoloader::add_core_namespace('Mypackage');
// Add as core namespace (classes are aliased to global, thus useable without namespace prefix)
// Set the second argument to true to prefix and be able to overwrite core classes
Autoloader::add_core_namespace('Mypackage', true);
// And add the classes, this is useful for:
// - optimization: no path searching is necessary
// - it's required to be able to use as a core namespace
// - if you want to break the autoloader's path search rules
Autoloader::add_classes(array(
'Mypackage\\Classname' => __DIR__.'/classes/classname.php',
'Mypackage\\Anotherclass' => __DIR__.'/classes/anotherclass.php',
));
// fetch the output of a controller
$widget = Request::forge('mycontroller/mymethod/parms')->execute();
echo $widget;
// or fetch the output of a module
$widget = Request::forge('mymodule/mycontroller/mymethod/parms', false)->execute();
echo $widget;
// and if you need to pass in some data
$widget = Request::forge('mymodule/mycontroller/mymethod/parms', false)->execute(array('tree'=>'apple'));
echo $widget;
$request->parent()
and $request->children()
. The parent is the Request during which the current Request was created (null for the main Request). The children are all the Requests created during the current Request. Migrate::current()
to work out which migrations should be run. The current version is found in core/config/migration.php
so like any other config file you should copy this to app/config to make changes.Key | Type | Default | Description |
---|---|---|---|
folder | string |
|
The folder in which migration files will be found. |
connection | string |
|
Configuration name of a database connection to use to write migrations. |
table | string |
|
The database table used to store migration data. |
flush_cache | boolean |
|
If true, all cached data will be erased after all migrations have run, via a call to Cache::delete_all(). |
app/migrations/001_example.php
.namespace Fuel\Migrations;
class Example
{
function up()
{
\DBUtil::create_table('posts', array(
'id' => array('type' => 'int', 'constraint' => 5),
'title' => array('type' => 'varchar', 'constraint' => 100),
'body' => array('type' => 'text'),
), array('id'));
}
function down()
{
\DBUtil::drop_table('posts');
}
}
$ php oil refine migrate
$ php oil refine migrate:current
$ php oil refine migrate:up
$ php oil refine migrate:down
$ php oil refine migrate --version=10
$ php oil refine migrate -all
$ php oil refine migrate --modules=module1,module2 --packages=package1
$ php oil refine migrate:up --packages=package1
$ php oil refine migrate:down --modules=module1,module2 --default
$ php oil refine migrate --version=10
up()
or down()
method return false. This can be useful if your migration has external dependencies, for example the existence of a table created in a different migration. before()
and/or after()
methods, that can be used for prepping, validation or cleanup functionality. If you have generic functionality, you could create a migration base class for your migrations containing these methods, so you don't have to duplicate code in every migration.up()
method, the before()
and after()
methods can return false to signal a failure. This can be useful if your migration has generic external dependencies, or perhaps additional validation steps. When it does, the migration will be skipped, and ultimately aborted if a retry fails too. In the case of the after()
method returning false, the migration will be reverted by calling the reverse migration method (i.e. calling down()
when on an up()
migration, and vice-versa).namespace Fuel\Tasks;
class Example
{
public function run($message = 'Hello!')
{
echo $message;
}
}
$ php oil refine example "Good morning"​
run()
" is referenced.public function current_date()
{
echo date('Y-m-d');
}
$ php oil refine example:current_date
$ php oil test
Tests Running...This may take a few moments.
PHPUnit 3.6.10 by Sebastian Bergmann.
Configuration read from /home/user/sites/example/fuel/core/phpunit.xml
............................................................... 63 / 251 ( 25%)
............................................................... 126 / 251 ( 50%)
............................................................... 189 / 251 ( 75%)
..............................................................
Time: 6 seconds, Memory: 22.25Mb
OK (251 tests, 206 assertions)
fuel/app/tests
directory and its subdirectories. If this directory does not exist, go ahead and create it. By convention, test files are placed in the same subpath of fuel/app/tests
as the tested class is of fuel/app/classes
, so a test for the class at fuel/app/classes/model/login.php
would be in the file fuel/app/tests/model/login.php
.PHPUnit_Framework_TestCase
class, so you'll be able to use all the usual PHPUnit assertions and methods in your test. By convention, test classes are named after the class they test, prefixed with Test_
, so a test for the Model_Login
class would be named Test_Model_Login
.class Test_Model_Login extends TestCase
{
public function test_foo()
{
}
}
app/config/routes.php
and must point to the controller/method
that handles the 404 pages. Read more about it in the routing section.HttpNotFoundException
. Fuel will exit for you once it has run the 404 page.throw new HttpNotFoundException;
// Generate the request, execute it and send the output.
try
{
$response = Request::forge()->execute()->response();
}
catch (HttpNotFoundException $e)
{
$route = array_key_exists('_404_', Router::$routes) ? Router::$routes['_404_']->translation : Config::get('routes._404_');
if ($route)
{
// add 'false' to the forge request do disable the routing engine
$response = Request::forge($route, false)->execute()->response();
}
else
{
throw $e;
}
}
_404_ route
points to welcome/404
, let's take a look at that method:// Inside Controller_Welcome
/**
* The 404 action for the application.
*
* @access public
* @return void
*/
public function action_404()
{
$messages = array('Aw, crap!', 'Bloody Hell!', 'Uh Oh!', 'Nope, not here.', 'Huh?');
$data['title'] = $messages[array_rand($messages)];
// Set a HTTP 404 output header
return Response::forge(Presenter::forge('welcome/404', $data), 404);
}
// Inside your 404 controller
public function action_my404()
{
$original_uri = \Input::uri();
$result = \DB::select()->from('pages')->where('uri', $original_uri)->execute();
if(count($result) === 1)
{
// display that page in whatever way you like
}
else
{
// display your general 404 page
$messages = array('Aw, crap!', 'Bloody Hell!', 'Uh Oh!', 'Nope, not here.', 'Huh?');
$data['title'] = $messages[array_rand($messages)];
return Response::forge(View::forge('welcome/404', $data), 404);
}
}
a _500_ route
. It allows you to show a proper error message, do additional error logging, or send a notification to an administrator to get the issue fixed.throw new HttpServerErrorException;
HttpNoAccessException
. This exception can be caught in the front controller by defining a _403_ route
. The handler could for example store the current URI, ask for a login, and if a success, return to the stored URI so the user can return to where the violation occured.throw new HttpNoAccessException;
$_GET
array. $_POST
array.config/config.php
file.'profiling' => true,​
config/<environment>/db.php
to true.'profiling' => true,