UndefinedOffset / SortableGridField

Adds drag and drop functionality to Silverstripe's GridField
BSD 3-Clause "New" or "Revised" License
93 stars 62 forks source link

Breaks when used with GridFieldManyRelationHandler #40

Closed AlphaCactus closed 11 years ago

AlphaCactus commented 11 years ago

When using the GridFieldManyRelationHandler module https://github.com/simonwelsh/silverstripe-GridFieldRelationHandler on the same GridField, GridFieldSortableRows::fixSortColumn breaks on line 134.

ERROR [User Error]: Sort column SortOrder could not be found in Biography's ancestry.

The problem is occuring because the list being passed in is a DataList and not a ManyManyList, even though it Should be a ManyManyList.

I"m not really sure if this is a problem in SortableGridField or in GridFieldManyRelationHandler, but the error is occuring in code in SortableGridField so I thought I'd start here.

Relevant Code:

$config->addComponent( new GridFieldSortableRows('SortOrder') );
$config->addComponent( new GridFieldManyRelationHandler(), 'GridFieldPaginator' );

Error Report

ERROR [User Error]: Sort column SortOrder could not be found in Biography's ancestry
IN POST /admin/pages/edit/EditForm/field/Biographies
Line 133 in C:\wamp\www\snwp_v31\SortableGridField\code\forms\GridFieldSortableRows.php

Source
======
  124:          $query->limit(array());
  125:          return $query;
  126:      });
  127:      $many_many = ($list instanceof ManyManyList);
  128:      if (!$many_many) {
  129:          $sng=singleton($gridField->getModelClass());
  130:          $fieldType=$sng->db($this->sortColumn);
  131:          if(!$fieldType || !($fieldType=='Int' || is_subclass_of('Int', $fieldType))) {
  132:              if(is_array($fieldType)) {
* 133:                  user_error('Sort column '.$this->sortColumn.' could not be found in
       '.$gridField->getModelClass().'\'s ancestry', E_USER_ERROR);
  134:              }else {
  135:                  user_error('Sort column '.$this->sortColumn.' must be an Int, column is of type '.$fieldType,
       E_USER_ERROR);
  136:              }
  137:              
  138:              exit;
  139:          }

Trace
=====
user_error(Sort column SortOrder could not be found in Biography's ancestry,256)
GridFieldSortableRows.php:133

GridFieldSortableRows->fixSortColumn(GridField,DataList)
GridFieldSortableRows.php:95

GridFieldSortableRows->getManipulatedData(GridField,DataList)
GridField.php:222

GridField->getManipulatedList()
GridField.php:264

GridField->FieldHolder()
GridField.php:644

GridField->gridFieldAlterAction(Array,Form,SS_HTTPRequest)
GridField.php:108

GridField->index(SS_HTTPRequest)
RequestHandler.php:278

RequestHandler->handleAction(SS_HTTPRequest,index)
RequestHandler.php:190

RequestHandler->handleRequest(SS_HTTPRequest,DataModel)
GridField.php:749

GridField->handleRequest(SS_HTTPRequest,DataModel)
RequestHandler.php:212

RequestHandler->handleRequest(SS_HTTPRequest,DataModel)
RequestHandler.php:212

RequestHandler->handleRequest(SS_HTTPRequest,DataModel)
Controller.php:153

Controller->handleRequest(SS_HTTPRequest,DataModel)
LeftAndMain.php:438

LeftAndMain->handleRequest(SS_HTTPRequest,DataModel)
AdminRootController.php:89

AdminRootController->handleRequest(SS_HTTPRequest,DataModel)
Director.php:325

Director::handleRequest(SS_HTTPRequest,Session,DataModel)
Director.php:143

Director::direct(/admin/pages/edit/EditForm/field/Biographies,DataModel)
main.php:128
UndefinedOffset commented 11 years ago

What version of SilverStripe are you using? As well have you tried eliminating GridFieldManyRelationHandler see if that solves the issue? Also what does your model look like (the dataobject and the page type)? And the implementation code for the gridfield, for the model simplified versions are fine i.e just the getCMSFields and relationship definition on the dataobject. For the managed object just the database statics at the top are really all I need.

UndefinedOffset commented 11 years ago

Also in looking at the module you're referencing it maybe the case that GridFieldSortableRows may not work with this type of list. I'll need to do some experimenting, but please do provide the information I asked for in the previous post. It will help me narrow things down, and could lead me to discovering the issue may not be related to this module at all. Hard to say :)

AlphaCactus commented 11 years ago

Silverstripe 3.1 master Removing either module allows both modules to work just fine. SortableGridField works fine regardless. It is only when clicking the "Change Relation Status" button provided by GridFieldManyRelationHandler that there is a problem because, it seems, that GridFieldManyRelationHandler is likely [incorrectly] modifying the list and then passing it to GridFieldSortableRows.

here is relevant code:

class BiographiesPage extends Page {    
    private static $many_many = array(
        'Biographies' => 'Biography'
    );

function getCMSFields() {
        $fields = parent::getCMSFields();

        $gf = GridField::create( 'Biographies', 'Biographies', $this->Biographies(), GridFieldConfig_RelationEditor::create() );
        $config = $gf->getConfig();
        $config->addComponent( new GridFieldSortableRows('SortOrder') );
        // @TODO: Can't use GridFieldManyRelationHandler with GridFeidlSortableRows beacuse GridFieldSortableRows breaks GridFieldManyRelationHandler (though the bug may be in GridFieldManyRelationHandler)
        //$config->addComponent( new GridFieldManyRelationHandler(), 'GridFieldPaginator' );
        $fields->addFieldToTab( 'Root.Biographies', $gf );
        CMSutils::addGridFieldManyRelationHandlerWarning( $fields, "Biographies");
        return $fields;
    }

    // Sorting Support
    private static $many_many_extraFields = array(
        'Biographies' => array( 'SortOrder' => 'Int' )
    );  

    public function Biographies() {
    return $this->getManyManyComponents('Biographies')->sort('SortOrder');
}
AlphaCactus commented 11 years ago

I just had a flash of genius and modified addComponent to force GridFieldSortableRows to go before GridFieldManyRelationHandler. This seems to be working. You might add a note to the readme.

$config->addComponent( new GridFieldManyRelationHandler(), 'GridFieldPaginator' );
// GridFieldSortableRows must be set to go before GridFieldManyRelationHandler
$config->addComponent( new GridFieldSortableRows('SortOrder'), 'GridFieldManyRelationHandler' );
UndefinedOffset commented 11 years ago

Sweet thanks, I will definitely do that.

AlphaCactus commented 11 years ago

Thanks for your help. As far as I'm concerned you may close this issue.

UndefinedOffset commented 11 years ago

I'll leave it for now so I'll remember to update the readme lol