gallery3/modules/forge/libraries/Forge.php
2009-12-31 15:49:43 -08:00

324 lines
6.8 KiB
PHP

<?php defined("SYSPATH") or die("No direct script access.");
/**
* FORGE (FORm GEneration) library.
*
* $Id: Forge.php 3326 2008-08-09 21:24:30Z Shadowhand $
*
* @package Forge
* @author Kohana Team
* @copyright (c) 2007-2008 Kohana Team
* @license http://kohanaphp.com/license.html
*/
class Forge_Core {
// Template variables
protected $template = array
(
'title' => '',
'class' => '',
'open' => '',
'close' => '',
);
// Form attributes
protected $attr = array();
// Form inputs and hidden inputs
public $inputs = array();
public $hidden = array();
// Error message format, only used with custom templates
public $error_format = '<p class="error">{message}</p>';
public $newline_char = "\n";
/**
* Form constructor. Sets the form action, title, method, and attributes.
*
* @return void
*/
public function __construct($action = NULL, $title = '', $method = NULL, $attr = array())
{
// Set form attributes
$this->attr['action'] = $action;
$this->attr['method'] = empty($method) ? 'post' : $method;
// Set template variables
$this->template['title'] = $title;
// Empty attributes sets the class to "form"
empty($attr) and $attr = array('class' => 'form');
// String attributes is the class name
is_string($attr) and $attr = array('class' => $attr);
// Extend the template with the attributes
$this->attr += $attr;
}
/**
* Magic __get method. Returns the specified form element.
*
* @param string unique input name
* @return object
*/
public function __get($key)
{
if (isset($this->inputs[$key]))
{
return $this->inputs[$key];
}
elseif (isset($this->hidden[$key]))
{
return $this->hidden[$key];
}
}
/**
* Magic __call method. Creates a new form element object.
*
* @throws Kohana_Exception
* @param string input type
* @param string input name
* @return object
*/
public function __call($method, $args)
{
// Class name
$input = 'Form_'.ucfirst($method);
// Create the input
switch (count($args))
{
case 1:
$input = new $input($args[0]);
break;
case 2:
$input = new $input($args[0], $args[1]);
break;
default:
throw new Kohana_Exception('forge.invalid_input', $input);
}
if ( ! ($input instanceof Form_Input) AND ! ($input instanceof Forge))
throw new Kohana_Exception('forge.unknown_input', get_class($input));
$input->method = $this->attr['method'];
if ($name = $input->name)
{
// Assign by name
if ($method == 'hidden')
{
$this->hidden[$name] = $input;
}
else
{
$this->inputs[$name] = $input;
}
}
else
{
// No name, these are unretrievable
$this->inputs[] = $input;
}
return $input;
}
/**
* Set a form attribute. This method is chainable.
*
* @param string|array attribute name, or an array of attributes
* @param string attribute value
* @return object
*/
public function set_attr($key, $val = NULL)
{
if (is_array($key))
{
// Merge the new attributes with the old ones
$this->attr = array_merge($this->attr, $key);
}
else
{
// Set the new attribute
$this->attr[$key] = $val;
}
return $this;
}
/**
* Validates the form by running each inputs validation rules.
*
* @return bool
*/
public function validate()
{
$status = TRUE;
$inputs = array_merge($this->hidden, $this->inputs);
foreach ($inputs as $input)
{
if ($input->validate() == FALSE)
{
$status = FALSE;
}
}
return $status;
}
/**
* Returns the form as an array of input names and values.
*
* @return array
*/
public function as_array()
{
$data = array();
foreach (array_merge($this->hidden, $this->inputs) as $input)
{
if (is_object($input->name)) // It's a Forge_Group object (hopefully)
{
foreach ($input->inputs as $group_input)
{
if ($name = $group_input->name)
{
$data[$name] = $group_input->value;
}
}
}
else if (is_array($input->inputs))
{
foreach ($input->inputs as $group_input)
{
if ($name = $group_input->name)
{
$data[$name] = $group_input->value;
}
}
}
else if ($name = $input->name) // It's a normal input
{
// Return only named inputs
$data[$name] = $input->value;
}
}
return $data;
}
/**
* Changes the error message format. Your message formatting must
* contain a {message} placeholder.
*
* @throws Kohana_Exception
* @param string new message format
* @return void
*/
public function error_format($string = '')
{
if (strpos((string) $string, '{message}') === FALSE)
throw new Kohana_Exception('validation.error_format');
$this->error_format = $string;
}
/**
* Creates the form HTML
*
* @param string form view template name
* @param boolean use a custom view
* @return string
*/
public function render($template = 'forge_template', $custom = FALSE)
{
// Load template
$form = new View($template);
if ($custom)
{
// Using a custom view
$data = array();
foreach (array_merge($this->hidden, $this->inputs) as $input)
{
$data[$input->name] = $input;
// Groups will never have errors, so skip them
if ($input instanceof Form_Group)
continue;
// Compile the error messages for this input
$messages = '';
$errors = $input->error_messages();
if (is_array($errors) AND ! empty($errors))
{
foreach ($errors as $error)
{
// Replace the message with the error in the html error string
$messages .= str_replace('{message}', $error, $this->error_format).$this->newline_char;
}
}
$data[$input->name.'_errors'] = $messages;
}
$form->set($data);
}
else
{
// Using a template view
$form->set($this->template);
$hidden = array();
if ( ! empty($this->hidden))
{
foreach ($this->hidden as $input)
{
$hidden['name'] = $input->name;
$hidden['value'] = $input->value;
}
}
$form_type = 'open';
// See if we need a multipart form
$check_inputs = array($this->inputs);
while ($check_inputs) {
foreach (array_shift($check_inputs) as $input) {
if ($input instanceof Form_Upload)
{
$form_type = 'open_multipart';
}
if ($input instanceof Form_Group)
{
$check_inputs += array($input->inputs);
}
}
}
// Set the form open and close
$form->open = form::$form_type(arr::remove('action', $this->attr), $this->attr);
foreach ($this->hidden as $hidden) {
$form->open .= form::hidden($hidden->name, $hidden->value);
}
$form->close = "</form>";
// Set the inputs
$form->inputs = $this->inputs;
}
return $form;
}
/**
* Returns the form HTML
*/
public function __toString()
{
return (string) $this->render();
}
} // End Forge