XML

Brain’s XML class performs some common tasks that make working with XML a lot easier.

XML From Array

$arr = [
  'animals' => [
    'duck' => 'Daffy',
    'pig'  => 'Porky',
    'dog'  => 'Buster'
  ]
];

$xml = XML::from_array( $arr );

XML To Array

$xml = '
<?xml version="1.0" ?>
<animals>
  <duck>Daffy</duck>
  <pig>Porky</pig>
  <dog>Buster</dog>
</animals>
';

$arr = XML::to_array( $xml );

Prep String

$str = XML::prep_string( $str );

View

Views are generated two ways in Brain. First is the standard way we’re used to, like in CodeIgniter. Brain can also store views in the database, which can be handy if you want to search to content using MySQL.

Standard Views

View::load( 
  $view, 
  $view_data = array(), 
  $return = FALSE 
);

DB Views

Adding a DB type view is done through the CLI. This creates a record in the database, and also creates a file that you will work with on the dev environment. When the file gets changed, you’ll simply run and update through the CLI, and the current version of the file is saved in the database record. This is all sort of a proof of concept. If this was to be used in a production environment, further development would be needed.

Add a View

php index.php manual_tests add_view db/test manual_tests/db_view "View from DB" "Testing of a view stored in the database"

This would create the view by calling the add_view method of the manual_tests controller. The file version of the view is saved in the app/views directory, and in this case app/views/db/test.php. The URI string, in this case “manual_tests/db_view”, is the joined URI segments that we want to use to access the page via a browser. The title parameter allows for the database record to hold a title, in case we need to display one in the document head. Last, the desc parameter allows for us to save a short description about the page the view would be displayed on.

Update a View

php index.php manual_tests update_views

Just run the CLI command and the database view records are updated to match the file version.

Validate

If you don’t know what this class does just based on its name, then Brain might not be for you. Therefore, without any further introduction, here is how Brain’s Validate class works:

Get an Instance of Validate

// Assuming container access
$v = $this->container['validate'];

Setting or Importing Validation Rules

// Example of setting a rule manually
$v->set_rules(array(
  array(
    'field' => 'name',
    'label' => 'NAME',
    'rules' => 'trim|required|xss_clean|max_length[30]'
  )
));
/**
 * Example of setting rules from a config file.
 * In this case we are getting the rules from a 
 * file located at config/form_validation/contact_form.php.
 * This is just another config file, and without a second
 * parameter, the element holding the rules is assumed to 
 * be named "form_validation_rules".
 */
$v->import_rules('contact_form');

The Actual Rules

The actual rules, such as “required”, “xss_clean”, and “max_length” in the code example shown above, are just like CodeIgniter’s rules. Very little was changing frameworks would be as simple as possible.

Regular Callbacks

Callbacks can go right in your controller, model, or library as methods. Set them as you would any other rule, but prefixed by “callback_”. Make sure you use the set_callback_object() method so the validation class can run your callbacks.

$v->set_callback_object( $this );
// Check the field using the check_awesomeness method in THIS class
$v->set_rules(array(
  array(
    'field' => 'awesomeness',
    'label' => 'AWESOMENESS',
    'rules' => 'callback_check_awesomeness'
  )
));

CodeIgniter does allow callbacks, but never had the functionality to call external files, so I developed a validation rule called “external_callbacks”.

External Callbacks

// In the rules that are imported
$cfg['form_validation_rules'] = array(
  array(
    'field' => 'name',
    'label' => 'NAME',
    'rules' => 'external_callbacks[name_callbacks,_check_name,TRUE]'
  )
);
// In a class named Name_callbacks located at config/form_validation/name_callbacks.php
use \Brain\Lib\ContainerAccess;

class Name_callbacks extends ContainerAccess {

  private $validate = NULL;
  public static $container;

  public function __construct( $instance )
  {
    $this->validate =& $instance;
    self::$container = parent::$container;
  }

  public function _check_name( $name, $args )
  {
    if( $name == 'skunkbad' && $args[0] === 'TRUE' )
    {
      return $name;
    }
    else
    {
      $this->validate->set_message(
        'external_callbacks',
        '%s must be skunkbad, and $args[0] must be TRUE'
      );
    }
  }
}

You can see in the code above that we passed in a single argument “TRUE” to the callback. If we want to pass in more values, we simply add them inside the brackets of the call to the external callback. For instance, if we wanted to add a second argument of “skunk”, and a third argument of “bad”, it would look like this:

// In the rules that are imported
$cfg['form_validation_rules'] = array(
  array(
    'field' => 'name',
    'label' => 'NAME',
    'rules' => 'external_callbacks[name_callbacks,_check_name,TRUE,skunk,bad]'
  )
);

These arguments would be available inside our external callback as $args[1] and $args[2].

Running the Validation

if( $v->run() )
{
  // Validation passed
  $name = $v->set_value('name');

  /**
   * The validate class sets a view variable named $validation_passed to TRUE.
   */
}
else
{
  // Validation failed
  echo '
    

Errors:

    ' . $v->error_string() . '
'; /** * The validate class sets a view variable named $validation_errors * to the value of $v->error_string(). */ }

Special Methods

CodeIgniter lacked some methods that I found myself needing, so I built them into Brain’s Validate class.

set_callback_object()

If external callbacks are too much for you, you might add a method or two to your controller, model, library, etc. The validate class needs to know where the callbacks are though, so pass $this to it!

$v->set_callback_object( $this );

get_error_array()

Access the protected $_error_array through this method.

unset_error( $field )

If there are errors and you need to unset one for any reason, pass the field name to this method.

get_field_data()

Access the protected $_field_data through this method.

unset_field_data( $element )

This method removes a field from the $_field_data. This is especially helpful if you are using set_value() but you don’t want to repopulate a form with a bad value. Pass an asterisk “*” as the param to unset the entire $_field_data array.

set_value()

The BaseController class autoloads a super tiny validation helper, and it’s only content is a set_value() function. This function is just like its CodeIgniter version. Very simple, yet used so often.

URL

The URL is similar in function to CodeIgniter’s URL helper.

Base

Returns URL of home page. The only param, FALSE by default, can be set to TRUE if a secure URL is desired, or “match” if the URL generated should match the scheme of the current URI.

// Without secure scheme
URL::base();

// With secure scheme
URL::base(TRUE);

// Match the scheme of the current URI
URL::base('match');

Site

The site method is just like the base method, except that a path can be provided.

// Without secure scheme
URL::site('example/path');

// With secure scheme
URL::site('example/path',TRUE);

// Match the scheme of the current URI
URL::site('example/path','match');

Current

Return the current URI with or without the query string.

// With query string
URL::current();

// Without query string
URL::current(FALSE);

Anchor

Return an HTML anchor tag where the href is a site URL.

// Regular anchor
URL::anchor('somepage','Some Page');

// Secure anchor
URL::anchor('somepage','Some Page',TRUE);

// Regular anchor with attribute(s)
URL::anchor('somepage','Some Page',FALSE,' class="foo"');

Redirect

Redirect to another site URL. Redirect can be standard, secure, or match the current URI.

URL::redirect( 
  $uri = '', 
  $secure = FALSE, 
  $method = 'location', 
  $http_response_code = 302 
);

URI

The URI class parses the current request URI and gives access to those parts.

Autoloaded on Every Request

The URI class is autoloaded on every request. We can access it through the container, or via the static URI class.

Scheme

Returns “http” or “https”.

URI::scheme();

Base

Returns the host.

URI::base();

Path

Returns the path with any slash trimmed.

URI::path();

Query String

Returns the query string or NULL if there was none.

URI::query_string();

Current

Returns the current URL with or without the query string.

// With query string
URI::current();

// Without query string
URI::current(FALSE)

Segment

Returns the value of a specific URI segment, or FALSE if it doesn’t exist.

URI::segment(1);

Segments

Return all of the URI segments as an array.

URI::segments();

String

Returns all of the URI segments as a string, separated by slashes.

URI::string();

Upload

Brain’s Upload class allows for uploading of files to the server filesystem, database, or to be handed off to SFTP for storage on a different server. Configuration options are similar to CodeIgniter’s upload config, but there are substantial differences.

Config

Sample upload configuration can be found in config/upload.php for each of the three upload types. By default, the upload type is for filesystem storage, but a “driver” can be specified in the config array. “database” and “sftp” are to be used when the upload type is not “filesystem”. If files are to be stored in the database, the table used for uploads is specified in config/db.php.

The success_callback Config Option

When a file is successfully uploaded, we’ll normally want to do something. Just uploading the file doesn’t mean much if we don’t store it’s location in the database, or output the image somehow. For that reason, we use an anonymous function to handle what is done. The sole parameter to the anonymous function is $obj, which is the object of the specific upload type that was done, complete with information about the upload. If you need to output something to the browser, or pass something back to the controller, this is a good place to set a config item. I’ve used a config item named “callback_output” in each of my examples when testing the three upload types.

Usage

Usage for all three upload types is very similar.

// If filesystem upload type
$u = $this->container['upload'];

// If database upload type
$u = $this->container['db_upload'];

// If SFTP upload type
$u = $this->container['sftp_upload'];

if( ! empty( $_FILES ) )
{
	$u->process_upload();
}

Tokens

The Tokens class provides a CSRF type service for form token matching. Multiple tokens may be issued so that the site visitor can use multi-tabbed or multi-windowed browsing. When a token is issued it is added to the token cookie, and when it is matched it is removed from the cookie. There is a maximum amount of tokens that are stored per cookie, which is the “jar_size” config option in config.tokens.php.

For better security, tokens are put in two separate cookies, one for SSL encrypted pages, and one for pages that aren’t SSL encrypted. You can name these cookies, and configure Tokens’ cookies in config.tokens.php

The cookie for SSL encrypted pages is deleted when a site visitor successfully logs in using the Auth class, or logs out using the Auth class. Auth therefore has a dependency on Tokens.

Usage

// Use the form open tag to automatically generate a token input
echo Form::open();

// Create the token manually
$tokens = $container['tokens'];
echo '<input type="hidden" name="' . $tokens->name . '" value="' . $tokens->token() . '" />';

// In form processing, simply check if the token matches
if( $tokens->match )
{
  // The posted value matched one in the cookie ...
}
else
{
  // There was no match ...
}