Ticket #3037: admin_generator-self_referential.patch
| File admin_generator-self_referential.patch, 7.6 kB (added by georgsorst, 8 months ago) |
|---|
-
data/symfony/generator/sfPropelAdmin/default/template/actions/actions.class.php
old new 141 141 $user_params = $this->getParameterValue('edit.fields.'.$column->getName().'.params'); 142 142 $user_params = is_array($user_params) ? $user_params : sfToolkit::stringToArray($user_params); 143 143 $through_class = isset($user_params['through_class']) ? $user_params['through_class'] : ''; 144 $remote_column = isset($user_params['related_column']) ? $user_params['related_column'] : ''; 144 145 145 146 ?> 146 147 <?php if ($through_class): ?> 147 148 <?php 148 149 149 150 $class = $this->getClassName(); 150 $related_class = sfPropelManyToMany::getRelatedClass($class, $through_class );151 $related_class = sfPropelManyToMany::getRelatedClass($class, $through_class, $remote_column); 151 152 $related_table = constant($related_class.'Peer::TABLE_NAME'); 152 153 $middle_table = constant($through_class.'Peer::TABLE_NAME'); 153 154 $this_table = constant($class.'Peer::TABLE_NAME'); 154 155 155 $related_column = sfPropelManyToMany::getRelatedColumn($class, $through_class );156 $column = sfPropelManyToMany::getColumn($class, $through_class );156 $related_column = sfPropelManyToMany::getRelatedColumn($class, $through_class, $remote_column); 157 $column = sfPropelManyToMany::getColumn($class, $through_class, $remote_column); 157 158 158 159 ?> 159 160 <?php if ($input_type == 'admin_double_list' || $input_type == 'admin_check_list' || $input_type == 'admin_select_list'): ?> -
symfony/addon/propel/sfPropelManyToMany.class.php
old new 18 18 */ 19 19 class sfPropelManyToMany 20 20 { 21 public static function getColumn($class, $middleClass )21 public static function getColumn($class, $middleClass, $relatedColumn = '') 22 22 { 23 23 // find the related class 24 24 $tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap')); 25 25 $object_table_name = constant($class.'Peer::TABLE_NAME'); 26 27 if (!empty($relatedColumn)) 28 { 29 $relatedColumnName = $tableMap->getColumn($relatedColumn)->getPhpName(); 30 } 31 26 32 foreach ($tableMap->getColumns() as $column) 27 33 { 28 34 if ($column->isForeignKey() && $object_table_name == $column->getRelatedTableName()) 29 35 { 30 return $column; 36 if (!empty($relatedColumn)) 37 { 38 if ($column->getPhpName() != $relatedColumnName) 39 { 40 return $column; 41 } 42 } 43 else 44 { 45 return $column; 46 } 31 47 } 32 48 } 33 49 } 34 50 35 public static function getRelatedColumn($class, $middleClass )51 public static function getRelatedColumn($class, $middleClass, $relatedColumn = '') 36 52 { 37 53 // find the related class 38 54 $tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap')); 39 55 $object_table_name = constant($class.'Peer::TABLE_NAME'); 56 57 if (!empty($relatedColumn)) 58 { 59 return $tableMap->getColumn($relatedColumn); 60 } 61 40 62 foreach ($tableMap->getColumns() as $column) 41 63 { 42 64 if ($column->isForeignKey() && $object_table_name != $column->getRelatedTableName()) … … 46 68 } 47 69 } 48 70 49 public static function getRelatedClass($class, $middleClass )71 public static function getRelatedClass($class, $middleClass, $relatedColumn = '') 50 72 { 51 $column = self::getRelatedColumn($class, $middleClass );73 $column = self::getRelatedColumn($class, $middleClass, $relatedColumn); 52 74 53 75 // we must load all map builder classes 54 76 $classes = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs()); … … 64 86 return $tableMap->getDatabaseMap()->getTable($column->getRelatedTableName())->getPhpName(); 65 87 } 66 88 67 public static function getAllObjects($object, $middleClass, $ criteria = null)89 public static function getAllObjects($object, $middleClass, $relatedColumn = '', $criteria = null) 68 90 { 69 91 if (null === $criteria) 70 92 { 71 93 $criteria = new Criteria(); 72 94 } 73 95 74 $relatedClass = self::getRelatedClass(get_class($object), $middleClass); 96 $relatedClass = self::getRelatedClass(get_class($object), $middleClass, $relatedColumn); 97 98 // don't show $this object for self-referential relation 99 // make sure to use all primary keys 100 if (!empty($relatedColumn)) 101 { 102 $tempCriteria = $object->buildPkeyCriteria(); 103 foreach ($tempCriteria->getIterator() as $criterion) 104 { 105 $criteria->add($criterion->getTable().'.'.$criterion->getColumn(), $criterion->getValue(), Criteria::NOT_EQUAL); 106 } 107 } 75 108 76 109 return call_user_func(array($relatedClass.'Peer', 'doSelect'), $criteria); 77 110 } … … 83 116 * @param $middleClass The middle class used for the many-to-many relationship. 84 117 * @param $criteria Criteria to apply to the selection. 85 118 */ 86 public static function getRelatedObjects($object, $middleClass, $ criteria = null)119 public static function getRelatedObjects($object, $middleClass, $relatedColumn = '', $criteria = null) 87 120 { 88 121 if (null === $criteria) 89 122 { 90 123 $criteria = new Criteria(); 91 124 } 92 125 93 $relatedClass = self::getRelatedClass(get_class($object), $middleClass );126 $relatedClass = self::getRelatedClass(get_class($object), $middleClass, $relatedColumn); 94 127 95 128 $relatedObjects = array(); 96 $objectMethod = 'get'.$middleClass.'sJoin'.$relatedClass; 97 $relatedMethod = 'get'.$relatedClass; 98 $rels = $object->$objectMethod($criteria); 129 if (empty($relatedColumn)) 130 { 131 $objectMethod = 'get'.$middleClass.'sJoin'.$relatedClass; 132 $relatedMethod = 'get'.$relatedClass; 133 $rels = $object->$objectMethod($criteria); 134 } 135 else 136 { 137 // as there is no way to join the related objects starting from this object we'll use the through class peer instead 138 $localColumn = self::getColumn(get_class($object), $middleClass, $relatedColumn); 139 $remoteColumn = self::getRelatedColumn(get_class($object), $middleClass, $relatedColumn); 140 $c = new Criteria(); 141 $c->add(constant($middleClass.'Peer::'.$localColumn->getColumnName()), $object->getId()); 142 $relatedMethod = 'get'.$relatedClass.'RelatedBy'.$remoteColumn->getPhpName(); 143 $rels = call_user_func(array($middleClass.'Peer', 'doSelectJoin'.$relatedClass.'RelatedBy'.$remoteColumn->getPhpName()), $c); 144 } 99 145 foreach ($rels as $rel) 100 146 { 101 147 $relatedObjects[] = $rel->$relatedMethod(); -
symfony/helper/ObjectAdminHelper.php
old new 189 189 { 190 190 // get the lists of objects 191 191 $through_class = _get_option($options, 'through_class'); 192 $related_column = _get_option($options, 'related_column', null); 192 193 193 $objects = sfPropelManyToMany::getAllObjects($object, $through_class );194 $objects_associated = sfPropelManyToMany::getRelatedObjects($object, $through_class );194 $objects = sfPropelManyToMany::getAllObjects($object, $through_class, $related_column); 195 $objects_associated = sfPropelManyToMany::getRelatedObjects($object, $through_class, $related_column); 195 196 $ids = array_map(create_function('$o', 'return $o->getPrimaryKey();'), $objects_associated); 196 197 197 198 return array($objects, $objects_associated, $ids);