I found a solution to the problem of sorting Items in DataObjectManager by a field that exists in the Parent / has_one relation of th DataObject.
We take this simple setup:
MyDataObject.php - the DataObject that is rendered via DataObjectManager
class MyDataObject extends DataObject {
public static $db = array (
'Title' => 'Varchar'
);
public static $has_one = array(
'DataObjectToSortBy' => 'DataObjectToSortBy', // our DataObject that we want to sort by
'MyPage' => 'MyPage' // the Page that contains the DataObjectManager
);
public function getCMSFields_forPopup() {
$f = new FieldSet();
$f->push(new Textfield('Title', 'Title');
return $f;
}
}
DataObjectToSortBy.php - the DataObject that contains the field we want the DataObjectManager to sort by
class DataObjectToSortBy extends DataObject {
public static $db = array (
'SortTitle' => 'Varchar'
);
public function getCMSFields() {
$f = new FieldSet();
$f->push(new Textfield('SortTitle', 'SortTitle');
return $f;
}
}
MyPage.php - the Page that contains the DataObjectManager
class MyPage extends Page {
public static $has_many = array(
'MyDataObjects' => 'MyDataObject'
);
public function getCMSFields() {
$f = parent::getCMSFields();
$f->addFieldToTab('Root.Content.MyDataObjects', new ManyManyDataObjectManager(
$this,
'MyDataObjects',
'MyDataObject',
array(
'Title' => 'Title,
'DataObjectToSortBy.SortTitle' => 'SortTitle'
),
'getCMSFields_forPopup',
null,
'SortTitle', // DO NOT USE 'DataObjectToSortBy.SortTitle' NOR USE 'ASC' or 'DESC'!! -> This uses field DataObjectToSortBy.SortTitle
'LEFT JOIN DataObjectToSortBy ON DataObjectToSortBy.MyDataObjectID = MyDataObject.ID'
);
return $f;
}
}
The Solution
The Solution is to use the fieldname of the has_one (or even has_many) relation but
- WITHOUT using the class name of the object (e.g. 'DataObjectToSortBy.SortTitle' -> ERROR) and
- WITHOUT using a sort direction (e.g. 'SortTitle ASC' -> ERROR).
Then use a Join clause to join your has_one or has_many DataObject with the DataObject in the DOM.
Downsides
- The field you want to sort by has to be unique in the MySQL Query (if DataObject has a field 'SortTitle' as well this does not work)
- You can only sort ascending (as the default dort direction)
It took me hours to figure this out. But this solution is tested and works.
It doen´t break the sorting functionality in the table field labels (you can still click the links) and is doesn´t break loading the popups.
Hope this helps!
@UncleCheese: I know there must be a better solution, as the sorting gets kind of messed up when you add the class name or sorting direction. But I didn´t find the code where this happens.
Just as a starting point: When you use 'DataObjectToSortBy.SortTitle ASC' as sorting clause $this->sourceSort becomes '"DataObjectToSortBy.SortTitle" ASC, DataObjectToSortBy.SortTitle' and produeces an MySQL Error.