fullName = $fullName; // sets $this->name and $this->relation $this->addRelation($fullName); $this->value = $value; $this->setModifiers($modifiers); } /** * Called by constructor to convert a string pathname into * a well defined relationship sequence. * * @param string $name */ protected function addRelation($name) { if (strstr($name, '.')) { $parts = explode('.', $name); $this->name = array_pop($parts); $this->relation = $parts; } else { $this->name = $name; } } /** * Set the root model class to be selected by this * search query. * * @param string $className */ public function setModel($className) { $this->model = $className; } /** * Set the current value to be filtered on. * * @param string $value */ public function setValue($value) { $this->value = $value; } /** * Accessor for the current value to be filtered on. * Caution: Data is not escaped. * * @return string */ public function getValue() { return $this->value; } /** * Set the current modifiers to apply to the filter * * @param array $modifiers */ public function setModifiers(array $modifiers) { $this->modifiers = array_map('strtolower', $modifiers); } /** * Accessor for the current modifiers to apply to the filter. * * @return array */ public function getModifiers() { return $this->modifiers; } /** * The original name of the field. * * @return string */ public function getName() { return $this->name; } /** * @param String */ public function setName($name) { $this->name = $name; } /** * The full name passed to the constructor, * including any (optional) relations in dot notation. * * @return string */ public function getFullName() { return $this->fullName; } /** * @param String */ public function setFullName($name) { $this->fullName = $name; } /** * Normalizes the field name to table mapping. * * @return string */ public function getDbName() { // Special handler for "NULL" relations if($this->name == "NULL") return $this->name; // SRM: This code finds the table where the field named $this->name lives // Todo: move to somewhere more appropriate, such as DataMapper, the magical class-to-be? $candidateClass = $this->model; while($candidateClass != 'DataObject') { if(DataObject::has_own_table($candidateClass) && singleton($candidateClass)->hasOwnTableDatabaseField($this->name)) { break; } $candidateClass = get_parent_class($candidateClass); } if($candidateClass == 'DataObject') { user_error("Couldn't find field $this->name in any of $this->model's tables.", E_USER_ERROR); } return "\"$candidateClass\".\"$this->name\""; } /** * Return the value of the field as processed by the DBField class * * @return string */ public function getDbFormattedValue() { // SRM: This code finds the table where the field named $this->name lives // Todo: move to somewhere more appropriate, such as DataMapper, the magical class-to-be? $candidateClass = $this->model; $dbField = singleton($this->model)->dbObject($this->name); $dbField->setValue($this->value); return $dbField->RAW(); } /** * Apply filter criteria to a SQL query. * * @param DataQuery $query * @return DataQuery */ public function apply(DataQuery $query) { if(($key = array_search('not', $this->modifiers)) !== false) { unset($this->modifiers[$key]); return $this->exclude($query); } if(is_array($this->value)) { return $this->applyMany($query); } else { return $this->applyOne($query); } } /** * Apply filter criteria to a SQL query with a single value. * * @param DataQuery $query * @return DataQuery */ abstract protected function applyOne(DataQuery $query); /** * Apply filter criteria to a SQL query with an array of values. * * @param DataQuery $query * @return DataQuery */ protected function applyMany(DataQuery $query) { throw new InvalidArgumentException(get_class($this) . "can't be used to filter by a list of items."); } /** * Exclude filter criteria from a SQL query. * * @param DataQuery $query * @return DataQuery */ public function exclude(DataQuery $query) { if(($key = array_search('not', $this->modifiers)) !== false) { unset($this->modifiers[$key]); return $this->apply($query); } if(is_array($this->value)) { return $this->excludeMany($query); } else { return $this->excludeOne($query); } } /** * Exclude filter criteria from a SQL query with a single value. * * @param DataQuery $query * @return DataQuery */ abstract protected function excludeOne(DataQuery $query); /** * Exclude filter criteria from a SQL query with an array of values. * * @param DataQuery $query * @return DataQuery */ protected function excludeMany(DataQuery $query) { throw new InvalidArgumentException(get_class($this) . "can't be used to filter by a list of items."); } /** * Determines if a field has a value, * and that the filter should be applied. * Relies on the field being populated with * {@link setValue()} * * @return boolean */ public function isEmpty() { return false; } /** * Determines case sensitivity based on {@link getModifiers()}. * * @return Mixed TRUE or FALSE to enforce sensitivity, NULL to use field collation. */ protected function getCaseSensitive() { $modifiers = $this->getModifiers(); if(in_array('case', $modifiers)) return true; else if(in_array('nocase', $modifiers)) return false; else return null; } }