Summary_fields decorator

Silverstripe Version: 5.2

Coming back to Silverstripe after a while and hit a problem I don’t remember having.

I have a database field IsRepeatingDate defined in a model.

Usually in the models $summary_fields array I would do:

private static $summary_fields = [
    'IsRepeatingDate'
    // or
    'getIsRepeatingDate' => 'IsRepeatingDate'
];

And a model function:

public function getIsRepeatingDate()
{
    return $this->IsRepeatingDate ? 'Yes' : 'No';
}

That results in an error:

[Warning] Undefined property: DateConfig::$IsRepeatingDate

This is when editing a record and this model is a has_many on a parent model so is a GridField display not a main model admin.

For some reason I have to get() the record first/again:

public function getIsRepeatingDate()
{
    return $this->get()->IsRepeatingDate ? 'Yes' : 'No';
}

Is that normal/expected? There is other data in the table I’m not formatting and that sorts itself out.

There’s a few things going on here.

Firstly, $this->get() is not doing what you think it’s doing. Assuming you’re working with a DataObject subclass, you’re calling the static DataObject::get() method which is returning a DataList. It’s not getting your record.

Secondly, the reason you’re getting that warning is because calling IsRepeatingDate goes through the magic __get() method, which finds the getIsRepeatingDate() method and calls it.
Then, because __get() is already in the call stack, it can’t use that method again to try get the IsRepeatingDate property (if it could it would result in an infinite loop), so it looks for a native PHP property. Since you defined IsRepeatingDate in the $db configuration array, there’s no PHP property, so it warns you about that.

The correct way to get a db field from inside a getter method is like this:

public function getIsRepeatingDate()
{
    return $this->getField('IsRepeatingDate') ? 'Yes' : 'No';
}

Though note that for your use case, the getter is entirely unnecessary. You can just use the Nice() method:

private static array $summary_fields = [
    'IsRepeatingDate.Nice' => 'IsRepeatingDate',
];

Thanks for breaking that down. Appreciate it.

This worked:

private static $summary_fields = [
    'getIsRepeatingDateForTable' => 'IsRepeatingDate'
}
public function getIsRepeatingDateForTable()
{
    return $this->IsRepeatingDate ? 'Yes' : 'No';
}

Though note that for your use case, the getter is entirely unnecessary. You can just use the Nice() method:

Ahh of course!