Development

#924 (Sort on foreign key and partials on admin generator)

You must first sign up to be able to contribute.

Ticket #924 (reopened enhancement)

Opened 2 years ago

Last modified 9 months ago

Sort on foreign key and partials on admin generator

Reported by: fred Assigned to:
Priority: minor Milestone:
Component: generator Version:
Keywords: Cc:
Qualification: Unreviewed

Description

To sort on foreign keys in admin generator, you need to overload the processSort function by defining the sorting column in the foreign table like this in actions.class.php :

protected function processSort()
{
  parent::processSort();
  if ($sort_column = $this->getUser()->getAttribute('sort', null, 'sf_admin/stat/sort'))
  {
    if ($sort_column === 'person_id')
    {
      $this->getUser()->setAttribute('sort', 'last_name', 'sf_admin/stat/sort');
    }
  }
}

You need also to overload the addSortCriteria function like this :

protected function addSortCriteria(&$c)                                                 
{                                                                                       
  parent::addSortCriteria($c);                                                          
  if ($sort_column = $this->getUser()->getAttribute('sort', null, 'sf_admin/stat/sort'))
  {                                                                                     
    if ($sort_column === 'last_name')                                                   
    {                                                                                   
      $this->getUser()->setAttribute('sort', 'person_id', 'sf_admin/stat/sort');        
    }                                                                                   
  }                                                                                     
}                                                                                       

This method works this v0.6.3 but not after.

With a newer version, the solution seems to pass an array instead of 'last_name' (second parameter) to setAttribute, array containing the table and column name, but we need to change the behaviour of the generated translateFieldName function in the Peer class.

Attachments

_list_th_tabular.php (1.9 kB) - added by Leon.van.der.Ree on 08/12/07 19:12:48.
actions.class.php (21.1 kB) - added by Leon.van.der.Ree on 08/12/07 19:13:16.
actions.class.php.diff (1.0 kB) - added by dyfrgi on 01/23/08 01:24:57.

Change History

01/05/07 15:03:00 changed by fabien

  • status changed from new to closed.
  • resolution set to invalid.

08/12/07 19:12:14 changed by Leon.van.der.Ree

  • status changed from closed to reopened.
  • type changed from defect to enhancement.
  • component set to generator.
  • summary changed from Sort on foreign key on admin generator to Sort on foreign key and partials on admin generator.
  • version deleted.
  • milestone deleted.
  • resolution deleted.

I have created a correct working version to sort on foreign keys.

In the generator.yml file you can now define on which (foreign)field(s) you want to sort.

For example you use the sfGuard plugin and add a relation to a profile table which contain firstname, nameadditions, a lastname and an emailaddress. In your user-list you want to see the username, fullname and emailaddress. Then your generator.yml file should contain the following lines to make the sorting on foreign fields to work (my profile class is simply called user and the primary key id-column is called userid):

generator:

class: sfPropelAdminGenerator param:

model_class: sfGuardUser theme: default

list:

title: Users display: [ =username, _show_fullname, _show_emailaddress] fields:

show_fullname:

name: Fullname join_fields: [sfGuardUserPeer::ID, UserPeer::USERID] sort_column: [UserPeer::FIRSTNAME, UserPeer::NAMEADDITIONS, UserPeer::LASTNAME]

show_emailaddress:

name: E-mailaddress sort_column: UserPeer::EMAILADDRESS

As you can see the fullname-column contains a join_fields option which defines the foreign-key relationship. In the emailaddress-column this now is obsolete but you can define it twice if you like. Furthermore the emailaddress-column only sorts on one foreign-column, called emailaddress, while the fullname-column gets sorted on 3 foreign-columns.

If your table would contain the columns itself, but you use a partial to show something like fullname you also don't need to specify the join_fields-option.

If you don't specify the sort_column-option the column simply still can't be sorted just like currently is the case for partials and foreign columns.

I've altered the action.class.php and _list_th_tabular.php files from the theme.


the change in _list_th_tabular.php :

...

<?php $sort_column = $this->getParameterValue('list.fields.'.$column->getName().'.sort_column'); ?>

<?php if ( ($column->isReal()) ($sort_column) ): ?>

...


and the changes in action.class.php are:

for the function executeList(): (adding the join(s) to the criteria)

...

$c = new Criteria();

<?php if ($fields = $this->getParameterValue('list.fields')): ?> <?php foreach ($fields as $key => $field): ?> <?php if ($join_fields= $this->getParameterValue('list.fields.'.$key.'.join_fields')): ?>

$c->addJoin(<?=$join_fields[0]?>,<?=$join_fields[1]?>);

<?php endif; ?> <?php endforeach; ?> <?php endif; ?>

$this->addSortCriteria($c);

...

the function addSortCriteria() is almost completely changed:

protected function addSortCriteria($c) {

if ($sort_column = $this->getUser()->getAttribute('sort', null, 'sf_admin/<?php echo $this->getSingularName() ?>/sort')) {

switch ($sort_column) {

<?php if ($fields = $this->getParameterValue('list.fields')): ?> <?php foreach ($fields as $key => $field): ?> <?php if ($this->getParameterValue('list.fields.'.$key.'.sort_column')): ?>

case '<?=$key?>':

<?php $column = $this->getParameterValue('list.fields.'.$key.'.sort_column');?>

<?php if ( is_array($column) ) : ?>

$sort_columns = Array(<?php

foreach ($column as $c) {

echo $c; if (next($column)) echo ", ";

} ?>);

<?php else: ?>

$sort_columns = Array(<?= $column ?>);

<?php endif; ?>

break;

<?php endif; ?> <?php endforeach; ?> <?php endif; ?>

default:

$sort_columns = Array(<?php echo $this->getClassName() ?>Peer::translateFieldName($sort_column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME)); break;

}

foreach ($sort_columns as $sort_column) {

if ($this->getUser()->getAttribute('type', null, 'sf_admin/<?php echo $this->getSingularName() ?>/sort') == 'asc') {

$c->addAscendingOrderByColumn($sort_column);

} else {

$c->addDescendingOrderByColumn($sort_column);

}

}

}

}


I'm going to add an other option, to also have the ability to sort on multiple fields! this will become an other ticket, but will continue on this base...

I'll attach both files

08/12/07 19:12:48 changed by Leon.van.der.Ree

  • attachment _list_th_tabular.php added.

08/12/07 19:13:16 changed by Leon.van.der.Ree

  • attachment actions.class.php added.

01/23/08 01:24:14 changed by dyfrgi

  • qualification set to Unreviewed.

I have a system in which there is an optional foreign key column. When used with this template, if the column is null, then that record is not displayed. The problem is the default INNER JOIN used. I've modified the template to allow specifying the join type using an additional key in the YAML, join_type. I've only tested it with left joins; I'm not sure it makes sense using any other join type. Inner join is clearly wrong in many circumstances, but could be a useful speed optimization in certain cases, so perhaps left join should be made the default in the future.

I'll attach a diff.

01/23/08 01:24:57 changed by dyfrgi

  • attachment actions.class.php.diff added.