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:
467
ci4/app/ThirdParty/DatatablesEditor/Editor/SearchPaneOptions.php
vendored
Normal file
467
ci4/app/ThirdParty/DatatablesEditor/Editor/SearchPaneOptions.php
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user