Hey @JonoM,
Sort of. The relationship between Groups and Filters (the left side of the diagram) is handled pretty easily with a GridField on FilterGroups for it’s Filters and going the other way, a select on a Filter for it’s one FilterGroup.
Those Groups are then added to a page with a list box. Probably change this to a TagField even though they’re basically the same with createable=false. Tried to get away from GridField here as it’s a cumbersome interface and users really just need to tag FilterGroups to a Page.
Products are then managed on a Page with another GridField. The gap was the big pink area above, a Product needed to have access to only the GroupFilters it’s related page had.
That’s where I ran into a host of problems. I needed to display different TagFields for each applicable FilterGroup with the applicable Filters for that Group.
I did find a way to do it.
In Product::getCMSFields:
# Get the FilterGroups as applied on the related ProductListPage
if (array_key_exists('ProductListPagesID', $this->record))
{
$FilterGroups = FilterGroup::get()->filter('ProductListPages.ID', $this->record['ProductListPagesID']);
foreach ($FilterGroups as $Group)
{
# Create a TagField for the FilterGroup
$fields->addFieldToTab('Root.Filters', TagField::create(
$Group->Title,
$Group->Title,
$Group->Filters()
)
->setShouldLazyLoad(false)
->setCanCreate(false)
);
}
}
else
{
$fields->addFieldToTab('Root.Filters', LabelField::create('Before adding any filters, please select a Product List Page to associate this Product with and click save.'));
}
Gets:
![g2](https://forum.silverstripe.org/uploads/default/original/1X/94db5168857a7bb751efaca6ed99854987870779.jpeg)
To get around the problem previously posted of “BadMethodException Method Cars doesn’t exist on Product”. I added:
public function defineMethods()
{
parent::defineMethods();
$FilterGroups = FilterGroup::get();
foreach ($FilterGroups as $Group)
{
$this->addWrapperMethod($Group->Title, 'FilterWrapper');
}
}
So that’ll wrap up any FilterGroup created and send it to “FilterWrapper” method. No more errors.
public function FilterWrapper($GroupTitle)
{
$Group = FilterGroup::get()->filter(['Title' => $GroupTitle])->first();
return $this->Filters()->filter(['ProductsID' => $this->ID, 'FilterGroupID' => $Group->ID]);
}
And that’ll apply the values selected for each FilterGroup.
The last problem was saving a Product. TagField seems to only want to save two ID’s but I need three, Product.ID FilterGroup.ID and the Filter.ID. So in Product::onAfterWrite:
public function onAfterWrite()
{
parent::onAfterWrite();
$store = [];
# Get all the Filters and their group in a flattened array
foreach (Filter::get() as $Filter)
{
$store[$Filter->ID] = $Filter->FilterGroupsID;
}
# Update each applied Filter row to include it's parent FilterGroup
foreach ($this->Filters() as $Filter)
{
$this->Filters()->add($Filter, ['FilterGroupID' => $store[$Filter->ID]]);
}
}
I update the Product → Filter relationship to include the FilterGroup.ID so I can find the Filters to apply to the correct FilterGroup when editing a Product.