/** * Filters the records in the record set via a callback * * The `$callback` parameter can be one of three different forms to filter * the records in the set: * * - A callback that accepts a single record and returns `FALSE` if it should be removed * - A psuedo-callback in the form `'{record}::methodName'` to filter out any records where the output of `$record->methodName()` is equivalent to `FALSE` * - A conditions array that will remove any records that don't meet all of the conditions * * The conditions array can use one or more of the following `key => value` * syntaxes to perform various comparisons. The array keys are method * names followed by a comparison operator. * * {{{ * // The following forms work for any $value that is not an array * 'methodName=' => $value // If the output is equal to $value * 'methodName!' => $value // If the output is not equal to $value * 'methodName!=' => $value // If the output is not equal to $value * 'methodName<>' => $value // If the output is not equal to $value * 'methodName<' => $value // If the output is less than $value * 'methodName<=' => $value // If the output is less than or equal to $value * 'methodName>' => $value // If the output is greater than $value * 'methodName>=' => $value // If the output is greater than or equal to $value * 'methodName~' => $value // If the output contains the $value (case insensitive) * 'methodName!~' => $value // If the output does not contain the $value (case insensitive) * 'methodName|methodName2|methodName3~' => $value // Parses $value as a search string and make sure each term is present in at least one output (case insensitive) * * // The following forms work for any $array that is an array * 'methodName=' => $array // If the output is equal to at least one value in $array * 'methodName!' => $array // If the output is not equal to any value in $array * 'methodName!=' => $array // If the output is not equal to any value in $array * 'methodName<>' => $array // If the output is not equal to any value in $array * 'methodName~' => $array // If the output contains one of the strings in $array (case insensitive) * 'methodName!~' => $array // If the output contains none of the strings in $array (case insensitive) * 'methodName&~' => $array // If the output contains all of the strings in $array (case insensitive) * 'methodName|methodName2|methodName3~' => $array // If each value in the array is present in the output of at least one method (case insensitive) * * // The following works for an equal number of methods and values in the array * 'methodName!|methodName2<|methodName3=' => array($value, $value2, $value3) // An OR statement - one of the method to value comparisons must be TRUE * * // The following accepts exactly two methods and two values, although the second value may be NULL * 'methodName|methodName2><' => array($value, $value2) // If the range of values from the methods intersects the range of $value and $value2 - should be dates, times, timestamps or numbers * }}} * * @param callback|string|array $procedure The way in which to filter the records - see method description for possible forms * @param boolean $remember_original_count If the number of records in the current set should be saved as the non-limited count for the new set - the page will be reset to `1` either way * @return fRecordSet A new fRecordSet with the filtered records */ public function filter($procedure, $remember_original_count = FALSE) { if (!$this->records) { return clone $this; } if (is_array($procedure) && is_string(key($procedure))) { $type = 'conditions'; $conditions = $procedure; } elseif (is_string($procedure) && preg_match('#^\\{record\\}::([a-z0-9_\\-]+)$#iD', $procedure, $matches)) { $type = 'psuedo-callback'; $method = $matches[1]; } else { $type = 'callback'; $callback = $procedure; if (is_string($callback) && strpos($callback, '::') !== FALSE) { $callback = explode('::', $callback); } } $new_records = array(); $classes = !is_array($this->class) ? array($this->class => TRUE) : array(); foreach ($this->records as $record) { switch ($type) { case 'conditions': $value = fActiveRecord::checkConditions($record, $conditions); break; case 'psuedo-callback': $value = $record->{$method}(); break; case 'callback': $value = call_user_func($callback, $record); break; } if ($value) { $classes[get_class($record)] = TRUE; $new_records[] = $record; } } return new fRecordSet(array_keys($classes), $new_records, $remember_original_count ? $this->count() : NULL); }