silverstripe-framework: BUG DataList:canFilterBy() returns false for relations in dot notation

DataList:canFilterBy() only checks immediate database fields, not fields on relations which the ORM is quite capable of filtering on.

I noticed this when attempting to use a filter on a gridfield that included the Title from a has_one relation in the summary fields. No filter field is displayed for that column. If I amend DataList:canFilterBy() to simply return true, the filter field shows up and works perfectly.

@tractorcow you’re probably the authority on this subject is this something you could take a look at?

I suspect DataList:canSortBy() has a similar limitation.

silverstripe_-_edit_page

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 24 (24 by maintainers)

Commits related to this issue

Most upvoted comments

When I was working on the fix, I also had another idea I’d like to throw in. The main problem is that there is no good way to know if we are facing a dot notation that represent and relation or a formatting, therefore you need a lot of checks and such.

A really simple solution that would make the string notation more expressive is to make it clear by using some other kind of separator, for instance:

private static $casting = array(
    'TotalSpent' => 'Currency',
);
private static $summary_fields = array(
    'Title' => 'Title',
    'Member.Title' => 'Member Name',
    'Amount:Nice' => 'Amount' // We use : instead of . for formatting notation
    'Member.TotalSpent:Nice' => 'Total Amount Spent' // TotalSpent() is a method, not a field. We need to check if it's something we can sort/filter on. Since there is not underlying DBField, we could use the "casting" array to allow formatting even on computed fields?
);

As an added bonus, I think it would be great to handle formatting on computed fields like TotalSpent in my example, otherwise you need to define formatting at two places (partly in summary_fields, partly in setFieldFormatting) or having a method that return formatted data (TotalSpentFormatted… I did that a lot 😃 )

Having an array is nice because it’s very flexible, but it’s also very verbose. Would there by any use case where we have more than two parts? Otherwise we could have [‘TheLabel’, ‘TheFormatting’].