PDA

View Full Version : [PHP5] Filters



dumpfi
11-06-2005, 04:51 PM
<?php
/* Usage
$filter = new *Filter(values, search terms, filter type, case sensitivity);
$result = $filter->apply();
*/
/* values
array of values who may or may not be included in the result set dependent on the filter
*/
/* search terms
array of search terms the filter will search for in the values to decide whether to include a value in the result set or not
*/
/* filter type
FILTER_SKIP: matching values will be excluded from the result set
FILTER_ACCEPT: non-matching values will be excluded from the result set
default for filters: FILTER_SKIP
*/
/* case sensitivity
FILTER_CASE_SENSITIVE: filter is case-sensitive
FILTER_CASE_INSENSITIVE: filter is not case-sensitive
default for filters: FILTER_CASE_INSENSITIVE
*/
/* predefined filters
FileExtensionFilter
FileNameFilter
PrefixFilter
SuffixFilter
LimitFilter
*/

define('FILTER_SKIP', FALSE);
define('FILTER_ACCEPT', TRUE);

define('FILTER_CASE_SENSITIVE', TRUE);
define('FILTER_CASE_INSENSITIVE', FALSE);

class SimpleArray implements Iterator
{
protected
$pointer,
$dataArrayName;

public function current()
{
return $this->{$this->dataArrayName}[$this->pointer];
}
public function key()
{
return $this->pointer;
}
public function next()
{
++$this->pointer;
}
public function valid()
{
return ($this->pointer < count($this->{$this->dataArrayName}));
}
public function rewind()
{
$this->pointer = 0;
}
}

abstract class Filter extends SimpleArray implements Iterator
{
protected
$searchTerms = array(),
$values = array(),
$type,
$isCaseSensitive,
$changeOccured = 1,
$dataArrayName = 'filteredValues';

public
$filteredValues;

public function rewind()
{
parent::rewind();
if($this->changeOccured) $this->apply();
}
protected function isTraversable($var)
{
if(is_array($var)) return true;
if($var instanceof Iterator) return true;
return false;
}
protected function toArray($vars)
{
$ary = array();
foreach($vars as $var)
{
array_push($ary, $var);
}
return $ary;
}
protected function makeCommonCase(&$item)
{
if($this->isTraversable($item))
{
foreach($item as &$i)
{
$this->makeCommonCase($i);
}
}
else $item = strtolower($item);
}

public function getSearchTerms()
{
return $this->searchTerms;
}
public function setSearchTerms($searchTerms)
{
if(!$this->isTraversable($searchTerms)) $searchTerms = array($searchTerms);
$this->searchTerms = $searchTerms;
$this->changeOccured = 1;
}
public function addSearchTerms($searchTerms)
{
if(!is_array($searchTerms))
{
if($this->isTraversable($searchTerms)) $searchTerms = $this->toArray($searchTerms);
else $searchTerms = array($searchTerms);
}
$this->searchTerms = array_merge($this->searchTerms, $searchTerms);
$this->changeOccured = 1;
}
public function removeSearchTerms($searchTerms)
{
if(!is_array($searchTerms))
{
if($this->isTraversable($searchTerms)) $searchTerms = $this->toArray($searchTerms);
else $searchTerms = array($searchTerms);
}
$this->searchTerms = array_diff($this->searchTerms, $searchTerms);
$this->changeOccured = 1;
}

public function getType()
{
return $this->type;
}
public function setType($type)
{
$this->type = (bool) $type;
$this->changeOccured = 1;
}

public function getCaseSensitivity()
{
return $this->isCaseSensitive;
}
public function setCaseSensitivity($isCaseSensitive)
{
$this->isCaseSensitive = (bool) $isCaseSensitive;
$this->changeOccured = 1;
}

public function getValues()
{
return $this->values;
}
public function setValues($values)
{
if(!$this->isTraversable($values)) $values = array($values);
$this->values = $values;
$this->changeOccured = 1;
}
public function addValues($values)
{
if(!is_array($values))
{
if($this->isTraversable($values)) $values = $this->toArray($values);
else $values = array($values);
}
$this->values = array_merge($this->values, $values);
$this->changeOccured = 1;
}
public function removeValues($values)
{
if(!is_array($values))
{
if($this->isTraversable($values)) $values = $this->toArray($values);
else $values = array($values);
}
$this->values = array_diff($this->values, $values);
$this->changeOccured = 1;
}

public function apply()
{
if(!$this->changeOccured) return $this->filteredValues;
$filteredValues = array();
$searchTerms = $this->searchTerms;
$values = $this->values;
if(!$this->isCaseSensitive)
{
$this->makeCommonCase($searchTerms);
$this->makeCommonCase($values);
}
foreach($values as $value)
{
$applies = $this->_apply($value, $searchTerms);
if(($applies && $this->type) || (!$applies && !$this->type)) array_push($filteredValues, $value);
}
$this->filteredValues = $filteredValues;
$this->changeOccured = 0;
return $filteredValues;
}
protected function _apply($value, $searchTerms)
{
foreach($searchTerms as $searchTerm)
{
if($this->matches($value, $searchTerm)) return TRUE;
}
return FALSE;
}
abstract protected function matches($value, $searchTerm);

public function __construct($values = array(), $searchTerms = array(), $type = FILTER_SKIP, $isCaseSensitive = FILTER_CASE_INSENSITIVE)
{
$this->addSearchTerms($searchTerms);
$this->addValues($values);
$this->setType($type);
$this->setCaseSensitivity($isCaseSensitive);
}
}
class FileExtensionFilter extends Filter
{
protected function matches($value, $searchTerm)
{
if(($lastDotPos = strrpos($value, '.')) !== FALSE) return (substr($value, $lastDotPos + 1) == $searchTerm);
return empty($searchTerm);
}
}
class FileNameFilter extends Filter
{
protected function matches($value, $searchTerm)
{
if(($lastDotPos = strrpos($value, '.')) !== FALSE) return (substr($value, 0, $lastDotPos) == $searchTerm);
return ($value == $searchTerm);
}
}
class PrefixFilter extends Filter
{
protected function matches($value, $searchTerm)
{
return (strpos($value, $searchTerm) === 0);
}
}
class SuffixFilter extends Filter
{
protected function matches($value, $searchTerm)
{
return (strpos($value, $searchTerm) === strlen($value) - strlen($searchTerm));
}
}
class LimitFilter extends Filter
{
protected
$count = 0;

public function apply()
{
$this->count = 0;
return parent::apply();
}
protected function matches($value, $searchTerm)
{
return ($searchTerm < ++$this->count);
}
}

/* example usage */
$values = array('aa_a.html', 'aa_b.html', 'aa_c.html', 'd.html', 'e.htm', 'f.HTML', 'aa_g.xml', 'aa_c.htm', 'aa_c.xml', 'aa_c.jpg');
$searchTerms1 = array('html');
$fef = new FileExtensionFilter($values, $searchTerms1);
$searchTerms2 = array('aa_c');
$fnf = new FileNameFilter($values, $searchTerms2, FILTER_ACCEPT);
$searchTerms3 = array('aa_', 'e.h');
$pf = new PrefixFilter($values, $searchTerms3);
$searchTerms4 = array('html', 'jpg', 'png');
$sf = new SuffixFilter($values, $searchTerms4, FILTER_ACCEPT, FILTER_CASE_SENSITIVE);
$searchTerms5 = array('aa_');
$pf2 = new PrefixFilter($fef, $searchTerms5);
$lf1 = new LimitFilter($fef, 1, FILTER_ACCEPT);
$lf2 = new LimitFilter($lf1, 3);
echo 'Values:<pre>';print_r($values);
echo '</pre><br>';
echo '1. FileExtensionFilter "html":<pre>';
print_r($fef->apply());
echo '</pre><br>';
echo '2. FileNameFilter "aa_c" (accept):<pre>';
print_r($fnf->apply());
echo '</pre><br>';
echo '3. PrefixFilter "aa_, e.h":<pre>';
print_r($pf->apply());
echo '</pre><br>';
echo '4. SuffixFilter "html, jpg, png" (accept, case-sensitive):<pre>';
print_r($sf->apply());
echo '</pre><br>';
echo '5. PrefixFilter "aa_" (filtering the result set of filter #1):<pre>';
print_r($pf2->apply());
echo '</pre><br>';
echo '6. Getting 3 values of the result set of filter #1 starting at offset 1 using the LimitFilter:<pre>';
print_r($lf2->apply());
echo '</pre><br>';
?>dumpfi