Completed
Push — new-committers ( 29cb6f...bcba16 )
by Sam
12:18 queued 33s
created

DBField::XML()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * Single field in the database.
4
 *
5
 * Every field from the database is represented as a sub-class of DBField.
6
 *
7
 * <b>Multi-value DBField objects</b>
8
 *
9
 * Sometimes you will want to make DBField classes that don't have a 1-1 match
10
 * to database fields.  To do this, there are a number of fields for you to
11
 * overload:
12
 *
13
 *  - Overload {@link writeToManipulation} to add the appropriate references to
14
 *		the INSERT or UPDATE command
15
 *  - Overload {@link addToQuery} to add the appropriate items to a SELECT
16
 *		query's field list
17
 *  - Add appropriate accessor methods
18
 *
19
 * <b>Subclass Example</b>
20
 *
21
 * The class is easy to overload with custom types, e.g. the MySQL "BLOB" type
22
 * (http://dev.mysql.com/doc/refman/5.0/en/blob.html).
23
 *
24
 * <code>
25
 * class Blob extends DBField {
26
 * 	function requireField() {
27
 * 		DB::requireField($this->tableName, $this->name, "blob");
28
 *  }
29
 * }
30
 * </code>
31
 *
32
 * @todo remove MySQL specific code from subclasses
33
 *
34
 * @package framework
35
 * @subpackage model
36
 */
37
abstract class DBField extends ViewableData {
38
39
	protected $value;
40
41
	protected $tableName;
42
43
	protected $name;
44
45
	protected $arrayValue;
46
47
	/**
48
	 * The escape type for this field when inserted into a template - either "xml" or "raw".
49
	 *
50
	 * @var string
51
	 * @config
52
	 */
53
	private static $escape_type = 'raw';
54
55
	/**
56
	 * Subclass of {@link SearchFilter} for usage in {@link defaultSearchFilter()}.
57
	 *
58
	 * @var string
59
	 * @config
60
	 */
61
	private static $default_search_filter_class = 'PartialMatchFilter';
62
63
	/**
64
	 * @var $default mixed Default-value in the database.
65
	 * Might be overridden on DataObject-level, but still useful for setting defaults on
66
	 * already existing records after a db-build.
67
	 */
68
	protected $defaultVal;
69
70
	public function __construct($name = null) {
71
		$this->name = $name;
72
73
		parent::__construct();
74
	}
75
76
	/**
77
	 * Create a DBField object that's not bound to any particular field.
78
	 *
79
	 * Useful for accessing the classes behaviour for other parts of your code.
80
	 *
81
	 * @param string $className class of field to construct
82
	 * @param mixed $value value of field
83
	 * @param string $name Name of field
84
	 * @param mixed $object Additional parameter to pass to field constructor
85
	 * @return DBField
86
	 */
87
	public static function create_field($className, $value, $name = null, $object = null) {
88
		$dbField = Object::create($className, $name, $object);
89
		$dbField->setValue($value, null, false);
0 ignored issues
show
Unused Code introduced by
The call to DBField::setValue() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
90
91
		return $dbField;
92
	}
93
94
	/**
95
	 * Set the name of this field.
96
	 *
97
	 * The name should never be altered, but it if was never given a name in
98
	 * the first place you can set a name.
99
	 *
100
	 * If you try an alter the name a warning will be thrown.
101
	 *
102
	 * @param string $name
103
	 *
104
	 * @return DBField
105
	 */
106
	public function setName($name) {
107
		if($this->name && $this->name !== $name) {
108
			user_error("DBField::setName() shouldn't be called once a DBField already has a name."
109
				. "It's partially immutable - it shouldn't be altered after it's given a value.", E_USER_WARNING);
110
		}
111
112
		$this->name = $name;
113
114
		return $this;
115
	}
116
117
	/**
118
	 * Returns the name of this field.
119
	 *
120
	 * @return string
121
	 */
122
	public function getName() {
123
		return $this->name;
124
	}
125
126
	/**
127
	 * Returns the value of this field.
128
	 *
129
	 * @return mixed
130
	 */
131
	public function getValue() {
132
		return $this->value;
133
	}
134
135
	/**
136
	 * Set the value on the field.
137
	 *
138
	 * Optionally takes the whole record as an argument, to pick other values.
139
	 *
140
	 * @param mixed $value
141
	 * @param array $record
142
	 */
143
	public function setValue($value, $record = null) {
144
		$this->value = $value;
145
	}
146
147
148
	/**
149
	 * Determines if the field has a value which is not considered to be 'null'
150
	 * in a database context.
151
	 *
152
	 * @return boolean
153
	 */
154
	public function exists() {
155
		return (bool)$this->value;
156
	}
157
158
	/**
159
	 * Return the transformed value ready to be sent to the database. This value
160
	 * will be escaped automatically by the prepared query processor, so it
161
	 * should not be escaped or quoted at all.
162
	 *
163
	 * The field values could also be in paramaterised format, such as
164
	 * array('MAX(?,?)' => array(42, 69)), allowing the use of raw SQL values such as
165
	 * array('NOW()' => array()).
166
	 *
167
	 * @see SQLWriteExpression::addAssignments for syntax examples
168
	 *
169
	 * @param $value mixed The value to check
170
	 * @return mixed The raw value, or escaped parameterised details
171
	 */
172
	public function prepValueForDB($value) {
173
		if($value === null || $value === "" || $value === false) {
174
			return null;
175
		} else {
176
			return $value;
177
		}
178
	}
179
180
	/**
181
	 * Prepare the current field for usage in a
182
	 * database-manipulation (works on a manipulation reference).
183
	 *
184
	 * Make value safe for insertion into
185
	 * a SQL SET statement by applying addslashes() -
186
	 * can also be used to apply special SQL-commands
187
	 * to the raw value (e.g. for GIS functionality).
188
	 * {@see prepValueForDB}
189
	 *
190
	 * @param array $manipulation
191
	 */
192
	public function writeToManipulation(&$manipulation) {
193
		$manipulation['fields'][$this->name] = $this->exists()
194
			? $this->prepValueForDB($this->value) : $this->nullValue();
195
	}
196
197
	/**
198
	 * Add custom query parameters for this field,
199
	 * mostly SELECT statements for multi-value fields.
200
	 *
201
	 * By default, the ORM layer does a
202
	 * SELECT <tablename>.* which
203
	 * gets you the default representations
204
	 * of all columns.
205
	 *
206
	 * @param SS_Query $query
207
	 */
208
	public function addToQuery(&$query) {
209
210
	}
211
212
	public function setTable($tableName) {
213
		$this->tableName = $tableName;
214
	}
215
216
	/**
217
	 * @return string
218
	 */
219
	public function forTemplate() {
220
		return $this->XML();
221
	}
222
223
	public function HTMLATT() {
224
		return Convert::raw2htmlatt($this->value);
225
	}
226
227
	public function URLATT() {
228
		return urlencode($this->value);
229
	}
230
231
	public function RAWURLATT() {
232
		return rawurlencode($this->value);
233
	}
234
235
	public function ATT() {
236
		return Convert::raw2att($this->value);
237
	}
238
239
	public function RAW() {
240
		return $this->value;
241
	}
242
243
	public function JS() {
244
		return Convert::raw2js($this->value);
245
	}
246
247
	public function HTML(){
248
		return Convert::raw2xml($this->value);
249
	}
250
251
	public function XML(){
252
		return Convert::raw2xml($this->value);
253
	}
254
255
	/**
256
	 * Returns the value to be set in the database to blank this field.
257
	 * Usually it's a choice between null, 0, and ''
258
	 *
259
	 * @return mixed
260
	 */
261
	public function nullValue() {
262
		return null;
263
	}
264
265
	/**
266
	 * Saves this field to the given data object.
267
	 */
268 View Code Duplication
	public function saveInto($dataObject) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
269
		$fieldName = $this->name;
270
		if($fieldName) {
271
			$dataObject->$fieldName = $this->value;
272
		} else {
273
			user_error("DBField::saveInto() Called on a nameless '" . get_class($this) . "' object", E_USER_ERROR);
274
		}
275
	}
276
277
	/**
278
	 * Returns a FormField instance used as a default
279
	 * for form scaffolding.
280
	 *
281
	 * Used by {@link SearchContext}, {@link ModelAdmin}, {@link DataObject::scaffoldFormFields()}
282
	 *
283
	 * @param string $title Optional. Localized title of the generated instance
284
	 * @return FormField
285
	 */
286
	public function scaffoldFormField($title = null) {
287
		$field = new TextField($this->name, $title);
288
289
		return $field;
290
	}
291
292
	/**
293
	 * Returns a FormField instance used as a default
294
	 * for searchform scaffolding.
295
	 *
296
	 * Used by {@link SearchContext}, {@link ModelAdmin}, {@link DataObject::scaffoldFormFields()}.
297
	 *
298
	 * @param string $title Optional. Localized title of the generated instance
299
	 * @return FormField
300
	 */
301
	public function scaffoldSearchField($title = null) {
302
		return $this->scaffoldFormField($title);
303
	}
304
305
	/**
306
	 * @todo documentation
307
	 *
308
	 * @todo figure out how we pass configuration parameters to
309
	 *       search filters (note: parameter hack now in place to pass in the required full path - using $this->name
310
	 *       won't work)
311
	 *
312
	 * @return SearchFilter
313
	 */
314
	public function defaultSearchFilter($name = false) {
315
		$name = ($name) ? $name : $this->name;
316
		$filterClass = $this->stat('default_search_filter_class');
317
		return new $filterClass($name);
318
	}
319
320
	/**
321
	 * Add the field to the underlying database.
322
	 */
323
	abstract public function requireField();
324
325
	public function debug() {
326
		return <<<DBG
327
<ul>
328
	<li><b>Name:</b>{$this->name}</li>
329
	<li><b>Table:</b>{$this->tableName}</li>
330
	<li><b>Value:</b>{$this->value}</li>
331
</ul>
332
DBG;
333
	}
334
335
	public function __toString() {
336
		return $this->forTemplate();
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->forTemplate(); of type array|string adds the type array to the return on line 336 which is incompatible with the return type of the parent method Object::__toString of type string.
Loading history...
337
	}
338
}
339