First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
542
sites/all/modules/civicrm/packages/HTML/QuickForm/Controller.php
Normal file
542
sites/all/modules/civicrm/packages/HTML/QuickForm/Controller.php
Normal file
|
@ -0,0 +1,542 @@
|
|||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* The class representing a Controller of MVC design pattern.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.01 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_01.txt If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm_Controller
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @copyright 2003-2007 The PHP Group
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: Controller.php,v 1.13 2007/05/18 09:34:18 avb Exp $
|
||||
* @link http://pear.php.net/package/HTML_QuickForm_Controller
|
||||
*/
|
||||
|
||||
/**
|
||||
* The class representing a page of a multipage form.
|
||||
*/
|
||||
require_once 'HTML/QuickForm/Page.php';
|
||||
|
||||
/**
|
||||
* The class representing a Controller of MVC design pattern.
|
||||
*
|
||||
* This class keeps track of pages and (default) action handlers for the form,
|
||||
* it manages keeping the form values in session, setting defaults and
|
||||
* constants for the form as a whole and getting its submit values.
|
||||
*
|
||||
* Generally you don't need to subclass this.
|
||||
*
|
||||
* @category HTML
|
||||
* @package HTML_QuickForm_Controller
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @version Release: 1.0.9
|
||||
*/
|
||||
class HTML_QuickForm_Controller
|
||||
{
|
||||
/**
|
||||
* Contains the pages (HTML_QuickForm_Page objects) of the miultipage form
|
||||
* @var array
|
||||
*/
|
||||
var $_pages = array();
|
||||
|
||||
/**
|
||||
* Contains the mapping of actions to corresponding HTML_QuickForm_Action objects
|
||||
* @var array
|
||||
*/
|
||||
var $_actions = array();
|
||||
|
||||
/**
|
||||
* Name of the form, used to store the values in session
|
||||
* @var string
|
||||
*/
|
||||
var $_name;
|
||||
|
||||
/**
|
||||
* Whether the form is modal
|
||||
* @var bool
|
||||
*/
|
||||
var $_modal = true;
|
||||
|
||||
/**
|
||||
* The action extracted from HTTP request: array('page', 'action')
|
||||
* @var array
|
||||
*/
|
||||
var $_actionName = null;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* Sets the form name and modal/non-modal behaviuor. Different multipage
|
||||
* forms should have different names, as they are used to store form
|
||||
* values in session. Modal forms allow passing to the next page only when
|
||||
* all of the previous pages are valid.
|
||||
*
|
||||
* @access public
|
||||
* @param string form name
|
||||
* @param bool whether the form is modal
|
||||
*/
|
||||
function __construct($name, $modal = true)
|
||||
{
|
||||
$this->_name = $name;
|
||||
$this->_modal = $modal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a reference to a session variable containing the form-page
|
||||
* values and pages' validation status.
|
||||
*
|
||||
* This is a "low-level" method, use exportValues() if you want just to
|
||||
* get the form's values.
|
||||
*
|
||||
* @access public
|
||||
* @param bool If true, then reset the container: clear all default, constant and submitted values
|
||||
* @return array
|
||||
*/
|
||||
function &container($reset = false)
|
||||
{
|
||||
$name = '_' . $this->_name . '_container';
|
||||
if (!isset($_SESSION[$name]) || $reset) {
|
||||
$_SESSION[$name] = array(
|
||||
'defaults' => array(),
|
||||
'constants' => array(),
|
||||
'values' => array(),
|
||||
'valid' => array()
|
||||
);
|
||||
}
|
||||
foreach (array_keys($this->_pages) as $pageName) {
|
||||
if (!isset($_SESSION[$name]['values'][$pageName])) {
|
||||
$_SESSION[$name]['values'][$pageName] = array();
|
||||
$_SESSION[$name]['valid'][$pageName] = null;
|
||||
}
|
||||
}
|
||||
return $_SESSION[$name];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes the request.
|
||||
*
|
||||
* This finds the current page, the current action and passes the action
|
||||
* to the page's handle() method.
|
||||
*
|
||||
* @access public
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function run()
|
||||
{
|
||||
// the names of the action and page should be saved
|
||||
list($page, $action) = $this->_actionName = $this->getActionName();
|
||||
return $this->_pages[$page]->handle($action);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers a handler for a specific action.
|
||||
*
|
||||
* @access public
|
||||
* @param string name of the action
|
||||
* @param HTML_QuickForm_Action the handler for the action
|
||||
*/
|
||||
function addAction($actionName, $action)
|
||||
{
|
||||
$this->_actions[$actionName] = $action;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new page to the form
|
||||
*
|
||||
* @access public
|
||||
* @param HTML_QuickForm_Page
|
||||
*/
|
||||
function addPage(&$page)
|
||||
{
|
||||
$page->controller =& $this;
|
||||
$this->_pages[$page->getAttribute('id')] =& $page;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a page
|
||||
*
|
||||
* @access public
|
||||
* @param string Name of a page
|
||||
* @return HTML_QuickForm_Page A reference to the page
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function &getPage($pageName)
|
||||
{
|
||||
if (!isset($this->_pages[$pageName])) {
|
||||
return PEAR::raiseError('HTML_QuickForm_Controller: Unknown page "' . $pageName . '"');
|
||||
}
|
||||
return $this->_pages[$pageName];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles an action.
|
||||
*
|
||||
* This will be called if the page itself does not have a handler
|
||||
* to a specific action. The method also loads and uses default handlers
|
||||
* for common actions, if specific ones were not added.
|
||||
*
|
||||
* @access public
|
||||
* @param HTML_QuickForm_Page The page that failed to handle the action
|
||||
* @param string Name of the action
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function handle(&$page, $actionName)
|
||||
{
|
||||
if (isset($this->_actions[$actionName])) {
|
||||
return $this->_actions[$actionName]->perform($page, $actionName);
|
||||
}
|
||||
switch ($actionName) {
|
||||
case 'next':
|
||||
case 'back':
|
||||
case 'submit':
|
||||
case 'display':
|
||||
case 'jump':
|
||||
include_once 'HTML/QuickForm/Action/' . ucfirst($actionName) . '.php';
|
||||
$className = 'HTML_QuickForm_Action_' . $actionName;
|
||||
$this->_actions[$actionName] = new $className();
|
||||
return $this->_actions[$actionName]->perform($page, $actionName);
|
||||
break;
|
||||
default:
|
||||
return PEAR::raiseError('HTML_QuickForm_Controller: Unhandled action "' . $actionName . '" in page "' . $page->getAttribute('id') . '"');
|
||||
} // switch
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the form is modal.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isModal()
|
||||
{
|
||||
return $this->_modal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the pages of the controller are valid
|
||||
*
|
||||
* @access public
|
||||
* @param string If set, check only the pages before (not including) that page
|
||||
* @return bool
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function isValid($pageName = null)
|
||||
{
|
||||
$data =& $this->container();
|
||||
foreach (array_keys($this->_pages) as $key) {
|
||||
if (isset($pageName) && $pageName == $key) {
|
||||
return true;
|
||||
} elseif (!$data['valid'][$key]) {
|
||||
// We should handle the possible situation when the user has never
|
||||
// seen a page of a non-modal multipage form
|
||||
if (!$this->isModal() && null === $data['valid'][$key]) {
|
||||
$page =& $this->_pages[$key];
|
||||
// Fix for bug #8687: the unseen page was considered
|
||||
// submitted, so defaults for checkboxes and multiselects
|
||||
// were not used. Shouldn't break anything since this flag
|
||||
// will be reset right below in loadValues().
|
||||
$page->_flagSubmitted = false;
|
||||
// Use controller's defaults and constants, if present
|
||||
$this->applyDefaults($key);
|
||||
$page->isFormBuilt() or $page->BuildForm();
|
||||
// We use defaults and constants as if they were submitted
|
||||
$data['values'][$key] = $page->exportValues();
|
||||
$page->loadValues($data['values'][$key]);
|
||||
// Is the page now valid?
|
||||
if (PEAR::isError($valid = $page->validate())) {
|
||||
return $valid;
|
||||
}
|
||||
$data['valid'][$key] = $valid;
|
||||
if (true === $valid) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the page before the given.
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getPrevName($pageName)
|
||||
{
|
||||
$prev = null;
|
||||
foreach (array_keys($this->_pages) as $key) {
|
||||
if ($key == $pageName) {
|
||||
return $prev;
|
||||
}
|
||||
$prev = $key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the page after the given.
|
||||
*
|
||||
* @access public
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getNextName($pageName)
|
||||
{
|
||||
$prev = null;
|
||||
foreach (array_keys($this->_pages) as $key) {
|
||||
if ($prev == $pageName) {
|
||||
return $key;
|
||||
}
|
||||
$prev = $key;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the (first) invalid page
|
||||
*
|
||||
* @access public
|
||||
* @return string Name of an invalid page
|
||||
*/
|
||||
function findInvalid()
|
||||
{
|
||||
$data =& $this->container();
|
||||
foreach (array_keys($this->_pages) as $key) {
|
||||
if (!$data['valid'][$key]) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extracts the names of the current page and the current action from
|
||||
* HTTP request data.
|
||||
*
|
||||
* @access public
|
||||
* @return array first element is page name, second is action name
|
||||
*/
|
||||
function getActionName()
|
||||
{
|
||||
if (is_array($this->_actionName)) {
|
||||
return $this->_actionName;
|
||||
}
|
||||
$names = array_map('preg_quote', array_keys($this->_pages));
|
||||
$regex = '/^_qf_(' . implode('|', $names) . ')_(.+?)(_.+?)?(_x)?$/';
|
||||
$data =& $this->container();
|
||||
unset( $data['_qf_button_name'] );
|
||||
foreach (array_keys($_REQUEST) as $key) {
|
||||
if (preg_match($regex, $key, $matches)) {
|
||||
$data['_qf_button_name'] = $key;
|
||||
if ( array_key_exists( 3, $matches ) ) {
|
||||
$key = preg_replace( '/_(x|y)$/', '', $key );
|
||||
}
|
||||
return array($matches[1], $matches[2]);
|
||||
}
|
||||
}
|
||||
if (isset($_REQUEST['_qf_default'])) {
|
||||
$matches = explode(':', $_REQUEST['_qf_default'], 2);
|
||||
if (isset($this->_pages[$matches[0]])) {
|
||||
return $matches;
|
||||
}
|
||||
}
|
||||
reset($this->_pages);
|
||||
return array(key($this->_pages), 'display');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes default form values.
|
||||
*
|
||||
* @access public
|
||||
* @param array default values
|
||||
* @param mixed filter(s) to apply to default values
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function setDefaults($defaultValues = null, $filter = null)
|
||||
{
|
||||
if (is_array($defaultValues)) {
|
||||
$data =& $this->container();
|
||||
return $this->_setDefaultsOrConstants($data['defaults'], $defaultValues, $filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes constant form values.
|
||||
* These values won't get overridden by POST or GET vars
|
||||
*
|
||||
* @access public
|
||||
* @param array constant values
|
||||
* @param mixed filter(s) to apply to constant values
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function setConstants($constantValues = null, $filter = null)
|
||||
{
|
||||
if (is_array($constantValues)) {
|
||||
$data =& $this->container();
|
||||
return $this->_setDefaultsOrConstants($data['constants'], $constantValues, $filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds new values to defaults or constants array
|
||||
*
|
||||
* @access private
|
||||
* @param array array to add values to (either defaults or constants)
|
||||
* @param array values to add
|
||||
* @param mixed filters to apply to new values
|
||||
* @throws PEAR_Error
|
||||
*/
|
||||
function _setDefaultsOrConstants(&$values, $newValues, $filter = null)
|
||||
{
|
||||
if (isset($filter)) {
|
||||
if (is_array($filter) && (2 != count($filter) || !is_callable($filter))) {
|
||||
foreach ($filter as $val) {
|
||||
if (!is_callable($val)) {
|
||||
return PEAR::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm_Controller::_setDefaultsOrConstants()", 'HTML_QuickForm_Error', true);
|
||||
} else {
|
||||
$newValues = $this->_arrayMapRecursive($val, $newValues);
|
||||
}
|
||||
}
|
||||
} elseif (!is_callable($filter)) {
|
||||
return PEAR::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm_Controller::_setDefaultsOrConstants()", 'HTML_QuickForm_Error', true);
|
||||
} else {
|
||||
$newValues = $this->_arrayMapRecursive($val, $newValues);
|
||||
}
|
||||
}
|
||||
$values = HTML_QuickForm::arrayMerge($values, $newValues);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively applies the callback function to the value
|
||||
*
|
||||
* @param mixed Callback function
|
||||
* @param mixed Value to process
|
||||
* @access private
|
||||
* @return mixed Processed values
|
||||
*/
|
||||
function _arrayMapRecursive($callback, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
return call_user_func($callback, $value);
|
||||
} else {
|
||||
$map = array();
|
||||
foreach ($value as $k => $v) {
|
||||
$map[$k] = $this->_arrayMapRecursive($callback, $v);
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the default values for the given page
|
||||
*
|
||||
* @access public
|
||||
* @param string Name of a page
|
||||
*/
|
||||
function applyDefaults($pageName)
|
||||
{
|
||||
$data =& $this->container();
|
||||
if (!empty($data['defaults'])) {
|
||||
$this->_pages[$pageName]->setDefaults($data['defaults']);
|
||||
}
|
||||
if (!empty($data['constants'])) {
|
||||
$this->_pages[$pageName]->setConstants($data['constants']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the form's values
|
||||
*
|
||||
* @access public
|
||||
* @param string name of the page, if not set then returns values for all pages
|
||||
* @return array
|
||||
*/
|
||||
function exportValues($pageName = null)
|
||||
{
|
||||
$data =& $this->container();
|
||||
$values = array();
|
||||
if (isset($pageName)) {
|
||||
$pages = array($pageName);
|
||||
} else {
|
||||
$pages = array_keys($data['values']);
|
||||
}
|
||||
foreach ($pages as $page) {
|
||||
// skip elements representing actions
|
||||
foreach ($data['values'][$page] as $key => $value) {
|
||||
if (0 !== strpos($key, '_qf_')) {
|
||||
if (isset($values[$key]) && is_array($value)) {
|
||||
$values[$key] = HTML_QuickForm::arrayMerge($values[$key], $value);
|
||||
} else {
|
||||
$values[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the element's value
|
||||
*
|
||||
* @access public
|
||||
* @param string name of the page
|
||||
* @param string name of the element in the page
|
||||
* @return mixed value for the element
|
||||
*/
|
||||
function exportValue($pageName, $elementName)
|
||||
{
|
||||
$data =& $this->container();
|
||||
return isset($data['values'][$pageName][$elementName])? $data['values'][$pageName][$elementName]: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* resets a specifc page in the container
|
||||
*
|
||||
* @access public
|
||||
* @param string name of the page
|
||||
* @return void
|
||||
*/
|
||||
function resetPage($pageName, $valid = null)
|
||||
{
|
||||
$data =& $this->container();
|
||||
if (isset($data['values'][$pageName]) ||
|
||||
isset($data['valid'][$pageName])) {
|
||||
$data['values'][$pageName] = array( );
|
||||
$data['valid'][$pageName] = $valid;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
Loading…
Add table
Add a link
Reference in a new issue