2007-07-19 12:40:28 +02:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Single field in the database.
|
2014-06-28 00:29:07 +02:00
|
|
|
*
|
2008-08-09 04:16:46 +02:00
|
|
|
* Every field from the database is represented as a sub-class of DBField.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2010-10-15 01:58:09 +02:00
|
|
|
* <b>Multi-value DBField objects</b>
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2014-06-28 00:29:07 +02:00
|
|
|
* Sometimes you will want to make DBField classes that don't have a 1-1 match
|
|
|
|
* to database fields. To do this, there are a number of fields for you to
|
|
|
|
* overload:
|
|
|
|
*
|
|
|
|
* - Overload {@link writeToManipulation} to add the appropriate references to
|
|
|
|
* the INSERT or UPDATE command
|
|
|
|
* - Overload {@link addToQuery} to add the appropriate items to a SELECT
|
|
|
|
* query's field list
|
2014-08-15 08:53:05 +02:00
|
|
|
* - Add appropriate accessor methods
|
|
|
|
*
|
2010-10-15 01:58:09 +02:00
|
|
|
* <b>Subclass Example</b>
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2012-09-26 23:34:00 +02:00
|
|
|
* The class is easy to overload with custom types, e.g. the MySQL "BLOB" type
|
|
|
|
* (http://dev.mysql.com/doc/refman/5.0/en/blob.html).
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2010-10-15 01:58:09 +02:00
|
|
|
* <code>
|
2012-09-26 23:34:00 +02:00
|
|
|
* class Blob extends DBField {
|
2012-09-19 12:07:39 +02:00
|
|
|
* function requireField() {
|
2010-10-15 01:58:09 +02:00
|
|
|
* DB::requireField($this->tableName, $this->name, "blob");
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
* </code>
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2012-04-12 08:02:46 +02:00
|
|
|
* @package framework
|
2008-02-25 03:10:37 +01:00
|
|
|
* @subpackage model
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
|
|
|
abstract class DBField extends ViewableData {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
protected $value;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
protected $tableName;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
protected $name;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-09-30 00:00:45 +02:00
|
|
|
protected $arrayValue;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
/**
|
|
|
|
* The escape type for this field when inserted into a template - either "xml" or "raw".
|
|
|
|
*
|
|
|
|
* @var string
|
2013-03-21 19:48:54 +01:00
|
|
|
* @config
|
2009-10-11 02:06:58 +02:00
|
|
|
*/
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $escape_type = 'raw';
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-11 01:17:51 +02:00
|
|
|
/**
|
|
|
|
* Subclass of {@link SearchFilter} for usage in {@link defaultSearchFilter()}.
|
|
|
|
*
|
|
|
|
* @var string
|
2013-03-21 19:48:54 +01:00
|
|
|
* @config
|
2008-08-11 01:17:51 +02:00
|
|
|
*/
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $default_search_filter_class = 'PartialMatchFilter';
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-02-25 03:10:37 +01:00
|
|
|
/**
|
|
|
|
* @var $default mixed Default-value in the database.
|
|
|
|
* Might be overridden on DataObject-level, but still useful for setting defaults on
|
|
|
|
* already existing records after a db-build.
|
|
|
|
*/
|
|
|
|
protected $defaultVal;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function __construct($name = null) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->name = $name;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
parent::__construct();
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Create a DBField object that's not bound to any particular field.
|
2014-06-28 00:29:07 +02:00
|
|
|
*
|
2007-07-19 12:40:28 +02:00
|
|
|
* Useful for accessing the classes behaviour for other parts of your code.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @param string $className class of field to construct
|
|
|
|
* @param mixed $value value of field
|
|
|
|
* @param string $name Name of field
|
|
|
|
* @param mixed $object Additional parameter to pass to field constructor
|
|
|
|
* @return DBField
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public static function create_field($className, $value, $name = null, $object = null) {
|
2008-10-14 00:20:41 +02:00
|
|
|
$dbField = Object::create($className, $name, $object);
|
2009-05-27 02:09:23 +02:00
|
|
|
$dbField->setValue($value, null, false);
|
2014-06-28 00:29:07 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
return $dbField;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 04:16:46 +02:00
|
|
|
/**
|
|
|
|
* Set the name of this field.
|
2014-06-28 00:29:07 +02:00
|
|
|
*
|
|
|
|
* The name should never be altered, but it if was never given a name in
|
|
|
|
* the first place you can set a name.
|
|
|
|
*
|
2014-08-15 08:53:05 +02:00
|
|
|
* If you try an alter the name a warning will be thrown.
|
2014-06-28 00:29:07 +02:00
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
*
|
|
|
|
* @return DBField
|
2008-08-09 04:16:46 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setName($name) {
|
2014-06-28 00:29:07 +02:00
|
|
|
if($this->name && $this->name !== $name) {
|
2012-09-26 23:34:00 +02:00
|
|
|
user_error("DBField::setName() shouldn't be called once a DBField already has a name."
|
|
|
|
. "It's partially immutable - it shouldn't be altered after it's given a value.", E_USER_WARNING);
|
2008-08-09 04:16:46 +02:00
|
|
|
}
|
2014-06-28 00:29:07 +02:00
|
|
|
|
2008-08-09 04:16:46 +02:00
|
|
|
$this->name = $name;
|
2014-06-28 00:29:07 +02:00
|
|
|
|
|
|
|
return $this;
|
2008-08-09 04:16:46 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 04:16:46 +02:00
|
|
|
/**
|
2009-02-02 00:49:53 +01:00
|
|
|
* Returns the name of this field.
|
2014-06-28 00:29:07 +02:00
|
|
|
*
|
2009-02-02 00:49:53 +01:00
|
|
|
* @return string
|
2008-08-09 04:16:46 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function getName() {
|
2008-08-09 04:16:46 +02:00
|
|
|
return $this->name;
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-02-13 10:30:32 +01:00
|
|
|
/**
|
|
|
|
* Returns the value of this field.
|
2014-06-28 00:29:07 +02:00
|
|
|
*
|
2009-02-13 10:30:32 +01:00
|
|
|
* @return mixed
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function getValue() {
|
2009-02-13 10:30:32 +01:00
|
|
|
return $this->value;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 04:00:40 +02:00
|
|
|
/**
|
|
|
|
* Set the value on the field.
|
2014-06-28 00:29:07 +02:00
|
|
|
*
|
|
|
|
* Optionally takes the whole record as an argument, to pick other values.
|
2008-08-09 04:00:40 +02:00
|
|
|
*
|
|
|
|
* @param mixed $value
|
|
|
|
* @param array $record
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setValue($value, $record = null) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->value = $value;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
|
|
|
2008-08-09 04:00:40 +02:00
|
|
|
/**
|
2014-06-28 00:29:07 +02:00
|
|
|
* Determines if the field has a value which is not considered to be 'null'
|
|
|
|
* in a database context.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-08-09 04:00:40 +02:00
|
|
|
* @return boolean
|
|
|
|
*/
|
2009-10-11 02:06:58 +02:00
|
|
|
public function exists() {
|
2012-04-11 04:48:06 +02:00
|
|
|
return ($this->value);
|
2009-10-11 02:06:58 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-09-11 08:22:33 +02:00
|
|
|
/**
|
2013-06-21 00:32:08 +02:00
|
|
|
* Return the transformed value ready to be sent to the database. This value
|
|
|
|
* will be escaped automatically by the prepared query processor, so it
|
|
|
|
* should not be escaped or quoted at all.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* The field values could also be in paramaterised format, such as
|
2014-08-15 08:53:05 +02:00
|
|
|
* array('MAX(?,?)' => array(42, 69)), allowing the use of raw SQL values such as
|
2013-06-21 00:32:08 +02:00
|
|
|
* array('NOW()' => array()).
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2013-06-21 00:32:08 +02:00
|
|
|
* @see SQLWriteExpression::addAssignments for syntax examples
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-09-11 08:22:33 +02:00
|
|
|
* @param $value mixed The value to check
|
2013-06-21 00:32:08 +02:00
|
|
|
* @return mixed The raw value, or escaped parameterised details
|
2008-09-11 08:22:33 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function prepValueForDB($value) {
|
2008-09-11 08:22:33 +02:00
|
|
|
if($value === null || $value === "" || $value === false) {
|
2013-06-21 00:32:08 +02:00
|
|
|
return null;
|
2008-09-11 08:22:33 +02:00
|
|
|
} else {
|
2013-06-21 00:32:08 +02:00
|
|
|
return $value;
|
2008-09-11 08:22:33 +02:00
|
|
|
}
|
2012-03-20 09:20:35 +01:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 04:00:40 +02:00
|
|
|
/**
|
2014-08-15 08:53:05 +02:00
|
|
|
* Prepare the current field for usage in a
|
2008-08-09 04:00:40 +02:00
|
|
|
* database-manipulation (works on a manipulation reference).
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-08-09 04:00:40 +02:00
|
|
|
* Make value safe for insertion into
|
2014-08-15 08:53:05 +02:00
|
|
|
* a SQL SET statement by applying addslashes() -
|
2008-09-11 08:22:33 +02:00
|
|
|
* can also be used to apply special SQL-commands
|
|
|
|
* to the raw value (e.g. for GIS functionality).
|
|
|
|
* {@see prepValueForDB}
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-08-09 04:00:40 +02:00
|
|
|
* @param array $manipulation
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function writeToManipulation(&$manipulation) {
|
2014-08-15 08:53:05 +02:00
|
|
|
$manipulation['fields'][$this->name] = $this->exists()
|
2012-09-26 23:34:00 +02:00
|
|
|
? $this->prepValueForDB($this->value) : $this->nullValue();
|
2008-08-09 04:00:40 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 04:00:40 +02:00
|
|
|
/**
|
|
|
|
* Add custom query parameters for this field,
|
2014-08-15 08:53:05 +02:00
|
|
|
* mostly SELECT statements for multi-value fields.
|
|
|
|
*
|
2008-08-09 04:00:40 +02:00
|
|
|
* By default, the ORM layer does a
|
|
|
|
* SELECT <tablename>.* which
|
|
|
|
* gets you the default representations
|
|
|
|
* of all columns.
|
|
|
|
*
|
API CHANGE: Renamed conflicting classes to have an "SS_" namespace, and renamed existing "SS" namespace to "SS_". The affected classes are: HTTPRequest, HTTPResponse, Query, Database, SSBacktrace, SSCli, SSDatetime, SSDatetimeTest, SSLog, SSLogTest, SSLogEmailWriter, SSLogErrorEmailFormatter, SSLogErrorFileFormatter, SSLogFileWriter and SSZendLog.
MINOR: Replaced usage of renamed classes with the new namespaced name.
From: Andrew Short <andrewjshort@gmail.com>
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@90075 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-10-26 04:06:31 +01:00
|
|
|
* @param SS_Query $query
|
2008-08-09 04:00:40 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function addToQuery(&$query) {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 04:16:46 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setTable($tableName) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->tableName = $tableName;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function forTemplate() {
|
|
|
|
return $this->XML();
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function HTMLATT() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return Convert::raw2htmlatt($this->value);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function URLATT() {
|
2008-04-06 05:52:57 +02:00
|
|
|
return urlencode($this->value);
|
|
|
|
}
|
2012-01-31 11:44:16 +01:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function RAWURLATT() {
|
2008-04-06 06:02:55 +02:00
|
|
|
return rawurlencode($this->value);
|
|
|
|
}
|
2012-01-31 11:44:16 +01:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function ATT() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return Convert::raw2att($this->value);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function RAW() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return $this->value;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function JS() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return Convert::raw2js($this->value);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function HTML(){
|
2007-07-19 12:40:28 +02:00
|
|
|
return Convert::raw2xml($this->value);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function XML(){
|
2007-07-19 12:40:28 +02:00
|
|
|
return Convert::raw2xml($this->value);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-22 05:36:00 +02:00
|
|
|
/**
|
2007-07-19 12:40:28 +02:00
|
|
|
* Returns the value to be set in the database to blank this field.
|
|
|
|
* Usually it's a choice between null, 0, and ''
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
|
|
|
* @return mixed
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function nullValue() {
|
2013-06-21 00:32:08 +02:00
|
|
|
return null;
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Saves this field to the given data object.
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function saveInto($dataObject) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$fieldName = $this->name;
|
|
|
|
if($fieldName) {
|
|
|
|
$dataObject->$fieldName = $this->value;
|
|
|
|
} else {
|
|
|
|
user_error("DBField::saveInto() Called on a nameless '" . get_class($this) . "' object", E_USER_ERROR);
|
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-06 04:43:46 +02:00
|
|
|
/**
|
|
|
|
* Returns a FormField instance used as a default
|
|
|
|
* for form scaffolding.
|
|
|
|
*
|
2009-03-22 23:59:14 +01:00
|
|
|
* Used by {@link SearchContext}, {@link ModelAdmin}, {@link DataObject::scaffoldFormFields()}
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-08-06 04:43:46 +02:00
|
|
|
* @param string $title Optional. Localized title of the generated instance
|
|
|
|
* @return FormField
|
|
|
|
*/
|
|
|
|
public function scaffoldFormField($title = null) {
|
|
|
|
$field = new TextField($this->name, $title);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-06 04:43:46 +02:00
|
|
|
return $field;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-06 04:43:46 +02:00
|
|
|
/**
|
|
|
|
* Returns a FormField instance used as a default
|
|
|
|
* for searchform scaffolding.
|
|
|
|
*
|
2009-03-22 23:59:14 +01:00
|
|
|
* Used by {@link SearchContext}, {@link ModelAdmin}, {@link DataObject::scaffoldFormFields()}.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-08-06 04:43:46 +02:00
|
|
|
* @param string $title Optional. Localized title of the generated instance
|
|
|
|
* @return FormField
|
|
|
|
*/
|
|
|
|
public function scaffoldSearchField($title = null) {
|
|
|
|
return $this->scaffoldFormField($title);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-06 05:28:25 +02:00
|
|
|
/**
|
|
|
|
* @todo documentation
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2008-08-06 05:28:25 +02:00
|
|
|
* @todo figure out how we pass configuration parameters to
|
2012-09-26 23:34:00 +02:00
|
|
|
* search filters (note: parameter hack now in place to pass in the required full path - using $this->name
|
|
|
|
* won't work)
|
2008-08-06 05:28:25 +02:00
|
|
|
*
|
|
|
|
* @return SearchFilter
|
|
|
|
*/
|
2008-08-09 08:53:26 +02:00
|
|
|
public function defaultSearchFilter($name = false) {
|
|
|
|
$name = ($name) ? $name : $this->name;
|
2008-08-11 01:17:51 +02:00
|
|
|
$filterClass = $this->stat('default_search_filter_class');
|
|
|
|
return new $filterClass($name);
|
2008-08-06 05:28:25 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Add the field to the underlying database.
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
abstract public function requireField();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function debug() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return <<<DBG
|
|
|
|
<ul>
|
|
|
|
<li><b>Name:</b>{$this->name}</li>
|
|
|
|
<li><b>Table:</b>{$this->tableName}</li>
|
|
|
|
<li><b>Value:</b>{$this->value}</li>
|
2007-09-14 03:24:30 +02:00
|
|
|
</ul>
|
2007-07-19 12:40:28 +02:00
|
|
|
DBG;
|
|
|
|
}
|
2013-03-12 00:17:20 +01:00
|
|
|
|
|
|
|
public function __toString() {
|
|
|
|
return $this->forTemplate();
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|