/model/fieldtypes/CompositeDBField.php
PHP | 182 lines | 9 code | 9 blank | 164 comment | 0 complexity | cd9ca09f79d644d45a6b060f54b1f28a MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, CC-BY-3.0, GPL-2.0, AGPL-1.0, LGPL-2.1
- <?php
- /**
- * Apply this interface to any {@link DBField} that doesn't have a 1-1 mapping with a database field.
- * This includes multi-value fields and transformed fields
- *
- * @todo Unittests for loading and saving composite values (see GIS module for existing similiar unittests)
- *
- * Example with a combined street name and number:
- * <code>
- * 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());
- * }
- * }
- * </code>
- *
- * @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();
-
- }