* class Street extends DBFields implements CompositeDBField() { * protected $streetNumber; * protected $streetName; * protected $isChanged = false; * static $composite_db = return array( * "Number" => "Int", * "Name" => "Text" * ); * * function requireField() { * DB::requireField($this->tableName, "{$this->name}Number", 'Int'); * DB::requireField($this->tableName, "{$this->name}Name", 'Text'); * } * * function writeToManipulation(&$manipulation) { * if($this->getStreetName()) { * $manipulation['fields']["{$this->name}Name"] = $this->prepValueForDB($this->getStreetName()); * } else { * $manipulation['fields']["{$this->name}Name"] = DBField::create('Varchar', $this->getStreetName())->nullValue(); * } * * if($this->getStreetNumber()) { * $manipulation['fields']["{$this->name}Number"] = $this->prepValueForDB($this->getStreetNumber()); * } else { * $manipulation['fields']["{$this->name}Number"] = DBField::create('Int', $this->getStreetNumber())->nullValue(); * } * } * * function addToQuery(&$query) { * parent::addToQuery($query); * $query->select[] = "{$this->name}Number"; * $query->select[] = "{$this->name}Name"; * } * * function setValue($value, $record = null, $markChanged=true) { * if ($value instanceof Street && $value->hasValue()) { * $this->setStreetName($value->getStreetName(), $markChanged); * $this->setStreetNumber($value->getStreetNumber(), $markChanged); * if($markChanged) $this->isChanged = true; * } else if($record && isset($record[$this->name . 'Name']) && isset($record[$this->name . 'Number'])) { * if($record[$this->name . 'Name'] && $record[$this->name . 'Number']) { * $this->setStreetName($record[$this->name . 'Name'], $markChanged); * $this->setStreetNumber($record[$this->name . 'Number'], $markChanged); * } * if($markChanged) $this->isChanged = true; * } else if (is_array($value)) { * if (array_key_exists('Name', $value)) { * $this->setStreetName($value['Name'], $markChanged); * } * if (array_key_exists('Number', $value)) { * $this->setStreetNumber($value['Number'], $markChanged); * } * if($markChanged) $this->isChanged = true; * } * } * * function setStreetNumber($val, $markChanged=true) { * $this->streetNumber = $val; * if($markChanged) $this->isChanged = true; * } * * function setStreetName($val, $markChanged=true) { * $this->streetName = $val; * if($markChanged) $this->isChanged = true; * } * * function getStreetNumber() { * return $this->streetNumber; * } * * function getStreetName() { * return $this->streetName; * } * * function isChanged() { * return $this->isChanged; * } * * function hasValue() { * return ($this->getStreetName() || $this->getStreetNumber()); * } * } * * * @package sapphire * @subpackage model */ interface CompositeDBField { /** * Similiar to {@link DataObject::$db}, * holds an array of composite field names. * Don't include the fields "main name", * it will be prefixed in {@link requireField()}. * * @var array $composite_db */ //static $composite_db; /** * Set the value of this field in various formats. * Used by {@link DataObject->getField()}, {@link DataObject->setCastedField()} * {@link DataObject->dbObject()} and {@link DataObject->write()}. * * As this method is used both for initializing the field after construction, * and actually changing its values, it needs a {@link $markChanged} * parameter. * * @param DBField|array $value * @param array $record Map of values loaded from the database * @param boolean $markChanged Indicate wether this field should be marked changed. * Set to FALSE if you are initializing this field after construction, rather * than setting a new value. */ function setValue($value, $record = null, $markChanged = true); /** * Used in constructing the database schema. * Add any custom properties defined in {@link $composite_db}. * Should make one or more calls to {@link DB::requireField()}. */ //abstract function requireField(); /** * Add the custom internal values to an INSERT or UPDATE * request passed through the ORM with {@link DataObject->write()}. * Fields are added in $manipulation['fields']. Please ensure * these fields are escaped for database insertion, as no * further processing happens before running the query. * Use {@link DBField->prepValueForDB()}. * Ensure to write NULL or empty values as well to allow * unsetting a previously set field. Use {@link DBField->nullValue()} * for the appropriate type. * * @param array $manipulation */ function writeToManipulation(&$manipulation); /** * Add all columns which are defined through {@link requireField()} * and {@link $composite_db}, or any additional SQL that is required * to get to these columns. Will mostly just write to the {@link SQLQuery->select} * array. * * @param SQLQuery $query */ function addToQuery(&$query); /** * Return array in the format of {@link $composite_db}. * Used by {@link DataObject->hasOwnDatabaseField()}. * @return array */ function compositeDatabaseFields(); /** * Determines if the field has been changed since its initialization. * Most likely relies on an internal flag thats changed when calling * {@link setValue()} or any other custom setters on the object. * * @return boolean */ function isChanged(); /** * Determines if any of the properties in this field have a value, * meaning at least one of them is not NULL. * * @return boolean */ function hasValue(); }