Development

/branches/1.4/lib/form/addon/sfFormObject.class.php

You must first sign up to be able to contribute.

root/branches/1.4/lib/form/addon/sfFormObject.class.php

Revision 33250, 6.1 kB (checked in by fabien, 2 years ago)

[1.4] fixed saving i18n fields in subforms (closes #7626, patch from yoshy71)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * Base class for forms that deal with a single object.
13  *
14  * @package    symfony
15  * @subpackage form
16  * @author     Kris Wallsmith <kris.wallsmith@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 abstract class sfFormObject extends BaseForm
20 {
21   protected
22     $isNew  = true,
23     $object = null;
24
25   /**
26    * Returns the current model name.
27    *
28    * @return string
29    */
30   abstract public function getModelName();
31
32   /**
33    * Returns the default connection for the current model.
34    *
35    * @return mixed A database connection
36    */
37   abstract public function getConnection();
38
39   /**
40    * Updates the values of the object with the cleaned up values.
41    *
42    * If you want to add some logic before updating or update other associated
43    * objects, this is the method to override.
44    *
45    * @param array $values An array of values
46    */
47   abstract protected function doUpdateObject($values);
48
49   /**
50    * Processes cleaned up values.
51    *
52    * @param  array $values An array of values
53    *
54    * @return array An array of cleaned up values
55    */
56   abstract public function processValues($values);
57
58   /**
59    * Returns true if the current form embeds a new object.
60    *
61    * @return Boolean true if the current form embeds a new object, false otherwise
62    */
63   public function isNew()
64   {
65     return $this->isNew;
66   }
67
68   /**
69    * Returns the current object for this form.
70    *
71    * @return mixed The current object
72    */
73   public function getObject()
74   {
75     return $this->object;
76   }
77
78   /**
79    * Binds the current form and saves the object to the database in one step.
80    *
81    * @param  array An array of tainted values to use to bind the form
82    * @param  array An array of uploaded files (in the $_FILES or $_GET format)
83    * @param  mixed An optional connection object
84    *
85    * @return Boolean true if the form is valid, false otherwise
86    */
87   public function bindAndSave($taintedValues, $taintedFiles = null, $con = null)
88   {
89     $this->bind($taintedValues, $taintedFiles);
90     if ($this->isValid())
91     {
92       $this->save($con);
93
94       return true;
95     }
96
97     return false;
98   }
99
100
101   /**
102    * Saves the current object to the database.
103    *
104    * The object saving is done in a transaction and handled by the doSave() method.
105    *
106    * @param mixed $con An optional connection object
107    *
108    * @return mixed The current saved object
109    *
110    * @see doSave()
111    *
112    * @throws sfValidatorError If the form is not valid
113    */
114   public function save($con = null)
115   {
116     if (!$this->isValid())
117     {
118       throw $this->getErrorSchema();
119     }
120
121     if (null === $con)
122     {
123       $con = $this->getConnection();
124     }
125
126     try
127     {
128       $con->beginTransaction();
129
130       $this->doSave($con);
131
132       $con->commit();
133     }
134     catch (Exception $e)
135     {
136       $con->rollBack();
137
138       throw $e;
139     }
140
141     return $this->getObject();
142   }
143
144   /**
145    * Updates and saves the current object.
146    *
147    * If you want to add some logic before saving or save other associated
148    * objects, this is the method to override.
149    *
150    * @param mixed $con An optional connection object
151    */
152   protected function doSave($con = null)
153   {
154     if (null === $con)
155     {
156       $con = $this->getConnection();
157     }
158
159     $this->updateObject();
160
161     $this->getObject()->save($con);
162
163     // embedded forms
164     $this->saveEmbeddedForms($con);
165   }
166
167   /**
168    * Updates the values of the object with the cleaned up values.
169    *
170    * @param  array $values An array of values
171    *
172    * @return mixed The current updated object
173    */
174   public function updateObject($values = null)
175   {
176     if (null === $values)
177     {
178       $values = $this->values;
179     }
180
181     $values = $this->processValues($values);
182
183     $this->doUpdateObject($values);
184
185     // embedded forms
186     $this->updateObjectEmbeddedForms($values);
187
188     return $this->getObject();
189   }
190
191   /**
192    * Updates the values of the objects in embedded forms.
193    *
194    * @param array $values An array of values
195    * @param array $forms  An array of forms
196    */
197   public function updateObjectEmbeddedForms($values, $forms = null)
198   {
199     if (null === $forms)
200     {
201       $forms = $this->embeddedForms;
202     }
203
204     foreach ($forms as $name => $form)
205     {
206       if (!isset($values[$name]) || !is_array($values[$name]))
207       {
208         continue;
209       }
210
211       if ($form instanceof sfFormObject)
212       {
213         $form->updateObject($values[$name]);
214       }
215       else
216       {
217         $this->updateObjectEmbeddedForms($values[$name], $form->getEmbeddedForms());
218       }
219     }
220   }
221
222   /**
223    * Saves embedded form objects.
224    *
225    * @param mixed $con   An optional connection object
226    * @param array $forms An array of forms
227    */
228   public function saveEmbeddedForms($con = null, $forms = null)
229   {
230     if (null === $con)
231     {
232       $con = $this->getConnection();
233     }
234
235     if (null === $forms)
236     {
237       $forms = $this->embeddedForms;
238     }
239
240     foreach ($forms as $form)
241     {
242       if ($form instanceof sfFormObject)
243       {
244         $form->getObject()->save($con);
245         $form->saveEmbeddedForms($con);
246       }
247       else
248       {
249         $this->saveEmbeddedForms($con, $form->getEmbeddedForms());
250       }
251     }
252   }
253
254   /**
255    * Renders a form tag suitable for the related object.
256    *
257    * The method is automatically guessed based on the Doctrine object:
258    *
259    *  * if the object is new, the method is POST
260    *  * if the object already exists, the method is PUT
261    *
262    * @param  string $url         The URL for the action
263    * @param  array  $attributes  An array of HTML attributes
264    *
265    * @return string An HTML representation of the opening form tag
266    *
267    * @see sfForm
268    */
269   public function renderFormTag($url, array $attributes = array())
270   {
271     if (!isset($attributes['method']))
272     {
273       $attributes['method'] = $this->isNew() ? 'post' : 'put';
274     }
275
276     return parent::renderFormTag($url, $attributes);
277   }
278
279   protected function camelize($text)
280   {
281     return preg_replace(array('#/(.?)#e', '/(^|_|-)+(.)/e'), array("'::'.strtoupper('\\1')", "strtoupper('\\2')"), $text);
282   }
283 }
284
Note: See TracBrowser for help on using the browser.