Projekt

Obecné

Profil

<?php defined('SYSPATH') or die('No direct script access.');
/*
* This file is part of open source system FreeNetIS
* and it is released under GPLv3 licence.
*
* More info about licence can be found:
* http://www.gnu.org/licenses/gpl-3.0.html
*
* More info about project can be found:
* http://www.freenetis.org/
*
*/

/**
* This is library for filter form
*
* @author Michal Kliment
* @version 1.0
*/
class Filter_form
{
/**
* Template to show filter form
* @var string
*/
protected $template = 'filter_form_template';

/**
* Array of all filters
* @var array
*/
protected $filters = array();

/**
* Array of all filter's values
* @var array
*/
protected $values = array();

/**
* Array of all filter's types
* @var array
*/
protected $types = array();

/**
* Array of all filter's operations
* @var array
*/
protected $operations = array();

/**
* Array of all filter's tables
* @var array
*/
protected $tables = array();

/**
* Array of boolean values whether filter is default
* @var array
*/
protected $default = array();

/**
* Count of default filters
* @var integer
*/
protected $default_count = 0;

/**
* Definition of constants
*/
const OPER_CONTAINS = 1;
const OPER_CONTAINS_NOT = 2;
const OPER_IS = 3;
const OPER_IS_NOT = 4;
const OPER_EQUAL = 5;
const OPER_EQUAL_NOT = 6;
const OPER_SMALLER = 7;
const OPER_SMALLER_OR_EQUAL = 8;
const OPER_GREATER = 9;
const OPER_GREATER_OR_EQUAL = 10;
const OPER_BIT_IS = 11;
const OPER_BIT_IS_NOT = 12;
const OPER_NETWORK_IS_IN = 13;
const OPER_NETWORK_IS_NOT_IN = 14;
const OPER_IS_EMPTY = 15;
const OPER_IS_NOT_EMPTY = 16;

/**
* Array with definition of all operations
* @var array
*/
protected $opers = array
(
self::OPER_CONTAINS => array
(
'name' => 'contains',
'sql' => "LIKE '%{VALUE}%' COLLATE utf8_general_ci",
),
self::OPER_CONTAINS_NOT => array
(
'name' => 'contains not',
'sql' => "NOT LIKE '%{VALUE}%' COLLATE utf8_general_ci",
),
self::OPER_IS => array
(
'name' => 'is',
'sql' => "LIKE '{VALUE}' COLLATE utf8_general_ci"
),
self::OPER_IS_NOT => array
(
'name' => 'is not',
'sql' => "NOT LIKE '{VALUE}' COLLATE utf8_general_ci" ,
),
self::OPER_EQUAL => array
(
'name' => '=',
'sql' => "= '{VALUE}'",
),
self::OPER_EQUAL_NOT => array
(
'name' => '!=',
'sql' => "<> '{VALUE}'",
),
self::OPER_SMALLER => array
(
'name' => '<',
'sql' => "< '{VALUE}'",
),
self::OPER_SMALLER_OR_EQUAL => array
(
'name' => '<=',
'sql' => "<= '{VALUE}'",
),
self::OPER_GREATER => array
(
'name' => '>',
'sql' => "> '{VALUE}'",
),
self::OPER_GREATER_OR_EQUAL => array
(
'name' => '>=',
'sql' => ">= '{VALUE}'",
),
self::OPER_BIT_IS => array
(
'name' => 'is',
'sql' => "& {VALUE} > 0",
),
self::OPER_BIT_IS_NOT => array
(
'name' => 'is not',
'sql' => "& {VALUE} = 0",
),
self::OPER_NETWORK_IS_IN => array
(
'name' => 'is in',
'pattern' => '/^(?P<VALUE1>((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9]))\/(?P<VALUE2>(3[0-2])|(2[0-9])|(1[0-9])|([0-9]))$/',
'sql' => "& (0xffffffff<<(32-{VALUE2}) & 0xffffffff) = inet_aton('{VALUE1}')",
'function' => 'inet_aton'
),
self::OPER_NETWORK_IS_NOT_IN => array
(
'name' => 'is not in',
'pattern' => '/^(?P<VALUE1>((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9])\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9][0-9])|[0-9]))\/(?P<VALUE2>(3[0-2])|(2[0-9])|(1[0-9])|([0-9]))$/',
'sql' => "& (0xffffffff<<(32-{VALUE2}) & 0xffffffff) <> inet_aton('{VALUE1}')",
'function' => 'inet_aton'
),
self::OPER_IS_EMPTY => array
(
'name' => 'is empty',
'sql' => 'LIKE ""',
'null' => TRUE
),
self::OPER_IS_NOT_EMPTY => array
(
'name' => 'is not empty',
'sql' => 'NOT LIKE ""',
'null' => TRUE
)
);

/**
* Array with definition of types and its operations
* @var array
*/
protected $operation_types = array
(
'combo' => array
(
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_CONTAINS,
self::OPER_CONTAINS_NOT
),
'select' => array
(
self::OPER_IS,
self::OPER_IS_NOT
),
'text' => array
(
self::OPER_CONTAINS,
self::OPER_CONTAINS_NOT,
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_IS_EMPTY,
self::OPER_IS_NOT_EMPTY
),
'number' => array
(
self::OPER_EQUAL,
self::OPER_EQUAL_NOT,
self::OPER_SMALLER,
self::OPER_SMALLER_OR_EQUAL,
self::OPER_GREATER,
self::OPER_GREATER_OR_EQUAL
),
'bit' => array
(
self::OPER_BIT_IS,
self::OPER_BIT_IS_NOT
),
'date' => array
(
self::OPER_EQUAL,
self::OPER_EQUAL_NOT,
self::OPER_SMALLER,
self::OPER_SMALLER_OR_EQUAL,
self::OPER_GREATER,
self::OPER_GREATER_OR_EQUAL
),
'select_number' => array
(
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_EQUAL,
self::OPER_EQUAL_NOT,
self::OPER_SMALLER,
self::OPER_SMALLER_OR_EQUAL,
self::OPER_GREATER,
self::OPER_GREATER_OR_EQUAL
),
'network_address' => array
(
self::OPER_IS,
self::OPER_IS_NOT,
self::OPER_CONTAINS,
self::OPER_CONTAINS_NOT,
self::OPER_NETWORK_IS_IN,
self::OPER_NETWORK_IS_NOT_IN
)
);

/**
* Array with definition of minlengths of types
* @var array
*/
protected $minlengths = array
(
'combo' => 0,
'select' => 0,
'text' => 1,
'bit' => 0,
'date' => 1,
'select_number' => 0,
'network_address' => 1
);

/**
* Array with definition of return type of type (key or value)
* @var array
*/
protected $returns = array
(
'combo' => 'value',
'select' => 'key',
'text' => 'value',
'bit' => 'key',
'number' => 'value',
'date' => 'value',
'select_number' => 'key',
'network_address' => 'value'
);

/**
* Constructor, sets table name and compiles values from $_GET
*
* @author Michal Kliment
* @param string $table
*/
public function __construct($table = '')
{
$this->table = $table;

$this->template = new View ($this->template);

$this->types = array();
$this->operations = array();
$this->values = array();

$types = Input::instance()->get('types');
$operations = Input::instance()->get('opers');
$values = Input::instance()->get('values');
$tables = Input::instance()->get('tables');
$default = Input::instance()->get('default');

if (count($values))
{
foreach ($values as $i => $value)
{
$value = trim($value);
if ($value != '' || (
isset($this->opers[$operations[$i]]['null']) &&
$this->opers[$operations[$i]]['null']
))
{
$this->values[] = $value;
$this->types[] = $types[$i];
$this->operations[] = $operations[$i];
$this->tables[] = $tables[$i];
$this->default[] = $default[$i];
$this->default_count += $default[$i];
}
}
}
}

/**
* Automatic loads filters from $_GET
*
* @author Michal Kliment
* @return int
*/
public function autoload()
{
$loaded = 0;
foreach ($this->types as $i => $type)
{
$loaded++;

$filter = new Filter($type, $this->tables[$i]);

$this->filters[$type] = $filter;
}
return $loaded;
}

/**
* Adds new filter to filter form
*
* @author Michal Kliment
* @param string $name
* @return Filter object
*/
public function add($name)
{
$filter = new Filter($name, $this->table);

$this->filters[$name] = $filter;

return $filter;
}

/**
* Loads default filter's values
*
* @author Michal Kliment
* @return int
*/
private function load_default()
{
if (!count ($this->values))
{
foreach ($this->filters as $filter)
{
foreach ($filter->default as $default)
{
$this->values[] = $default['value'];
$this->types[] = $filter->name;
$this->operations[] = $default['oper'];
$this->default[] = 1;
$this->default_count++;
}
}
}
return $this->default_count;
}

/**
* Renders filter form as HTML
*
* @author Michal Kliment
* @return string
*/
public function html()
{
// load default filter's values
$this->load_default();

// local variables
$types = array();
$value_options = array();
$js_operation_values = array();
$js_types = array();
$callbacks = array();
$minlengths = array();
$withouts = array();
$tables = array();
$classes = array();

foreach ($this->filters as $filter)
{
$types[$filter->name] = $filter->label;

foreach ($this->operation_types[$filter->type] as $operation_type)
{
$js_operation_values[$filter->name][$operation_type] = _($this->opers[$operation_type]['name']);
}

$js_types[$filter->name] = $filter->type;
$value_options[$filter->name] = $filter->values;

if ($filter->callback != '')
$callbacks[$filter->name] = url_lang::base().$filter->callback;

if (isset($this->minlengths[$filter->type]))
{
$minlengths[$filter->name] = $this->minlengths[$filter->type];
$withouts[$filter->name] = ($this->minlengths[$filter->type]) ? 1 : 0;
}
else
$withouts[$filter->name] = 1;

$tables[$filter->name] = $filter->table;

if (is_array($filter->class))
$classes[$filter->name] = $filter->class;
else
$classes[$filter->name] = array('all' => $filter->class);
}

$operations = array();
foreach ($this->opers as $i => $operation)
{
$operations[$i] = url_lang::lang('texts.'.$operation['name']);
}

$this->template->type_values = $types;
$this->template->operation_values = $operations;
$this->template->js_operation_values = $js_operation_values;
$this->template->js_types = $js_types;
$this->template->value_options = $value_options;
$this->template->callbacks = $callbacks;
$this->template->minlengths = $minlengths;
$this->template->withouts = $withouts;
$this->template->tables = $tables;
$this->template->classes = $classes;

$this->template->default = $this->default;
$this->template->default_count = $this->default_count;
$this->template->types = $this->types;
$this->template->operations = $this->operations;
$this->template->values = $this->values;
return $this->template->render();
}

/**
* Returns SQL query (only part after WHERE) to use in model methods
*
* @author Michal Kliment
* @return string
*/
public function as_sql ()
{
// loads default filter's values
$this->load_default();

$queries = array();
foreach ($this->types as $i => $type)
{
$filter = $this->filters[$type];

$value = trim($this->values[$i]);

if ($this->returns[$filter->type] == 'key' &&
arr::search($value, $filter->values) !== FALSE)
{
$value = arr::search($value, $filter->values);
}
$sql = $this->opers[$this->operations[$i]]['sql'];

if (isset($this->opers[$this->operations[$i]]['pattern']))
{
if (!preg_match(
$this->opers[$this->operations[$i]]['pattern'],
mysql_real_escape_string($value), $matches
))
{
continue;
}

foreach ($matches as $key => $value)
{
$sql = str_replace('{'.$key.'}', mysql_real_escape_string($value), $sql);
}
}
$table_pom = mb_strlen($filter->table) ? $filter->table . '.' : '';

if (isset($this->opers[$this->operations[$i]]['function']))
{
$queries[] = $this->opers[$this->operations[$i]]['function']
. "(" . $table_pom . $filter->name . ") "
. str_replace("{VALUE}", mysql_real_escape_string($value), $sql);
}
else
{
$queries[] = $table_pom . $filter->name . " "
. str_replace("{VALUE}", mysql_real_escape_string($value), $sql);
}
}

return implode (" AND ", $queries);
}

/**
*
* @return array
*/
public function as_array()
{
// loads default filter's values
$this->load_default();

$data = array();
foreach ($this->types as $i => $type)
{
$filter = $this->filters[$type];

$value = trim($this->values[$i]);

if ($this->returns[$filter->type] == 'key' &&
arr::search($value, $filter->values) !== FALSE)
{
$value = arr::search($value, $filter->values);
}

$data[] = array
(
'key' => $filter->name,
'value' => $value,
'op' => $this->operations[$i]
);
}

return $data;
}

/**
* Prints filter form as HTML
*
* @author Michal Kliment
* @return string
*/
public function __toString()
{
return $this->html();
}
}
(5-5/23)