Файл: concrete5.7.5.6/concrete/src/Form/Service/Form.php
Строк: 696
<?php
namespace ConcreteCoreFormService;
use Core;
use View;
/**
* Helpful functions for working with forms. Includes HTML input tags and the like.
*
* @package Helpers
* @category Concrete
* @author Andrew Embler <andrew@concrete5.org>
* @copyright Copyright (c) 2003-2008 Concrete5. (http://www.concrete5.org)
* @license http://www.concrete5.org/license/ MIT License
*/
class Form
{
/**
* Internal counter used to generate unique IDs for radio inputs with the same name.
*
* @var int
*/
protected $radioIndex = 1;
/**
* Internal counter used to generate unique IDs for select inputs with the same name.
*
* @var int
*/
protected $selectIndex = 1;
/**
* Text helper instance.
*
* @var ConcreteCoreUtilityServiceText
*/
protected $th;
/**
* Arrays helper instance.
*
* @var ConcreteCoreUtilityServiceArrays
*/
protected $ah;
/**
* Initialize the instance.
*/
public function __construct()
{
$this->th = Core::make('helper/text');
$this->ah = Core::make('helper/arrays');
}
/**
* Returns an action suitable for including in a form action property.
*
* @param string $action
* @param string $task
*/
public function action($action, $task = null)
{
return View::url($action, $task);
}
/**
* Creates a submit button.
*
* @param string $key The name/id of the element.
* @param string value The value of the element.
* @param array $miscFields Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param string $additionalClasses List of additional space-separated CSS class names.
*
* @return string
*/
public function submit($key, $value, $miscFields = array(), $additionalClasses = '')
{
return '<input type="submit"' . $this->parseMiscFields('btn ccm-input-submit ' . $additionalClasses, $miscFields) . ' id="' . $key . '" name="' . $key . '" value="' . $value . '" />';
}
/**
* Creates a button.
*
* @param string $key The name/id of the element.
* @param string value The value of the element.
* @param array $miscFields Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param string $additionalClasses List of additional space-separated CSS class names.
*
* @return string
*/
public function button($key, $value, $miscFields = array(), $additionalClasses = '')
{
return '<input type="button"' . $this->parseMiscFields('btn ccm-input-button ' . $additionalClasses, $miscFields) . ' id="' . $key . '" name="' . $key . '" value="' . $value . '" />';
}
/**
* Creates a label tag.
*
* @param string $forFieldID The id of the associated element.
* @param string $innerHTML The inner html of the label.
* @param array $miscFields Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function label($forFieldID, $innerHTML, $miscFields = array())
{
return '<label for="' . $forFieldID . '"' . $this->parseMiscFields('control-label ', $miscFields) . '>' . $innerHTML . '</label>';
}
/**
* Creates a file input element.
*
* @param string $key The name/id of the element.
* @param array $miscFields Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function file($key, $miscFields = array())
{
return '<input type="file" id="' . $key . '" name="' . $key . '" value=""' . $this->parseMiscFields('form-control', $miscFields) . ' />';
}
/**
* Creates a hidden form field.
*
* @param string $key The name/id of the element.
* @param string $value The value of the element (overriden if we received some data in POST or GET).
* @param array $miscFields Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function hidden($key, $value = null, $miscFields = array())
{
$requestValue = $this->getRequestValue($key);
if ($requestValue !== false && (!is_array($requestValue))) {
$value = $requestValue;
}
return '<input type="hidden" id="' . $key . '" name="' . $key . '"' . $this->parseMiscFields('', $miscFields) . ' value="' . $value . '" />';
}
/**
* Generates a checkbox.
*
* @param string $key The name/id of the element. It should end with '[]' if it's to return an array on submit.
* @param string $value String value sent to server, if checkbox is checked, on submit
* @param string $isChecked "Checked" value (subject to be overridden by $_REQUEST). Checkbox is checked if value is true (string). Note that 'false' (string) evaluates to true (boolean)!
* @param array $miscFields Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function checkbox($key, $value, $isChecked = false, $miscFields = array())
{
if (substr($key, -2) == '[]') {
$_field = substr($key, 0, -2);
$id = $_field . '_' . $value;
} else {
$_field = $key;
$id = $key;
}
$checked = false;
if ($isChecked && Request::request($_field) === null && !Request::isPost()) {
$checked = true;
} else {
$requestValue = $this->getRequestValue($key);
if ($requestValue !== false) {
if (is_array($requestValue)) {
if (in_array($value, $requestValue)) {
$checked = true;
}
} elseif ($requestValue == $value) {
$checked = true;
}
}
}
$checked = $checked ? ' checked="checked"' : '';
return '<input type="checkbox" id="' . $id . '" name="' . $key . '"'. $this->parseMiscFields('ccm-input-checkbox', $miscFields) . ' value="' . $value . '"' . $checked . ' />';
}
/**
* Creates a textarea field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function textarea($key, $valueOrMiscFields = '', $miscFields = array())
{
if (is_array($valueOrMiscFields)) {
$value = '';
$miscFields = $valueOrMiscFields;
} else {
$value = $valueOrMiscFields;
}
$requestValue = $this->getRequestValue($key);
if (is_string($requestValue)) {
$value = $requestValue;
}
return '<textarea id="' . $key . '" name="' . $key . '"' . $this->parseMiscFields('form-control', $miscFields) . '>' . $value . '</textarea>';
}
/**
* Generates a radio button.
*
* @param string $key The name of the element (its id will start with $key but will have a progressive unique number added).
* @param string $value The value of the radio button.
* @param string|array $valueOrMiscFields The value of the element (if it should be initially checked) or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function radio($key, $value, $checkedValueOrMiscFields = '', $miscFields = array())
{
if (is_array($checkedValueOrMiscFields)) {
$checkedValue = '';
$miscFields = $checkedValueOrMiscFields;
} else {
$checkedValue = $checkedValueOrMiscFields;
}
$checked = false;
if (isset($_REQUEST[$key])) {
if ($_REQUEST[$key] == $value) {
$checked = true;
}
} else {
if ($checkedValue == $value) {
$checked = true;
}
}
$id = null;
if (isset($miscFields['id'])) {
$id = $miscFields['id'];
unset($miscFields['id']);
}
$id = $id ?: $key.$this->radioIndex;
$str = '<input type="radio" id="' . $id . '" name="' . $key . '" value="' . $value . '"';
$str .= $this->parseMiscFields('ccm-input-radio', $miscFields);
if ($checked) {
$str .= ' checked="checked"';
}
$str .= ' />';
$this->radioIndex++;
return $str;
}
/**
* Checks the request based on the key passed.
* If $key denotes an array (eg akID[34]['value']) we'll turn the key into arrays if the key has text versions of [ and ] in it
* If the result is a string, it'll be escaped (with htmlspecialchars).
*
* @param string $key The name of the field to be checked.
* @param string $type 'post' to check in POST data, other values to check in GET data.
*
* @return false|array|string Returns an array if $key denotes an array and we received that data, a string if $key is the name of a received data, false if $key is not found in the received data.
*/
protected function processRequestValue($key, $type = 'post')
{
$arr = ($type == 'post') ? $_POST : $_GET;
if (strpos($key, '[') !== false) {
$key = str_replace(']', '', $key);
$key = explode('[', trim($key, '['));
$v2 = $this->ah->get($arr, $key);
if (isset($v2)) {
if (is_string($v2)) {
return $this->th->specialchars($v2);
} else {
return $v2;
}
}
} elseif (isset($arr[$key]) && is_string($arr[$key])) {
return $this->th->specialchars($arr[$key]);
}
return false;
}
/**
* Checks the request (first POST then GET) based on the key passed.
* If $key denotes an array (eg akID[34]['value']) we'll turn the key into arrays if the key has text versions of [ and ] in it
* If the result is a string, it'll be escaped (with htmlspecialchars).
*
* @param string $key The name of the field to be checked.
* @param string $type 'post' to check in POST data, other values to check in GET data.
*
* @return false|array|string Returns an array if $key denotes an array and we received that data, a string if $key is the name of a received data, false if $key is not found in the received data.
*/
public function getRequestValue($key)
{
$result = $this->processRequestValue($key, 'post');
if ($result === false) {
$result = $this->processRequestValue($key, 'get');
}
return $result;
}
/**
* Internal function that creates an <input> element of type $type. Handles the messiness of evaluating $valueOrMiscFields. Assigns a default class of ccm-input-$type.
*
* @param string $key The name/id of the element.
* @param string $type Accepted value for HTML attribute "type"
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
protected function inputType($key, $type, $valueOrMiscFields, $miscFields)
{
if (is_array($valueOrMiscFields)) {
$value = '';
$miscFields = $valueOrMiscFields;
} else {
$value = $valueOrMiscFields;
}
$requestValue = $this->getRequestValue($key);
if (is_string($requestValue)) {
$value = $requestValue;
}
$value = h($value);
return "<input type="$type" id="$key" name="$key" value="$value"" . $this->parseMiscFields("form-control ccm-input-$type", $miscFields) . ' />';
}
/**
* Renders a text input field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function text($key, $valueOrMiscFields = '', $miscFields = array())
{
return $this->inputType($key, 'text', $valueOrMiscFields, $miscFields);
}
/**
* Renders a number input field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function number($key, $valueOrMiscFields = '', $miscFields = array())
{
return $this->inputType($key, 'number', $valueOrMiscFields, $miscFields);
}
/**
* Renders an email input field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function email($key, $valueOrMiscFields = '', $miscFields = array())
{
return $this->inputType($key, 'email', $valueOrMiscFields, $miscFields);
}
/**
* Renders a telephone input field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function telephone($key, $valueOrMiscFields = '', $miscFields = array())
{
return $this->inputType($key, 'tel', $valueOrMiscFields, $miscFields);
}
/**
* Renders a URL input field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function url($key, $valueOrMiscFields = '', $miscFields = array())
{
return $this->inputType($key, 'url', $valueOrMiscFields, $miscFields);
}
/**
* Renders a search input field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function search($key, $valueOrMiscFields = '', $miscFields = array())
{
return $this->inputType($key, 'search', $valueOrMiscFields, $miscFields);
}
/**
* Renders a select field.
*
* @param string $key The name of the element. If $key denotes an array, the ID will start with $key but will have a progressive unique number added; if $key does not denotes an array, the ID attribute will be $key.
* @param array $optionValues An associative array of key => display.
* @param string|array $valueOrMiscFields The value of the field to be selected or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return $html
*/
public function select($key, $optionValues, $valueOrMiscFields = '', $miscFields = array())
{
if (!is_array($optionValues)) {
$optionValues = array();
}
if (is_array($valueOrMiscFields)) {
$selectedValue = '';
$miscFields = $valueOrMiscFields;
} else {
$selectedValue = (string) $valueOrMiscFields;
}
if ($selectedValue !== '') {
$miscFields['ccm-passed-value'] = $selectedValue;
}
$requestValue = $this->getRequestValue($key);
if (is_array($requestValue) && isset($requestValue[0]) && is_string($requestValue[0])) {
$selectedValue = (string) $requestValue[0];
} elseif ($requestValue !== false) {
if (!is_array($requestValue)) {
$selectedValue = (string)$requestValue;
} else {
$selectedValue = '';
}
}
if (substr($key, -2) == '[]') {
$_key = substr($key, 0, -2);
$id = $_key . $this->selectIndex;
$this->selectIndex++;
} else {
$id = $key;
}
$str = '<select id="' . $id . '" name="' . $key . '"' . $this->parseMiscFields('form-control', $miscFields) . '>';
foreach ($optionValues as $k => $text) {
$str .= '<option value="' . $k . '"';
if ((string) $k === (string) $selectedValue) {
$str .= ' selected="selected"';
}
$str .= '>' . $text . '</option>';
}
$str .= '</select>';
return $str;
}
/**
* Renders a multiple select box.
*
* @param string $key The ID of the element. The name attribute will be $key followed by '[].
* @param array $optionValues Hash array with name/value as the select's option value/text
* @param array|string $defaultValues Default value(s) which match with the option values; overridden by $_REQUEST
* @param array $miscFields Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return $html
*/
public function selectMultiple($key, $optionValues, $defaultValues = false, $miscFields = array())
{
$requestValue = $this->getRequestValue($key . '[]');
if ($requestValue !== false) {
$selectedValues = $requestValue;
} else {
$selectedValues = $defaultValues;
}
if (!is_array($selectedValues)) {
if (isset($selectedValues) && ($selectedValues !== false)) {
$selectedValues = (array) $selectedValues;
} else {
$selectedValues = array();
}
}
if (!is_array($optionValues)) {
$optionValues = array();
}
$str = "<select id="$key" name="{$key}[]" multiple="multiple"" . $this->parseMiscFields('form-control', $miscFields) . ">";
foreach ($optionValues as $k => $text) {
$str .= '<option value="' . $k . '"';
if (in_array($k, $selectedValues)) {
$str .= ' selected="selected"';
}
$str .= '>' . $text . '</option>';
}
$str .= "</select>";
return $str;
}
/**
* Renders a password input field.
*
* @param string $key The name/id of the element.
* @param string|array $valueOrMiscFields The value of the element or an array with additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
* @param array $miscFields (used if $valueOrMiscFields is not an array) Additional fields appended to the element (a hash array of attributes name => value), possibly including 'class'.
*
* @return string
*/
public function password($key, $valueOrMiscFields = '', $miscFields = array())
{
return $this->inputType($key, 'password', $valueOrMiscFields, $miscFields);
}
/**
* Create an HTML fragment of attribute values, merging any CSS class names as necessary.
*
* @param string $defaultClass Default CSS class name
* @param array $attributes A hash array of attributes (name => value), possibly including 'class'.
*
* @return string A fragment of attributes suitable to put inside of an HTML tag
*/
protected function parseMiscFields($defaultClass, $attributes)
{
$attributes = (array) $attributes;
if ($defaultClass) {
$attributes['class'] = trim((isset($attributes['class']) ? $attributes['class'] : '') . ' ' . $defaultClass);
}
$attr = '';
foreach ($attributes as $k => $v) {
$attr .= " $k="$v"";
}
return $attr;
}
}