Yii Advanced Filters Extension
  • Package
  • Class

Packages

  • advancedfilters
    • components
    • dbhelpers
    • filters

Classes

  • AfBaseFilter
  • AfDefaultFilter
  • AfExactFilter
  • AfRangeFilter
  • AfRegexFilter
  • AfSubstringFilter
  1 <?php
  2 
  3 /**
  4  * AfBaseFilter class file.
  5  * 
  6  * @author Keith Burton <kburton@kappasoft.net>
  7  * @package advancedfilters.filters
  8  */
  9 
 10 /**
 11  * All filter classes should extend AfBaseFilter. It contains abstract functions
 12  * that must be implemented by child classes, as well as some helper functions
 13  * for common filter operations.
 14  */
 15 abstract class AfBaseFilter extends CComponent
 16 {
 17     /**
 18      * @var boolean whether this filter should be included when processing
 19      * filter expressions.
 20      */
 21     public $active = true;
 22     
 23     /**
 24      * @var integer the priority with which this should be processed. Smaller
 25      * numbers are processed first.
 26      */
 27     public $priority = 0;
 28     
 29     /**
 30      * @var boolean whether null results from column expressions should be
 31      * coalesced to empty strings. This allows the columns to be included in
 32      * filter results.
 33      */
 34     public $treatNullAsEmptyString = true;
 35     
 36     private $columnExpression;
 37     private $filterExpression;
 38     private $invertLogic = false;
 39     private $dbHelper;
 40     private $dbConnection;
 41     
 42     /**
 43      * Constructor. Subclasses of AfBaseFilter should not be instantiated
 44      * directly, but by using methods of the application component.
 45      * 
 46      * @param string $columnExpression the disambiguated column name (or a
 47      * valid SQL expression).
 48      * @param string $filterExpression the entered filter expression.
 49      * @param boolean $invertLogic whether the condition logic should be
 50      * inverted to return the opposite results.
 51      * @param CDbConnection $dbConnection the database connection object.
 52      * @param AfBaseDbHelper $dbHelper the database helper object.
 53      */
 54     public function __construct($columnExpression, $filterExpression,
 55             $invertLogic, $dbConnection, $dbHelper)
 56     {
 57         $this->columnExpression = $columnExpression;
 58         $this->filterExpression = $filterExpression;
 59         $this->invertLogic = $invertLogic;
 60         $this->dbConnection = $dbConnection;
 61         $this->dbHelper = $dbHelper;
 62     }
 63     
 64     /**
 65      * Gets the column expression, with the result coalesced to an empty string
 66      * if $this->treatNullAsEmptyString is true.
 67      * 
 68      * @return string the column expression.
 69      */
 70     protected function getColumnExpression()
 71     {
 72         return $this->treatNullAsEmptyString
 73                 ? $this->getDbHelper()
 74                         ->convertNullToEmptyString($this->columnExpression)
 75                 : $this->columnExpression;
 76     }
 77     
 78     /**
 79      * Gets the filter expression segment entered by the user.
 80      * 
 81      * @return string the entered filter expression segment.
 82      */
 83     protected function getFilterExpression()
 84     {
 85         return $this->filterExpression;
 86     }
 87     
 88     /**
 89      * Specifies whether the filter logic should be inverted in the resulting
 90      * database criteria.
 91      * 
 92      * @return boolean whether the filter logic should be inverted.
 93      */
 94     protected function getInvertLogic()
 95     {
 96         return $this->invertLogic;
 97     }
 98     
 99     /**
100      * Gets a database helper class to provide database specific syntax for
101      * filter criteria.
102      * 
103      * @return AfBaseDbHelper the database helper object.
104      */
105     protected function getDbHelper()
106     {
107         return $this->dbHelper;
108     }
109     
110     /**
111      * Gets a connection to the relevant database so that filters can perform
112      * queries directly, in order to validate syntax.
113      * 
114      * @return CDbConnection the connection object.
115      */
116     protected function getDbConnection()
117     {
118         return $this->dbConnection;
119     }
120     
121     /**
122      * Instantiate and return the first filter that can process the provided
123      * filter expression.
124      * 
125      * This is guaranteed to return a valid class as the AfDefaultFilter
126      * responds to any expression and is returned if no other filter can process
127      * the expression.
128      * 
129      * @param string $columnExpression the column or expression to which to
130      * apply this filter.
131      * @param string $filterExpression the string containing the filter pattern.
132      * @param boolean $invertLogic whether the condition logic should be
133      * inverted.
134      * @param CDbConnection $dbConnection the database connection object.
135      * @param AfBaseDbHelper $dbHelper the helper to use when dealing with
136      * database specific syntax.
137      * @param array $filterConfig an array of configuration for all available
138      * filter types.
139      * @return AfBaseFilter an instance of a subclass of AfBaseFilter.
140      */
141     public static function createFilter($columnExpression, $filterExpression,
142             $invertLogic, $dbConnection, $dbHelper, $filterConfig)
143     {
144         // Sort the available filters by priority value
145         usort($filterConfig, function($a, $b){
146             $aPriority = isset($a['priority']) ? $a['priority'] : 0;
147             $bPriority = isset($b['priority']) ? $b['priority'] : 0;
148             
149             return $aPriority == $bPriority ? 0
150                     : ($aPriority < $bPriority ? -1 : 1);
151         });
152         
153         foreach ($filterConfig as $classConfig)
154         {
155             // Ignore filters that have been marked as not active
156             if (isset($classConfig['active']) && !$classConfig['active'])
157                 continue;
158             
159             $filter = Yii::createComponent($classConfig, $columnExpression,
160                     $filterExpression, $invertLogic, $dbConnection,
161                     $dbHelper);
162             
163             if ($filter->acceptsFilterExpression())
164                 return $filter;
165         }
166         
167         // If no matching filter has been found, return the default filter
168         return Yii::createComponent('AfDefaultFilter', $columnExpression,
169                 $filterExpression, $invertLogic, $dbConnection, $dbHelper);
170     }
171     
172     /**
173      * A generic helper function to strip a specified prefix and suffix from
174      * a string if both are found.
175      * The prefix and/or suffix can be an empty string, to allow matching at
176      * only one side of the string.
177      * Comparison of the prefix and suffix is case insensitive.
178      * 
179      * If the string is surrounded by the specified prefix and suffix, the
180      * stripped string will be returned with any whitespace intact. Otherwise,
181      * boolean false is returned.
182      * 
183      * @param string $string the string to test and strip.
184      * @param string $prefix the prefix to compare. Use an empty string to
185      * ignore the prefix.
186      * @param string $suffix the suffix to compare. Use an empty string to
187      * ignore the suffix.
188      * @return boolean|string the stripped string if the specified prefix and
189      * suffix are matched. Boolean false otherwise.
190      */
191     protected static function stripPrefixSuffixString($string, $prefix, $suffix)
192     {
193         $prefix = strtolower($prefix);
194         $suffix = strtolower($suffix);
195         
196         $prefixLength = strlen($prefix);
197         $suffixLength = strlen($suffix);
198         $stringLength = strlen($string);
199         
200         // Not accepted if the string is shorter than the prefix and suffix
201         if ($stringLength < $prefixLength + $suffixLength)
202             return false;
203         
204         // Not accepted if the prefix doesn't match
205         if (strtolower(substr($string, 0, $prefixLength)) !== $prefix)
206             return false;
207         
208         // Not accepted if the suffix doesn't match
209         if (strtolower(substr($string, -$suffixLength, $suffixLength))
210                 !== $suffix)
211             return false;
212         
213         // Return empty string if only the prefix and suffix are found
214         if ($stringLength === $prefixLength + $suffixLength)
215             return '';
216         
217         // Strip the prefix and suffix and return the resulting string
218         return substr($string, $prefixLength,
219                 $stringLength - $prefixLength - $suffixLength);
220     }
221     
222     /**
223      * The implementation of this method should analyse the filter expression
224      * to determine whether this filter accepts the expression.
225      * 
226      * @return boolean whether the filter accepts the provided expression.
227      */
228     abstract public function acceptsFilterExpression();
229     
230     /**
231      * Gets a CDbCriteria object with the filter conditions applied. The
232      * criteria can be merged with an existing criteria object.
233      * 
234      * @return CDbCriteria the new criteria object.
235      */
236     abstract public function getCriteria();
237 }
238 
Yii Advanced Filters Extension API documentation generated by ApiGen