Development

/branches/1.2/lib/plugins/sfPropelPlugin/lib/builder/SfObjectBuilder.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/plugins/sfPropelPlugin/lib/builder/SfObjectBuilder.php

Revision 23909, 9.6 kB (checked in by FabianLange, 4 years ago)

[1.2][1.3] updated SfObjectBuilder? so that Propel objects do not query the I18N table when they are new (fixes #7513, patch by joostdj)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 require_once 'propel/engine/builder/om/php5/PHP5ObjectBuilder.php';
4
5 /*
6  * This file is part of the symfony package.
7  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
8  *
9  * For the full copyright and license information, please view the LICENSE
10  * file that was distributed with this source code.
11  */
12
13 /**
14  * @package    symfony
15  * @subpackage propel
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 class SfObjectBuilder extends PHP5ObjectBuilder
20 {
21   public function build()
22   {
23     $objectCode = parent::build();
24     if (!DataModelBuilder::getBuildProperty('builderAddComments'))
25     {
26       $objectCode = sfToolkit::stripComments($objectCode);
27     }
28
29     if(!DataModelBuilder::getBuildProperty('builderAddIncludes'))
30     {
31        // remove all inline includes: object classes include the peers
32       $objectCode = preg_replace("/include_once\s*.*Base.*Peer\.php.*\s*/", "", $objectCode);
33     }
34
35     return $objectCode;
36   }
37
38   protected function addIncludes(&$script)
39   {
40     if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
41     {
42       return;
43     }
44
45     parent::addIncludes($script);
46
47     // include the i18n classes if needed
48     if ($this->getTable()->getAttribute('isI18N'))
49     {
50       $relatedTable   = $this->getDatabase()->getTable($this->getTable()->getAttribute('i18nTable'));
51
52       $script .= '
53 require_once \''.ClassTools::getFilePath($this->getStubObjectBuilder()->getPackage().'.', $relatedTable->getPhpName().'Peer').'\';
54 require_once \''.ClassTools::getFilePath($this->getStubObjectBuilder()->getPackage().'.', $relatedTable->getPhpName()).'\';
55 ';
56     }
57   }
58
59   protected function addClassBody(&$script)
60   {
61     parent::addClassBody($script);
62
63     if ($this->getTable()->getAttribute('isI18N'))
64     {
65       if (count($this->getTable()->getPrimaryKey()) > 1)
66       {
67         throw new Exception('i18n support only works with a single primary key');
68       }
69
70       $this->addCultureAccessorMethod($script);
71       $this->addCultureMutatorMethod($script);
72
73       $this->addI18nMethods($script);
74     }
75
76     if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
77     {
78       $this->addCall($script);
79     }
80   }
81
82   protected function addCall(&$script)
83   {
84     $script .= "
85
86   public function __call(\$method, \$arguments)
87   {
88     if (!\$callable = sfMixer::getCallable('{$this->getClassname()}:'.\$method))
89     {
90       throw new sfException(sprintf('Call to undefined method {$this->getClassname()}::%s', \$method));
91     }
92
93     array_unshift(\$arguments, \$this);
94
95     return call_user_func_array(\$callable, \$arguments);
96   }
97
98 ";
99   }
100
101   protected function addAttributes(&$script)
102   {
103     parent::addAttributes($script);
104
105     if ($this->getTable()->getAttribute('isI18N'))
106     {
107       $script .= '
108   /**
109    * The value for the culture field.
110    * @var string
111    */
112   protected $culture;
113 ';
114     }
115   }
116
117   protected function addCultureAccessorMethod(&$script)
118   {
119     $script .= '
120
121   /**
122    * Returns the culture.
123    *
124    * @return string The culture
125    */
126   public function getCulture()
127   {
128     return $this->culture;
129   }
130 ';
131   }
132
133   protected function addCultureMutatorMethod(&$script)
134   {
135     $script .= '
136   /**
137    * Sets the culture.
138    *
139    * @param string $culture The culture to set
140    *
141    * @return void
142    */
143   public function setCulture($culture)
144   {
145     $this->culture = $culture;
146   }
147 ';
148   }
149
150   protected function addI18nMethods(&$script)
151   {
152     $table = $this->getTable();
153     $pks = $table->getPrimaryKey();
154     $pk = $pks[0]->getPhpName();
155
156     foreach ($table->getReferrers() as $fk)
157     {
158       $tblFK = $fk->getTable();
159       if ($tblFK->getName() == $table->getAttribute('i18nTable'))
160       {
161         $className = $tblFK->getPhpName();
162         $culture = '';
163         $culture_peername = '';
164         foreach ($tblFK->getColumns() as $col)
165         {
166           if (("true" === strtolower($col->getAttribute('isCulture'))))
167           {
168             $culture = $col->getPhpName();
169             $culture_peername = PeerBuilder::getColumnName($col, $className);
170           }
171         }
172
173         foreach ($tblFK->getColumns() as $col)
174         {
175           if ($col->isPrimaryKey()) continue;
176
177           $script .= '
178   public function get'.$col->getPhpName().'($culture = null)
179   {
180     return $this->getCurrent'.$className.'($culture)->get'.$col->getPhpName().'();
181   }
182
183   public function set'.$col->getPhpName().'($value, $culture = null)
184   {
185     $this->getCurrent'.$className.'($culture)->set'.$col->getPhpName().'($value);
186   }
187 ';
188         }
189
190 $script .= '
191   protected $current_i18n = array();
192
193   public function getCurrent'.$className.'($culture = null)
194   {
195     if (is_null($culture))
196     {
197       $culture = is_null($this->culture) ? sfPropel::getDefaultCulture() : $this->culture;
198     }
199
200     if (!isset($this->current_i18n[$culture]))
201     {
202       $obj = $this->isNew() ? null : '.$className.'Peer::retrieveByPK($this->get'.$pk.'(), $culture);
203       if ($obj)
204       {
205         $this->set'.$className.'ForCulture($obj, $culture);
206       }
207       else
208       {
209         $this->set'.$className.'ForCulture(new '.$className.'(), $culture);
210         $this->current_i18n[$culture]->set'.$culture.'($culture);
211       }
212     }
213
214     return $this->current_i18n[$culture];
215   }
216
217   public function set'.$className.'ForCulture($object, $culture)
218   {
219     $this->current_i18n[$culture] = $object;
220     $this->add'.$className.'($object);
221   }
222 ';
223       }
224     }
225   }
226
227   protected function addDoSave(&$script)
228   {
229     $tmp = '';
230     parent::addDoSave($tmp);
231     // add autosave to i18n object even if the base object is not changed
232     $tmp = preg_replace_callback('#(\$this\->(.+?)\->isModified\(\))#', array($this, 'i18nDoSaveCallback'), $tmp);
233
234     $script .= $tmp;
235   }
236
237   private function i18nDoSaveCallback($matches)
238   {
239     $value = $matches[1];
240
241     // get the related class to see if it is a i18n one
242     $table = $this->getTable();
243     $column = null;
244     foreach ($table->getForeignKeys() as $fk)
245     {
246       if ($matches[2] == $this->getFKVarName($fk))
247       {
248         $column = $fk;
249         break;
250       }
251     }
252     $foreign_table = $this->getDatabase()->getTable($fk->getForeignTableName());
253     if ($foreign_table->getAttribute('isI18N'))
254     {
255       $foreign_tables_i18n_table = $this->getDatabase()->getTable($foreign_table->getAttribute('i18nTable'));
256       $value .= ' || ($this->'.$matches[2].'->getCulture() && $this->'.$matches[2].'->getCurrent'.$foreign_tables_i18n_table->getPhpName().'()->isModified())';
257     }
258
259     return $value;
260   }
261
262   protected function addDelete(&$script)
263   {
264     $tmp = '';
265     parent::addDelete($tmp);
266
267     if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
268     {
269       // add sfMixer call
270       $pre_mixer_script = "
271
272     foreach (sfMixer::getCallables('{$this->getClassname()}:delete:pre') as \$callable)
273     {
274       \$ret = call_user_func(\$callable, \$this, \$con);
275       if (\$ret)
276       {
277         return;
278       }
279     }
280
281 ";
282       $post_mixer_script = "
283
284     foreach (sfMixer::getCallables('{$this->getClassname()}:delete:post') as \$callable)
285     {
286       call_user_func(\$callable, \$this, \$con);
287     }
288
289 ";
290       $tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
291       $tmp = preg_replace('/}\s*$/', $post_mixer_script.'  }', $tmp);
292     }
293
294     // update current script
295     $script .= $tmp;
296   }
297
298   protected function addSave(&$script)
299   {
300     $tmp = '';
301     parent::addSave($tmp);
302
303     // add support for created_(at|on) and updated_(at|on) columns
304     $date_script = '';
305     $updated = false;
306     $created = false;
307     foreach ($this->getTable()->getColumns() as $col)
308     {
309       $clo = strtolower($col->getName());
310
311       if (!$updated && in_array($clo, array('updated_at', 'updated_on')))
312       {
313         $updated = true;
314         $date_script .= "
315     if (\$this->isModified() && !\$this->isColumnModified(".$this->getColumnConstant($col)."))
316     {
317       \$this->set".$col->getPhpName()."(time());
318     }
319 ";
320       }
321       else if (!$created && in_array($clo, array('created_at', 'created_on')))
322       {
323         $created = true;
324         $date_script .= "
325     if (\$this->isNew() && !\$this->isColumnModified(".$this->getColumnConstant($col)."))
326     {
327       \$this->set".$col->getPhpName()."(time());
328     }
329 ";
330       }
331     }
332     $tmp = preg_replace('/{/', '{'.$date_script, $tmp, 1);
333
334     if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
335     {
336       // add sfMixer call
337       $pre_mixer_script = "
338
339     foreach (sfMixer::getCallables('{$this->getClassname()}:save:pre') as \$callable)
340     {
341       \$affectedRows = call_user_func(\$callable, \$this, \$con);
342       if (is_int(\$affectedRows))
343       {
344         return \$affectedRows;
345       }
346     }
347
348 ";
349       $post_mixer_script = <<<EOF
350
351     foreach (sfMixer::getCallables('{$this->getClassname()}:save:post') as \$callable)
352     {
353       call_user_func(\$callable, \$this, \$con, \$affectedRows);
354     }
355
356 EOF;
357       $tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
358       $tmp = preg_replace('/(\$con\->commit\(\);)/', '$1'.$post_mixer_script, $tmp);
359     }
360
361     // update current script
362     $script .= $tmp;
363   }
364
365   protected function addClassClose(&$script)
366   {
367     parent::addClassClose($script);
368
369     $behaviors = $this->getTable()->getAttribute('behaviors');
370     if ($behaviors)
371     {
372       $behavior_file_name = 'Base'.$this->getTable()->getPhpName().'Behaviors';
373       $behavior_file_path = ClassTools::getFilePath($this->getStubObjectBuilder()->getPackage().'.om', $behavior_file_name);
374
375       $behavior_include_script = <<<EOF
376
377
378 if (sfProjectConfiguration::getActive() instanceof sfApplicationConfiguration)
379 {
380   include_once '%s';
381 }
382
383 EOF;
384       $script .= sprintf($behavior_include_script, $behavior_file_path);
385     }
386   }
387
388   protected function addConstants(&$script)
389   {
390     $script .= "\n  const PEER = '".$this->getPeerClassName()."';\n";
391   }
392 }
393
Note: See TracBrowser for help on using the browser.