Initial commit

This commit is contained in:
Caribana
2017-05-26 11:41:26 +02:00
commit 61c24500af
6264 changed files with 645934 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
<?php
/**
* Class for button controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Button extends Zebra_Form_Control
{
/**
* Constructor of the class
*
* Adds an <button> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a submit button to the form
* $obj = $form->add('button', 'my_button', 'Click me!', 'submit');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_button", one would use:
* echo $my_button;
* </code>
*
* @param string $caption Caption of the button control.
*
* Can be HTML markup.
*
* @param string $type (Optional) Type of the button: button, submit or reset.
*
* Default is "button".
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (size, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "disabled" attribute
* $obj = $form->add(
* 'button',
* 'my_button',
* 'Click me!',
* 'submit' // <- make this a submit button
* array(
* 'disabled' => 'disabled'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
* <b>id</b>, <b>name</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $caption, $type = 'button', $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
'value',
);
// set the default attributes for the button control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => $type,
'name' => $id,
'id' => $id,
'value' => $caption,
'class' => 'button' . ($type != 'button' ? ' ' . $type : ''),
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<button ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>' . $this->attributes['value'] . '</button>';
}
}
?>

View File

@@ -0,0 +1,123 @@
<?php
/**
* Class for CAPTCHA controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Captcha extends Zebra_Form_Control
{
/**
* Adds a CAPTCHA image to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <b>You must also place a {@link Zebra_Form_Text textbox} control on the form and set the "captcha" rule to it!
* (through {@link set_rule()})</b>
*
* Properties of the CAPTCHA image can be altered by editing the file includes/captcha.php.
*
* By default, captcha values are triple md5 hashed and stored in cookies, and when the user enters the captcha
* value the value is also triple md5 hashed and the two values are then compared. Sometimes, your users may have
* a very restrictive cookie policy and so cookies will not be set, and therefore they will never be able to get
* past the CAPTCHA control. If it's the case, call the {@link Zebra_Form::captcha_storage() captcha_storage}
* method and set the storage method to "session".
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a CAPTCHA image
* $form->add('captcha', 'my_captcha', 'my_text');
*
* // add a label for the textbox
* $form->add('label', 'label_my_text', 'my_text', 'Are you human?');
*
* // add a CAPTCHA to the form
* $obj = $form->add('text', 'my_text');
*
* // set the "captcha" rule to the textbox
* $obj->set_rule(array(
* 'captcha' => array('error', 'Characters not entered correctly!')
* ));
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* This is the name of the variable to be used in the template file, containing
* the generated HTML for the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_captcha", one would use:
* echo $my_captcha;
* </code>
*
* @param string $attach_to The <b>id</b> attribute of the {@link Zebra_Form_Text textbox} control to attach
* the CAPTCHA image to.
*
* @return void
*/
function __construct($id, $attach_to, $storage = 'cookie')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'for',
'locked',
);
// set the default attributes for the text control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'captcha',
'name' => $id,
'id' => $id,
'for' => $attach_to,
)
);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<div class="captcha-container"><img src="' . $this->form_properties['assets_url'] . 'process.php?captcha=' . ($this->form_properties['captcha_storage'] == 'session' ? 2 : 1) . '&amp;nocache=' . time() . '" alt=""' . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '><a href="javascript:void(0)" title="' . $this->form_properties['language']['new_captcha'] . '">' . $this->form_properties['language']['new_captcha'] . '</a></div>';
}
}
?>

View File

@@ -0,0 +1,243 @@
<?php
/**
* Class for checkbox controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Checkbox extends Zebra_Form_Control
{
/**
* Constructor of the class
*
* Adds an <input type="checkbox"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // single checkbox
* $obj = $form->add('checkbox', 'my_checkbox', 'my_checkbox_value');
*
* // multiple checkboxes
* // notice that is "checkboxes" instead of "checkbox"
* // checkboxes values will be "0", "1" and "2", respectively, and will be available in a custom template like
* // "mycheckbox_0", "mycheckbox_1" and "mycheckbox_2".
* // label controls will be automatically created having the names "label_mycheckbox_0", "label_mycheckbox_1" and
* // "label_mycheckbox_2" (label + underscore + control name + underscore + value with anything else other than
* // letters and numbers replaced with underscores - also, note that multiple consecutive underscores will be
* // replaced by a single one)
* // $obj is a reference to the first checkbox
* $obj = $form->add('checkboxes', 'mycheckbox',
* array(
* 'Value 1',
* 'Value 2',
* 'Value 3'
* )
* );
*
* // multiple checkboxes with specific indexes
* // checkboxes values will be "v1", "v2" and "v3", respectively, and will be available in a custom template like
* // "mycheckbox_v1", "mycheckbox_v2" and "mycheckbox_v3".
* // label controls will be automatically created having the names "label_mycheckbox_v1", "label_mycheckbox_v2" and
* // "label_mycheckbox_v3" (label + underscore + control name + underscore + value with anything else other than
* // letters and numbers replaced with underscores - also, note that multiple consecutive underscores will be
* // replaced by a single one)
* $obj = $form->add('checkboxes', 'mycheckbox',
* array(
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* )
* );
*
* // multiple checkboxes with preselected value
* // "Value 2" will be the preselected value
* // note that for preselecting values you must use the actual indexes of the values, if available, (like
* // in the current example) or the default, zero-based index, otherwise (like in the next example)
* $obj = $form->add('checkboxes', 'mycheckbox',
* array(
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* ),
* 'v2' // note the index!
* );
*
* // "Value 2" will be the preselected value.
* // note that for preselecting values you must use the actual indexes of the values, if available, (like
* // in the example above) or the default, zero-based index, otherwise (like in the current example)
* $obj = $form->add('checkboxes', 'mycheckbox',
* array(
* 'Value 1',
* 'Value 2',
* 'Value 3'
* ),
* 1 // note the index!
* );
*
* // multiple checkboxes with multiple preselected values
* $obj = $form->add('checkboxes', 'mycheckbox[]',
* array(
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* ),
* array('v1', 'v2')
* );
*
* // custom classes (or other attributes) can also be added to all of the elements by specifying a 4th argument;
* // this needs to be specified in the same way as you would by calling {@link set_attributes()} method:
* $obj = $form->add('checkboxes', 'mycheckbox[]',
* array(
* '1' => 'Value 1',
* '2' => 'Value 2',
* '3' => 'Value 3',
* ),
* '', // no default value
* array('class' => 'my_custom_class')
* );
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* <samp>By default, for checkboxes, radio buttons and select boxes, the library will prevent the submission of other
* values than those declared when creating the form, by triggering the error: "SPAM attempt detected!". Therefore,
* if you plan on adding/removing values dynamically, from JavaScript, you will have to call the
* {@link Zebra_Form_Control::disable_spam_filter() disable_spam_filter()} method to prevent that from happening!</samp>
*
* @param string $id Unique name to identify the control in the form.
*
* <b>$id needs to be suffixed with square brackets if there are more checkboxes
* sharing the same name, so that PHP treats them as an array!</b>
*
* The control's <b>name</b> attribute will be as indicated by <i>$id</i>
* argument while the control's <b>id</b> attribute will be <i>$id</i>, stripped of
* square brackets (if any), followed by an underscore and followed by <i>$value</i>
* with all the spaces replaced by <i>underscores</i>.
*
* So, if the <i>$id</i> arguments is "my_checkbox" and the <i>$value</i> argument
* is "value 1", the control's <b>id</b> attribute will be <b>my_checkbox_value_1</b>.
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_checkbox" and having the value of "value 1",
* // one would use:
* echo $my_checkbox_value_1;
* </code>
*
* <i>Note that when adding the required rule to a group of checkboxes (checkboxes
* sharing the same name), it is sufficient to add the rule to the first checkbox!</i>
*
* @param mixed $value Value of the checkbox.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (disabled, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "checked" attribute
* $obj = $form->add(
* 'checkbox',
* 'my_checkbox',
* 'v1',
* array(
* 'checked' => 'checked'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>type</b>, <b>id</b>, <b>name</b>, <b>value</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $value, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_spam_filter',
'disable_xss_filters',
'locked',
);
// set the default attributes for the checkbox control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'checkbox',
'name' => $id,
'id' => str_replace(array(' ', '[', ']'), array('_', ''), $id) . '_' . str_replace(' ', '_', $value),
'value' => $value,
'class' => 'control checkbox',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,185 @@
<?php
/**
* Class for file upload controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_File extends Zebra_Form_Control
{
/**
* Adds an <input type="file"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a file upload control to the form
* $obj = $form->add('file', 'my_file_upload');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
*
* // all the information about the uploaded file will be
* // available in the "file_upload" property
* print_r('<pre>');
* print_r($form->file_upload['my_file_upload']);
*
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_file_upload", one would use:
* echo $my_file_upload;
* </code>
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (size, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "disabled" attribute
* $obj = $form->add(
* 'file',
* 'my_file_upload',
* '',
* array(
* 'disabled' => 'disabled'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>type</b>, <b>id</b>, <b>name</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
'files',
);
// set the default attributes for the text control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'file',
'name' => $id,
'id' => $id,
'class' => 'control file',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
// all file upload controls must have the "upload" rule set or we trigger an error
if (!isset($this->rules['upload'])) _zebra_form_show_error('The control named <strong>"' . $this->attributes['name'] . '"</strong> in form <strong>"' . $this->form_properties['name'] . '"</strong> must have the <em>"upload"</em> rule set', E_USER_ERROR);
// if the "image" rule is set
if (isset($this->rules['image']))
// these are the allowed file extensions
$allowed_file_types = array('jpe', 'jpg', 'jpeg', 'png', 'gif');
// if the "filetype" rule is set
elseif (isset($this->rules['filetype']))
// get the array of allowed file extensions
$allowed_file_types = array_map(create_function('$value', 'return trim($value);'), explode(',', $this->rules['filetype'][0]));
// if file selection should be restricted to certain file types
if (isset($allowed_file_types)) {
$mimes = array();
// iterate through allowed extensions
foreach ($allowed_file_types as $extension)
// get the mime type for each extension
if (isset($this->form_properties['mimes'][$extension]))
$mimes = array_merge($mimes, (array)$this->form_properties['mimes'][$extension]);
// set the "accept" attribute
// see http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#file-upload-state-%28type=file%29
// at the time of writing, on December 30, 2012, this was only working on Chrome 23 and IE 10
$this->set_attributes(array('accept' => '.' . implode(',.', $allowed_file_types) . ',' . implode(',', $mimes)));
}
// show the file upload control
$output = '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
// return the generated output
return $output;
}
}
?>

View File

@@ -0,0 +1,102 @@
<?php
/**
* Class for hidden controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Hidden extends Zebra_Form_Control
{
/**
* Adds an <input type="hidden"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a hidden control to the form
* $obj = $form->add('hidden', 'my_hidden', 'Secret value');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* <b>Hidden controls are automatically rendered when the {@link Zebra_Form::render() render()}
* method is called!</b><br>
* <b>Do not print them in template files!</b>
*
* @param string $default (Optional) Default value of the text box.
*
* @return void
*/
function __construct($id, $default = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
);
// set the default attributes for the hidden control
// put them in the order you'd like them rendered
// notice that if control's name is 'MAX_FILE_SIZE' we'll generate a random ID attribute for the control
// as, with multiple forms having upload controls on them, this hidden control appears as many times as the
// forms do and we don't want to have the same ID assigned to multiple controls
$this->set_attributes(
array(
'type' => 'hidden',
'name' => $id,
'id' => ($id != 'MAX_FILE_SIZE' ? $id : 'mfs_' . rand(0, 100000)),
'value' => $default,
)
);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

View File

@@ -0,0 +1,144 @@
<?php
/**
* Class for image controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Image extends Zebra_Form_Control
{
/**
* Adds an <input type="image"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add an image control to the form
* $obj = $form->add('image', 'my_image', 'path/to/image');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_image", one would use:
* echo $my_image;
* </code>
*
* @param string $src (Optional) Path to an image file.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (size, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "alt" attribute
* $obj = $form->add(
* 'image',
* 'my_image',
* 'path/to/image',
* array(
* 'alt' => 'Click to submit form'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>type</b>, <b>id</b>, <b>name</b>, <b>src</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $src, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
);
// set the default attributes for the image control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'alt' => $id,
'class' => 'image',
'id' => $id,
'name' => $id,
'src' => $src,
'type' => 'image',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the table cell
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

View File

@@ -0,0 +1,192 @@
<?php
/**
* Class for labels
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Label extends Zebra_Form_Control
{
/**
* Add an <label> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a label, attached to a textbox control
* $form->add('label', 'label_my_text', 'my_text', 'Enter some text:');
*
* // add a text control to the form
* $obj = $form->add('text', 'my_text');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* This is the name of the variable to be used in the template file, containing
* the generated HTML for the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_label", one would use:
* echo $my_label;
* </code>
*
* @param string $attach_to The <b>id</b> attribute of the control to attach the note to.
*
* <i>Notice that this must be the "id" attribute of the control you are attaching
* the label to, and not the "name" attribute!</i>
*
* This is important as while most of the controls have their <b>id</b> attribute
* set to the same value as their <b>name</b> attribute, for {@link Zebra_Form_Checkbox checkboxes},
* {@link Zebra_Form_Select selects} and {@link Zebra_Form_Radio radio&nbsp;buttons} this
* is different.
*
* <b>Exception to the rule:</b>
*
* Just like in the case of {@link Zebra_Form_Note notes}, if you want a <b>master</b>
* label, a label that is attached to a <b>group</b> of checkboxes/radio buttons
* rather than individual controls, this attribute must instead refer to the <b>name</b>
* of the controls (which, for groups of checkboxes/radio buttons, is one and the same).
* This is important because if the group of checkboxes/radio buttons have the
* <i>required</i> rule set, this is the only way in which the "required" symbol
* (the red asterisk) will be attached to the master label instead of being attached
* to the first checkbox/radio button from the group.
*
* @param mixed $caption Caption of the label.
*
* <i>Putting a $ (dollar) sign before a character will turn that specific character into
* the accesskey.</i><br>
* <i>If you need the dollar sign in the label, escape it with</i> \ <i>(backslash)</i>
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#edef-LABEL label}
* elements (style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "style" attribute
* $obj = $form->add(
* 'label',
* 'label_my_text',
* 'my_text',
* 'My Label:'
* array(
* 'style' => 'font-weight: normal'
* )
* );
* </code>
*
* <b>Special attribute:</b>
*
* When setting the special attribute <b>inside</b> to <b>true</b>, the label will
* appear inside the control is attached to (if the control the label is attached to
* is a {@link Zebra_Form_Text textbox} or a {@link Zebra_Form_Textarea textarea}) and
* will disappear when the control will receive focus. When the "inside" attribute is
* set to TRUE, the label will not be available in the template file as it will be
* contained by the control the label is attached to!
*
* <code>
* $form->add('label', 'my_label', 'my_control', 'My Label:', array('inside' => true));
* </code>
*
* <samp>Sometimes, when using floats, the inside-labels will not be correctly positioned
* as jQuery will return invalid numbers for the parent element's position; If this is
* the case, make sure you enclose the form in a div with position:relative to fix
* this issue.</samp>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
* <b>id</b>, <b>for</b>
*
* @return void
*/
function __construct($id, $attach_to, $caption, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
$this->private_attributes = array(
'disable_xss_filters',
'for_group',
'inside',
'label',
'locked',
'name',
'type',
);
// set the default attributes for the label
$this->set_attributes(
array(
'for' => $attach_to,
'id' => $id,
'label' => $caption,
'name' => $id,
'type' => 'label',
)
);
// sets user specified attributes for the table cell
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
// get private attributes
$attributes = $this->get_attributes('label');
// if access key needs to be showed
if (preg_match('/(?<!\\\)\$(.{1})/', $attributes['label'], $matches) > 0) {
// set the requested accesskey
$this->set_attributes(array('accesskey' => strtolower($matches[1])));
// make the accesskey visible
$attributes['label'] = preg_replace('/\$(.{1})/', '<span class="underline">$1</span>', $attributes['label']);
}
return '<label ' . $this->_render_attributes() . '>' . preg_replace('/\\\\\$/', '$', $attributes['label']) . '</label>';
}
}
?>

View File

@@ -0,0 +1,163 @@
<?php
/**
* Class for notes attached to controls
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Note extends Zebra_Form_Control
{
/**
* Adds a "note" to the form, attached to a control.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a text control to the form
* $obj = $form->add('text', 'my_text');
*
* // attach a note to the textbox control
* $form->add('note', 'note_my_text', 'my_text', 'Enter some text in the field above');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* This is the name of the variable to be used in the template file, containing
* the generated HTML for the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_note", one would use:
* echo $my_note;
* </code>
*
* @param string $attach_to The <b>id</b> attribute of the control to attach the note to.
*
* <i>Notice that this must be the "id" attribute of the control you are attaching
* the label to, and not the "name" attribute!</i>
*
* This is important as while most of the controls have their <b>id</b> attribute
* set to the same value as their <b>name</b> attribute, for {@link Zebra_Form_Checkbox checkboxes},
* {@link Zebra_Form_Select selects} and {@link Zebra_Form_Radio radio&nbsp;buttons} this
* is different.
*
* <b>Exception to the rule:</b>
*
* Just like in the case of {@link Zebra_Form_Label labels}, if you want a <b>master</b>
* note, a note that is attached to a <b>group</b> of checkboxes/radio buttons rather than
* individual controls, this attribute must instead refer to the <b>name</b> of the
* controls (which, for groups of checkboxes/radio buttons, is one and the same).
*
* @param string $caption Content of the note (can be both plain text and/or HTML)
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/struct/global.html#h-7.5.4 div}
* elements (style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "style" attribute
* $obj = $form->add(
* 'note',
* 'note_my_text',
* 'my_text',
* array(
* 'style' => 'width:250px'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
* <b>class</b>
*
* @return void
*/
function __construct($id, $attach_to, $caption, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
$this->private_attributes = array(
'caption',
'disable_xss_filters',
'locked',
'for',
'name',
'type',
);
// set the default attributes for the HTML control
$this->set_attributes(
array(
'class' => 'note',
'caption' => $caption,
'for' => $attach_to,
'id' => $id,
'name' => $id,
'type' => 'note',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
$attributes = $this->get_attributes('caption');
return '<div ' . $this->_render_attributes() . '>' . $attributes['caption'] . '</div>';
}
}
?>

View File

@@ -0,0 +1,178 @@
<?php
/**
* Class for password controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Password extends Zebra_Form_Control
{
/**
* Adds an <input type="password"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a password control to the form
* $obj = $form->add('password', 'my_password');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_password", one would use:
* echo $my_password;
* </code>
*
* @param string $default (Optional) Default value of the password field.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (size, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "disabled" attribute
* $obj = $form->add(
* 'password',
* 'my_password',
* '',
* array(
* 'disabled' => 'disabled'
* )
* );
* </code>
*
* There's a special <b>data-prefix</b> attribute that you can use to add <i>uneditable
* prefixes</i> to input fields (text, images, or plain HTML), as seen in the image
* below. It works by injecting an absolutely positioned element into the DOM, right
* after the parent element, and then positioning it on the left side of the parent
* element and adjusting the width and the left padding of the parent element, so it
* looks like the prefix is part of the parent element.
*
* <i>If the prefix is plain text or HTML code, it will be contained in a <div> tag
* having the class </i> <b>Zebra_Form_Input_Prefix</b><i>; if the prefix is a path to an
* image, it will be an <img> tag having the class </i> <b>Zebra_Form_Input_Prefix</b><i>.</i>
*
* <samp>For anything other than plain text, you must use CSS to set the width and
* height of the prefix, or it will not be correctly positioned because when the image
* is not cached by the browser the code taking care of centering the image will
* be executed before the image is loaded by the browser and it will not know the
* image's width and height!</samp>
*
* {@img src=../media/zebra-form-prefix.jpg class=graphic}
*
* <code>
* // add simple text
* // style the text through the Zebra_Form_Input_Prefix class
* $form->add('password', 'my_password', '', array('data-prefix' => 'Hash:'));
*
* // add images
* // set the image's width and height through the img.Zebra_Form_Input_Prefix class
* // in your CSS or the image will not be correctly positioned!
* $form->add('password', 'my_password', '', array('data-prefix' => 'img:path/to/image'));
*
* // add html - useful when using sprites
* // again, make sure that you set somewhere the width and height of the prefix!
* $form->add('password', 'my_password', '', array('data-prefix' => '<div class="sprite image1"></div>'));
* $form->add('password', 'my_password', '', array('data-prefix' => '<div class="sprite image2"></div>'));
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>type</b>, <b>id</b>, <b>name</b>, <b>value</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $default = '', $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'default_value',
'disable_xss_filters',
'locked',
);
// set the default attributes for the button control
$this->set_attributes(
array(
'type' => 'password',
'name' => $id,
'id' => $id,
'value' => $default,
'class' => 'control password',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

View File

@@ -0,0 +1,229 @@
<?php
/**
* Class for radio button controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Radio extends Zebra_Form_Control
{
/**
* Adds an <input type="radio"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // single radio button
* $obj = $form->add('radio', 'myradio', 'my_radio_value');
*
* // multiple radio buttons
* // notice that is "radios" instead of "radio"
* // radio buttons' values will be "0", "1" and "2", respectively, and will be available in a custom template like
* // "myradio_0", "myradio_1" and "myradio_2".
* // label controls will be automatically created having the names "label_myradio_0", "label_myradio_1" and
* // "label_myradio_2" (label + underscore + control name + underscore + value with anything else other than
* // letters and numbers replaced with underscores - also, note that multiple consecutive underscores will be
* // replaced by a single one)
* // $obj is a reference to the first radio button
* $obj = $form->add('radios', 'myradio',
* array(
* 'Value 1',
* 'Value 2',
* 'Value 3'
* )
* );
*
* // multiple radio buttons with specific indexes
* // radio buttons' values will be "v1", "v2" and "v3", respectively, and will be available in a custom template
* // like "myradio_v1", "myradio_v2" and "myradio_v3".
* // label controls will be automatically created having the names "label_myradio_v1", "label_myradio_v2" and
* // "label_myradio_v3" (label + underscore + control name + underscore + value with anything else other than
* // letters and numbers replaced with underscores - also, note that multiple consecutive underscores will be
* // replaced by a single one)
* $obj = $form->add('radios', 'myradio',
* array(
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* )
* );
*
* // multiple radio buttons with preselected value
* // "Value 2" will be the preselected value
* // note that for preselecting values you must use the actual indexes of the values, if available, (like
* // in the current example) or the default, zero-based index, otherwise (like in the next example)
* $obj = $form->add('radios', 'myradio',
* array(
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* ),
* 'v2' // note the index!
* );
*
* // "Value 2" will be the preselected value.
* // note that for preselecting values you must use the actual indexes of the values, if available, (like
* // in the example above) or the default, zero-based index, otherwise (like in the current example)
* $obj = $form->add('radios', 'myradio',
* array(
* 'Value 1',
* 'Value 2',
* 'Value 3'
* ),
* 1 // note the index!
* );
*
* // custom classes (or other attributes) can also be added to all of the elements by specifying a 4th argument;
* // this needs to be specified in the same way as you would by calling {@link set_attributes()} method:
* $obj = $form->add('radios', 'myradio',
* array(
* '1' => 'Value 1',
* '2' => 'Value 2',
* '3' => 'Value 3',
* ),
* '', // no default value
* array('class' => 'my_custom_class')
* );
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* <samp>By default, for checkboxes, radio buttons and select boxes, the library will prevent the submission of other
* values than those declared when creating the form, by triggering the error: "SPAM attempt detected!". Therefore,
* if you plan on adding/removing values dynamically, from JavaScript, you will have to call the
* {@link Zebra_Form_Control::disable_spam_filter() disable_spam_filter()} method to prevent that from happening!</samp>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be as indicated by <i>$id</i>
* argument while the control's <b>id</b> attribute will be <i>$id</i> followd by an
* underscore and followed by <i>$value</i> with all the spaces replaced by
* <i>underscores</i>.
*
* So, if the <i>$id</i> arguments is "my_radio" and the <i>$value</i> argument
* is "value 1", the control's <b>id</b> attribute will be <b>my_radio_value_1</b>.
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_radio" and having the value of "value 1",
* // one would use:
* echo $my_radio_value_1;
* </code>
*
* <i>Note that when adding the required rule to a group of radio buttons (radio
* buttons sharing the same name), it is sufficient to add the rule to the first
* radio button!</i>
*
* @param mixed $value Value of the radio button.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (disabled, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "checked" attribute
* $obj = $form->add(
* 'radio',
* 'my_radio',
* 'v1',
* array(
* 'checked' => 'checked'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>type</b>, <b>id</b>, <b>name</b>, <b>value</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $value, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_spam_filter',
'disable_xss_filters',
'locked',
);
// set the default attributes for the radio button control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'radio',
'name' => $id,
'id' => str_replace(' ', '_', $id) . '_' . str_replace(' ', '_', $value),
'value' => $value,
'class' => 'control radio',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

View File

@@ -0,0 +1,142 @@
<?php
/**
* Class for reset button controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Reset extends Zebra_Form_Control
{
/**
* Adds an <input type="reset"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a reset control to the form
* $obj = $form->add('reset', 'my_reset', 'Reset');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_reset", one would use:
* echo $my_reset;
* </code>
*
* @param string $caption Caption of the reset button control.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (size, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "alt" attribute
* $obj = $form->add(
* 'reset',
* 'my_reset',
* 'Reset',
* array(
* 'alt' => 'Click to reset values'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
* <b>type</b>, <b>id</b>, <b>name</b>, <b>value</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $caption, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
);
// set the default attributes for the reset button control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'reset',
'name' => $id,
'id' => $id,
'value' => $caption,
'class' => 'reset',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

View File

@@ -0,0 +1,385 @@
<?php
/**
* Class for select box controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Select extends Zebra_Form_Control
{
/**
* Adds an <select> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* By default, unless the <b>multiple</b> attribute is set, the control will have a default first option added
* automatically inviting users to select one of the available options. Default value for English is
* "<i>-&nbsp;select&nbsp;-</i>" taken from the language file - see the {@link Zebra_Form::language() language()}
* method. If you don't want it or want to set it at runtime, set the <i>overwrite</i> argument to TRUE when calling
* the {@link add_options()} method.
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // single-option select box
* $obj = $form->add('select', 'my_select');
*
* // add selectable values with default indexes
* // values will be "0", "1" and "2", respectively
* // a default first value, "- select -" (language dependent) will also be added
* $obj->add_options(array(
* 'Value 1',
* 'Value 2',
* 'Value 3'
* ));
*
* // single-option select box
* $obj = $form->add('select', 'my_select2');
*
* // add selectable values with specific indexes
* // values will be "v1", "v2" and "v3", respectively
* // a default first value, "- select -" (language dependent) will also be added
* $obj->add_options(array(
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* ));
*
* // single-option select box with the second value selected
* $obj = $form->add('select', 'my_select3', 'v2');
*
* // add selectable values with specific indexes
* // values will be "v1", "v2" and "v3", respectively
* // also, overwrite the language-specific default first value (notice the boolean TRUE at the end)
* $obj->add_options(array(
* '' => '- select a value -',
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* ), true);
*
* // multi-option select box with the first two options selected
* $obj = $form->add('select', 'my_select4[]', array('v1', 'v2'), array('multiple' => 'multiple'));
*
* // add selectable values with specific indexes
* // values will be "v1", "v2" and "v3", respectively
* $obj->add_options(array(
* 'v1' => 'Value 1',
* 'v2' => 'Value 2',
* 'v3' => 'Value 3'
* ));
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* <samp>By default, for checkboxes, radio buttons and select boxes, the library will prevent the submission of other
* values than those declared when creating the form, by triggering the error: "SPAM attempt detected!". Therefore,
* if you plan on adding/removing values dynamically, from JavaScript, you will have to call the
* {@link Zebra_Form_Control::disable_spam_filter() disable_spam_filter()} method to prevent that from happening!</samp>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be as specified by the <i>$id</i>
* argument.<br>
* The <b>id</b> attribute will be as specified by the <i>$id</i> argument but with
* square brackets trimmed off (if any).
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable (again, with square brackets trimmed off
* if it's the case) to be used in the template file, containing the generated HTML
* for the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_select", one would use:
* echo $my_select;
* </code>
*
* @param mixed $default (Optional) Default selected option.
*
* This argument can also be an array in case the <b>multiple</b> attribute is set
* and multiple options need to be preselected by default.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#edef-SELECT select}
* controls (multiple, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "multiple" attribute
* $obj = $form->add(
* 'select',
* 'my_select',
* '',
* array(
* 'multiple' => 'multiple'
* )
* );
* </code>
*
* <b>Special attribute:</b>
*
* When setting the special attribute <b>other</b> to <b>true</b>, a
* {@link Zebra_Form_Text textbox} control will be automatically created having the
* name <i>[id]_other</i> where [id] is the select control's <b>id</b> attribute.
* The text box will be hidden until the user selects the automatically added
* <i>Other...</i> option (language dependent) from the selectable options. The
* option's value will be <b>other</b>. If the template is not automatically
* generated you will have to manually add the automatically generated control to
* the template.
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>id</b>, <b>name</b>
*
* @param string $default_other The default value in the "other" field (if the "other" attribute is set to true,
* see above)
*
* @return void
*/
function __construct($id, $default = '', $attributes = '', $default_other = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'default_other',
'disable_spam_filter',
'disable_xss_filters',
'locked',
'options',
'other',
'type',
'value',
);
// set the default attributes for the textarea control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'name' => $id,
'id' => str_replace(array('[', ']'), '', $id),
'class' => 'control',
'options' => array(),
'type' => 'select',
'value' => $default,
'default_other' => $default_other,
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Adds options to the select box control
*
* <b>If the "multiple" attribute is not set, the first option will be always considered as the "nothing is selected"
* state of the control!</b>
*
* @param array $options An associative array of options where the key is the value of the option and the
* value is the actual text to be displayed for the option.
*
* <b>Option groups</b> can be set by giving an array of associative arrays as argument:
*
* <code>
* // add as groups:
* $obj->add_options(array(
* 'group' => array('option 1', 'option 2')
* ));
* </code>
*
* @param boolean $overwrite (Optional) By default, succesive calls of this method will appended the options
* given as arguments to the already existing options.
*
* Setting this argument to TRUE will instead overwrite the previously existing options.
*
* Default is FALSE
*
* @return void
*/
function add_options($options, $overwrite = false)
{
// continue only if parameter is an array
if (is_array($options)) {
// get some properties of the select control
$attributes = $this->get_attributes(array('options', 'multiple'));
// if there are no options so far AND
// we're not overwriting existing options AND
// the "multiple" attribute is not set
if (empty($attributes['options']) && $overwrite === false && !isset($attributes['multiple']))
// add the default value
// we'll replace the value with the appropriate language
$options = array('' => $this->form_properties['language']['select']) + $options;
// set the options attribute of the control
$this->set_attributes(
array(
'options' => ($overwrite ? $options : $attributes['options'] + $options)
)
);
// if options are not specified as an array
} else {
// trigger an error message
_zebra_form_show_error('
Selectable values for the <strong>' . $this->attributes['id'] . '</strong> control must be specified as
an array
');
}
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
// get the options of the select control
$attributes = $this->get_attributes(array('options', 'value', 'multiple', 'other'));
// if select box is not "multi-select" and the "other" attribute is set
if (!isset($attributes['multiple']) && isset($attributes['other']))
// add an extra options to the already existing ones
$attributes['options'] += array('other' => $this->form_properties['language']['other']);
// if the default value, as added when instantiating the object is still there
// or if no options were specified
if (($key = array_search('#replace-with-language#', $attributes['options'])) !== false || empty($attributes['options']))
// put the label from the language file
$attributes['options'][$key] = $this->form_properties['language']['select'];
// use a private, recursive method to generate the select's content
$optContent = $this->_generate($attributes['options'], $attributes['value']);
// return generated HTML
return '<select '. $this->_render_attributes() . '>' . $optContent . '</select>';
}
/**
* Takes the options array and recursively generates options and optiongroups
*
* @return string Resulted HTML code
*
* @access private
*/
private function _generate(&$options, &$selected, $level = 0)
{
$content = '';
// character(s) used for indenting levels
$indent = '&nbsp;&nbsp;';
// iterate through the available options
foreach ($options as $value => $caption) {
// if option has child options
if (is_array($caption)) {
// create a dummy option group (for valid HTML/XHTML we are not allowed to create nested option groups
// and also empty optiongroups are not allowed)
// BUT because in IE7 the "disabled" attribute is not supported and in all versions of IE these
// can't be styled, we will remove them from JavaScript
// having a dummy option in them (the option is disabled and, from CSS, rendered invisible)
$content .= '
<optgroup label="' . str_repeat($indent, $level) . $value . '">
<option disabled="disabled" class="dummy"></option>
</optgroup>
';
// call the method recursively to generate the output for the children options
$content .= $this->_generate($caption, $selected, $level + 1);
// if entry is a standard option
} else {
// create the appropriate code
$content .= '<option value="' . $value . '"' .
// if anything was selected
($selected !== '' && $value !== '' &&
(
// and the current option is selected
(is_array($selected) && in_array($value, $selected)) ||
(!is_array($selected) && (string)$value === (string)$selected)
// set the appropriate attribute
) ? ' selected="selected"' : ''
) . '>' .
// indent appropriately
str_repeat($indent, $level) . $caption . '</option>';
}
}
// return generated content
return $content;
}
}
?>

View File

@@ -0,0 +1,142 @@
<?php
/**
* Class for submit controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Submit extends Zebra_Form_Control
{
/**
* Adds an <input type="submit"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a submit control to the form
* $obj = $form->add('submit', 'my_submit', 'Submit');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_submit", one would use:
* echo $my_submit;
* </code>
*
* @param string $caption Caption of the submit button control.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (size, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "alt" attribute
* $obj = $form->add(
* 'submit',
* 'my_submit',
* 'Submit',
* array(
* 'alt' => 'Click to submit values'
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
* <b>type</b>, <b>id</b>, <b>name</b>, <b>value</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $caption, $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
);
// set the default attributes for the submit button control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'submit',
'name' => $id,
'id' => $id,
'value' => $caption,
'class' => 'submit',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

View File

@@ -0,0 +1,181 @@
<?php
/**
* Class for text controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Text extends Zebra_Form_Control
{
/**
* Adds an <input type="text"> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a text control to the form
* $obj = $form->add('text', 'my_text');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_text", one would use:
* echo $my_text;
* </code>
*
* @param string $default (Optional) Default value of the text box.
*
* @param array $attributes (Optional) An array of attributes valid for
* {@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4 input}
* controls (size, readonly, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "readonly" attribute
* $obj = $form->add(
* 'text',
* 'my_text',
* '',
* array(
* 'readonly' => 'readonly'
* )
* );
* </code>
*
* There's a special <b>data-prefix</b> attribute that you can use to add <i>uneditable
* prefixes</i> to input fields (text, images, or plain HTML), as seen in the image
* below. It works by injecting an absolutely positioned element into the DOM, right
* after the parent element, and then positioning it on the left side of the parent
* element and adjusting the width and the left padding of the parent element, so it
* looks like the prefix is part of the parent element.
*
* <i>If the prefix is plain text or HTML code, it will be contained in a <div> tag
* having the class </i> <b>Zebra_Form_Input_Prefix</b><i>; if the prefix is a path to an
* image, it will be an <img> tag having the class </i> <b>Zebra_Form_Input_Prefix</b><i>.</i>
*
* <samp>For anything other than plain text, you must use CSS to set the width and
* height of the prefix, or it will not be correctly positioned because when the image
* is not cached by the browser the code taking care of centering the image will
* be executed before the image is loaded by the browser and it will not know the
* image's width and height!</samp>
*
* {@img src=../media/zebra-form-prefix.jpg class=graphic}
*
* <code>
* // add simple text
* // style the text through the Zebra_Form_Input_Prefix class
* $form->add('text', 'my_text', '', array('data-prefix' => 'http://'));
* $form->add('text', 'my_text', '', array('data-prefix' => '(+1 917)'));
*
* // add images
* // set the image's width and height through the img.Zebra_Form_Input_Prefix class
* // in your CSS or the image will not be correctly positioned!
* $form->add('text', 'my_text', '', array('data-prefix' => 'img:path/to/image'));
*
* // add html - useful when using sprites
* // again, make sure that you set somewhere the width and height of the prefix!
* $form->add('text', 'my_text', '', array('data-prefix' => '<div class="sprite image1"></div>'));
* $form->add('text', 'my_text', '', array('data-prefix' => '<div class="sprite image2"></div>'));
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>type</b>, <b>id</b>, <b>name</b>, <b>value</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $default = '', $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'default_value',
'locked',
);
// set the default attributes for the text control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'text',
'name' => $id,
'id' => $id,
'value' => $default,
'class' => 'control text',
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
return '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>';
}
}
?>

View File

@@ -0,0 +1,151 @@
<?php
/**
* Class for textarea controls
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Textarea extends Zebra_Form_Control
{
/**
* Adds an <textarea> control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a textarea control to the form
* $obj = $form->add('textarea', 'my_textarea');
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
* // put code here
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_textarea", one would use:
* echo $my_textarea;
* </code>
*
* @param string $default (Optional) Default value of the textarea.
*
* @param array $attributes (Optional) An array of attributes valid for
* <b>{@link http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.7 textarea}</b>
* controls (rows, cols, style, etc)
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
* <code>
* // setting the "rows" attribute
* $obj = $form->add(
* 'textarea',
* 'my_textarea',
* '',
* array(
* 'rows' => 10
* )
* );
* </code>
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* The following attributes are automatically set when the control is created and
* should not be altered manually:<br>
*
* <b>id</b>, <b>name</b>, <b>class</b>
*
* @return void
*/
function __construct($id, $default = '', $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'default_value',
'disable_xss_filters',
'locked',
'type',
'value',
);
// set the default attributes for the textarea control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'name' => $id,
'id' => $id,
'rows' => 5,
'cols' => '80', // used only for passing W3C validation
'class' => 'control',
'type' => 'textarea',
'value' => $default,
)
);
// if "class" is amongst user specified attributes
if (is_array($attributes) && isset($attributes['class'])) {
// we need to set the "class" attribute like this, so it doesn't overwrite previous values
$this->set_attributes(array('class' => $attributes['class']), false);
// make sure we don't set it again below
unset($attributes['class']);
}
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
// get private attributes
$attributes = $this->get_attributes('value');
return '<textarea ' . $this->_render_attributes() . '>' . (isset($attributes['value']) ? $attributes['value'] : '') . '</textarea>';
}
}
?>

View File

@@ -0,0 +1,292 @@
<?php
/**
* Class for time picker controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Time extends Zebra_Form_Control
{
/**
* Adds a time picker control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* The output of this control will be one, two, three or four {@link Zebra_Form_Select select} controls for hour,
* minutes, seconds and AM/PM respectively, according to the given format as set by the <i>$attributes</i> argument.
*
* Note that even though there will be more select boxes, the submitted values will be available as a single merged
* value (in the form of hh:mm:ss AM/PM, depending on the format), with the name as given by the <i>id</i> argument.
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a time picker control for hour and minutes
* $obj = $form->add('time', 'my_time', date('H:i'), array('format' => 'hm'));
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
*
* // note that even though there will be more select boxes, the submitted
* // values will be available as a single merged value (in the form of
* // mm:mm:ss AM/PM, depending on the format), with the name as given by
* // the "id" argument:
* echo $_POST['my_time'];
*
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_time", one would use:
* echo $my_time;
* </code>
*
* @param string $default (Optional) String representing the default time to be shown. Must be set according
* to the format of the time, as specified in <i>$attributes</i>. For example, for a
* time format of "hm", one would set the default time in the form of "hh:mm" while
* for a time format of "hms", one would set the time in the form of "hh:mm:ss".
*
* Default is current system time.
*
* @param array $attributes (Optional) An array of user specified attributes valid for an time picker
* control (format, hours, minutes, seconds, am/pm).
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
*
* Available attributes are:
*
* - format - format of time; a string containing one, or a combination of the four
* allowed characters: "h" (hours), "m" (minutes) and "s" (seconds) and "g" for
* using 12-hours format instead of the default 23-hours format; (i.e. setting the
* format to "hm" would allow the selection of hours and minutes, setting the
* format to "hms" would allow the selection of hours, minutes and seconds, and
* setting the format to "hmg" would allow the selection of hours and minutes
* using the 12-hours format instead of the 24-hours format)
*
* - hours - an array of selectable hours (i.e. array(10, 11, 12))
*
* - minutes - an array of selectable minutes (i.e. array(15, 30, 45))
*
* - seconds - an array of selectable seconds
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* @return void
*/
function __construct($id, $default = '', $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// these will hold the default selectable hours, minutes and seconds
$hours = $minutes = $seconds = array();
// all the 24 hours are available by default
for ($i = 0; $i < 24; $i++) $hours[] = $i;
// all the minutes and seconds are available by default
for ($i = 0; $i < 60; $i++) $minutes[] = $seconds[] = $i;
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
'type',
'name',
'id',
'format',
'hours',
'minutes',
'seconds',
'value',
);
// set the default attributes for the text control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'time',
'name' => $id,
'id' => $id,
'value' => $default,
'class' => 'control time',
'format' => 'hm',
'hours' => $hours,
'minutes' => $minutes,
'seconds' => $seconds,
)
);
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates and returns the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
// get some attributes of the control
$attributes = $this->get_attributes(array('name', 'value', 'class', 'format', 'hours', 'minutes', 'seconds'));
// make sure format is in lower characters
$attributes['format'] = strtolower($attributes['format']);
// if invalid format specified, revert to the default "hm"
if (preg_match('/^[hmsg]+$/i', $attributes['format']) == 0 || strlen(preg_replace('/([a-z]{2,})/i', '$1', $attributes['format'])) != strlen($attributes['format'])) $attributes['format'] = 'hm';
// see what have we sepcified as default time
$time = array_diff(explode(':', trim(str_replace(array('am', 'pm'), '', strtolower($attributes['value'])))), array(''));
// if, according to the time format, we have to show the hours, and the hour is given in the default time
if (($hour_position = strpos($attributes['format'], 'h')) !== false && isset($time[$hour_position]))
// the default selected hour
$selected_hour = $time[$hour_position];
// if, according to the time format, we have to show the minutes, and the minutes are given in the default time
if (($minutes_position = strpos($attributes['format'], 'm')) !== false && isset($time[$minutes_position]))
// the default selected minute
$selected_minute = $time[$minutes_position];
// if, according to the time format, we have to show the seconds, and the seconds are given in the default time
if (($seconds_position = strpos($attributes['format'], 's')) !== false && isset($time[$seconds_position]))
// the default selected minute
$selected_second = $time[$seconds_position];
// if 12-hours format is to be used
if (strpos($attributes['format'], 'g')) {
// set a flag
$ampm = true;
// if this is also present in the default time
if (preg_match('/\bam\b|\bpm\b/i', $attributes['value'], $matches))
// extract the format from the default time
$ampm = strtolower($matches[0]);
}
$output = '';
// if the hour picker is to be shown
if ($hour_position !== false) {
// generate the hour picker
$output .= '
<select name="' . $attributes['name'] . '_hours" id="' . $attributes['name'] . '_hours" ' . $this->_render_attributes() . '>
<option value="">-</option>';
foreach ($attributes['hours'] as $hour)
// show 12 or 24 hours depending on the format
if (!isset($ampm) || ($hour > 0 && $hour < 13))
$output .= '<option value="' . str_pad($hour, 2, '0', STR_PAD_LEFT) . '"' . (isset($selected_hour) && ltrim($selected_hour, '0') == ltrim($hour, '0') ? ' selected="selected"' : '') . '>' . str_pad($hour, 2, '0', STR_PAD_LEFT) . '</option>';
$output .= '
</select>
';
}
// if the minute picker is to be shown
if ($minutes_position !== false) {
// generate the minute picker
$output .= '
<select name="' . $attributes['name'] . '_minutes" id="' . $attributes['name'] . '_minutes" ' . $this->_render_attributes() . '>
<option value="">-</option>';
foreach ($attributes['minutes'] as $minute)
$output .= '<option value="' . str_pad($minute, 2, '0', STR_PAD_LEFT) . '"' . (isset($selected_minute) && ltrim($selected_minute, '0') == ltrim($minute, '0') ? ' selected="selected"' : '') . '>' . str_pad($minute, 2, '0', STR_PAD_LEFT) . '</option>';
$output .= '
</select>
';
}
// if the seconds picker is to be shown
if ($seconds_position !== false) {
// generate the seconds picker
$output .= '
<select name="' . $attributes['name'] . '_seconds" id="' . $attributes['name'] . '_seconds" ' . $this->_render_attributes() . '>
<option value="">-</option>';
foreach ($attributes['seconds'] as $second)
$output .= '<option value="' . str_pad($second, 2, '0', STR_PAD_LEFT) . '"' . (isset($selected_second) && ltrim($selected_second, '0') == ltrim($second, '0') ? ' selected="selected"' : '') . '>' . str_pad($second, 2, '0', STR_PAD_LEFT) . '</option>';
$output .= '
</select>
';
}
// if am/pm picker is to be shown
if (isset($ampm)) {
// generate the AM/PM picker
$output .= '
<select name="' . $attributes['name'] . '_ampm" id="' . $attributes['name'] . '_ampm" ' . $this->_render_attributes() . '>
<option value="">-</option>';
$output .= '<option value="AM"' . ($ampm === 'am' ? ' selected="selected"' : '') . '>AM</option>';
$output .= '<option value="PM"' . ($ampm === 'pm' ? ' selected="selected"' : '') . '>PM</option>';
$output .= '
</select>
';
}
$output .= '<div class="clear"></div>';
return $output;
}
}
?>

View File

@@ -0,0 +1,605 @@
<?php
/**
* Sanitizes data so that Cross Site Scripting Hacks can be prevented.
*
* @package XSS_Clean
* @author EllisLab Dev Team
* @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
*/
class XSS_Clean
{
/**
* Random Hash for protecting URLs
*
* @var string
*
* @access private
*/
var $_xss_hash = '';
/**
* List of never allowed strings
*
* @var array
*
* @access private
*/
var $_never_allowed_str = array(
'document.cookie' => '[removed]',
'document.write' => '[removed]',
'.parentNode' => '[removed]',
'.innerHTML' => '[removed]',
'window.location' => '[removed]',
'-moz-binding' => '[removed]',
'<!--' => '&lt;!--',
'-->' => '--&gt;',
'<![CDATA[' => '&lt;![CDATA[',
'<comment>' => '&lt;comment&gt;'
);
/**
* List of never allowed regex replacement
*
* @var array
*
* @access private
*/
var $_never_allowed_regex = array(
'javascript\s*:',
'expression\s*(\(|&\#40;)', // CSS and IE
'vbscript\s*:', // IE, surprise!
'Redirect\s+302',
"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
);
/**
* Sanitizes submitted data so that Cross Site Scripting Hacks can be prevented.
*
* This class is taken from the {@link http://codeigniter.com/ CodeIgniter PHP Framework},
* version 2.1.2.
*
* <i>This method is automatically run for each control when calling {@link Zebra_Form::validate() validate()}, unless
* specifically disabled by {@link Zebra_Form_Control::disable_xss_filters() disable_xss_filters()})!</i>
*
* <b>Following is the original documentation of the class, as found in CodeIgniter:</b>
*
* Sanitizes data so that Cross Site Scripting Hacks can be prevented. This function does a fair amount of work but
* it is extremely thorough, designed to prevent even the most obscure XSS attempts. Nothing is ever 100% foolproof,
* of course, but I haven't been able to get anything passed the filter.
*
* Note: This function should only be used to deal with data upon submission. It's not something that should be used
* for general runtime processing.
*
* This function was based in part on some code and ideas I got from Bitflux:
* {@link http://blog.bitflux.ch/wiki/XSS_Prevention}
*
* To help develop this script I used this great list of vulnerabilities along with a few other hacks I've
* harvested from examining vulnerabilities in other programs: {@link http://ha.ckers.org/xss.html}
*
* @param string $str String to be filtered
*
* @return string Returns filtered string
*/
function sanitize($str, $rawurldecode = true)
{
// Remove Invisible Characters
$str = $this->_remove_invisible_characters($str);
/*
* URL Decode
*
* Just in case stuff like this is submitted:
*
* <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
*
* Note: Use rawurldecode() so it does not remove plus signs
*/
if ($rawurldecode) $str = rawurldecode($str);
/*
* Convert character entities to ASCII
*
* This permits our tests below to work reliably.
* We only convert entities that are within tags since
* these are the ones that will pose security problems.
*/
$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
$str = preg_replace_callback('/<\w+.*?(?=>|<|$)/si', array($this, '_decode_entity'), $str);
// Remove Invisible Characters Again!
$str = $this->_remove_invisible_characters($str);
/*
* Convert all tabs to spaces
*
* This prevents strings like this: ja vascript
* NOTE: we deal with spaces between characters later.
* NOTE: preg_replace was found to be amazingly slow here on
* large blocks of data, so we use str_replace.
*/
$str = str_replace("\t", ' ', $str);
// Capture converted string for later comparison
$converted_string = $str;
// Remove Strings that are never allowed
$str = $this->_do_never_allowed($str);
/*
* Makes PHP tags safe
*
* Note: XML tags are inadvertently replaced too:
*
* <?xml
*
* But it doesn't seem to pose a problem.
*/
$str = str_replace(array('<?', '?'.'>'), array('&lt;?', '?&gt;'), $str);
/*
* Compact any exploded words
*
* This corrects words like: j a v a s c r i p t
* These words are compacted back to their correct state.
*/
$words = array(
'javascript', 'expression', 'vbscript', 'script', 'base64',
'applet', 'alert', 'document', 'write', 'cookie', 'window'
);
foreach ($words as $word)
{
$word = implode('\s*', str_split($word)).'\s*';
// We only want to do this when it is followed by a non-word character
// That way valid stuff like "dealer to" does not become "dealerto"
$str = preg_replace_callback('#('.substr($word, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
}
/*
* Remove disallowed Javascript in links or img tags
* We used to do some version comparisons and use of stripos for PHP5,
* but it is dog slow compared to these simplified non-capturing
* preg_match(), especially if the pattern exists in the string
*/
do
{
$original = $str;
if (preg_match('/<a/i', $str))
{
$str = preg_replace_callback('#<a\s+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str);
}
if (preg_match('/<img/i', $str))
{
$str = preg_replace_callback('#<img\s+([^>]*?)(?:\s?/?\>|$)#si', array($this, '_js_img_removal'), $str);
}
if (preg_match('/script|xss/i', $str))
{
$str = preg_replace('#</*(?:script|xss).*?\>#si', '[removed]', $str);
}
}
while ($original !== $str);
unset($original);
// Remove evil attributes such as style, onclick and xmlns
$str = $this->_remove_evil_attributes($str, false);
/*
* Sanitize naughty HTML elements
*
* If a tag containing any of the words in the list
* below is found, the tag gets converted to entities.
*
* So this: <blink>
* Becomes: &lt;blink&gt;
*/
$naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
/*
* Sanitize naughty scripting elements
*
* Similar to above, only instead of looking for
* tags it looks for PHP and JavaScript commands
* that are disallowed. Rather than removing the
* code, it simply converts the parenthesis to entities
* rendering the code un-executable.
*
* For example: eval('some code')
* Becomes: eval&#40;'some code'&#41;
*/
$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',
'\\1\\2&#40;\\3&#41;',
$str);
// Final clean up
// This adds a bit of extra precaution in case
// something got through the above filters
$str = $this->_do_never_allowed($str);
return $str;
}
// --------------------------------------------------------------------
/**
* Random Hash for protecting URLs
*
* @return string
*
* @access private
*/
function xss_hash()
{
if ($this->_xss_hash === '')
{
mt_srand();
$this->_xss_hash = md5(time() + mt_rand(0, 1999999999));
}
return $this->_xss_hash;
}
// --------------------------------------------------------------------
/**
* HTML Entities Decode
*
* This function is a replacement for html_entity_decode()
*
* The reason we are not using html_entity_decode() by itself is because
* while it is not technically correct to leave out the semicolon
* at the end of an entity most browsers will still interpret the entity
* correctly. html_entity_decode() does not convert entities without
* semicolons, so we are left with our own little solution here. Bummer.
*
* @param string
* @param string
* @return string
*
* @access private
*/
function entity_decode($str, $charset = NULL)
{
if (strpos($str, '&') === FALSE)
{
return $str;
}
if (empty($charset))
{
$charset = 'UTF-8';
}
$str = html_entity_decode($str, ENT_COMPAT, $charset);
$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
}
// ----------------------------------------------------------------
/**
* Compact Exploded Words
*
* Callback function for xss_clean() to remove whitespace from
* things like j a v a s c r i p t
*
* @param array
* @return string
*
* @access private
*/
function _compact_exploded_words($matches)
{
return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
}
// --------------------------------------------------------------------
/**
* Remove Evil HTML Attributes (like event handlers and style)
*
* It removes the evil attribute and either:
* - Everything up until a space
* For example, everything between the pipes:
* <a |style=document.write('hello');alert('world');| class=link>
* - Everything inside the quotes
* For example, everything between the pipes:
* <a |style="document.write('hello'); alert('world');"| class="link">
*
* @param string $str The string to check
* @param boolean $is_image TRUE if this is an image
* @return string The string with the evil attributes removed
*
* @access private
*/
function _remove_evil_attributes($str, $is_image)
{
// All javascript event handlers (e.g. onload, onclick, onmouseover), style, and xmlns
$evil_attributes = array('on\w*', 'style', 'xmlns', 'formaction');
if ($is_image === TRUE)
{
/*
* Adobe Photoshop puts XML metadata into JFIF images,
* including namespacing, so we have to allow this for images.
*/
unset($evil_attributes[array_search('xmlns', $evil_attributes)]);
}
do {
$count = 0;
$attribs = array();
// find occurrences of illegal attribute strings without quotes
preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
foreach ($matches as $attr)
{
$attribs[] = preg_quote($attr[0], '/');
}
// find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)
preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is', $str, $matches, PREG_SET_ORDER);
foreach ($matches as $attr)
{
$attribs[] = preg_quote($attr[0], '/');
}
// replace illegal attribute strings that are inside an html tag
if (count($attribs) > 0)
{
$str = preg_replace('/<(\/?[^><]+?)([^A-Za-z<>\-])(.*?)('.implode('|', $attribs).')(.*?)([\s><])([><]*)/i', '<$1 $3$5$6$7', $str, -1, $count);
}
} while ($count);
return $str;
}
// --------------------------------------------------------------------
/**
* Sanitize Naughty HTML
*
* Callback function for xss_clean() to remove naughty HTML elements
*
* @param array
* @return string
*
* @access private
*/
function _sanitize_naughty_html($matches)
{
return '&lt;'.$matches[1].$matches[2].$matches[3] // encode opening brace
// encode captured opening or closing brace to prevent recursive vectors:
.str_replace(array('>', '<'), array('&gt;', '&lt;'), $matches[4]);
}
// --------------------------------------------------------------------
/**
* JS Link Removal
*
* Callback function for xss_clean() to sanitize links
* This limits the PCRE backtracks, making it more performance friendly
* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
* PHP 5.2+ on link-heavy strings
*
* @param array
* @return string
*
* @access private
*/
function _js_link_removal($match)
{
return str_replace($match[1],
preg_replace('#href=.*?(?:alert\(|alert&\#40;|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
'',
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
),
$match[0]);
}
// --------------------------------------------------------------------
/**
* JS Image Removal
*
* Callback function for xss_clean() to sanitize image tags
* This limits the PCRE backtracks, making it more performance friendly
* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
* PHP 5.2+ on image tag heavy strings
*
* @param array
* @return string
*
* @access private
*/
function _js_img_removal($match)
{
return str_replace($match[1],
preg_replace('#src=.*?(?:alert\(|alert&\#40;|javascript:|livescript:|mocha:|charset=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
'',
$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
),
$match[0]);
}
// --------------------------------------------------------------------
/**
* Attribute Conversion
*
* Used as a callback for XSS Clean
*
* @param array
* @return string
*
* @access private
*/
function _convert_attribute($match)
{
return str_replace(array('>', '<', '\\'), array('&gt;', '&lt;', '\\\\'), $match[0]);
}
// --------------------------------------------------------------------
/**
* Filter Attributes
*
* Filters tag attributes for consistency and safety
*
* @param string
* @return string
*
* @access private
*/
function _filter_attributes($str)
{
$out = '';
if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))
{
foreach ($matches[0] as $match)
{
$out .= preg_replace('#/\*.*?\*/#s', '', $match);
}
}
return $out;
}
// --------------------------------------------------------------------
/**
* HTML Entity Decode Callback
*
* Used as a callback for XSS Clean
*
* @param array
* @return string
*
* @access private
*/
function _decode_entity($match)
{
return $this->entity_decode($match[0], strtoupper('UTF-8'));
}
// --------------------------------------------------------------------
/**
* Validate URL entities
*
* Called by xss_clean()
*
* @param string
* @return string
*
* @access private
*/
function _validate_entities($str)
{
/*
* Protect GET variables in URLs
*/
// 901119URL5918AMP18930PROTECT8198
$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash().'\\1=\\2', $str);
/*
* Validate standard character entities
*
* Add a semicolon if missing. We do this to enable
* the conversion of entities to ASCII later.
*/
$str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', '\\1;\\2', $str);
/*
* Validate UTF16 two byte encoding (x00)
*
* Just as above, adds a semicolon if missing.
*/
$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i', '\\1\\2;', $str);
/*
* Un-Protect GET variables in URLs
*/
return str_replace($this->xss_hash(), '&', $str);
}
// ----------------------------------------------------------------------
/**
* Do Never Allowed
*
* A utility function for xss_clean()
*
* @param string
* @return string
*
* @access private
*/
function _do_never_allowed($str)
{
$str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str);
foreach ($this->_never_allowed_regex as $regex)
{
$str = preg_replace('#'.$regex.'#is', '[removed]', $str);
}
return $str;
}
/**
* Remove Invisible Characters
*
* This prevents sandwiching null characters
* between ascii characters, like Java\0script.
*
* @access private
* @param string
* @return string
*/
function _remove_invisible_characters($str)
{
static $non_displayables;
if ( ! isset($non_displayables))
{
// every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09),
$non_displayables = array(
'/%0[0-8bcef]/', // url encoded 00-08, 11, 12, 14, 15
'/%1[0-9a-f]/', // url encoded 16-31
'/[\x00-\x08]/', // 00-08
'/\x0b/', '/\x0c/', // 11, 12
'/[\x0e-\x1f]/' // 14-31
);
}
do
{
$cleaned = $str;
$str = preg_replace($non_displayables, '', $str);
}
while ($cleaned != $str);
return $str;
}
}
?>

Binary file not shown.

View File

@@ -0,0 +1,8 @@
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>