Development

#3037: admin_generator-self_referential.patch

You must first sign up to be able to contribute.

Ticket #3037: admin_generator-self_referential.patch

File admin_generator-self_referential.patch, 7.6 kB (added by georgsorst, 8 months ago)

Fix for self-referential relations for the admin generator

  • data/symfony/generator/sfPropelAdmin/default/template/actions/actions.class.php

    old new  
    141141$user_params = $this->getParameterValue('edit.fields.'.$column->getName().'.params'); 
    142142$user_params = is_array($user_params) ? $user_params : sfToolkit::stringToArray($user_params); 
    143143$through_class = isset($user_params['through_class']) ? $user_params['through_class'] : ''; 
     144$remote_column = isset($user_params['related_column']) ? $user_params['related_column'] : ''; 
    144145 
    145146?> 
    146147<?php if ($through_class): ?> 
    147148<?php 
    148149 
    149150$class = $this->getClassName(); 
    150 $related_class = sfPropelManyToMany::getRelatedClass($class, $through_class); 
     151$related_class = sfPropelManyToMany::getRelatedClass($class, $through_class, $remote_column); 
    151152$related_table = constant($related_class.'Peer::TABLE_NAME'); 
    152153$middle_table = constant($through_class.'Peer::TABLE_NAME'); 
    153154$this_table = constant($class.'Peer::TABLE_NAME'); 
    154155 
    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); 
    157158 
    158159?> 
    159160<?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  
    1818 */ 
    1919class sfPropelManyToMany 
    2020{ 
    21   public static function getColumn($class, $middleClass
     21  public static function getColumn($class, $middleClass, $relatedColumn = ''
    2222  { 
    2323    // find the related class 
    2424    $tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap')); 
    2525    $object_table_name = constant($class.'Peer::TABLE_NAME'); 
     26 
     27    if (!empty($relatedColumn)) 
     28    { 
     29      $relatedColumnName = $tableMap->getColumn($relatedColumn)->getPhpName(); 
     30    } 
     31 
    2632    foreach ($tableMap->getColumns() as $column) 
    2733    { 
    2834      if ($column->isForeignKey() && $object_table_name == $column->getRelatedTableName()) 
    2935      { 
    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        } 
    3147      } 
    3248    } 
    3349  } 
    3450 
    35   public static function getRelatedColumn($class, $middleClass
     51  public static function getRelatedColumn($class, $middleClass, $relatedColumn = ''
    3652  { 
    3753    // find the related class 
    3854    $tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap')); 
    3955    $object_table_name = constant($class.'Peer::TABLE_NAME'); 
     56 
     57    if (!empty($relatedColumn)) 
     58    { 
     59      return $tableMap->getColumn($relatedColumn); 
     60    } 
     61 
    4062    foreach ($tableMap->getColumns() as $column) 
    4163    { 
    4264      if ($column->isForeignKey() && $object_table_name != $column->getRelatedTableName()) 
     
    4668    } 
    4769  } 
    4870 
    49   public static function getRelatedClass($class, $middleClass
     71  public static function getRelatedClass($class, $middleClass, $relatedColumn = ''
    5072  { 
    51     $column = self::getRelatedColumn($class, $middleClass); 
     73    $column = self::getRelatedColumn($class, $middleClass, $relatedColumn); 
    5274 
    5375    // we must load all map builder classes 
    5476    $classes = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs()); 
     
    6486    return $tableMap->getDatabaseMap()->getTable($column->getRelatedTableName())->getPhpName(); 
    6587  } 
    6688 
    67   public static function getAllObjects($object, $middleClass, $criteria = null) 
     89  public static function getAllObjects($object, $middleClass, $relatedColumn = '', $criteria = null) 
    6890  { 
    6991    if (null === $criteria) 
    7092    { 
    7193      $criteria = new Criteria(); 
    7294    } 
    7395 
    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    } 
    75108 
    76109    return call_user_func(array($relatedClass.'Peer', 'doSelect'), $criteria); 
    77110  } 
     
    83116   * @param  $middleClass   The middle class used for the many-to-many relationship. 
    84117   * @param  $criteria      Criteria to apply to the selection. 
    85118   */ 
    86   public static function getRelatedObjects($object, $middleClass, $criteria = null) 
     119  public static function getRelatedObjects($object, $middleClass, $relatedColumn = '', $criteria = null) 
    87120  { 
    88121    if (null === $criteria) 
    89122    { 
    90123      $criteria = new Criteria(); 
    91124    } 
    92125 
    93     $relatedClass = self::getRelatedClass(get_class($object), $middleClass); 
     126    $relatedClass = self::getRelatedClass(get_class($object), $middleClass, $relatedColumn); 
    94127 
    95128    $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    } 
    99145    foreach ($rels as $rel) 
    100146    { 
    101147      $relatedObjects[] = $rel->$relatedMethod(); 
  • symfony/helper/ObjectAdminHelper.php

    old new  
    189189{ 
    190190  // get the lists of objects 
    191191  $through_class = _get_option($options, 'through_class'); 
     192  $related_column = _get_option($options, 'related_column', null); 
    192193 
    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); 
    195196  $ids = array_map(create_function('$o', 'return $o->getPrimaryKey();'), $objects_associated); 
    196197 
    197198  return array($objects, $objects_associated, $ids);