Hello, e-Commerce enthusiast! Contribute to the 2023 edition happening this month. Click.

e-Commerce Advent Calendar

The e-Commerce geek's favorite time of year
2023 Edition

The adventure of writing a Magento module for X-mas lights

by Jisse Reitsma
Jisse Reitsma

Jisse is the brain behind Yireo, helping Magento and Shopware developers with on-site training, on-demand videos, blogs and open source extensions

So I want to write a Magento module. I got a Raspberry Pi that is connected to the lights of my Christmas tree and whenever I get a new Magento order coming in (higher than 10 Euro), I want the lights to go off-and-on. Let's get to it.

The Raspberry Pi vicissitudes

The GPIO Zero-based script is already done (first via REPL, then in a Python script). The Java webserver to listen to incoming REST API requests on my pi and then kickstart the Python magic is done as well. I've played via Guzzle, running a few calls - it seems to accept requests great and the lights are toggling. Maybe WebSphere was not the best of choices when it comes to resources. I might want to rewrite this one day to FrankenPHP combined with gRPC, whenever that starts to make sense.

The pi is connected by the way to a home battery, charged via the solar panels on the roof of our house. The days before Christmas are dark and the panels don't give a lot. But the pi doesn't consume much either, so it has been running solid since I connected it all together.

The Magento 2 module

The Magento module is not done yet. I'm clueless on where to begin. Of course, the first dozen of files will be generated by ChatGPT - my Zapier integration is able to take care of that: Programming in Google Docs has been a breeze, ever since I got the syntax highlighting working. And the Zapier tasks simply pick up on the right doc if it is ending with a .module suffix. It will include the necessary etc/extension_attributes.xml and etc/db_schema.xml to be on the safe-side. But I'm wondering where to go next.

My technical design is already taken care of: Whenever an order is placed by an end-customer in my shop, a DI after-plugin on getPayment() triggers my own logic (because observers suck). I first check if the payment data in the order data matches with the remote payment gateway API and double-check that there is no spam involved. With climate change and all, we don't want to consume too much energy, do we?

Queue the request and make it generic

Next, a new request-for-light-toggling message is triggered from the DI plugin and pushed to my RabbitMQ main queue. So much XML to get started with message queuing made me sick at first - I might just migrate this to ElasticSearch and move things around with LogStash beans or something. Anyway, the benefit is still scalability: Whenever a second Christmas tree would need to be lighted up, this is where things will pay off.

The worker is quiet straigth-forward: It makes sure that the transferred data is logged properly - I'll explain this part in a bit. And next, it sends out the REST request to the WebSphere API, which then leads to the Pi-based procedure mentioned earlier. And obviously, if this request fails, or the response from WebSphere contains any error (like the Pi resources being too high), this is logged as well.


The logger is a bit overengineered but for reasons: I want to make sure that any toggling attempt (with all its different steps) is tracked. If the tree lights are off, simply because my wife pulled the plug at night, I want to make sure that any toggling request can be debugged later. I still need to see if the message then simply retries (in the queue) until the next morning. Or that after 3 retries, it dies, so that a second queue picks up on all of the failed attempts and simply runs them all at once. Our cat will go crazy with that last option, lol.

At first, the logging is nothing more than a simple Monolog logger. However, for some other projects, I already created a custom handler that logs towards a flat table. Simple approach, just a model, resource model, collection, with a repository (and custom search criteria builder and custom search results) in front of it. This is where I needed the DB schema (mentioned earlier already). I added integration tests just to make sure that this database abstraction doesn't have any issues.

And to make sure that every entry could be extended by third party developers as well (after all, this project is going to be open source, perhaps even successful), I converted my own columns into extension attributes (with the extension_attributes.xml) as a blueprint for others.


Of course, all of the code in my module is going to be written with reusability in mind. Every class is going to be shipped with its own API interface plus DI preference. And all code is going to be checked for with a whopping Magento Coding Standard level 10 - try to beat that!

To guarantee code stability, CI/CD pipelines will be set up: Every class and every method in it is of course going to be shipped with unit tests and integration tests - just a unit test doesn't always make sense in Magento. And I'm think about adding phpstan, PHPCS (go go Juliette), PHPCPD, PHPMD, Psalm, phan and phploc. Adding phpmnd seems a bit much.

Looking for your feedback

All of this is going to be open source. I don't have any selfish interest in adding benefits with it. I will open up a Kickstart project on it though, just to see if the community is actually interested in it. And it helps me pay the bills for all the missed income, because I will be quite busy with building the entire thing before Christmas.

Let me know if you want to collaborate on this project. And I'm also happy to hear your feedback! Let's get in touch.

(Disclaimer: I do have a Christmas tree with lights, I do have a Raspberry Pi, I do have a Magento shop. But I only had time to write this post, not to write the actual module.)

Jisse Reitsma

Interested in submiting an article?

Please check our contribute page in case you are interest to submit an article.