2007-07-19 12:40:28 +02:00
< ? php
/**
* Single field in the database .
2008-08-09 04:16:46 +02:00
* Every field from the database is represented as a sub - class of DBField .
*
2010-10-15 01:58:09 +02:00
* < b > Multi - value DBField objects </ b >
*
2008-08-09 04:16:46 +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
* - Add appropriate accessor methods
2008-08-06 04:43:46 +02:00
*
2010-10-15 01:58:09 +02:00
* < b > Subclass Example </ b >
*
* 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 ) .
*
* < code >
* class Blob extends DBField {
* function requireField () {
* DB :: requireField ( $this -> tableName , $this -> name , " blob " );
* }
* }
* </ code >
*
2008-02-25 03:10:37 +01:00
* @ package sapphire
* @ subpackage model
2007-07-19 12:40:28 +02:00
*/
abstract class DBField extends ViewableData {
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
protected $value ;
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
protected $tableName ;
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
protected $name ;
2009-09-30 00:00:45 +02:00
protected $arrayValue ;
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
*/
public static $escape_type = 'raw' ;
2008-08-11 01:17:51 +02:00
/**
* Subclass of { @ link SearchFilter } for usage in { @ link defaultSearchFilter ()} .
*
* @ var string
*/
2009-05-06 08:36:16 +02:00
public static $default_search_filter_class = 'PartialMatchFilter' ;
2008-08-11 01:17:51 +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 ;
2008-11-05 00:17:14 +01:00
function __construct ( $name = null ) {
2007-07-19 12:40:28 +02:00
$this -> name = $name ;
parent :: __construct ();
}
2012-03-27 06:57:42 +02:00
static function create () {
Deprecation :: notice ( '3.0' , 'DBField::create_field() is deprecated as it clashes with Object::create(). Use DBField::create_field() instead.' );
return call_user_func_array ( array ( 'DBField' , 'create_field' ), func_get_args ());
}
2007-07-19 12:40:28 +02:00
/**
* Create a DBField object that ' s not bound to any particular field .
* Useful for accessing the classes behaviour for other parts of your code .
*/
2012-03-27 06:57:42 +02:00
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 );
2007-07-19 12:40:28 +02:00
return $dbField ;
}
2008-08-09 04:16:46 +02:00
/**
* Set the name of this field .
* The name should never be altered , but it if was never given a name in the first place you can set a name .
* If you try an alter the name a warning will be thrown .
*/
function setName ( $name ) {
if ( $this -> name ) {
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 );
}
$this -> name = $name ;
}
/**
2009-02-02 00:49:53 +01:00
* Returns the name of this field .
* @ return string
2008-08-09 04:16:46 +02:00
*/
function getName () {
return $this -> name ;
2007-07-19 12:40:28 +02:00
}
2008-02-25 03:10:37 +01:00
2009-02-13 10:30:32 +01:00
/**
* Returns the value of this field .
* @ return mixed
*/
function getValue () {
return $this -> value ;
}
2008-08-09 04:00:40 +02:00
/**
* Set the value on the field .
* Optionally takes the whole record as an argument ,
* to pick other values .
*
* @ param mixed $value
* @ param array $record
*/
function setValue ( $value , $record = null ) {
2007-07-19 12:40:28 +02:00
$this -> value = $value ;
}
2008-02-25 03:10:37 +01:00
2012-04-11 04:48:06 +02:00
2008-08-09 04:00:40 +02:00
/**
* Determines if the field has a value which
* is not considered to be 'null' in
* a database context .
*
* @ 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
}
2008-09-11 08:22:33 +02:00
/**
* Return an encoding of the given value suitable
* for inclusion in a SQL statement . If necessary ,
* this should include quotes .
*
* @ param $value mixed The value to check
* @ return string The encoded value
*/
function prepValueForDB ( $value ) {
if ( $value === null || $value === " " || $value === false ) {
return " null " ;
} else {
2012-03-20 09:20:35 +01:00
return DB :: getConn () -> prepStringForDB ( $value );
2008-09-11 08:22:33 +02:00
}
2012-03-20 09:20:35 +01:00
}
2008-09-11 08:22:33 +02:00
2008-08-09 04:00:40 +02:00
/**
* Prepare the current field for usage in a
* database - manipulation ( works on a manipulation reference ) .
*
* Make value safe for insertion into
* 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 }
2008-08-09 04:00:40 +02:00
*
* @ param array $manipulation
*/
function writeToManipulation ( & $manipulation ) {
2012-04-11 04:48:06 +02:00
$manipulation [ 'fields' ][ $this -> name ] = $this -> exists () ? $this -> prepValueForDB ( $this -> value ) : $this -> nullValue ();
2008-08-09 04:00:40 +02:00
}
/**
* Add custom query parameters for this field ,
* mostly SELECT statements for multi - value fields .
*
* 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
*/
2008-08-09 04:16:46 +02:00
function addToQuery ( & $query ) {
}
2008-08-09 04:00:40 +02:00
2007-07-19 12:40:28 +02:00
function setTable ( $tableName ) {
$this -> tableName = $tableName ;
}
2008-02-25 03:10:37 +01: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
}
function HTMLATT () {
return Convert :: raw2htmlatt ( $this -> value );
}
2012-01-31 11:44:16 +01:00
2008-04-06 05:52:57 +02:00
function URLATT () {
return urlencode ( $this -> value );
}
2012-01-31 11:44:16 +01:00
2008-04-06 06:02:55 +02:00
function RAWURLATT () {
return rawurlencode ( $this -> value );
}
2012-01-31 11:44:16 +01:00
2007-07-19 12:40:28 +02:00
function ATT () {
return Convert :: raw2att ( $this -> value );
}
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
function RAW () {
return $this -> value ;
}
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
function JS () {
return Convert :: raw2js ( $this -> value );
}
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
function HTML (){
return Convert :: raw2xml ( $this -> value );
}
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
function XML (){
return Convert :: raw2xml ( $this -> value );
}
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 ' '
*/
function nullValue () {
return " null " ;
}
/**
* Saves this field to the given data object .
*/
function saveInto ( $dataObject ) {
$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 );
}
}
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 ()}
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 );
return $field ;
}
/**
* 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 ()} .
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 );
}
2008-08-06 05:28:25 +02:00
/**
* @ todo documentation
*
* @ todo figure out how we pass configuration parameters to
2008-08-09 08:53:26 +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
}
2007-07-19 12:40:28 +02:00
/**
* Add the field to the underlying database .
*/
abstract function requireField ();
function debug () {
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 ;
}
2008-09-11 08:22:33 +02:00
2007-07-19 12:40:28 +02:00
}