mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Añadida la libreria datatables editor a third party
This commit is contained in:
961
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Field.php.txt
vendored
Normal file
961
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Field.php.txt
vendored
Normal file
@ -0,0 +1,961 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2012 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
use
|
||||
DataTables,
|
||||
DataTables\Editor,
|
||||
DataTables\Editor\Options,
|
||||
DataTables\Editor\Join;
|
||||
use DataTables\HtmLawed\Htmlaw;
|
||||
|
||||
|
||||
/**
|
||||
* Field definitions for the DataTables Editor.
|
||||
*
|
||||
* Each Database column that is used with Editor can be described with this
|
||||
* Field method (both for Editor and Join instances). It basically tells
|
||||
* Editor what table column to use, how to format the data and if you want
|
||||
* to read and/or write this column.
|
||||
*
|
||||
* Field instances are used with the {@see Editor->field()} and
|
||||
* {@see Join->field()} methods to describe what fields should be interacted
|
||||
* with by the editable table.
|
||||
*
|
||||
* @example
|
||||
* Simply get a column with the name "city". No validation is performed.
|
||||
* ```php
|
||||
* Field::inst( 'city' )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Get a column with the name "first_name" - when edited a value must
|
||||
* be given due to the "required" validation from the {@see Validate} class.
|
||||
* ```php
|
||||
* Field::inst( 'first_name' )->validator( 'Validate::required' )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Working with a date field, which is validated, and also has *get* and
|
||||
* *set* formatters.
|
||||
* ```php
|
||||
* Field::inst( 'registered_date' )
|
||||
* ->validator( 'Validate::dateFormat', 'D, d M y' )
|
||||
* ->getFormatter( 'Format::date_sql_to_format', 'D, d M y' )
|
||||
* ->setFormatter( 'Format::date_format_to_sql', 'D, d M y' )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Using an alias in the first parameter
|
||||
* ```php
|
||||
* Field::inst( 'name.first as first_name' )
|
||||
* ```
|
||||
*/
|
||||
class Field extends DataTables\Ext {
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Statics
|
||||
*/
|
||||
|
||||
/** Set option flag (`set()`) - do not set data */
|
||||
const SET_NONE = 'none';
|
||||
|
||||
/** Set option flag (`set()`) - write to database on both create and edit */
|
||||
const SET_BOTH = 'both';
|
||||
|
||||
/** Set option flag (`set()`) - write to database only on create */
|
||||
const SET_CREATE = 'create';
|
||||
|
||||
/** Set option flag (`set()`) - write to database only on edit */
|
||||
const SET_EDIT = 'edit';
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Field instance constructor.
|
||||
* @param string $dbField Name of the database column
|
||||
* @param string $name Name to use in the JSON output from Editor and the
|
||||
* HTTP submit from the client-side when editing. If not given then the
|
||||
* $dbField name is used.
|
||||
*/
|
||||
function __construct( $dbField=null, $name=null )
|
||||
{
|
||||
if ( $dbField !== null && $name === null ) {
|
||||
// Allow just a single parameter to be passed - each can be
|
||||
// overridden if needed later using the API.
|
||||
$this->name( $dbField );
|
||||
$this->dbField( $dbField );
|
||||
}
|
||||
else {
|
||||
$this->name( $name );
|
||||
$this->dbField( $dbField );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private parameters
|
||||
*/
|
||||
|
||||
/** @var string */
|
||||
private $_dbField = null;
|
||||
|
||||
/** @var boolean */
|
||||
private $_get = true;
|
||||
|
||||
/** @var mixed */
|
||||
private $_getFormatter = null;
|
||||
|
||||
/** @var mixed */
|
||||
private $_getFormatterOpts = null;
|
||||
|
||||
/** @var mixed */
|
||||
private $_getValue = null;
|
||||
|
||||
/** @var Options */
|
||||
private $_opts = null;
|
||||
|
||||
/** @var SearchPaneOptions */
|
||||
private $_spopts = null;
|
||||
|
||||
/** @var SearchBuilderOptions */
|
||||
private $_sbopts = null;
|
||||
|
||||
/** @var callable */
|
||||
private $_optsFn = null;
|
||||
|
||||
/** @var callable */
|
||||
private $_spoptsFn = null;
|
||||
|
||||
/** @var callable */
|
||||
private $_sboptsFn = null;
|
||||
|
||||
/** @var string */
|
||||
private $_name = null;
|
||||
|
||||
/** @var string */
|
||||
private $_set = Field::SET_BOTH;
|
||||
|
||||
/** @var mixed */
|
||||
private $_setFormatter = null;
|
||||
|
||||
/** @var mixed */
|
||||
private $_setFormatterOpts = null;
|
||||
|
||||
/** @var mixed */
|
||||
private $_setValue = null;
|
||||
|
||||
/** @var mixed */
|
||||
private $_validator = array();
|
||||
|
||||
/** @var Upload */
|
||||
private $_upload = null;
|
||||
|
||||
/** @var callable */
|
||||
private $_xss = null;
|
||||
|
||||
/** @var boolean */
|
||||
private $_xssFormat = true;
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Get / set the DB field name.
|
||||
*
|
||||
* Note that when used as a setter, an alias can be given for the field
|
||||
* using the SQL `as` keyword - for example: `firstName as name`. In this
|
||||
* situation the dbField is set to the field name before the `as`, and the
|
||||
* field's name (`name()`) is set to the name after the ` as `.
|
||||
*
|
||||
* As a result of this, the following constructs have identical
|
||||
* functionality:
|
||||
*
|
||||
* Field::inst( 'firstName as name' );
|
||||
* Field::inst( 'firstName', 'name' );
|
||||
*
|
||||
* @param string $_ Value to set if using as a setter.
|
||||
* @return string|self The name of the db field if no parameter is given,
|
||||
* or self if used as a setter.
|
||||
*/
|
||||
public function dbField ( $_=null )
|
||||
{
|
||||
if ( $_ === null ) {
|
||||
return $this->_dbField;
|
||||
}
|
||||
|
||||
// Don't split on an `as` inside paraenthesis
|
||||
$a = preg_split( '/ as (?![^\(]*\))/i', $_ );
|
||||
if ( count($a) > 1 ) {
|
||||
$this->_dbField = trim( $a[0] );
|
||||
$this->_name = trim( $a[1] );
|
||||
}
|
||||
else {
|
||||
$this->_dbField = $_;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get / set the 'get' property of the field.
|
||||
*
|
||||
* A field can be marked as write only when setting the get property to false
|
||||
* here.
|
||||
* @param boolean $_ Value to set if using as a setter.
|
||||
* @return boolean|self The get property if no parameter is given, or self
|
||||
* if used as a setter.
|
||||
*/
|
||||
public function get ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_get, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get formatter for the field's data.
|
||||
*
|
||||
* When the data has been retrieved from the server, it can be passed through
|
||||
* a formatter here, which will manipulate (format) the data as required. This
|
||||
* can be useful when, for example, working with dates and a particular format
|
||||
* is required on the client-side.
|
||||
*
|
||||
* Editor has a number of formatters available with the {@see Format} class
|
||||
* which can be used directly with this method.
|
||||
* @param callable|string $_ Value to set if using as a setter. Can be given as
|
||||
* a closure function or a string with a reference to a function that will
|
||||
* be called with call_user_func().
|
||||
* @param mixed $opts Variable that is passed through to the get formatting
|
||||
* function - can be useful for passing through extra information such as
|
||||
* date formatting string, or a required flag. The actual options available
|
||||
* depend upon the formatter used.
|
||||
* @return callable|string|self The get formatter if no parameter is given, or
|
||||
* self if used as a setter.
|
||||
*/
|
||||
public function getFormatter ( $_=null, $opts=null )
|
||||
{
|
||||
if ( $opts !== null ) {
|
||||
$this->_getFormatterOpts = $opts;
|
||||
}
|
||||
return $this->_getSet( $this->_getFormatter, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get / set a get value. If given, then this value is used to send to the
|
||||
* client-side, regardless of what value is held by the database.
|
||||
*
|
||||
* @param callable|string|number $_ Value to set, or no value to use as a
|
||||
* getter
|
||||
* @return callable|string|self Value if used as a getter, or self if used
|
||||
* as a setter.
|
||||
*/
|
||||
public function getValue ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_getValue, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get / set the 'name' property of the field.
|
||||
*
|
||||
* The name is typically the same as the dbField name, since it makes things
|
||||
* less confusing(!), but it is possible to set a different name for the data
|
||||
* which is used in the JSON returned to DataTables in a 'get' operation and
|
||||
* the field name used in a 'set' operation.
|
||||
* @param string $_ Value to set if using as a setter.
|
||||
* @return string|self The name property if no parameter is given, or self
|
||||
* if used as a setter.
|
||||
*/
|
||||
public function name ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_name, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of values that can be used for the options list in radio,
|
||||
* select and checkbox inputs from the database for this field.
|
||||
*
|
||||
* Note that this is for simple 'label / value' pairs only. For more complex
|
||||
* data, including pairs that require joins and where conditions, use a
|
||||
* closure to provide a query
|
||||
*
|
||||
* @param string|callable $table Database table name to use to get the
|
||||
* paired data from, or a closure function if providing a method
|
||||
* @param string $value Table column name that contains the pair's
|
||||
* value. Not used if the first parameter is given as a closure
|
||||
* @param string $label Table column name that contains the pair's
|
||||
* label. Not used if the first parameter is given as a closure
|
||||
* @param callable $condition Function that will add `where`
|
||||
* conditions to the query
|
||||
* @param callable $format Function will render each label
|
||||
* @param string $order SQL ordering
|
||||
* @return Field Self for chaining
|
||||
*/
|
||||
public function options ( $table=null, $value=null, $label=null, $condition=null, $format=null, $order=null )
|
||||
{
|
||||
if ( $table === null ) {
|
||||
return $this->_opts;
|
||||
}
|
||||
|
||||
// Overloads for backwards compatibility
|
||||
if ( is_a( $table, '\DataTables\Editor\Options' ) ) {
|
||||
// Options class
|
||||
$this->_optsFn = null;
|
||||
$this->_opts = $table;
|
||||
}
|
||||
else if ( is_callable($table) && is_object($table) ) {
|
||||
// Function
|
||||
$this->_opts = null;
|
||||
$this->_optsFn = $table;
|
||||
}
|
||||
else {
|
||||
$this->_optsFn = null;
|
||||
$this->_opts = Options::inst()
|
||||
->table( $table )
|
||||
->value( $value )
|
||||
->label( $label );
|
||||
|
||||
if ( $condition ) {
|
||||
$this->_opts->where( $condition );
|
||||
}
|
||||
|
||||
if ( $format ) {
|
||||
$this->_opts->render( $format );
|
||||
}
|
||||
|
||||
if ( $order ) {
|
||||
$this->_opts->order( $order );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of values that can be used for the options list in SearchPanes
|
||||
*
|
||||
* @param SearchPaneOptions|callable $spInput SearchPaneOptions instance or a closure function if providing a method
|
||||
* @return self
|
||||
*/
|
||||
public function searchPaneOptions ( $spInput=null )
|
||||
{
|
||||
if ( $spInput === null ) {
|
||||
return $this->_spopts;
|
||||
}
|
||||
|
||||
// Overloads for backwards compatibility
|
||||
if ( is_a( $spInput, '\DataTables\Editor\SearchPaneOptions' ) ) {
|
||||
// Options class
|
||||
$this->_spoptsFn = null;
|
||||
$this->_spopts = $spInput;
|
||||
}
|
||||
else if ( is_callable($spInput) && is_object($spInput) ) {
|
||||
// Function
|
||||
$this->_spopts = null;
|
||||
$this->_spoptsFn = $spInput;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of values that can be used for the options list in SearchBuilder
|
||||
*
|
||||
* @param SearchBuilderOptions|callable $sbInput SearchBuilderOptions instance or a closure function if providing a method
|
||||
* @return self
|
||||
*/
|
||||
public function searchBuilderOptions ( $sbInput=null )
|
||||
{
|
||||
if ( $sbInput === null ) {
|
||||
return $this->_sbopts;
|
||||
}
|
||||
|
||||
// Overloads for backwards compatibility
|
||||
if ( is_a( $sbInput, '\DataTables\Editor\SearchBuilderOptions' ) ) {
|
||||
// Options class
|
||||
$this->_sboptsFn = null;
|
||||
$this->_sbopts = $sbInput;
|
||||
}
|
||||
else if ( is_callable($sbInput) && is_object($sbInput) ) {
|
||||
// Function
|
||||
$this->_sbopts = null;
|
||||
$this->_sboptsFn = $sbInput;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get / set the 'set' property of the field.
|
||||
*
|
||||
* A field can be marked as read only using this option, to be set only
|
||||
* during an create or edit action or to be set during both actions. This
|
||||
* provides the ability to have fields that are only set when a new row is
|
||||
* created (for example a "created" time stamp).
|
||||
* @param string|boolean $_ Value to set when the method is being used as a
|
||||
* setter (leave as undefined to use as a getter). This can take the
|
||||
* value of:
|
||||
*
|
||||
* * `true` - Same as `Field::SET_BOTH`
|
||||
* * `false` - Same as `Field::SET_NONE`
|
||||
* * `Field::SET_BOTH` - Set the database value on both create and edit commands
|
||||
* * `Field::SET_NONE` - Never set the database value
|
||||
* * `Field::SET_CREATE` - Set the database value only on create
|
||||
* * `Field::SET_EDIT` - Set the database value only on edit
|
||||
* @return string|self The set property if no parameter is given, or self
|
||||
* if used as a setter.
|
||||
*/
|
||||
public function set ( $_=null )
|
||||
{
|
||||
if ( $_ === true ) {
|
||||
$_ = Field::SET_BOTH;
|
||||
}
|
||||
else if ( $_ === false ) {
|
||||
$_ = Field::SET_NONE;
|
||||
}
|
||||
|
||||
return $this->_getSet( $this->_set, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set formatter for the field's data.
|
||||
*
|
||||
* When the data has been retrieved from the server, it can be passed through
|
||||
* a formatter here, which will manipulate (format) the data as required. This
|
||||
* can be useful when, for example, working with dates and a particular format
|
||||
* is required on the client-side.
|
||||
*
|
||||
* Editor has a number of formatters available with the {@see Format} class
|
||||
* which can be used directly with this method.
|
||||
* @param callable|string $_ Value to set if using as a setter. Can be given as
|
||||
* a closure function or a string with a reference to a function that will
|
||||
* be called with call_user_func().
|
||||
* @param mixed $opts Variable that is passed through to the get formatting
|
||||
* function - can be useful for passing through extra information such as
|
||||
* date formatting string, or a required flag. The actual options available
|
||||
* depend upon the formatter used.
|
||||
* @return callable|string|self The set formatter if no parameter is given, or
|
||||
* self if used as a setter.
|
||||
*/
|
||||
public function setFormatter ( $_=null, $opts=null )
|
||||
{
|
||||
if ( $opts !== null ) {
|
||||
$this->_setFormatterOpts = $opts;
|
||||
}
|
||||
return $this->_getSet( $this->_setFormatter, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get / set a set value. If given, then this value is used to write to the
|
||||
* database regardless of what data is sent from the client-side.
|
||||
*
|
||||
* @param callable|string|number $_ Value to set, or no value to use as a
|
||||
* getter
|
||||
* @return callable|string|self Value if used as a getter, or self if used
|
||||
* as a setter.
|
||||
*/
|
||||
public function setValue ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_setValue, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get / set the upload class for this field.
|
||||
* @param Upload $_ Upload class if used as a setter
|
||||
* @return Upload|self Value if used as a getter, or self if used
|
||||
* as a setter.
|
||||
*/
|
||||
public function upload ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_upload, $_ );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get / set the 'validator' of the field.
|
||||
*
|
||||
* The validator can be used to check if any abstract piece of data is valid
|
||||
* or not according to the given rules of the validation function used.
|
||||
*
|
||||
* Multiple validation options can be applied to a field instance by calling
|
||||
* this method multiple times. For example, it would be possible to have a
|
||||
* 'required' validation and a 'maxLength' validation with multiple calls.
|
||||
*
|
||||
* Editor has a number of validation available with the {@see Validate} class
|
||||
* which can be used directly with this method.
|
||||
* @param callable|string $_ Value to set if using as the validation method.
|
||||
* Can be given as a closure function or a string with a reference to a
|
||||
* function that will be called with call_user_func().
|
||||
* @param mixed $opts Variable that is passed through to the validation
|
||||
* function - can be useful for passing through extra information such as
|
||||
* date formatting string, or a required flag. The actual options available
|
||||
* depend upon the validation function used.
|
||||
* @return callable|string|self The validation method if no parameter is given,
|
||||
* or self if used as a setter.
|
||||
*/
|
||||
public function validator ( $_=null, $opts=null )
|
||||
{
|
||||
if ( $_ === null ) {
|
||||
return $this->_validator;
|
||||
}
|
||||
else {
|
||||
$this->_validator[] = array(
|
||||
"func" => $_,
|
||||
"opts" => $opts
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a formatting method that will be used for XSS checking / removal.
|
||||
* This should be a function that takes a single argument (the value to be
|
||||
* cleaned) and returns the cleaned value.
|
||||
*
|
||||
* Editor will use HtmLawed by default for this operation, which is built
|
||||
* into the software and no additional configuration is required, but a
|
||||
* custom function can be used if you wish to use a different formatter such
|
||||
* as HTMLPurifier.
|
||||
*
|
||||
* If you wish to disable this option (which you would only do if you are
|
||||
* absolutely confident that your validation will pick up on any XSS inputs)
|
||||
* simply provide a closure function that returns the value given to the
|
||||
* function. This is _not_ recommended.
|
||||
*
|
||||
* @param callable|false $xssFormatter XSS cleaner function, use `false` or
|
||||
* `null` to disable XSS cleaning.
|
||||
* @return Field Self for chaining.
|
||||
*/
|
||||
public function xss ( $xssFormatter )
|
||||
{
|
||||
if ( $xssFormatter === true || $xssFormatter === false || $xssFormatter === null ) {
|
||||
$this->_xssFormat = $xssFormatter;
|
||||
}
|
||||
else {
|
||||
$this->_xss = $xssFormatter;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
* Used by the Editor class and not generally for public use
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check to see if a field should be used for a particular action (get or set).
|
||||
*
|
||||
* Called by the Editor / Join class instances - not expected for general
|
||||
* consumption - internal.
|
||||
* @param string $action Direction that the data is travelling - 'get' is
|
||||
* reading DB data, `create` and `edit` for writing to the DB
|
||||
* @param array $data Data submitted from the client-side when setting.
|
||||
* @return boolean true if the field should be used in the get / set.
|
||||
* @internal
|
||||
*/
|
||||
public function apply ( $action, $data=null )
|
||||
{
|
||||
if ( $action === 'get' ) {
|
||||
// Get action - can we get this field
|
||||
return $this->_get;
|
||||
}
|
||||
else {
|
||||
// Note that validation must be done on input data before we get here
|
||||
|
||||
// Create or edit action, are we configured to use this field
|
||||
if ( $action === 'create' &&
|
||||
($this->_set === Field::SET_NONE || $this->_set === Field::SET_EDIT)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
else if ( $action === 'edit' &&
|
||||
($this->_set === Field::SET_NONE || $this->_set === Field::SET_CREATE)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check it was in the submitted data. If not, then not required
|
||||
// (validation would have failed if it was) and therefore we don't
|
||||
// set it. Check for a value as well, as it can format data from
|
||||
// some other source
|
||||
if ( $this->_setValue === null && ! $this->_inData( $this->name(), $data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In the data set, so use it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the ipOpts to get the list of options to return to the client-
|
||||
* side
|
||||
*
|
||||
* @param \DataTables\Database $db Database instance
|
||||
* @return Array Array of value / label options for the list
|
||||
* @internal
|
||||
*/
|
||||
public function optionsExec ( $db )
|
||||
{
|
||||
if ( $this->_optsFn ) {
|
||||
$fn = $this->_optsFn;
|
||||
return $fn($db);
|
||||
}
|
||||
else if ( $this->_opts ) {
|
||||
return $this->_opts->exec( $db );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the spopts to get the list of options for SearchPanes to return
|
||||
* to the client-side
|
||||
*
|
||||
* @param DataTables\Field $field The field to retrieve the data from
|
||||
* @param DataTables\Editor $editor The editor instance
|
||||
* @param DataTables\DTRequest $http The http request sent to the server
|
||||
* @param DataTables\Field[] $fields All of the fields
|
||||
* @param any $leftJoin Info for a leftJoin if required
|
||||
* @return Promise<IOption[]> | boolean
|
||||
* @internal
|
||||
*/
|
||||
public function searchPaneOptionsExec ( $field, $editor, $http, $fields, $leftJoin)
|
||||
{
|
||||
if ( $this->_spoptsFn ) {
|
||||
$fn = $this->_spoptsFn;
|
||||
return $fn($editor->db(), $editor);
|
||||
}
|
||||
else if ( $this->_spopts ) {
|
||||
return $this->_spopts->exec( $field, $editor, $http, $fields, $leftJoin );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the spopts to get the list of options for SearchBuilder to return
|
||||
* to the client-side
|
||||
*
|
||||
* @param DataTables\Field $field The field to retrieve the data from
|
||||
* @param DataTables\Editor $editor The editor instance
|
||||
* @param DataTables\DTRequest $http The http request sent to the server
|
||||
* @param DataTables\Field[] $fields All of the fields
|
||||
* @param any $leftJoin Info for a leftJoin if required
|
||||
* @return Promise<IOption[]> | boolean
|
||||
* @internal
|
||||
*/
|
||||
public function searchBuilderOptionsExec ( $field, $editor, $http, $fields, $leftJoin)
|
||||
{
|
||||
if ( $this->_sboptsFn ) {
|
||||
$fn = $this->_sboptsFn;
|
||||
return $fn($editor->db(), $editor);
|
||||
}
|
||||
else if ( $this->_sbopts ) {
|
||||
return $this->_sbopts->exec( $field, $editor, $http, $fields, $leftJoin );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of the field, taking into account if it is coming from the
|
||||
* DB or from a POST. If formatting has been specified for this field, it
|
||||
* will be applied here.
|
||||
*
|
||||
* Called by the Editor / Join class instances - not expected for general
|
||||
* consumption - internal.
|
||||
* @param string $direction Direction that the data is travelling - 'get' is
|
||||
* reading data, and 'set' is writing it to the DB.
|
||||
* @param array $data Data submitted from the client-side when setting or the
|
||||
* data for the row when getting data from the DB.
|
||||
* @return string Value for the field
|
||||
* @internal
|
||||
*/
|
||||
public function val ( $direction, $data )
|
||||
{
|
||||
if ( $direction === 'get' ) {
|
||||
if ( $this->_getValue !== null ) {
|
||||
$val = $this->_getAssignedValue( $this->_getValue );
|
||||
}
|
||||
else {
|
||||
// Getting data, so the db field name
|
||||
$val = isset( $data[ $this->_dbField ] ) ?
|
||||
$data[ $this->_dbField ] :
|
||||
null;
|
||||
}
|
||||
|
||||
return $this->_format(
|
||||
$val, $data, $this->_getFormatter, $this->_getFormatterOpts
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Sanity check that we aren't operating on a function
|
||||
if ( strpos( $this->dbField(), '(' ) !== false ) {
|
||||
throw new \Exception('Cannot set the value for an SQL function field. These fields are read only: ' . $this->name());
|
||||
}
|
||||
|
||||
// Setting data, so using from the payload (POST usually) and thus
|
||||
// use the 'name'
|
||||
$val = $this->_setValue !== null ?
|
||||
$this->_getAssignedValue( $this->_setValue ) :
|
||||
$this->_readProp( $this->name(), $data );
|
||||
|
||||
// XSS removal / checker
|
||||
if ( $this->_xssFormat && $val ) {
|
||||
$val = $this->xssSafety( $val );
|
||||
}
|
||||
|
||||
return $this->_format(
|
||||
$val, $data, $this->_setFormatter, $this->_setFormatterOpts
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the validity of the field based on the data submitted. Note that
|
||||
* this validation is performed on the wire data - i.e. that which is
|
||||
* submitted, before any setFormatter is run
|
||||
*
|
||||
* Called by the Editor / Join class instances - not expected for general
|
||||
* consumption - internal.
|
||||
*
|
||||
* @param array $data Data submitted from the client-side
|
||||
* @param Editor $editor Editor instance
|
||||
* @param mixed $id Row id that is being validated
|
||||
* @return boolean|string `true` if valid, string with error message if not
|
||||
* @internal
|
||||
*/
|
||||
public function validate ( $data, $editor, $id=null )
|
||||
{
|
||||
// Three cases for the validator - closure, string or null
|
||||
if ( ! count( $this->_validator ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Value could be from user data, or setValue might take priority
|
||||
$val = $this->_setValue !== null ?
|
||||
$this->_getAssignedValue( $this->_setValue ) :
|
||||
$this->_readProp( $this->name(), $data );
|
||||
|
||||
$processData = $editor->inData();
|
||||
$instances = array(
|
||||
'action' => $processData['action'],
|
||||
'id' => $id,
|
||||
'field' => $this,
|
||||
'editor' => $editor,
|
||||
'db' => $editor->db()
|
||||
);
|
||||
|
||||
for ( $i=0, $ien=count( $this->_validator ) ; $i<$ien ; $i++ ) {
|
||||
$validator = $this->_validator[$i];
|
||||
|
||||
// Backwards compatibility
|
||||
if ( is_string( $validator['func'] ) ) {
|
||||
if ( strpos($validator['func'], "Validate::") === 0 ) {
|
||||
$a = explode("::", $validator['func']);
|
||||
|
||||
// Validate class static methods - they have `Legacy` counter parts that
|
||||
// convert from the old style to the new so the old style options still work.
|
||||
if ( method_exists( "\\DataTables\\Editor\\".$a[0], $a[1].'Legacy' ) ) {
|
||||
$func = call_user_func( "\\DataTables\\Editor\\".$validator['func'].'Legacy', $validator['opts'] );
|
||||
$res = call_user_func( $func, $val, $data, $this, $instances );
|
||||
}
|
||||
else {
|
||||
// User style legacy function. Call it directly
|
||||
$func = "\\DataTables\\Editor\\".$validator['func'];
|
||||
$res = call_user_func( $func, $val, $data, $this, $instances );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// And for cases where a string was used to point to a function,
|
||||
// which was not in the Validate class
|
||||
$res = call_user_func( $validator['func'], $val, $data, $validator['opts'], $instances );
|
||||
}
|
||||
}
|
||||
else {
|
||||
$func = $validator['func'];
|
||||
$res = $func( $val, $data, $this, $instances );
|
||||
}
|
||||
|
||||
// Check if there was a validation error and if so, return it
|
||||
if ( $res !== true ) {
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
// Validation methods all run, must be valid
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write the value for this field to the output array for a read operation
|
||||
*
|
||||
* @param array $out Row output data (to the JSON)
|
||||
* @param mixed $srcData Row input data (raw, from the database)
|
||||
* @internal
|
||||
*/
|
||||
public function write( &$out, $srcData )
|
||||
{
|
||||
$this->_writeProp( $out, $this->name(), $this->val('get', $srcData) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform XSS prevention on an input.
|
||||
*
|
||||
* @param mixed $val Value to be escaped
|
||||
* @return string Safe value
|
||||
*/
|
||||
public function xssSafety ( $val ) {
|
||||
$xss = $this->_xss;
|
||||
|
||||
if ( is_array( $val ) ) {
|
||||
$res = array();
|
||||
|
||||
foreach ( $val as $individual ) {
|
||||
$res[] = $xss ?
|
||||
$xss( $individual ) :
|
||||
Htmlaw::filter( $individual );
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
return $xss ?
|
||||
$xss( $val ) :
|
||||
Htmlaw::filter( $val );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Apply a formatter to data. The caller will decide what formatter to apply
|
||||
* (get or set)
|
||||
*
|
||||
* @param mixed $val Value to be formatted
|
||||
* @param mixed $data Full row data
|
||||
* @param callable $formatter Formatting function to be called
|
||||
* @param array $opts Array of options to be passed to the formatter
|
||||
* @return mixed Formatted value
|
||||
*/
|
||||
private function _format( $val, $data, $formatter, $opts )
|
||||
{
|
||||
// Three cases for the formatter - closure, string or null
|
||||
if ( ! $formatter ) {
|
||||
return $val;
|
||||
}
|
||||
|
||||
if ( ! is_string( $formatter ) ) {
|
||||
return $formatter( $val, $data, $opts );
|
||||
}
|
||||
|
||||
// Backwards compatibility - strings will not be supported in v2
|
||||
if ( strpos($formatter, "Format::") === 0 ) {
|
||||
$a = explode( '::', $formatter );
|
||||
|
||||
// Old style Editor formatter - use the legacy functions to
|
||||
// convert to the new style
|
||||
if ( method_exists( "\\DataTables\\Editor\\".$a[0], $a[1].'Legacy' ) ) {
|
||||
$func = call_user_func( "\\DataTables\\Editor\\".$formatter.'Legacy', $opts );
|
||||
|
||||
return $func( $val, $data );
|
||||
}
|
||||
else {
|
||||
// User added old style methods
|
||||
return call_user_func( "\\DataTables\\Editor\\".$formatter, $val, $data, $opts );
|
||||
}
|
||||
}
|
||||
|
||||
// User function (string identifier)
|
||||
return call_user_func( $formatter, $val, $data, $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value from `_[gs]etValue` - taking into account if it is callable
|
||||
* function or not
|
||||
*
|
||||
* @param mixed $val Value to be evaluated
|
||||
* @return mixed Value assigned, or returned from the function
|
||||
*/
|
||||
private function _getAssignedValue ( $val )
|
||||
{
|
||||
return is_callable($val) && is_object($val) ?
|
||||
$val() :
|
||||
$val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is a parameter is in the submitted data set. This is functionally
|
||||
* the same as the `_readProp()` method, but in this case a binary value
|
||||
* is required to indicate if the value is present or not.
|
||||
*
|
||||
* @param string $name Javascript dotted object name to write to
|
||||
* @param array $data Data source array to read from
|
||||
* @return boolean `true` if present, `false` otherwise
|
||||
* @private
|
||||
*/
|
||||
private function _inData ( $name, $data )
|
||||
{
|
||||
if ( strpos($name, '.') === false ) {
|
||||
return isset( $data[ $name ] ) ?
|
||||
true :
|
||||
false;
|
||||
}
|
||||
|
||||
$names = explode( '.', $name );
|
||||
$inner = $data;
|
||||
|
||||
for ( $i=0 ; $i<count($names)-1 ; $i++ ) {
|
||||
if ( ! isset( $inner[ $names[$i] ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$inner = $inner[ $names[$i] ];
|
||||
}
|
||||
|
||||
return isset( $inner [ $names[count($names)-1] ] ) ?
|
||||
true :
|
||||
false;
|
||||
}
|
||||
}
|
||||
|
||||
346
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Format.php.txt
vendored
Normal file
346
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Format.php.txt
vendored
Normal file
@ -0,0 +1,346 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2012 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
|
||||
/**
|
||||
* Formatter methods for the DataTables Editor
|
||||
*
|
||||
* All methods in this class are static with common inputs and returns.
|
||||
*/
|
||||
class Format {
|
||||
/** Date format: 2012-03-09. jQuery UI equivalent format: yy-mm-dd */
|
||||
const DATE_ISO_8601 = "Y-m-d";
|
||||
|
||||
/** Date format: Fri, 9 Mar 12. jQuery UI equivalent format: D, d M y */
|
||||
const DATE_ISO_822 = "D, j M y";
|
||||
|
||||
/** Date format: Friday, 09-Mar-12. jQuery UI equivalent format: DD, dd-M-y */
|
||||
const DATE_ISO_850 = "l, d-M-y";
|
||||
|
||||
/** Date format: Fri, 9 Mar 12. jQuery UI equivalent format: D, d M y */
|
||||
const DATE_ISO_1036 = "D, j M y";
|
||||
|
||||
/** Date format: Fri, 9 Mar 2012. jQuery UI equivalent format: D, d M yy */
|
||||
const DATE_ISO_1123 = "D, j M Y";
|
||||
|
||||
/** Date format: Fri, 9 Mar 2012. jQuery UI equivalent format: D, d M yy */
|
||||
const DATE_ISO_2822 = "D, j M Y";
|
||||
|
||||
/** Date format: March-. jQuery UI equivalent format: D, d M yy */
|
||||
const DATE_USA = "m-d-Y";
|
||||
|
||||
/** Date format: 1331251200. jQuery UI equivalent format: @ */
|
||||
const DATE_TIMESTAMP = "U";
|
||||
|
||||
/** Date format: 1331251200. jQuery UI equivalent format: @ */
|
||||
const DATE_EPOCH = "U";
|
||||
|
||||
|
||||
/**
|
||||
* Convert from SQL date / date time format to a format given by the options
|
||||
* parameter.
|
||||
*
|
||||
* Typical use of this method is to use it with the
|
||||
* {@see Field::getFormatter()} and {@see Field::setFormatter()} methods of
|
||||
* {@see Field} where the parameters required for this method will be
|
||||
* automatically satisfied.
|
||||
* @param string $val Value to convert from MySQL date format
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Format to convert to using PHP date() options.
|
||||
* @return string Formatted date or empty string on error.
|
||||
*/
|
||||
public static function dateSqlToFormat( $format ) {
|
||||
return function ( $val, $data ) use ( $format ) {
|
||||
if ( $val === null || $val === '' ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$date = new \DateTime( $val );
|
||||
|
||||
// Allow empty strings or invalid dates
|
||||
if ( $date ) {
|
||||
return date_format( $date, $format );
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert from a format given by the options parameter to a format that
|
||||
* SQL servers will recognise as a date.
|
||||
*
|
||||
* Typical use of this method is to use it with the
|
||||
* {@see Field::getFormatter()} and {@see Field::setFormatter()} methods of
|
||||
* {@see Field} where the parameters required for this method will be
|
||||
* automatically satisfied.
|
||||
* @param string $val Value to convert to SQL date format
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Format to convert from using PHP date() options.
|
||||
* @return string Formatted date or null on error.
|
||||
*/
|
||||
public static function dateFormatToSql( $format ) {
|
||||
return function ( $val, $data ) use ( $format ) {
|
||||
if ( $val === null || $val === '' ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Note that this assumes the date is in the correct format (should be
|
||||
// checked by validation before being used here!)
|
||||
if ( substr($format, 0, 1) !== '!' ) {
|
||||
$format = '!'.$format;
|
||||
}
|
||||
$date = date_create_from_format($format, $val);
|
||||
|
||||
// Invalid dates or empty string are replaced with null. Use the
|
||||
// validation to ensure the date given is valid if you don't want this!
|
||||
if ( $date ) {
|
||||
return date_format( $date, 'Y-m-d' );
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert from one date time format to another
|
||||
*
|
||||
* Typical use of this method is to use it with the
|
||||
* {@see Field::getFormatter()} and {@see Field::setFormatter()} methods of
|
||||
* {@see Field} where the parameters required for this method will be
|
||||
* automatically satisfied.
|
||||
* @param string $val Value to convert
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Array with `from` and `to` properties which are the
|
||||
* formats to convert from and to
|
||||
* @return string Formatted date or null on error.
|
||||
*/
|
||||
public static function datetime( $from, $to ) {
|
||||
return function ( $val, $data ) use ( $from, $to ) {
|
||||
if ( $val === null || $val === '' ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( substr($from, 0, 1) !== '!' ) {
|
||||
$from = '!'.$from;
|
||||
}
|
||||
$date = date_create_from_format( $from, $val );
|
||||
|
||||
// Allow empty strings or invalid dates
|
||||
if ( $date ) {
|
||||
return date_format( $date, $to );
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a string of values into an array for use with checkboxes.
|
||||
* @param string $val Value to convert to from a string to an array
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Field delimiter
|
||||
* @return string Formatted value or null on error.
|
||||
*/
|
||||
public static function explode( $char='|' ) {
|
||||
return function ( $val, $data ) use ( $char ) {
|
||||
if ($val === null) {
|
||||
$val = '';
|
||||
}
|
||||
|
||||
return explode($char, $val);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an array of values from a checkbox into a string which can be
|
||||
* used to store in a text field in a database.
|
||||
* @param string $val Value to convert to from an array to a string
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Field delimiter
|
||||
* @return string Formatted value or null on error.
|
||||
*/
|
||||
public static function implode( $char='|' ) {
|
||||
return function ( $val, $data ) use ( $char ) {
|
||||
return implode($char, $val);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an empty string to `null`. Null values are very useful in
|
||||
* databases, but HTTP variables have no way of representing `null` as a
|
||||
* value, often leading to an empty string and null overlapping. This method
|
||||
* will check the value to operate on and return null if it is empty.
|
||||
* @param string $val Value to convert to from a string to an array
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Field delimiter
|
||||
* @return string Formatted value or null on error.
|
||||
*/
|
||||
public static function nullEmpty () {
|
||||
// Legacy function - use `ifEmpty` now
|
||||
return self::ifEmpty( null );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formatter that can be used to specify what value should be used if an
|
||||
* empty value is submitted by the client-side (e.g. null, 0, 'Not set',
|
||||
* etc)
|
||||
* @param string $val Value to convert to from a string to an array
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Empty value
|
||||
* @return string Formatted value or null on error.
|
||||
*/
|
||||
public static function ifEmpty ( $ret ) {
|
||||
return function ( $val, $data ) use ( $ret ) {
|
||||
return $val === '' ?
|
||||
$ret :
|
||||
$val;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a number from using any character other than a period (dot) to
|
||||
* one which does use a period. This is useful for allowing numeric user
|
||||
* input in regions where a comma is used as the decimal character. Use with
|
||||
* a set formatter.
|
||||
* @param string $val Value to convert to from a string to an array
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Decimal place character (default ',')
|
||||
* @return string Formatted value or null on error.
|
||||
*/
|
||||
public static function fromDecimalChar ( $char=',' ) {
|
||||
return function ( $val, $data ) use ( $char ) {
|
||||
return str_replace( $char, '.', $val );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a number with a period (dot) as the decimal character to use
|
||||
* a different character (typically a comma). Use with a get formatter.
|
||||
* @param string $val Value to convert to from a string to an array
|
||||
* @param string[] $data Data for the whole row / submitted data
|
||||
* @param string $opts Decimal place character (default ',')
|
||||
* @return string Formatted value or null on error.
|
||||
*/
|
||||
public static function toDecimalChar ( $char=',' ) {
|
||||
return function ( $val, $data ) use ( $char ) {
|
||||
return str_replace( '.', $char, $val );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal functions
|
||||
* These legacy methods are for backwards compatibility with the old way of
|
||||
* using the formatter methods. They basically do argument swapping.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function date_sql_to_format ( $opts ) {
|
||||
return self::dateSqlToFormat( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function date_sql_to_formatLegacy ( $opts ) {
|
||||
return self::dateSqlToFormat( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function date_format_to_sql ( $opts ) {
|
||||
return self::dateFormatToSql( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function date_format_to_sqlLegacy ( $opts ) {
|
||||
return self::dateFormatToSql( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function datetimeLegacy ( $opts ) {
|
||||
return self::datetime( $opts['from'], $opts['to'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function explodeLegacy ( $opts ) {
|
||||
if ( $opts === null ) {
|
||||
$opts = '|';
|
||||
}
|
||||
return self::explode( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function implodeLegacy ( $opts ) {
|
||||
if ( $opts === null ) {
|
||||
$opts = '|';
|
||||
}
|
||||
return self::implode( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function nullEmptyLegacy ( $opts ) {
|
||||
return self::nullEmpty( null );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function ifEmptyLegacy ( $opts ) {
|
||||
return self::ifEmpty( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function fromDecimalCharLegacy ( $opts ) {
|
||||
if ( $opts === null ) {
|
||||
$opts = ',';
|
||||
}
|
||||
return self::fromDecimalChar( $opts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function toDecimalCharLegacy ( $opts ) {
|
||||
if ( $opts === null ) {
|
||||
$opts = ',';
|
||||
}
|
||||
return self::toDecimalChar( $opts );
|
||||
}
|
||||
}
|
||||
|
||||
1049
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Join.php.txt
vendored
Normal file
1049
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Join.php.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
33
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Mjoin.php.txt
vendored
Normal file
33
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Mjoin.php.txt
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2012 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
use DataTables\Editor\Join;
|
||||
|
||||
|
||||
/**
|
||||
* The `Mjoin` class extends the `Join` class with the join data type set to
|
||||
* 'array', whereas the `Join` default is `object` which has been rendered
|
||||
* obsolete by the `Editor->leftJoin()` method. The API API is otherwise
|
||||
* identical.
|
||||
*
|
||||
* This class is recommended over the `Join` class.
|
||||
*/
|
||||
class Mjoin extends Join
|
||||
{
|
||||
function __construct( $table=null )
|
||||
{
|
||||
parent::__construct( $table, 'array' );
|
||||
}
|
||||
}
|
||||
341
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Options.php.txt
vendored
Normal file
341
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Options.php.txt
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2016 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
use DataTables;
|
||||
|
||||
/**
|
||||
* The Options class provides a convenient method of specifying where Editor
|
||||
* should get the list of options for a `select`, `radio` or `checkbox` field.
|
||||
* This is normally from a table that is _left joined_ to the main table being
|
||||
* edited, and a list of the values available from the joined table is shown to
|
||||
* the end user to let them select from.
|
||||
*
|
||||
* `Options` instances are used with the {@see Field->options()} method.
|
||||
*
|
||||
* @example
|
||||
* Get a list of options from the `sites` table
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( 'name' )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Get a list of options with custom ordering
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( 'name' )
|
||||
* ->order( 'name DESC' )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Get a list of options showing the id and name in the label
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( [ 'name', 'id' ] )
|
||||
* ->render( function ( $row ) {
|
||||
* return $row['name'].' ('.$row['id'].')';
|
||||
* } )
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
class Options extends DataTables\Ext {
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private parameters
|
||||
*/
|
||||
|
||||
/** @var string Table to get the information from */
|
||||
private $_table = null;
|
||||
|
||||
/** @var string Column name containing the value */
|
||||
private $_value = null;
|
||||
|
||||
/** @var string[] Column names for the label(s) */
|
||||
private $_label = array();
|
||||
|
||||
/** Information for left join */
|
||||
private $_leftJoin = array();
|
||||
|
||||
/** @var integer Row limit */
|
||||
private $_limit = null;
|
||||
|
||||
/** @var callable Callback function to do rendering of labels */
|
||||
private $_renderer = null;
|
||||
|
||||
/** @var callback Callback function to add where conditions */
|
||||
private $_where = null;
|
||||
|
||||
/** @var string ORDER BY clause */
|
||||
private $_order = null;
|
||||
|
||||
private $_manualAdd = array();
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add extra options to the list, in addition to any obtained from the database
|
||||
*
|
||||
* @param string $label The label to use for the option
|
||||
* @param string|null $value Value for the option. If not given, the label will be used
|
||||
* @return Options Self for chaining
|
||||
*/
|
||||
public function add ( $label, $value=null )
|
||||
{
|
||||
if ( $value === null ) {
|
||||
$value = $label;
|
||||
}
|
||||
|
||||
$this->_manualAdd[] = array(
|
||||
'label' => $label,
|
||||
'value' => $value
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the column(s) to use as the label value of the options
|
||||
*
|
||||
* @param null|string|string[] $_ null to get the current value, string or
|
||||
* array to get.
|
||||
* @return Options|string[] Self if setting for chaining, array of values if
|
||||
* getting.
|
||||
*/
|
||||
public function label ( $_=null )
|
||||
{
|
||||
if ( $_ === null ) {
|
||||
return $this;
|
||||
}
|
||||
else if ( is_string($_) ) {
|
||||
$this->_label = array( $_ );
|
||||
}
|
||||
else {
|
||||
$this->_label = $_;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a left join operation for the options
|
||||
*
|
||||
* @param string $table to get the information from
|
||||
* @param string $field1 the first field to get the information from
|
||||
* @param string $operator the operation to perform on the two fields
|
||||
* @param string $field2 the second field to get the information from
|
||||
* @return self
|
||||
*/
|
||||
public function leftJoin ( $table, $field1, $operator, $field2 )
|
||||
{
|
||||
$this->_leftJoin[] = array(
|
||||
"table" => $table,
|
||||
"field1" => $field1,
|
||||
"field2" => $field2,
|
||||
"operator" => $operator
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the LIMIT clause to limit the number of records returned.
|
||||
*
|
||||
* @param null|number $_ Number of rows to limit the result to
|
||||
* @return Options|string[] Self if setting for chaining, limit if getting.
|
||||
*/
|
||||
public function limit ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_limit, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the ORDER BY clause to use in the SQL. If this option is not
|
||||
* provided the ordering will be based on the rendered output, either
|
||||
* numerically or alphabetically based on the data returned by the renderer.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function order ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_order, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the label renderer. The renderer can be used to combine
|
||||
* multiple database columns into a single string that is shown as the label
|
||||
* to the end user in the list of options.
|
||||
*
|
||||
* @param null|callable $_ Function to set, null to get current value
|
||||
* @return Options|callable Self if setting for chaining, callable if
|
||||
* getting.
|
||||
*/
|
||||
public function render ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_renderer, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the database table from which to gather the options for the
|
||||
* list.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function table ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_table, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the column name to use for the value in the options list. This
|
||||
* would normally be the primary key for the table.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function value ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_value, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the method to use for a WHERE condition if it is to be
|
||||
* applied to the query to get the options.
|
||||
*
|
||||
* @param null|callable $_ Function to set, null to get current value
|
||||
* @return Options|callable Self if setting for chaining, callable if
|
||||
* getting.
|
||||
*/
|
||||
public function where ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_where, $_ );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the options (i.e. get them)
|
||||
*
|
||||
* @param Database $db Database connection
|
||||
* @return array List of options
|
||||
* @internal
|
||||
*/
|
||||
public function exec ( $db )
|
||||
{
|
||||
$label = $this->_label;
|
||||
$value = $this->_value;
|
||||
$formatter = $this->_renderer;
|
||||
|
||||
// Create a list of the fields that we need to get from the db
|
||||
$fields = array();
|
||||
$fields[] = $value;
|
||||
$fields = array_merge( $fields, $label );
|
||||
|
||||
// We need a default formatter if one isn't provided
|
||||
if ( ! $formatter ) {
|
||||
$formatter = function ( $row ) use ( $label ) {
|
||||
$a = array();
|
||||
|
||||
for ( $i=0, $ien=count($label) ; $i<$ien ; $i++ ) {
|
||||
$a[] = $row[ $label[$i] ];
|
||||
}
|
||||
|
||||
return implode(' ', $a);
|
||||
};
|
||||
}
|
||||
|
||||
// Get the data
|
||||
$q = $db
|
||||
->query('select')
|
||||
->distinct( true )
|
||||
->table( $this->_table )
|
||||
->left_join($this->_leftJoin)
|
||||
->get( $fields )
|
||||
->where( $this->_where );
|
||||
|
||||
if ( $this->_order ) {
|
||||
// For cases where we are ordering by a field which isn't included in the list
|
||||
// of fields to display, we need to add the ordering field, due to the
|
||||
// select distinct.
|
||||
$orderFields = explode( ',', $this->_order );
|
||||
|
||||
for ( $i=0, $ien=count($orderFields) ; $i<$ien ; $i++ ) {
|
||||
$field = strtolower( $orderFields[$i] );
|
||||
$field = str_replace( ' asc', '', $field );
|
||||
$field = str_replace( ' desc', '', $field );
|
||||
$field = trim( $field );
|
||||
|
||||
if ( ! in_array( $field, $fields ) ) {
|
||||
$q->get( $field );
|
||||
}
|
||||
}
|
||||
|
||||
$q->order( $this->_order );
|
||||
}
|
||||
|
||||
if ( $this->_limit !== null ) {
|
||||
$q->limit( $this->_limit );
|
||||
}
|
||||
|
||||
$rows = $q
|
||||
->exec()
|
||||
->fetchAll();
|
||||
|
||||
// Create the output array
|
||||
$out = array();
|
||||
|
||||
for ( $i=0, $ien=count($rows) ; $i<$ien ; $i++ ) {
|
||||
$out[] = array(
|
||||
"label" => $formatter( $rows[$i] ),
|
||||
"value" => $rows[$i][$value]
|
||||
);
|
||||
}
|
||||
|
||||
// Stick on any extra manually added options
|
||||
if ( count( $this->_manualAdd ) ) {
|
||||
$out = array_merge( $out, $this->_manualAdd );
|
||||
}
|
||||
|
||||
// Only sort if there was no SQL order field
|
||||
if ( ! $this->_order ) {
|
||||
usort( $out, function ( $a, $b ) {
|
||||
return is_numeric($a['label']) && is_numeric($b['label']) ?
|
||||
($a['label']*1) - ($b['label']*1) :
|
||||
strcmp( $a['label'], $b['label'] );
|
||||
} );
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
335
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/SearchBuilderOptions.php.txt
vendored
Normal file
335
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/SearchBuilderOptions.php.txt
vendored
Normal file
@ -0,0 +1,335 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2016 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
use DataTables;
|
||||
|
||||
/**
|
||||
* The Options class provides a convenient method of specifying where Editor
|
||||
* should get the list of options for a `select`, `radio` or `checkbox` field.
|
||||
* This is normally from a table that is _left joined_ to the main table being
|
||||
* edited, and a list of the values available from the joined table is shown to
|
||||
* the end user to let them select from.
|
||||
*
|
||||
* `Options` instances are used with the {@see Field->options()} method.
|
||||
*
|
||||
* @example
|
||||
* Get a list of options from the `sites` table
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( 'name' )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Get a list of options with custom ordering
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( 'name' )
|
||||
* ->order( 'name DESC' )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Get a list of options showing the id and name in the label
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( [ 'name', 'id' ] )
|
||||
* ->render( function ( $row ) {
|
||||
* return $row['name'].' ('.$row['id'].')';
|
||||
* } )
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
class SearchBuilderOptions extends DataTables\Ext {
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private parameters
|
||||
*/
|
||||
|
||||
/** @var string Table to get the information from */
|
||||
private $_table = null;
|
||||
|
||||
/** @var string Column name containing the value */
|
||||
private $_value = null;
|
||||
|
||||
/** @var string[] Column names for the label(s) */
|
||||
private $_label = array();
|
||||
|
||||
/** @var string[] Column names for left join */
|
||||
private $_leftJoin = array();
|
||||
|
||||
/** @var callable Callback function to do rendering of labels */
|
||||
private $_renderer = null;
|
||||
|
||||
/** @var callback Callback function to add where conditions */
|
||||
private $_where = null;
|
||||
|
||||
/** @var string ORDER BY clause */
|
||||
private $_order = null;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get / set the column(s) to use as the label value of the options
|
||||
*
|
||||
* @param null|string|string[] $_ null to get the current value, string or
|
||||
* array to get.
|
||||
* @return Options|string[] Self if setting for chaining, array of values if
|
||||
* getting.
|
||||
*/
|
||||
public function label ( $_=null )
|
||||
{
|
||||
if ( $_ === null ) {
|
||||
return $this;
|
||||
}
|
||||
else if ( is_string($_) ) {
|
||||
$this->_label = array( $_ );
|
||||
}
|
||||
else {
|
||||
$this->_label = $_;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the ORDER BY clause to use in the SQL. If this option is not
|
||||
* provided the ordering will be based on the rendered output, either
|
||||
* numerically or alphabetically based on the data returned by the renderer.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function order ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_order, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the label renderer. The renderer can be used to combine
|
||||
* multiple database columns into a single string that is shown as the label
|
||||
* to the end user in the list of options.
|
||||
*
|
||||
* @param null|callable $_ Function to set, null to get current value
|
||||
* @return Options|callable Self if setting for chaining, callable if
|
||||
* getting.
|
||||
*/
|
||||
public function render ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_renderer, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the database table from which to gather the options for the
|
||||
* list.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function table ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_table, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the column name to use for the value in the options list. This
|
||||
* would normally be the primary key for the table.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function value ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_value, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the method to use for a WHERE condition if it is to be
|
||||
* applied to the query to get the options.
|
||||
*
|
||||
* @param null|callable $_ Function to set, null to get current value
|
||||
* @return Options|callable Self if setting for chaining, callable if
|
||||
* getting.
|
||||
*/
|
||||
public function where ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_where, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the array values used for a leftJoin condition if it is to be
|
||||
* applied to the query to get the options.
|
||||
*
|
||||
* @param string $table to get the information from
|
||||
* @param string $field1 the first field to get the information from
|
||||
* @param string $operator the operation to perform on the two fields
|
||||
* @param string $field2 the second field to get the information from
|
||||
* @return self
|
||||
*/
|
||||
public function leftJoin ( $table, $field1, $operator, $field2 )
|
||||
{
|
||||
$this->_leftJoin[] = array(
|
||||
"table" => $table,
|
||||
"field1" => $field1,
|
||||
"field2" => $field2,
|
||||
"operator" => $operator
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the where conditions to the desired query
|
||||
*
|
||||
* @param string $query the query being built
|
||||
* @return self
|
||||
*/
|
||||
private function _get_where ( $query )
|
||||
{
|
||||
for ( $i=0 ; $i<count($this->_where) ; $i++ ) {
|
||||
if ( is_callable( $this->_where[$i] ) ) {
|
||||
$this->_where[$i]( $query );
|
||||
}
|
||||
else {
|
||||
$query->where(
|
||||
$this->_where[$i]['key'],
|
||||
$this->_where[$i]['value'],
|
||||
$this->_where[$i]['op']
|
||||
);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the options (i.e. get them)
|
||||
*
|
||||
* @param Database $db Database connection
|
||||
* @return array List of options
|
||||
* @internal
|
||||
*/
|
||||
public function exec ( $field, $editor, $http, $fields, $leftJoinIn )
|
||||
{
|
||||
// If the value is not yet set then set the variable to be the field name
|
||||
if ( $this->_value == null) {
|
||||
$value = $field->dbField();
|
||||
}
|
||||
else {
|
||||
$value = $this->_value;
|
||||
}
|
||||
|
||||
$readTable = $editor->readTable();
|
||||
|
||||
// If the table is not yet set then set the table variable to be the same as editor
|
||||
// This is not taking a value from the SearchBuilderOptions instance as the table should be defined in value/label. This throws up errors if not.
|
||||
if($this->_table !== null) {
|
||||
$table = $this->_table;
|
||||
}
|
||||
else if(count($readTable) > 0) {
|
||||
$table = $readTable;
|
||||
}
|
||||
else {
|
||||
$table = $editor->table();
|
||||
}
|
||||
|
||||
// If the label value has not yet been set then just set it to be the same as value
|
||||
if ( $this->_label == null ) {
|
||||
$label = $value;
|
||||
}
|
||||
else {
|
||||
$label = $this->_label[0];
|
||||
}
|
||||
|
||||
// Set the database from editor
|
||||
$db = $editor->db();
|
||||
|
||||
$formatter = $this->_renderer;
|
||||
|
||||
// We need a default formatter if one isn't provided
|
||||
if ( ! $formatter ) {
|
||||
$formatter = function ( $str ) {
|
||||
return $str;
|
||||
};
|
||||
}
|
||||
|
||||
// Set up the join variable so that it will fit nicely later
|
||||
$leftJoin = gettype($this->_leftJoin) === 'array' ?
|
||||
$this->_leftJoin :
|
||||
array($this->_leftJoin);
|
||||
|
||||
foreach($leftJoinIn as $lj) {
|
||||
$found = false;
|
||||
foreach($leftJoin as $lje) {
|
||||
if($lj['table'] === $lje['table']) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
if(!$found) {
|
||||
array_push($leftJoin, $lj);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the query to get the current counts for viewTotal
|
||||
$query = $db
|
||||
->query('select')
|
||||
->table( $table )
|
||||
->left_join($leftJoin);
|
||||
|
||||
if ( $field->apply('get') && $field->getValue() === null ) {
|
||||
$query->get($value." as value", $label." as label");
|
||||
$query->group_by( $value);
|
||||
}
|
||||
|
||||
$res = $query
|
||||
->exec()
|
||||
->fetchAll();
|
||||
|
||||
// Create the output array
|
||||
$out = array();
|
||||
|
||||
for( $j=0 ; $j<count($res) ; $j ++) {
|
||||
$out[] = array(
|
||||
"value" => $res[$j]['value'],
|
||||
"label" => $res[$j]['label']
|
||||
);
|
||||
}
|
||||
|
||||
// Only sort if there was no SQL order field
|
||||
if ( ! $this->_order ) {
|
||||
usort( $out, function ( $a, $b ) {
|
||||
return is_numeric($a['label']) && is_numeric($b['label']) ?
|
||||
($a['label']*1) - ($b['label']*1) :
|
||||
strcmp( $a['label'], $b['label'] );
|
||||
} );
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
467
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/SearchPaneOptions.php.txt
vendored
Normal file
467
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/SearchPaneOptions.php.txt
vendored
Normal file
@ -0,0 +1,467 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2016 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
use DataTables;
|
||||
|
||||
/**
|
||||
* The Options class provides a convenient method of specifying where Editor
|
||||
* should get the list of options for a `select`, `radio` or `checkbox` field.
|
||||
* This is normally from a table that is _left joined_ to the main table being
|
||||
* edited, and a list of the values available from the joined table is shown to
|
||||
* the end user to let them select from.
|
||||
*
|
||||
* `Options` instances are used with the {@see Field->options()} method.
|
||||
*
|
||||
* @example
|
||||
* Get a list of options from the `sites` table
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( 'name' )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Get a list of options with custom ordering
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( 'name' )
|
||||
* ->order( 'name DESC' )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Get a list of options showing the id and name in the label
|
||||
* ```php
|
||||
* Field::inst( 'users.site' )
|
||||
* ->options( Options::inst()
|
||||
* ->table( 'sites' )
|
||||
* ->value( 'id' )
|
||||
* ->label( [ 'name', 'id' ] )
|
||||
* ->render( function ( $row ) {
|
||||
* return $row['name'].' ('.$row['id'].')';
|
||||
* } )
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
class SearchPaneOptions extends DataTables\Ext {
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private parameters
|
||||
*/
|
||||
|
||||
/** @var string Table to get the information from */
|
||||
private $_table = null;
|
||||
|
||||
/** @var string Column name containing the value */
|
||||
private $_value = null;
|
||||
|
||||
/** @var string[] Column names for the label(s) */
|
||||
private $_label = array();
|
||||
|
||||
/** @var string[] Column names for left join */
|
||||
private $_leftJoin = array();
|
||||
|
||||
/** @var callable Callback function to do rendering of labels */
|
||||
private $_renderer = null;
|
||||
|
||||
/** @var callback Callback function to add where conditions */
|
||||
private $_where = null;
|
||||
|
||||
/** @var string ORDER BY clause */
|
||||
private $_order = null;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get / set the column(s) to use as the label value of the options
|
||||
*
|
||||
* @param null|string|string[] $_ null to get the current value, string or
|
||||
* array to get.
|
||||
* @return Options|string[] Self if setting for chaining, array of values if
|
||||
* getting.
|
||||
*/
|
||||
public function label ( $_=null )
|
||||
{
|
||||
if ( $_ === null ) {
|
||||
return $this;
|
||||
}
|
||||
else if ( is_string($_) ) {
|
||||
$this->_label = array( $_ );
|
||||
}
|
||||
else {
|
||||
$this->_label = $_;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the ORDER BY clause to use in the SQL. If this option is not
|
||||
* provided the ordering will be based on the rendered output, either
|
||||
* numerically or alphabetically based on the data returned by the renderer.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function order ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_order, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the label renderer. The renderer can be used to combine
|
||||
* multiple database columns into a single string that is shown as the label
|
||||
* to the end user in the list of options.
|
||||
*
|
||||
* @param null|callable $_ Function to set, null to get current value
|
||||
* @return Options|callable Self if setting for chaining, callable if
|
||||
* getting.
|
||||
*/
|
||||
public function render ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_renderer, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the database table from which to gather the options for the
|
||||
* list.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function table ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_table, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the column name to use for the value in the options list. This
|
||||
* would normally be the primary key for the table.
|
||||
*
|
||||
* @param null|string $_ String to set, null to get current value
|
||||
* @return Options|string Self if setting for chaining, string if getting.
|
||||
*/
|
||||
public function value ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_value, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the method to use for a WHERE condition if it is to be
|
||||
* applied to the query to get the options.
|
||||
*
|
||||
* @param null|callable $_ Function to set, null to get current value
|
||||
* @return Options|callable Self if setting for chaining, callable if
|
||||
* getting.
|
||||
*/
|
||||
public function where ( $_=null )
|
||||
{
|
||||
return $this->_getSet( $this->_where, $_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the array values used for a leftJoin condition if it is to be
|
||||
* applied to the query to get the options.
|
||||
*
|
||||
* @param string $table to get the information from
|
||||
* @param string $field1 the first field to get the information from
|
||||
* @param string $operator the operation to perform on the two fields
|
||||
* @param string $field2 the second field to get the information from
|
||||
* @return self
|
||||
*/
|
||||
public function leftJoin ( $table, $field1, $operator, $field2 )
|
||||
{
|
||||
$this->_leftJoin[] = array(
|
||||
"table" => $table,
|
||||
"field1" => $field1,
|
||||
"field2" => $field2,
|
||||
"operator" => $operator
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the where conditions to the desired query
|
||||
*
|
||||
* @param string $query the query being built
|
||||
* @return self
|
||||
*/
|
||||
private function _get_where ( $query )
|
||||
{
|
||||
for ( $i=0 ; $i<count($this->_where) ; $i++ ) {
|
||||
if ( is_callable( $this->_where[$i] ) ) {
|
||||
$this->_where[$i]( $query );
|
||||
}
|
||||
else {
|
||||
$query->where(
|
||||
$this->_where[$i]['key'],
|
||||
$this->_where[$i]['value'],
|
||||
$this->_where[$i]['op']
|
||||
);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the options (i.e. get them)
|
||||
*
|
||||
* @param Database $db Database connection
|
||||
* @return array List of options
|
||||
* @internal
|
||||
*/
|
||||
public function exec ( $field, $editor, $http, $fields, $leftJoinIn )
|
||||
{
|
||||
$db = $editor->db();
|
||||
$readTable = $editor->readTable();
|
||||
$filteringActive = isset($http['searchPanes']);
|
||||
$viewCount = isset($http['searchPanes_options'])
|
||||
? filter_var($http['searchPanes_options']['viewCount'], FILTER_VALIDATE_BOOLEAN)
|
||||
: true;
|
||||
$viewTotal = isset($http['searchPanes_options'])
|
||||
? filter_var($http['searchPanes_options']['viewTotal'], FILTER_VALIDATE_BOOLEAN)
|
||||
: false;
|
||||
$cascade = isset($http['searchPanes_options'])
|
||||
? filter_var($http['searchPanes_options']['cascade'], FILTER_VALIDATE_BOOLEAN)
|
||||
: false;
|
||||
$entries = null;
|
||||
|
||||
// If the value is not yet set then set the variable to be the field name
|
||||
$value = $this->_value == null
|
||||
? $field->dbField()
|
||||
: $this->_value;
|
||||
|
||||
|
||||
// If the table is not yet set then set the table variable to be the same as editor
|
||||
// This is not taking a value from the SearchPaneOptions instance as the table should be defined in value/label. This throws up errors if not.
|
||||
if($this->_table !== null) {
|
||||
$table = $this->_table;
|
||||
}
|
||||
else if(count($readTable) > 0) {
|
||||
$table = $readTable;
|
||||
}
|
||||
else {
|
||||
$table = $editor->table();
|
||||
}
|
||||
|
||||
// If the label value has not yet been set then just set it to be the same as value
|
||||
$label = $this->_label == null
|
||||
? $value
|
||||
: $this->_label[0];
|
||||
|
||||
$formatter = $this->_renderer
|
||||
? $this->_renderer
|
||||
: function ( $str ) {
|
||||
return $str;
|
||||
};
|
||||
|
||||
// Set up the join variable so that it will fit nicely later
|
||||
$leftJoin = gettype($this->_leftJoin) === 'array' ?
|
||||
$this->_leftJoin :
|
||||
array($this->_leftJoin);
|
||||
|
||||
foreach($leftJoinIn as $lj) {
|
||||
$found = false;
|
||||
|
||||
foreach($leftJoin as $lje) {
|
||||
if($lj['table'] === $lje['table']) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$found) {
|
||||
array_push($leftJoin, $lj);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the data for the pane options
|
||||
$q = $db
|
||||
->query('select')
|
||||
->distinct(true)
|
||||
->table( $table )
|
||||
->get( $label." as label", $value." as value" )
|
||||
->left_join($leftJoin)
|
||||
->group_by( $value )
|
||||
->where( $this->_where );
|
||||
|
||||
// If not cascading, then the total and count must be the same
|
||||
if ($viewTotal) {
|
||||
$q->get("COUNT(*) as total");
|
||||
}
|
||||
|
||||
if ( $this->_order ) {
|
||||
// For cases where we are ordering by a field which isn't included in the list
|
||||
// of fields to display, we need to add the ordering field, due to the
|
||||
// select distinct.
|
||||
$orderFields = explode( ',', $this->_order );
|
||||
|
||||
for ( $i=0, $ien=count($orderFields) ; $i<$ien ; $i++ ) {
|
||||
$orderField = strtolower( $orderFields[$i] );
|
||||
$orderField = str_replace( ' asc', '', $orderField );
|
||||
$orderField = str_replace( ' desc', '', $orderField );
|
||||
$orderField = trim( $orderField );
|
||||
|
||||
if ( ! in_array( $orderField, $fields ) ) {
|
||||
$q->get( $orderField );
|
||||
}
|
||||
}
|
||||
|
||||
$q->order( $this->_order );
|
||||
}
|
||||
|
||||
$rows = $q
|
||||
->exec()
|
||||
->fetchAll();
|
||||
|
||||
// Remove any filtering entries that don't exist in the database (values might have changed)
|
||||
if (isset($http['searchPanes'][$field->name()])) {
|
||||
$values = array_column($rows, 'value');
|
||||
$selected = $http['searchPanes'][$field->name()];
|
||||
|
||||
for ($i=0 ; $i<count($selected) ; $i++) {
|
||||
$idx = array_search($selected[$i], $values);
|
||||
|
||||
if ($idx === false) {
|
||||
array_splice($http['searchPanes'][$field->name()], $i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply filters to cascade tables
|
||||
if ($viewCount || $cascade) {
|
||||
$query = $db
|
||||
->query('select')
|
||||
->distinct(true)
|
||||
->table($table)
|
||||
->left_join($leftJoin);
|
||||
|
||||
if ( $field->apply('get') && $field->getValue() === null ) {
|
||||
$query->get($value." as value");
|
||||
$query->group_by($value);
|
||||
|
||||
// We viewTotal is enabled, we need to do a count to get the number of records,
|
||||
// If it isn't we still need to know it exists, but don't care about the cardinality
|
||||
if ($viewCount) {
|
||||
$query->get("COUNT(*) as count");
|
||||
}
|
||||
else {
|
||||
$query->get("(1) as count");
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the where queries based upon the options selected by the user
|
||||
foreach ($fields as $fieldOpt) {
|
||||
$add = false;
|
||||
$fieldName = $fieldOpt->name();
|
||||
|
||||
// If there is a last value set then a slightly different set of results is required for cascade
|
||||
// That panes results are based off of the results when only considering the selections of all of the others
|
||||
if (isset($http['searchPanesLast']) && $field->name() === $http['searchPanesLast']) {
|
||||
if (isset($http['searchPanes'][$fieldName]) && $fieldName !== $http['searchPanesLast']) {
|
||||
$add = true;
|
||||
}
|
||||
}
|
||||
else if (isset($http['searchPanes']) && isset($http['searchPanes'][$fieldName])) {
|
||||
$add = true;
|
||||
}
|
||||
|
||||
if ($add) {
|
||||
$query->where( function ($q) use ($fieldOpt, $http, $fieldName) {
|
||||
for($j=0, $jen=count($http['searchPanes'][$fieldName]); $j < $jen ; $j++) {
|
||||
$q->or_where(
|
||||
$fieldOpt->dbField(),
|
||||
isset($http['searchPanes_null'][$fieldName][$j])
|
||||
? null
|
||||
: $http['searchPanes'][$fieldName][$j],
|
||||
'='
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$entriesRows = $query
|
||||
->exec()
|
||||
->fetchAll();
|
||||
|
||||
// Key by the value for fast lookup
|
||||
$entriesKeys = array_column($entriesRows, 'value');
|
||||
$entries = array_combine($entriesKeys, $entriesRows);
|
||||
}
|
||||
|
||||
$out = array();
|
||||
|
||||
for ( $i=0, $ien=count($rows) ; $i<$ien ; $i++ ) {
|
||||
$row = $rows[$i];
|
||||
$value = $row['value'];
|
||||
$total = isset($row['total']) ? $row['total'] : null;
|
||||
$count = $total;
|
||||
|
||||
if ($entries !== null) {
|
||||
$count = isset($entries[$value]) && isset($entries[$value]['count'])
|
||||
? $entries[$value]['count']
|
||||
: 0;
|
||||
|
||||
// For when viewCount is enabled and viewTotal is not
|
||||
// the total needs to be the same as the count!
|
||||
if ($total === null) {
|
||||
$total = $count;
|
||||
}
|
||||
}
|
||||
|
||||
$out[] = array(
|
||||
"label" => $formatter($row['label']),
|
||||
"total" => $total,
|
||||
"value" => $value,
|
||||
"count" => $count
|
||||
);
|
||||
}
|
||||
|
||||
// Only sort if there was no SQL order field
|
||||
if ( ! $this->_order ) {
|
||||
usort( $out, function ( $a, $b ) {
|
||||
$aLabel = $a['label'];
|
||||
$bLabel = $b['label'];
|
||||
|
||||
if ($aLabel === null) {
|
||||
$aLabel = '';
|
||||
}
|
||||
|
||||
if ($bLabel === null) {
|
||||
$bLabel = '';
|
||||
}
|
||||
|
||||
return is_numeric($aLabel) && is_numeric($bLabel) ?
|
||||
($aLabel*1) - ($bLabel*1) :
|
||||
strcmp( $aLabel, $bLabel );
|
||||
} );
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
735
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Upload.php.txt
vendored
Normal file
735
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Upload.php.txt
vendored
Normal file
@ -0,0 +1,735 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2015 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
use DataTables;
|
||||
|
||||
|
||||
/**
|
||||
* Upload class for Editor. This class provides the ability to easily specify
|
||||
* file upload information, specifically how the file should be recorded on
|
||||
* the server (database and file system).
|
||||
*
|
||||
* An instance of this class is attached to a field using the {@see
|
||||
* Field->upload()} method. When Editor detects a file upload for that file the
|
||||
* information provided for this instance is executed.
|
||||
*
|
||||
* The configuration is primarily driven through the {@see Upload->db()} and
|
||||
* {@see Upload->action()} methods:
|
||||
*
|
||||
* * {@see Upload->db()} Describes how information about the uploaded file is to be
|
||||
* stored on the database.
|
||||
* * {@see Upload->action()} Describes where the file should be stored on the file system
|
||||
* and provides the option of specifying a custom action when a file is
|
||||
* uploaded.
|
||||
*
|
||||
* Both methods are optional - you can store the file on the server using the
|
||||
* {@see Upload->db()} method only if you want to store the file in the database, or if
|
||||
* you don't want to store relational data on the database us only
|
||||
* {@see Upload->action()}. However, the majority of the time it is best to use
|
||||
* both - store information about the file on the database for fast retrieval (using a
|
||||
* {@see Editor->leftJoin()} for example) and the file on the file system for direct
|
||||
* web access.
|
||||
*
|
||||
* @example
|
||||
* Store information about a file in a table called `files` and the actual
|
||||
* file in an `uploads` directory.
|
||||
* ```
|
||||
* Field::inst( 'imageId' )
|
||||
* ->upload(
|
||||
* Upload::inst( $_SERVER['DOCUMENT_ROOT'].'/uploads/__ID__.__EXTN__' )
|
||||
* ->db( 'files', 'id', array(
|
||||
* 'webPath' => Upload::DB_WEB_PATH,
|
||||
* 'fileName' => Upload::DB_FILE_NAME,
|
||||
* 'fileSize' => Upload::DB_FILE_SIZE,
|
||||
* 'systemPath' => Upload::DB_SYSTEM_PATH
|
||||
* ) )
|
||||
* ->allowedExtensions( array( 'png', 'jpg' ), "Please upload an image file" )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* As above, but with PHP 5.4 (which allows chaining from new instances of a
|
||||
* class)
|
||||
* ```
|
||||
* newField( 'imageId' )
|
||||
* ->upload(
|
||||
* new Upload( $_SERVER['DOCUMENT_ROOT'].'/uploads/__ID__.__EXTN__' )
|
||||
* ->db( 'files', 'id', array(
|
||||
* 'webPath' => Upload::DB_WEB_PATH,
|
||||
* 'fileName' => Upload::DB_FILE_NAME,
|
||||
* 'fileSize' => Upload::DB_FILE_SIZE,
|
||||
* 'systemPath' => Upload::DB_SYSTEM_PATH
|
||||
* ) )
|
||||
* ->allowedExtensions( array( 'png', 'jpg' ), "Please upload an image file" )
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
class Upload extends DataTables\Ext {
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Constants
|
||||
*/
|
||||
|
||||
/** Database value option (`Db()`) - File content. This should be written to
|
||||
* a blob. Typically this should be avoided and the file saved on the file
|
||||
* system, but there are cases where it can be useful to store the file in
|
||||
* the database.
|
||||
*/
|
||||
const DB_CONTENT = 'editor-content';
|
||||
|
||||
/** Database value option (`Db()`) - Content type */
|
||||
const DB_CONTENT_TYPE = 'editor-contentType';
|
||||
|
||||
/** Database value option (`Db()`) - File extension */
|
||||
const DB_EXTN = 'editor-extn';
|
||||
|
||||
/** Database value option (`Db()`) - File name (with extension) */
|
||||
const DB_FILE_NAME = 'editor-fileName';
|
||||
|
||||
/** Database value option (`Db()`) - File size (bytes) */
|
||||
const DB_FILE_SIZE = 'editor-fileSize';
|
||||
|
||||
/** Database value option (`Db()`) - MIME type */
|
||||
const DB_MIME_TYPE = 'editor-mimeType';
|
||||
|
||||
/** Database value option (`Db()`) - Full system path to the file */
|
||||
const DB_SYSTEM_PATH = 'editor-systemPath';
|
||||
|
||||
/** Database value option (`Db()`) - HTTP path to the file. This is derived
|
||||
* from the system path by removing `$_SERVER['DOCUMENT_ROOT']`. If your
|
||||
* images live outside of the document root a custom value would be to be
|
||||
* used.
|
||||
*/
|
||||
const DB_WEB_PATH = 'editor-webPath';
|
||||
|
||||
/** Read from the database - don't write to it
|
||||
*/
|
||||
const DB_READ_ONLY = 'editor-readOnly';
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private parameters
|
||||
*/
|
||||
|
||||
private $_action = null;
|
||||
private $_dbCleanCallback = null;
|
||||
private $_dbCleanTableField = null;
|
||||
private $_dbTable = null;
|
||||
private $_dbPKey = null;
|
||||
private $_dbFields = null;
|
||||
private $_dbFormat = null;
|
||||
private $_extns = null;
|
||||
private $_extnError = null;
|
||||
private $_error = null;
|
||||
private $_mode = 0644;
|
||||
private $_validators = array();
|
||||
private $_where = array();
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Upload instance constructor
|
||||
* @param string|callable $action Action to take on upload - this is applied
|
||||
* directly to {@see Upload->action()}.
|
||||
*/
|
||||
function __construct( $action=null )
|
||||
{
|
||||
if ( $action ) {
|
||||
$this->action( $action );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the action to take when a file is uploaded. This can be either of:
|
||||
*
|
||||
* * A string - the value given is the full system path to where the
|
||||
* uploaded file is written to. The value given can include three "macros"
|
||||
* which are replaced by the script dependent on the uploaded file:
|
||||
* * `__EXTN__` - the file extension
|
||||
* * `__NAME__` - the uploaded file's name (including the extension)
|
||||
* * `__ID__` - Database primary key value if the {@see Upload->db()} method is
|
||||
* used.
|
||||
* * A closure - if a function is given the responsibility of what to do
|
||||
* with the uploaded file is transferred to this function. That will
|
||||
* typically involve writing it to the file system so it can be used
|
||||
* later.
|
||||
*
|
||||
* @param string|callable $action Action to take - see description above.
|
||||
* @return self Current instance, used for chaining
|
||||
*/
|
||||
public function action ( $action )
|
||||
{
|
||||
$this->_action = $action;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An array of valid file extensions that can be uploaded. This is for
|
||||
* simple validation that the file is of the expected type - for example you
|
||||
* might use `[ 'png', 'jpg', 'jpeg', 'gif' ]` for images. The check is
|
||||
* case-insensitive. If no extensions are given, no validation is performed
|
||||
* on the file extension.
|
||||
*
|
||||
* @param string[] $extn List of file extensions that are allowable for
|
||||
* the upload
|
||||
* @param string $error Error message if a file is uploaded that doesn't
|
||||
* match the valid list of extensions.
|
||||
* @return self Current instance, used for chaining
|
||||
* @deprecated Use Validate::fileExtensions
|
||||
*/
|
||||
public function allowedExtensions ( $extn, $error="This file type cannot be uploaded" )
|
||||
{
|
||||
$this->_extns = $extn;
|
||||
$this->_extnError = $error;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Database configuration method. When used, this method will tell Editor
|
||||
* what information you want written to a database on file upload, should
|
||||
* you wish to store relational information about your file on the database
|
||||
* (this is generally recommended).
|
||||
*
|
||||
* @param string $table The name of the table where the file information
|
||||
* should be stored
|
||||
* @param string $pkey Primary key column name. The `Upload` class
|
||||
* requires that the database table have a single primary key so each
|
||||
* row can be uniquely identified.
|
||||
* @param array $fields A list of the fields to be written to on upload.
|
||||
* The property names are the database columns and the values can be
|
||||
* defined by the constants of this class. The value can also be a
|
||||
* string or a closure function if you wish to send custom information
|
||||
* to the database.
|
||||
* @param callable Formatting function that can change the data obtained
|
||||
* from the database. Only gets a single parameter passed in - the
|
||||
* database row for the file that is read.
|
||||
* @return self Current instance, used for chaining
|
||||
*/
|
||||
public function db ( $table, $pkey, $fields, $format=null )
|
||||
{
|
||||
$this->_dbTable = $table;
|
||||
$this->_dbPKey = $pkey;
|
||||
$this->_dbFields = $fields;
|
||||
$this->_dbFormat = $format;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a callback function that is used to remove files which no longer have
|
||||
* a reference in a source table.
|
||||
*
|
||||
* @param callable $callback Function that will be executed on clean. It is
|
||||
* given an array of information from the database about the orphaned
|
||||
* rows, and can return true to indicate that the rows should be
|
||||
* removed from the database. Any other return value (including none)
|
||||
* will result in the records being retained.
|
||||
* @return self Current instance, used for chaining
|
||||
*/
|
||||
public function dbClean( $tableField, $callback=null )
|
||||
{
|
||||
// Argument swapping
|
||||
if ( $callback === null ) {
|
||||
$callback = $tableField;
|
||||
$tableField = null;
|
||||
}
|
||||
|
||||
$this->_dbCleanCallback = $callback;
|
||||
$this->_dbCleanTableField = $tableField;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the permissions on the file after it has been uploaded using
|
||||
* chmod.
|
||||
*/
|
||||
public function mode( $m ) {
|
||||
$this->_mode = $m;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a validation method to check file uploads. Multiple validators can be
|
||||
* added by calling this method multiple times - they will be executed in
|
||||
* sequence when a file has been uploaded.
|
||||
*
|
||||
* @param callable $fn Validation function. A PHP `$_FILES` parameter is
|
||||
* passed in for the uploaded file and the return is either a string
|
||||
* (validation failed and error message), or `null` (validation passed).
|
||||
* @return self Current instance, used for chaining
|
||||
*/
|
||||
public function validator ( $fn )
|
||||
{
|
||||
$this->_validators[] = $fn;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a condition to the data to be retrieved from the database. This
|
||||
* must be given as a function to be executed (usually anonymous) and
|
||||
* will be passed in a single argument, the `Query` object, to which
|
||||
* conditions can be added. Multiple calls to this method can be made.
|
||||
*
|
||||
* @param callable $fn Where function.
|
||||
* @return self Current instance, used for chaining
|
||||
*/
|
||||
public function where ( $fn )
|
||||
{
|
||||
$this->_where[] = $fn;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get database information data from the table
|
||||
*
|
||||
* @param \DataTables\Database $db Database
|
||||
* @param number[] [$ids=null] Limit to a specific set of ids
|
||||
* @return array Database information
|
||||
* @internal
|
||||
*/
|
||||
public function data ( $db, $ids=null )
|
||||
{
|
||||
if ( ! $this->_dbTable ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Select the details requested, for the columns requested
|
||||
$q = $db
|
||||
->query( 'select' )
|
||||
->table( $this->_dbTable )
|
||||
->get( $this->_dbPKey );
|
||||
|
||||
foreach ( $this->_dbFields as $column => $prop ) {
|
||||
if ( $prop !== self::DB_CONTENT ) {
|
||||
$q->get( $column );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $ids !== null ) {
|
||||
$q->where_in( $this->_dbPKey, $ids );
|
||||
}
|
||||
|
||||
for ( $i=0, $ien=count($this->_where) ; $i<$ien ; $i++ ) {
|
||||
$q->where( $this->_where[$i] );
|
||||
}
|
||||
|
||||
$result = $q->exec()->fetchAll();
|
||||
$out = array();
|
||||
|
||||
for ( $i=0, $ien=count($result) ; $i<$ien ; $i++ ) {
|
||||
if ($this->_dbFormat) {
|
||||
$this->_dbFormat( $result[$i] );
|
||||
}
|
||||
|
||||
$out[ $result[$i][ $this->_dbPKey ] ] = $result[$i];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean the database
|
||||
* @param \DataTables\Editor $editor Calling Editor instance
|
||||
* @param Field $field Host field
|
||||
* @internal
|
||||
*/
|
||||
public function dbCleanExec ( $editor, $field )
|
||||
{
|
||||
// Database and file system clean up BEFORE adding the new file to
|
||||
// the db, otherwise it will be removed immediately
|
||||
$tables = $editor->table();
|
||||
$this->_dbClean( $editor->db(), $tables[0], $field->dbField() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the set error message
|
||||
*
|
||||
* @return string Class error
|
||||
* @internal
|
||||
*/
|
||||
public function error ()
|
||||
{
|
||||
return $this->_error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute an upload
|
||||
*
|
||||
* @param \DataTables\Editor $editor Calling Editor instance
|
||||
* @return int Primary key value
|
||||
* @internal
|
||||
*/
|
||||
public function exec ( $editor )
|
||||
{
|
||||
$id = null;
|
||||
$upload = $_FILES['upload'];
|
||||
|
||||
// Validation - PHP standard validation
|
||||
if ( $upload['error'] !== UPLOAD_ERR_OK ) {
|
||||
if ( $upload['error'] === UPLOAD_ERR_INI_SIZE ) {
|
||||
$this->_error = "File exceeds maximum file upload size";
|
||||
}
|
||||
else {
|
||||
$this->_error = "There was an error uploading the file (".$upload['error'].")";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validation - acceptable file extensions
|
||||
if ( is_array( $this->_extns ) ) {
|
||||
$extn = pathinfo($upload['name'], PATHINFO_EXTENSION);
|
||||
|
||||
if ( in_array( strtolower($extn), array_map( 'strtolower', $this->_extns ) ) === false ) {
|
||||
$this->_error = $this->_extnError;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validation - custom callback
|
||||
for ( $i=0, $ien=count($this->_validators) ; $i<$ien ; $i++ ) {
|
||||
$res = $this->_validators[$i]( $upload );
|
||||
|
||||
if ( is_string( $res ) ) {
|
||||
$this->_error = $res;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Database
|
||||
if ( $this->_dbTable ) {
|
||||
foreach ( $this->_dbFields as $column => $prop ) {
|
||||
// We can't know what the path is, if it has moved into place
|
||||
// by an external function - throw an error if this does happen
|
||||
if ( ! is_string( $this->_action ) &&
|
||||
($prop === self::DB_SYSTEM_PATH || $prop === self::DB_WEB_PATH )
|
||||
) {
|
||||
$this->_error = "Cannot set path information in database ".
|
||||
"if a custom method is used to save the file.";
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Commit to the database
|
||||
$id = $this->_dbExec( $upload, $editor->db() );
|
||||
}
|
||||
|
||||
// Perform file system actions
|
||||
return $this->_actionExec( $upload, $id );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the primary key column for the table
|
||||
*
|
||||
* @return string Primary key column name
|
||||
* @internal
|
||||
*/
|
||||
public function pkey ()
|
||||
{
|
||||
return $this->_dbPKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the db table name
|
||||
*
|
||||
* @return string DB table name
|
||||
* @internal
|
||||
*/
|
||||
public function table ()
|
||||
{
|
||||
return $this->_dbTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the configured action for the upload
|
||||
*
|
||||
* @param array $upload $_FILES['upload']
|
||||
* @param int $id Primary key value
|
||||
* @return int File identifier - typically the primary key
|
||||
*/
|
||||
private function _actionExec ( $upload, $id )
|
||||
{
|
||||
if ( ! is_string( $this->_action ) ) {
|
||||
// Custom function
|
||||
$action = $this->_action;
|
||||
return $action( $upload, $id );
|
||||
}
|
||||
|
||||
// Default action - move the file to the location specified by the
|
||||
// action string
|
||||
$to = $this->_path( $upload['name'], $id );
|
||||
$res = rename( $upload['tmp_name'], $to );
|
||||
|
||||
if ( $res === false ) {
|
||||
$this->_error = "An error occurred while moving the uploaded file.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->_mode) {
|
||||
chmod($to, $this->_mode);
|
||||
}
|
||||
|
||||
return $id !== null ?
|
||||
$id :
|
||||
$to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the database clean by first getting the information about the
|
||||
* orphaned rows and then calling the callback function. The callback can
|
||||
* then instruct the rows to be removed through the return value.
|
||||
*
|
||||
* @param \DataTables\Database $db Database instance
|
||||
* @param string $editorTable Editor Editor instance table name
|
||||
* @param string $fieldName Host field's name
|
||||
*/
|
||||
private function _dbClean ( $db, $editorTable, $fieldName )
|
||||
{
|
||||
$callback = $this->_dbCleanCallback;
|
||||
|
||||
if ( ! $this->_dbTable || ! $callback ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is a table / field that we should use to check if the value
|
||||
// is in use, then use that. Otherwise we'll try to use the information
|
||||
// from the Editor / Field instance.
|
||||
if ( $this->_dbCleanTableField ) {
|
||||
$fieldName = $this->_dbCleanTableField;
|
||||
}
|
||||
|
||||
$a = explode('.', $fieldName);
|
||||
if ( count($a) === 1 ) {
|
||||
$table = $editorTable;
|
||||
$field = $a[0];
|
||||
}
|
||||
else if ( count($a) === 2 ) {
|
||||
$table = $a[0];
|
||||
$field = $a[1];
|
||||
}
|
||||
else {
|
||||
$table = $a[1];
|
||||
$field = $a[2];
|
||||
}
|
||||
|
||||
// Select the details requested, for the columns requested
|
||||
$q = $db
|
||||
->query( 'select' )
|
||||
->table( $this->_dbTable )
|
||||
->get( $this->_dbPKey );
|
||||
|
||||
foreach ( $this->_dbFields as $column => $prop ) {
|
||||
if ( $prop !== self::DB_CONTENT ) {
|
||||
$q->get( $column );
|
||||
}
|
||||
}
|
||||
|
||||
$q->where( $this->_dbPKey, '(SELECT '.$field.' FROM '.$table.' WHERE '.$field.' IS NOT NULL)', 'NOT IN', false );
|
||||
|
||||
$data = $q->exec()->fetchAll();
|
||||
|
||||
if ( count( $data ) === 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $callback( $data );
|
||||
|
||||
// Delete the selected rows, iff the developer says to do so with the
|
||||
// returned value (i.e. acknowledge that the files have be removed from
|
||||
// the file system)
|
||||
if ( $result === true ) {
|
||||
$qDelete = $db
|
||||
->query( 'delete' )
|
||||
->table( $this->_dbTable );
|
||||
|
||||
for ( $i=0, $ien=count( $data ) ; $i<$ien ; $i++ ) {
|
||||
$qDelete->or_where( $this->_dbPKey, $data[$i][ $this->_dbPKey ] );
|
||||
}
|
||||
|
||||
$qDelete->exec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a record to the database for a newly uploaded file
|
||||
*
|
||||
* @param array $upload $_FILES['upload']
|
||||
* @param \DataTables\Database $db Database instance
|
||||
* @return int Primary key value for the newly uploaded file
|
||||
*/
|
||||
private function _dbExec ( $upload, $db )
|
||||
{
|
||||
$pathFields = array();
|
||||
$insertedId = null;
|
||||
|
||||
// Insert the details requested, for the columns requested
|
||||
$q = $db
|
||||
->query( 'insert' )
|
||||
->table( $this->_dbTable )
|
||||
->pkey( $this->_dbPKey );
|
||||
|
||||
foreach ( $this->_dbFields as $column => $prop ) {
|
||||
switch ( $prop ) {
|
||||
case self::DB_READ_ONLY:
|
||||
break;
|
||||
|
||||
case self::DB_CONTENT:
|
||||
$q->set( $column, file_get_contents($upload['tmp_name']) );
|
||||
break;
|
||||
|
||||
case self::DB_CONTENT_TYPE:
|
||||
case self::DB_MIME_TYPE:
|
||||
$finfo = finfo_open(FILEINFO_MIME);
|
||||
$mime = finfo_file($finfo, $upload['tmp_name']);
|
||||
finfo_close($finfo);
|
||||
|
||||
$q->set( $column, $mime );
|
||||
break;
|
||||
|
||||
case self::DB_EXTN:
|
||||
$extn = pathinfo($upload['name'], PATHINFO_EXTENSION);
|
||||
$q->set( $column, $extn );
|
||||
break;
|
||||
|
||||
case self::DB_FILE_NAME:
|
||||
$q->set( $column, $upload['name'] );
|
||||
break;
|
||||
|
||||
case self::DB_FILE_SIZE:
|
||||
$q->set( $column, $upload['size'] );
|
||||
break;
|
||||
|
||||
case self::DB_SYSTEM_PATH:
|
||||
$pathFields[ $column ] = self::DB_SYSTEM_PATH;
|
||||
$q->set( $column, '-' ); // Use a temporary value to avoid cases
|
||||
break; // where the db will reject empty values
|
||||
|
||||
case self::DB_WEB_PATH:
|
||||
$pathFields[ $column ] = self::DB_WEB_PATH;
|
||||
$q->set( $column, '-' ); // Use a temporary value (as above)
|
||||
break;
|
||||
|
||||
default:
|
||||
$val = $prop;
|
||||
|
||||
// Callable function - execute to get the value
|
||||
if ( is_callable($prop) && is_object($prop) ) {
|
||||
$val = $prop( $db, $upload );
|
||||
}
|
||||
|
||||
// If the primary key value was set - use that
|
||||
if ( $column === $this->_dbPKey ) {
|
||||
$insertedId = $val;
|
||||
}
|
||||
|
||||
if (is_string($val) && ! empty($val)) {
|
||||
// Allow for replacement of __ID__, etc when the value is a string
|
||||
$pathFields[ $column ] = $val;
|
||||
$q->set( $column, '-' ); // Use a temporary value (as above)
|
||||
}
|
||||
else {
|
||||
$q->set( $column, $val );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$res = $q->exec();
|
||||
$id = $insertedId !== null
|
||||
? $insertedId
|
||||
: $res->insertId();
|
||||
|
||||
// Update the newly inserted row with the path information. We have to
|
||||
// use a second statement here as we don't know in advance what the
|
||||
// database schema is and don't want to prescribe that certain triggers
|
||||
// etc be created. It makes it a bit less efficient but much more
|
||||
// compatible
|
||||
if ( count( $pathFields ) ) {
|
||||
// For this to operate the action must be a string, which is
|
||||
// validated in the `exec` method
|
||||
$path = $this->_path( $upload['name'], $id );
|
||||
$webPath = str_replace($_SERVER['DOCUMENT_ROOT'], '', $path);
|
||||
$q = $db
|
||||
->query( 'update' )
|
||||
->table( $this->_dbTable )
|
||||
->where( $this->_dbPKey, $id );
|
||||
|
||||
foreach ( $pathFields as $column => $type ) {
|
||||
$q->set( $column, $type === self::DB_WEB_PATH ? $webPath : $path );
|
||||
}
|
||||
|
||||
$q->exec();
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply macros to a user specified path
|
||||
*
|
||||
* @param string $name File path
|
||||
* @param int $id Primary key value for the file
|
||||
* @return string Resolved path
|
||||
*/
|
||||
private function _path ( $name, $id )
|
||||
{
|
||||
$extn = pathinfo( $name, PATHINFO_EXTENSION );
|
||||
|
||||
$to = $this->_action;
|
||||
$to = str_replace( "__NAME__", $name, $to );
|
||||
$to = str_replace( "__ID__", $id, $to );
|
||||
$to = str_replace( "__EXTN__", $extn, $to );
|
||||
|
||||
return $to;
|
||||
}
|
||||
}
|
||||
|
||||
1396
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Validate.php.txt
vendored
Normal file
1396
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/Validate.php.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
99
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/ValidateOptions.php.txt
vendored
Normal file
99
ci4/app/ThirdParty/DatatablesEditor/docs/files/Editor/ValidateOptions.php.txt
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* DataTables PHP libraries.
|
||||
*
|
||||
* PHP libraries for DataTables and DataTables Editor, utilising PHP 5.3+.
|
||||
*
|
||||
* @author SpryMedia
|
||||
* @copyright 2012-2014 SpryMedia ( http://sprymedia.co.uk )
|
||||
* @license http://editor.datatables.net/license DataTables Editor
|
||||
* @link http://editor.datatables.net
|
||||
*/
|
||||
|
||||
namespace DataTables\Editor;
|
||||
if (!defined('DATATABLES')) exit();
|
||||
|
||||
use DataTables;
|
||||
|
||||
/**
|
||||
* Common validation options that can be specified for all validation methods.
|
||||
*/
|
||||
class ValidateOptions extends DataTables\Ext {
|
||||
private $_empty = true;
|
||||
private $_message = 'Input not valid';
|
||||
private $_optional = true;
|
||||
|
||||
function __construct( $opts=null )
|
||||
{
|
||||
if ( $opts ) {
|
||||
if ( isset( $opts['empty'] ) ) {
|
||||
$this->allowEmpty( $opts['empty'] );
|
||||
}
|
||||
if ( isset( $opts['message'] ) ) {
|
||||
$this->message( $opts['message'] );
|
||||
}
|
||||
if ( isset( $opts['optional'] ) ) {
|
||||
$this->optional( $opts['optional'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the error message to use if validation fails
|
||||
* @param string $msg Error message to use. If not given, the currently
|
||||
* set message will be returned.
|
||||
* @return ValidateOptions|string Self if setting, message if getting.
|
||||
*/
|
||||
public function message ( $msg=null ) {
|
||||
if ( $msg === null ) {
|
||||
return $this->_message;
|
||||
}
|
||||
|
||||
$this->_message = $msg;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the field empty option
|
||||
* @param boolean $empty `false` if the field is not allowed to be
|
||||
* empty. `true` if it can be.
|
||||
* @return ValidateOptions|boolean Self if setting, current value if getting.
|
||||
*/
|
||||
public function allowEmpty ( $empty=null ) {
|
||||
if ( $empty === null ) {
|
||||
return $this->_empty;
|
||||
}
|
||||
|
||||
$this->_empty = $empty;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get / set the field optional option
|
||||
* @param boolean $optional `false` if the field does not need to be
|
||||
* submitted. `true` if it must be.
|
||||
* @return ValidateOptions|boolean Self if setting, current value if getting.
|
||||
*/
|
||||
public function optional ( $optional=null ) {
|
||||
if ( $optional === null ) {
|
||||
return $this->_optional;
|
||||
}
|
||||
|
||||
$this->_optional = $optional;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static public function select ( $user ) {
|
||||
if ( $user ) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
return new ValidateOptions();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user