2
votes

I have a list of dataobjects of which I'm trying to return all objects that match certain years e.g all objects that match 2015, 2013, 2002 etc

I first attempted to use ExactMatchMulti as per the question here: Silverstripe - filter DataObject list by many many relationship

However this has now been deprecated and Silverstripe suggests I use ExactMatchFilter instead. However I can't find much documentation/code usages of ExactMatchFilter so I'm not sure how to use it. Replacing ExactMatchMulti with ExactMatchFilter throws an exception.

$things->filter('PublicationDate:ExactMatchFilter', $filters);

Where $filters is just a simple array of years.

Does anyone have any examples or suggestions for this?

(Using 3.2.1)

3

3 Answers

1
votes

Exception details are good things to add to the question.

I think using exact match filter on a date field wouldn't work logically as you think. Does the field exactly contain 2015, or doest it contain a date timestamp? I'm presuming the latter as your field name is PublicationDate.

This is one we used to filter by year:

NewsItem()->get()->filter('Date:StartsWith', $year)

Or you could just filter with a greater than and lower than sets also by years.

EDIT:

The sample query is not tested on 3.2.1 but should be valid.

By using filter any you can get multiple with OR (based on https://docs.silverstripe.org/en/3.2/developer_guides/model/data_model_and_orm/#filterany):

 NewsItem()->get()->filterAny("Date:StartsWith",array('2015','2014'));

Then generate the array with the right years how do you want.

Tip:

Use ->sql() to see what is the sql query: Debug::dump(NewsItem()->get()->filterAny("Date:StartsWith",array('2014','2015'))->sql());

EDIT: revised to fix double key issue.

0
votes

In DataList, wording 'Filter' shouldn't be presented in filter() function.

Correct syntax should be

$things->filter('PublicationDate:ExactMatch', $filters);

Had a look at https://github.com/silverstripe/silverstripe-framework/blob/3.2.1/search/filters/ExactMatchFilter.php#L51

Passing array() to ExactMatchFilter should meet your requirement.

0
votes

Was actually very simple and just an oversight. Working example:

public function getPagesByFilter() {
    $filters = array('2015', '2014');
    Page::get()->filterAny('PublicationDate:PartialMatch', $filters);
}

The simple and obvious thing, as mentioned above was to use filterAny rather than just filter. This will return all pages with publication dates in 2015 and 2014.