Development

/branches/1.4/lib/plugins/sfPropelPlugin/lib/generator/sfPropelGenerator.class.php

You must first sign up to be able to contribute.

root/branches/1.4/lib/plugins/sfPropelPlugin/lib/generator/sfPropelGenerator.class.php

Revision 22943, 9.1 kB (checked in by Kris.Wallsmith, 5 years ago)

[1.3] fixed propel "Cannot fetch TableMap?" exception (closes #7316, refs #7319)

  • Property svn:mime-type set to text/x-php
  • 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  * Propel generator.
13  *
14  * @package    symfony
15  * @subpackage propel
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 class sfPropelGenerator extends sfModelGenerator
20 {
21   protected
22     $tableMap = null,
23     $dbMap    = null;
24
25   /**
26    * Initializes the current sfGenerator instance.
27    *
28    * @param sfGeneratorManager $generatorManager A sfGeneratorManager instance
29    */
30   public function initialize(sfGeneratorManager $generatorManager)
31   {
32     parent::initialize($generatorManager);
33
34     $this->setGeneratorClass('sfPropelModule');
35   }
36
37   /**
38    * Configures this generator.
39    */
40   public function configure()
41   {
42     // get some model metadata
43     $this->loadMapBuilderClasses();
44
45     // load all primary keys
46     $this->loadPrimaryKeys();
47   }
48
49   /**
50    * Gets the table map for the current model class.
51    *
52    * @return TableMap A TableMap instance
53    */
54   public function getTableMap()
55   {
56     return $this->tableMap;
57   }
58
59   /**
60    * Returns an array of tables that represents a many to many relationship.
61    *
62    * A table is considered to be a m2m table if it has 2 foreign keys that are also primary keys.
63    *
64    * @return array An array of tables.
65    */
66   public function getManyToManyTables()
67   {
68     $tables = array();
69
70     // go through all tables to find m2m relationships
71     foreach ($this->dbMap->getTables() as $tableName => $table)
72     {
73       // load this table's relations and related tables
74       $table->getRelations();
75
76       foreach ($table->getColumns() as $column)
77       {
78         if ($column->isForeignKey() && $column->isPrimaryKey() && $this->getTableMap()->getClassname() == $this->dbMap->getTable($column->getRelatedTableName())->getClassname())
79         {
80           // we have a m2m relationship
81           // find the other primary key
82           foreach ($table->getColumns() as $relatedColumn)
83           {
84             if ($relatedColumn->isForeignKey() && $relatedColumn->isPrimaryKey() && $this->getTableMap()->getClassname() != $this->dbMap->getTable($relatedColumn->getRelatedTableName())->getClassname())
85             {
86               // we have the related table
87               $tables[] = array(
88                 'middleTable'   => $table,
89                 'relatedTable'  => $this->dbMap->getTable($relatedColumn->getRelatedTableName()),
90                 'column'        => $column,
91                 'relatedColumn' => $relatedColumn,
92               );
93
94               break 2;
95             }
96           }
97         }
98       }
99     }
100
101     return $tables;
102   }
103
104   /**
105    * Loads primary keys.
106    *
107    * @throws sfException
108    */
109   protected function loadPrimaryKeys()
110   {
111     $this->primaryKey = array();
112     foreach ($this->tableMap->getColumns() as $column)
113     {
114       if ($column->isPrimaryKey())
115       {
116         $this->primaryKey[] = $column->getPhpName();
117       }
118     }
119
120     if (!count($this->primaryKey))
121     {
122       throw new sfException(sprintf('Cannot generate a module for a model without a primary key (%s)', $this->modelClass));
123     }
124   }
125
126   /**
127    * Loads map builder classes.
128    *
129    * @throws sfException
130    */
131   protected function loadMapBuilderClasses()
132   {
133     $this->dbMap = Propel::getDatabaseMap();
134     $this->tableMap = call_user_func(array($this->modelClass . 'Peer', 'getTableMap'));
135     // load all related table maps,
136     // and all tables related to the related table maps (for m2m relations)
137     foreach ($this->tableMap->getRelations() as $relation)
138     {
139       $relation->getForeignTable()->getRelations();
140     }
141   }
142
143   /**
144    * Returns the getter either non-developped: 'getFoo' or developped: '$class->getFoo()'.
145    *
146    * @param string  $column     The column name
147    * @param boolean $developed  true if you want developped method names, false otherwise
148    * @param string  $prefix     The prefix value
149    *
150    * @return string PHP code
151    */
152   public function getColumnGetter($column, $developed = false, $prefix = '')
153   {
154     try
155     {
156       $getter = 'get'.call_user_func(array(constant($this->getModelClass().'::PEER'), 'translateFieldName'), $column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME);
157     }
158     catch (PropelException $e)
159     {
160       // not a real column
161       $getter = 'get'.sfInflector::camelize($column);
162     }
163
164     if (!$developed)
165     {
166       return $getter;
167     }
168
169     return sprintf('$%s%s->%s()', $prefix, $this->getSingularName(), $getter);
170   }
171
172   /**
173    * Returns the type of a column.
174    *
175    * @param  object $column A column object
176    *
177    * @return string The column type
178    */
179   public function getType($column)
180   {
181     if ($column->isForeignKey())
182     {
183       return 'ForeignKey';
184     }
185
186     switch ($column->getType())
187     {
188       case PropelColumnTypes::BOOLEAN:
189         return 'Boolean';
190       case PropelColumnTypes::DATE:
191       case PropelColumnTypes::TIMESTAMP:
192         return 'Date';
193       case PropelColumnTypes::TIME:
194         return 'Time';
195       default:
196         return 'Text';
197     }
198   }
199
200   /**
201    * Returns the default configuration for fields.
202    *
203    * @return array An array of default configuration for all fields
204    */
205   public function getDefaultFieldsConfiguration()
206   {
207     $fields = array();
208
209     $names = array();
210     foreach ($this->getTableMap()->getColumns() as $column)
211     {
212       $name = $this->translateColumnName($column);
213       $names[] = $name;
214       $fields[$name] = array_merge(array(
215         'is_link'      => (Boolean) $column->isPrimaryKey(),
216         'is_real'      => true,
217         'is_partial'   => false,
218         'is_component' => false,
219         'type'         => $this->getType($column),
220       ), isset($this->config['fields'][$name]) ? $this->config['fields'][$name] : array());
221     }
222
223     foreach ($this->getManyToManyTables() as $tables)
224     {
225       $name = sfInflector::underscore($tables['middleTable']->getClassname()).'_list';
226       $names[] = $name;
227       $fields[$name] = array_merge(array(
228         'is_link'      => false,
229         'is_real'      => false,
230         'is_partial'   => false,
231         'is_component' => false,
232         'type'         => 'Text',
233       ), isset($this->config['fields'][$name]) ? $this->config['fields'][$name] : array());
234     }
235
236     if (isset($this->config['fields']))
237     {
238       foreach ($this->config['fields'] as $name => $params)
239       {
240         if (in_array($name, $names))
241         {
242           continue;
243         }
244
245         $fields[$name] = array_merge(array(
246           'is_link'      => false,
247           'is_real'      => false,
248           'is_partial'   => false,
249           'is_component' => false,
250           'type'         => 'Text',
251         ), is_array($params) ? $params : array());
252       }
253     }
254
255     unset($this->config['fields']);
256
257     return $fields;
258   }
259
260   /**
261    * Returns the configuration for fields in a given context.
262    *
263    * @param  string $context The Context
264    *
265    * @return array An array of configuration for all the fields in a given context
266    */
267   public function getFieldsConfiguration($context)
268   {
269     $fields = array();
270
271     $names = array();
272     foreach ($this->getTableMap()->getColumns() as $column)
273     {
274       $name = $this->translateColumnName($column);
275       $names[] = $name;
276       $fields[$name] = isset($this->config[$context]['fields'][$name]) ? $this->config[$context]['fields'][$name] : array();
277     }
278
279     foreach ($this->getManyToManyTables() as $tables)
280     {
281       $name = sfInflector::underscore($tables['middleTable']->getClassname()).'_list';
282       $names[] = $name;
283       $fields[$name] = isset($this->config[$context]['fields'][$name]) ? $this->config[$context]['fields'][$name] : array();
284     }
285
286     if (isset($this->config[$context]['fields']))
287     {
288       foreach ($this->config[$context]['fields'] as $name => $params)
289       {
290         if (in_array($name, $names))
291         {
292           continue;
293         }
294
295         $fields[$name] = is_array($params) ? $params : array();
296       }
297     }
298
299     unset($this->config[$context]['fields']);
300
301     return $fields;
302   }
303
304   /**
305    * Gets all the fields for the current model.
306    *
307    * @param  Boolean $withM2M Whether to include m2m fields or not
308    *
309    * @return array   An array of field names
310    */
311   public function getAllFieldNames($withM2M = true)
312   {
313     $names = array();
314     foreach ($this->getTableMap()->getColumns() as $column)
315     {
316       $names[] = $this->translateColumnName($column);
317     }
318
319     if ($withM2M)
320     {
321       foreach ($this->getManyToManyTables() as $tables)
322       {
323         $names[] = sfInflector::underscore($tables['middleTable']->getClassname()).'_list';
324       }
325     }
326
327     return $names;
328   }
329
330   public function translateColumnName($column, $related = false, $to = BasePeer::TYPE_FIELDNAME)
331   {
332     $peer = $related ? constant($column->getTable()->getDatabaseMap()->getTable($column->getRelatedTableName())->getPhpName().'::PEER') : constant($column->getTable()->getPhpName().'::PEER');
333     $field = $related ? $column->getRelatedName() : $column->getFullyQualifiedName();
334
335     return call_user_func(array($peer, 'translateFieldName'), $field, BasePeer::TYPE_COLNAME, $to);
336   }
337 }
338
Note: See TracBrowser for help on using the browser.