Hi Adam,
I found and tested a data integrity issue in the filter group / filter management logic.
The problem is in:
administrator/components/com_j2commerce/src/Model/FiltergroupModel.php
administrator/components/com_j2commerce/src/Table/FiltergroupTable.php
specifically in the saveFilters() method.
Current behavior:
When a filter group is saved, the component deletes all existing filters assigned to that group and then inserts all submitted filters again.
This causes all existing j2commerce_filter_id values to be destroyed and recreated.
That is unsafe because product filter assignments are stored separately in:
#__j2commerce_product_filters
using:
filter_id -> #__j2commerce_filters.j2commerce_filter_id
As a result, even a harmless change, such as renaming a filter group or renaming/reordering filters, can break existing product filter assignments. Products may keep references to old filter IDs that no longer exist, or their filter assignments appear to be reset/lost.
Example:
A product is assigned to filter ID 239.
After editing and saving the filter group, the old filter row may be deleted and recreated with a new ID, for example 243.
The product still references 239, so the relation is no longer valid.
Tested cases where this caused problems:
- renaming a filter group
- renaming a filter
- reordering filters
- deleting a filter from a group
- deleting a whole filter group
- deleting a filter group from trash / permanently deleting it
What we changed:
Instead of deleting all filters and inserting them again, saveFilters() now preserves existing filter IDs.
The new logic is:
- load existing filter IDs for the group
- update existing filters by j2commerce_filter_id
- insert only new filters
- detect filters removed from the submitted form
- before deleting removed filters, delete their product associations from #__j2commerce_product_filters
- then delete only the removed filters from #__j2commerce_filters
This preserves existing j2commerce_filter_id values and therefore keeps product filter relations intact.
We also added cleanup for full filter group deletion:
When a filter group is permanently deleted, the code now removes:
- product filter associations from #__j2commerce_product_filters
- filter rows from #__j2commerce_filters
- the filter group row itself
The fix was tested with:
- existing product assigned to multiple filters
- renaming the filter group
- renaming filters
- deleting one filter from the group
- saving the product afterwards
- deleting the entire group
- deleting the group through trash/permanent delete flow
After the fix:
- existing filters keep their original IDs
- product filter relations remain valid after group/filter edits
- deleting a filter removes only that filter and its product associations
- deleting a whole group removes its filters and their product associations
- no orphaned records remain in #__j2commerce_product_filters
In my opinion the current DELETE ALL + INSERT ALL approach is unsafe here because #__j2commerce_filters.j2commerce_filter_id is not just an internal child-row ID. It is a persistent relational key used by product assignments.
A safer implementation should treat existing filters as stable records and update them instead of recreating them on every save.
Below, I'll paste the finished files, which definitively solve the entire problem.
Best regards,
KK