diff --git a/include/db_filter.php b/include/db_filter.php
new file mode 100644
index 0000000..2ae001a
--- /dev/null
+++ b/include/db_filter.php
@@ -0,0 +1,191 @@
+
+ *
+*/
+
+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));
+ }
+
+}
+
+?>
diff --git a/include/db_filter_ui.php b/include/db_filter_ui.php
new file mode 100644
index 0000000..71c90c9
--- /dev/null
+++ b/include/db_filter_ui.php
@@ -0,0 +1,251 @@
+
+ *
+*/
+
+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 .= " ';
+
+ $shEditor .= "getData()}\" name='s{$sColumn}Data$sId' size='30' />";
+
+ return $shEditor;
+ }
+
+ public function getEditor()
+ {
+ $shEditor = '';
+ $aCounts = array();
+
+ $shEditor .= 'Add new filter
';
+ foreach($this->aFilterInfo as $oOption)
+ {
+ $oDummyFilter = new Filter($oOption->getColumn(), 0, '');
+ $shEditor .= $this->getItemEditor(-1, $oDummyFilter);
+ $shEditor .= '
';
+ }
+
+ if(sizeof($this->oFilterSet->getFilters()))
+ $shEditor .= '
Active filters
';
+ 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 .= '
';
+
+ $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
';
+
+ $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();
+ }
+}
+
+?>