silvershop-core
silvershop-core copied to clipboard
Various issues with creating custom Products by implementing the Buyable Interface
I am working on a project with ecommerce functionality, where the Product/Variation model does not really suit the domain. So I was pleased to see that Silvershop allows you to make any DataModel buyable by implementing the Buyable interface.
I came across a few issues. Firstly, the documentation on this is quite limited so it took me a long time to achieve what was obviously designed to be fairly straight forward. Secondly, there are a handful of places in silvershop-core code where it seems to have been overlooked that a Buyable might not be a Product. For instance, there are a handful of places calling OrderItem->Product() instead of OrderItem->Buyable() and there is a call in OrderItem (line 182) to $this->Buyable()->Image() where there is no guarantee that a Buyable actually has an Image association. This could be amended by adding a condition:
if ($this->Buyable() && $this->Buyable()->has_one("Image")) {
return $this->Buyable()->Image();
}
I have a temporary workaround which is to override these two methods in your Buyable's OrderItem Class
class MyBuyable_OrderItem extends OrderItem
{
...
public function Image()
{
return;
}
public function Product()
{
return $this->Buyable();
}
}
I propose the following changes:
- The documentation should be updated to include examples of implementing a custom Buyable AND a custom OrderItem
- Tests should be added to test that a basic custom Buyable can be created an added to the basket.
- All references to the OrderItem->Product() should be replaced with OrderItem->Buyable()
- Calls should not be made to Buyable->Image() where this association doesn't exist
I am happy to create a pull request but won't be able to do it for a few days
Thanks for raising this. These are all important problems which should be solved.
A PR would be really appreciated! And if we'd end up with some Unit-Tests that help identifying future issues with custom Buyables that would be great as well.