Add table filter system

This commit is contained in:
Alexander Nicolaysen Sørnes
2008-02-09 22:18:48 +01:00
committed by Chris Morgan
parent 13fe229774
commit b2adeab95a
2 changed files with 442 additions and 0 deletions

191
include/db_filter.php Normal file
View File

@@ -0,0 +1,191 @@
<?php
/**
* Classes for managing SQL filters (parts of SQL queries)
*
* Copyright 2008 BitSplash Software LLC
* Copyright 2008 Alexander N. Sørnes <alex@thehandofagony.com>
*
*/
define('FILTER_LIKE', 1);
define('FILTER_EQUALS', 2);
define('FILTER_GREATER_THAN', 3);
define('FILTER_LESS_THAN', 4);
define('FILTER_NOT_EQUALS', 5);
define('FILTER_NOT_LIKE', 6);
/* A filter as part of an SQL query, such as something = 'somevalue' */
class Filter
{
private $sColumn; // The table column the filter is for
private $iType; // The type of filter, like EQUALS, LIKE
private $sData; // What the column is to be compared to */
public function Filter($sColumn, $iType, $sData)
{
$this->sColumn = $sColumn;
$this->iType = $iType;
$this->sData = $sData;
}
public function getColumn()
{
return $this->sColumn;
}
public function setData($sData)
{
$this->sData = $sData;
}
public function getOperatorId()
{
return $this->iType;
}
public function getData()
{
return $this->sData;
}
public function getOperator()
{
switch($this->iType)
{
case FILTER_LIKE:
return 'LIKE';
case FILTER_EQUALS:
return '=';
case FILTER_LESS_THAN:
return '<';
case FILTER_GREATER_THAN:
return '>';
case FILTER_NOT_EQUALS:
return '!=';
case FILTER_NOT_LIKE:
return 'NOT LIKE';
default:
return 0; // error
}
}
public function getFilter()
{
$sOp = $this->getOperator();
return "{$this->sColumn} $sOp '{$this->sData}'";
}
}
/* Class handling tables where the user can filter contents */
class FilterSet
{
private $aFilters; // Array of filters for this table
public function FilterSet($sTableName = '')
{
$this->aFilters = array();
if($sTableName)
$this->loadTable($sTableName);
}
public function loadTable($sTableName)
{
$sQuery = "SELECT * FROM $sTableName";
$hResult = query_appdb($sQuery);
while($oRow = mysql_fetch_object($hResult))
{
$this->addFilterObject(new Filter($oRow->sColumn, $oRow->iType, $oRow->sData));
}
}
public function saveTable($sTableName)
{
$hResult = query_appdb("DROP TABLE IF EXISTS $sTableName");
$hResult = query_appdb("CREATE TABLE $sTableName (
sColumn VARCHAR(255) NOT NULL,
iType INT(3) NOT NULL,
sData VARCHAR(255) NOT NULL DEFAULT ''
)");
if(!$hResult)
return false;
$bSuccess = true;
foreach($this->aFilters as $oFilter)
{
$hResult = query_appdb("INSERT INTO $sTableName (sColumn,iType,sData)
VALUES('{$oFilter->getColumn()}','{$oFilter->getOperatorId()}','{$oFilter->getData()}')");
if(!$hResult)
$bSuccess = false;
}
return $bSuccess;
}
public function addFilterObject(Filter $oFilter)
{
$this->aFilters[] = $oFilter;
}
public function AddFilter($sColumn, $iType, $sData)
{
$this->aFilters[] = new Filter($sColumn, $iType, $sData);
}
public function getFilterCount()
{
return sizeof($this->aFilters);
}
public function getFilters()
{
return $this->aFilters;
}
public function getWhereClause()
{
$sFilter = '';
for($i = 0; $i < sizeof($this->aFilters); $i++)
{
$oFilter = $this->aFilters[$i];
$sFilter .= $oFilter->getFilter();
if($i < sizeof($this->aFilters) - 1)
$sFilter .= ' AND ';
}
return $sFilter;
}
function getQuery($sTable, $iLimit = 0)
{
$sWhere = $this->getFilterCount() ? 'WHERE '.$this->getWhereClause() : '';
$sQuery = "SELECT * FROM $sTable $sWhere";
$iLimit = mysql_real_escape_string($iLimit);
if($iLimit)
$sQuery .= " LIMIT 0,$iLimit";
return $sQuery;
}
function getMatchedItems($sTable, $iLimit = 0)
{
return query_appdb($this->getQuery($sTable, $iLimit));
}
function getMatchedItemsCount($sTable)
{
return mysql_num_rows($this->getMatchedItems($sTable));
}
}
?>

251
include/db_filter_ui.php Normal file
View File

@@ -0,0 +1,251 @@
<?php
/**
* User interface for the SQL filter classes
*
* Copyright 2008 BitSplash Software LLC
* Copyright 2008 Alexander N. Sørnes <alex@thehandofagony.com>
*
*/
require_once('db_filter.php');
/* Info describing an available filter: what column it applies to,
and what comparison options are available */
class FilterInfo
{
private $sColumn;
private $sDisplayName;
private $aTypes; // Available filters for this column
public function FilterInfo($sColumn, $sDisplayName, $aTypes)
{
$this->sColumn = $sColumn;
$this->sDisplayName = $sDisplayName;
$this->aTypes = $aTypes;
}
public function getColumn()
{
return $this->sColumn;
}
public function getDisplayName()
{
return $this->sDisplayName;
}
public function getTypes()
{
return $this->aTypes;
}
public static function getOpName($iOpId)
{
switch($iOpId)
{
case FILTER_EQUALS:
return 'equal to';
case FILTER_LIKE:
return 'like';
case FILTER_NOT_LIKE:
return 'not like';
case FILTER_NOT_EQUALS:
return 'not equal to';
case FILTER_LESS_THAN:
return 'less than';
case FILTER_GREATER_THAN:
return 'greater than';
}
}
}
/* Class handling tables where the user can filter contents */
class FilterInterface
{
private $aFilterInfo;
private $oFilterSet;
public function FilterInterface($sTableName = '')
{
$this->aFilterInfo = array();
$this->oFilterSet = new FilterSet(mysql_real_escape_string($sTableName));
}
public function AddFilterObject(Filter $oFilter)
{
$this->oFilterSet->AddFilterObject($oFilter);
}
public function setFilterSet(FilterSet $oSet)
{
$this->oFilterSet = $oSet;
}
/* Convenience function to add a filter option */
public function AddFilterInfo($sColumn, $sDisplayName, $aTypes)
{
$this->aFilterInfo[$sColumn] = new FilterInfo($sColumn, $sDisplayName, $aTypes);
}
public function getItemEditor($iId, Filter $oFilter)
{
$sColumn = $oFilter->getColumn();
$oColumn = $this->aFilterInfo[$sColumn];
$sId = ($iId == -1) ? '' : $iId;
$shEditor = $oColumn->getDisplayName();
$shEditor .= " <select name='i{$sColumn}Op$sId'>";
if($iId == -1)
{
$sText = 'select';
$sSel = " selected='selected'";
} else
{
$sSel = '';
$sText = 'remove';
}
$shEditor .= "<option value='0'$sSel>-- $sText --</option>";
foreach($oColumn->getTypes() as $iType)
{
if($oFilter->getOperatorId() == $iType)
$sSel = " selected='selected'";
else
$sSel = '';
$shEditor .= "<option value='$iType'$sSel>".$oColumn->getOpName($iType).'</option><br />';
}
$shEditor .= '</select> ';
$shEditor .= "<input type='text' value=\"{$oFilter->getData()}\" name='s{$sColumn}Data$sId' size='30' />";
return $shEditor;
}
public function getEditor()
{
$shEditor = '';
$aCounts = array();
$shEditor .= 'Add new filter<br />';
foreach($this->aFilterInfo as $oOption)
{
$oDummyFilter = new Filter($oOption->getColumn(), 0, '');
$shEditor .= $this->getItemEditor(-1, $oDummyFilter);
$shEditor .= '<br />';
}
if(sizeof($this->oFilterSet->getFilters()))
$shEditor .= '<br />Active filters<br />';
foreach($this->oFilterSet->getFilters() as $oFilter)
{
$sColumn = $oFilter->getColumn();
if(!array_key_exists($sColumn, $aCounts))
$aCounts[$sColumn] = 0;
$shEditor .= $this->getItemEditor($aCounts[$sColumn], $oFilter);
$shEditor .= '<br />';
$aCounts[$sColumn]++;
}
return $shEditor;
}
public function getFilterInfo()
{
return $this->aFilterInfo;
}
/* Reads all input related to filters for the given table column */
public function readInputForColumn($aClean, FilterInfo $oOption)
{
$aReturn = array();
for($i = 0; array_key_exists('i'.$oOption->getColumn()."Op$i", $aClean); $i++)
{
$sData = mysql_real_escape_string($aClean["s{$oOption->getColumn()}Data$i"]);
$iOp = $aClean["i{$oOption->getColumn()}Op$i"];
if(!$iOp)
continue;
$oFilter = new Filter($oOption->getColumn(), $iOp, $sData);
$aReturn[] = $oFilter;
}
if(array_key_exists('i'.$oOption->getColumn()."Op", $aClean))
{
$i = sizeof($aReturn);
$sData = $aClean["s{$oOption->getColumn()}Data"];
$iOp = $aClean["i{$oOption->getColumn()}Op"];
if($iOp)
{
$oFilter = new Filter($oOption->getColumn(), $iOp, $sData);
$aReturn[] = $oFilter;
}
}
return $aReturn;
}
/* Reads an input array get enabled filters from form data.
The given TableFilterSet defines available options */
public function readInput($aClean)
{
foreach($this->getFilterInfo() as $oOption)
{
foreach($this->readInputForColumn($aClean, $oOption) as $oNewFilter)
$this->AddFilterObject($oNewFilter);
}
}
public function loadTable($sTableName)
{
$this->oFilterSet->loadTable(mysql_real_escape_string($sTableName));
}
public function saveTable($sTableName)
{
$this->oFilterSet->saveTable(mysql_real_escape_string($sTableName));
}
public function getFilterCount()
{
return $this->oFilterSet->getFilterCount();
}
public function getTable($sTable, $iLimit = 0)
{
$hResult = $this->oFilterSet->getMatchedItems($sTable, $iLimit);
if(!$hResult)
return;
echo 'Selected '.$this->oFilterSet->getMatchedItemsCount($sTable).' rows<br><br>';
$oTable = new Table();
while($aRow = mysql_fetch_row($hResult))
{
$oRow = new TableRow();
foreach($aRow as $sCell)
{
$oRow->AddTextCell($sCell);
}
$oTable->AddRow($oRow);
}
return $oTable->getString();
}
}
?>