Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TScaffoldEditView class and IScaffoldEditRenderer interface file.
4
 *
5
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TScaffoldEditView.php 2541 2008-10-21 15:05:13Z qiang.xue $
10
 * @package System.Data.ActiveRecord.Scaffold
11
 */
12
 
13
/**
14
 * Load scaffold base.
15
 */
16
Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase');
17
 
18
/**
19
 * Template control for editing an Active Record instance.
20
 * The <b>RecordClass</b> determines the Active Record class to be edited.
21
 * A particular record can be edited by specifying the {@link setRecordPk RecordPk}
22
 * value (may be an array for composite keys).
23
 *
24
 * The default editor input controls are created based on the column types.
25
 * The editor layout can be specified by a renderer by set the value
26
 * of the {@link setEditRenderer EditRenderer} property to the class name of a
27
 * class that implements TScaffoldEditRenderer. A renderer is an external
28
 * template control that implements IScaffoldEditRenderer.
29
 *
30
 * The <b>Data</b> of the IScaffoldEditRenderer will be set as the current Active
31
 * Record to be edited. The <b>UpdateRecord()</b> method of IScaffoldEditRenderer
32
 * is called when request to save the record is requested.
33
 *
34
 * Validators in the custom external editor template should have the
35
 * {@link TBaseValidator::setValidationGroup ValidationGroup} property set to the
36
 * value of the {@link getValidationGroup} of the TScaffoldEditView instance
37
 * (the edit view instance is the <b>Parent</b> of the IScaffoldEditRenderer in most
38
 * cases.
39
 *
40
 * Cosmetic changes to the default editor should be done using Cascading Stylesheets.
41
 * For example, a particular field/property can be hidden by specifying "display:none" for
42
 * the corresponding style (each field/property has unique Css class name as "property_xxx", where
43
 * xxx is the property name).
44
 *
45
 * @author Wei Zhuo <weizho[at]gmail[dot]com>
46
 * @version $Id: TScaffoldEditView.php 2541 2008-10-21 15:05:13Z qiang.xue $
47
 * @package System.Data.ActiveRecord.Scaffold
48
 * @since 3.1
49
 */
50
class TScaffoldEditView extends TScaffoldBase
51
{
52
	/**
53
	 * @var IScaffoldEditRenderer custom scaffold edit renderer
54
	 */
55
	private $_editRenderer;
56
 
57
	/**
58
	 * Initialize the editor form if it is Visible.
59
	 */
60
	public function onLoad($param)
61
	{
62
		if($this->getVisible())
63
			$this->initializeEditForm();
64
	}
65
 
66
	/**
67
	 * @return string the class name for scaffold editor. Defaults to empty, meaning not set.
68
	 */
69
	public function getEditRenderer()
70
	{
71
		return $this->getViewState('EditRenderer', '');
72
	}
73
 
74
	/**
75
	 * @param string the class name for scaffold editor. Defaults to empty, meaning not set.
76
	 */
77
	public function setEditRenderer($value)
78
	{
79
		$this->setViewState('EditRenderer', $value, '');
80
	}
81
 
82
	/**
83
	 * @param array Active Record primary key value to be edited.
84
	 */
85
	public function setRecordPk($value)
86
	{
87
		$this->clearRecordObject();
88
		$val = TPropertyValue::ensureArray($value);
89
		$this->setViewState('PK', count($val) > 0 ? $val : null);
90
	}
91
 
92
	/**
93
	 * @return array Active Record primary key value.
94
	 */
95
	public function getRecordPk()
96
	{
97
		return $this->getViewState('PK');
98
	}
99
 
100
	/**
101
	 * @return TActiveRecord current Active Record instance
102
	 */
103
	protected function getCurrentRecord()
104
	{
105
		return $this->getRecordObject($this->getRecordPk());
106
	}
107
 
108
	/**
109
	 * Initialize the editor form
110
	 */
111
	public function initializeEditForm()
112
	{
113
		$record = $this->getCurrentRecord();
114
		$classPath = $this->getEditRenderer();
115
		if($classPath === '')
116
		{
117
			$columns = $this->getTableInfo()->getColumns();
118
			$this->getInputRepeater()->setDataSource($columns);
119
			$this->getInputRepeater()->dataBind();
120
		}
121
		else
122
		{
123
			if($this->_editRenderer===null)
124
				$this->createEditRenderer($record, $classPath);
125
			else
126
				$this->_editRenderer->setData($record);
127
		}
128
	}
129
 
130
	/**
131
	 * Instantiate the external edit renderer.
132
	 * @param TActiveRecord record to be edited
133
	 * @param string external edit renderer class name.
134
	 * @throws TConfigurationException raised when renderer is not an
135
	 * instance of IScaffoldEditRenderer.
136
	 */
137
	protected function createEditRenderer($record, $classPath)
138
	{
139
		$this->_editRenderer = Prado::createComponent($classPath);
140
		if($this->_editRenderer instanceof IScaffoldEditRenderer)
141
		{
142
			$index = $this->getControls()->remove($this->getInputRepeater());
143
			$this->getControls()->insertAt($index,$this->_editRenderer);
144
			$this->_editRenderer->setData($record);
145
		}
146
		else
147
		{
148
			throw new TConfigurationException(
149
				'scaffold_invalid_edit_renderer', $this->getID(), get_class($record));
150
		}
151
	}
152
 
153
	/**
154
	 * Initialize the default editor using the scaffold input builder.
155
	 */
156
	protected function createRepeaterEditItem($sender, $param)
157
	{
158
		$type = $param->getItem()->getItemType();
159
		if($type==TListItemType::Item || $type==TListItemType::AlternatingItem)
160
		{
161
			$item = $param->getItem();
162
			$column = $item->getDataItem();
163
			if($column===null)
164
				return;
165
 
166
			$record = $this->getCurrentRecord();
167
			$builder = $this->getScaffoldInputBuilder($record);
168
			$builder->createScaffoldInput($this, $item, $column, $record);
169
		}
170
	}
171
 
172
	/**
173
	 * Bubble the command name event. Stops bubbling when the page validator false.
174
	 * Otherwise, the bubble event is continued.
175
	 */
176
	public function bubbleEvent($sender, $param)
177
	{
178
		switch(strtolower($param->getCommandName()))
179
		{
180
			case 'save':
181
				return $this->doSave() ? false : true;
182
			case 'clear':
183
				$this->setRecordPk(null);
184
				$this->initializeEditForm();
185
				return false;
186
			default:
187
				return false;
188
		}
189
	}
190
 
191
	/**
192
	 * Check the validators, then tries to save the record.
193
	 * @return boolean true if the validators are true, false otherwise.
194
	 */
195
	protected function doSave()
196
	{
197
		if($this->getPage()->getIsValid())
198
		{
199
			$record = $this->getCurrentRecord();
200
			if($this->_editRenderer===null)
201
			{
202
				$table = $this->getTableInfo();
203
				$builder = $this->getScaffoldInputBuilder($record);
204
				foreach($this->getInputRepeater()->getItems() as $item)
205
				{
206
					$column = $table->getColumn($item->getCustomData());
207
					$builder->loadScaffoldInput($this, $item, $column, $record);
208
				}
209
			}
210
			else
211
			{
212
				$this->_editRenderer->updateRecord($record);
213
			}
214
			$record->save();
215
			return true;
216
		}
217
		else if($this->_editRenderer!==null)
218
		{
219
			//preserve the form data.
220
			$this->_editRenderer->updateRecord($this->getCurrentRecord());
221
		}
222
 
223
		return false;
224
	}
225
 
226
	/**
227
	 * @return TRepeater default editor input controls repeater
228
	 */
229
	protected function getInputRepeater()
230
	{
231
		$this->ensureChildControls();
232
		return $this->getRegisteredObject('_repeater');
233
	}
234
 
235
	/**
236
	 * @return TButton Button triggered to save the Active Record.
237
	 */
238
	public function getSaveButton()
239
	{
240
		$this->ensureChildControls();
241
		return $this->getRegisteredObject('_save');
242
	}
243
 
244
	/**
245
	 * @return TButton Button to clear the editor inputs.
246
	 */
247
	public function getClearButton()
248
	{
249
		$this->ensureChildControls();
250
		return $this->getRegisteredObject('_clear');
251
	}
252
 
253
	/**
254
	 * @return TButton Button to cancel the edit action (e.g. hide the edit view).
255
	 */
256
	public function getCancelButton()
257
	{
258
		$this->ensureChildControls();
259
		return $this->getRegisteredObject('_cancel');
260
	}
261
 
262
	/**
263
	 * Create the default scaffold editor control factory.
264
	 * @param TActiveRecord record instance.
265
	 * @return TScaffoldInputBase scaffold editor control factory.
266
	 */
267
	protected function getScaffoldInputBuilder($record)
268
	{
269
		static $_builders=array();
270
		$class = get_class($record);
271
		if(!isset($_builders[$class]))
272
		{
273
			Prado::using('System.Data.ActiveRecord.Scaffold.InputBuilder.TScaffoldInputBase');
274
			$_builders[$class] = TScaffoldInputBase::createInputBuilder($record);
275
		}
276
		return $_builders[$class];
277
	}
278
 
279
	/**
280
	 * @return string editor validation group name.
281
	 */
282
	public function getValidationGroup()
283
	{
284
		return 'group_'.$this->getUniqueID();
285
	}
286
}
287
 
288
/**
289
 * IScaffoldEditRenderer interface.
290
 *
291
 * IScaffoldEditRenderer defines the interface that an edit renderer
292
 * needs to implement. Besides the {@link getData Data} property, an edit
293
 * renderer also needs to provide {@link updateRecord updateRecord} method
294
 * that is called before the save() method is called on the TActiveRecord.
295
 *
296
 * @author Wei Zhuo <weizho[at]gmail[dot]com>
297
 * @version $Id: TScaffoldEditView.php 2541 2008-10-21 15:05:13Z qiang.xue $
298
 * @package System.Data.ActiveRecord.Scaffold
299
 * @since 3.1
300
 */
301
interface IScaffoldEditRenderer extends IDataRenderer
302
{
303
	/**
304
	 * This method should update the record with the user input data.
305
	 * @param TActiveRecord record to be saved.
306
	 */
307
	public function updateRecord($record);
308
}
309