?> berliozd, Author at Addeos

Author Archive

My first SaaS tool is live – Progr.io

A brillant idea needs a tracking tool

Are you an indie hacker, solopreneur, developer, or startupper with a brilliant idea but unsure of how to refine and track it? I've been there - the initial excitement of a new idea can quickly become overwhelming when it comes to the nitty-gritty details.

That's why I've developed a new SaaS tool progr.io, designed to help you transform your raw ideas into a structured plan, using the power of AI.

My tool allows you to track your ideas and refine them by adding details such as features, ways of monetization, targets, benefits, and more. With AI integration, it provides intelligent suggestions and insights, making the process of idea refinement more efficient and effective. It's like having a personal assistant for your ideas, helping you to see potential angles and opportunities you might not have considered.

Imagine you have an idea for a new web development tool. With my SaaS, you can input your idea and then start adding details. The AI might suggest potential features based on current market trends, or ways to monetize that you hadn't thought of. Or perhaps you have an idea for a new eCommerce platform. My tool can help you identify your target market, refine your unique selling propositions, and plan your benefits and features to meet your audience's needs.

I believe that everyone should have the opportunity to refine and track their ideas, which is why I'am offering a free version of my tool. With the free version, you can track up to 3 ideas at a time and access basic AI suggestions. While there are some limitations, I believe it's a great way to get started and see the value of my tool.

Ready to take your ideas to the next level? Try my tool today. Sign up now and start refining and tracking your ideas with the help of AI. I can't wait to see what you'll create! Go to progr.io.

I'am committed to making my tool the best it can be, and your feedback is invaluable. Let me know what you think - I'am always open to suggestions and improvements. Together, we can make idea refinement and tracking more accessible and efficient for everyone.

Join me in shaping progr.io into an exceptional tool that delivers value to all of us!


Generating PDF from Markdown with Grip

Markdown is a popular lightweight markup language used for formatting plain text documents. While Markdown excels in simplicity and ease of use, there are scenarios where the need arises to convert Markdown files to more portable and shareable formats, such as PDF. PDFs provide a consistent and printable representation of documents, making them an ideal choice for sharing content across various platforms.

However, when working with Markdown files containing images, the process of converting them to PDF can sometimes become challenging. The inclusion of images adds an extra layer of complexity to the conversion process, as certain tools may not seamlessly handle the transition from Markdown to PDF.

In this tutorial, we'll explore the use of Grip, a Markdown previewer, to generate a PDF file from a Markdown document. Additionally, we'll address the common concerns associated with images in Markdown files and provide solutions to ensure a smooth conversion process.

Whether you're looking to share documentation, create presentation materials, or simply preserve the formatting of your Markdown content for offline use, the ability to generate PDFs becomes invaluable. Let's dive into the step-by-step guide to harnessing Grip's capabilities for this purpose, and learn how to overcome challenges related to images in the Markdown-to-PDF conversion process.

Step 1: Install Grip

Grip is a lightweight GitHub-flavored Markdown previewer. You can install it using Python's pip package manager:

pip install grip

Step 2: Create a Markdown File

Create a Markdown file (e.g., example.md) containing your content. You can use any text editor to create and edit this file.

Step 3: Preview with Grip

Run Grip to preview your Markdown file:

grip example.md

This command will start a local server and provide you with a URL (e.g., http://localhost:6419). Open this URL in your web browser to see how your Markdown file will be rendered.

Step 4: Save as PDF

After previewing your Markdown file, you can save the rendered HTML as a PDF using your browser's print functionality.

In Google Chrome:

  • Click on the three dots in the top-right corner.
  • Select "Print..."
  • Change the destination to "Save as PDF."
  • Click "Save" to save the PDF file.

In Firefox:

  • Click on the three horizontal lines in the top-right corner.
  • Select "Print..."
  • Choose "Save to File" as the printer.
  • Click "Print" and save the PDF file.


Now you have successfully generated a PDF file from your Markdown file using Grip and printed it as a PDF.


Enhancing Magento 2 JavaScript Modules with Mixins: A Guide


Magento 2 provides a robust and extensible architecture that allows developers to customize and extend functionality easily. One powerful feature for extending JavaScript modules is the use of mixins. In this article, we will explore how to add a mixin to an existing JavaScript module in Magento 2, drawing parallels to the familiar concept of writing PHP plugins for adding specific treatments after, before or around existing functions.

Understanding Mixins in Magento 2:

Mixins in Magento 2 JavaScript development enable developers to add or override methods in existing classes. This approach promotes code reusability and allows for seamless customization without modifying the core codebase. Just as PHP plugins can extend and modify the behavior of existing PHP classes, mixins empower JavaScript developers to enhance the functionality of JavaScript modules in a clean and modular way.


Before diving into the mixin implementation, ensure you have a basic understanding of Magento 2 JavaScript development and are familiar with the structure of the module you intend to extend.

Step 1: Create Your Mixin File:

In your custom module, create a JavaScript mixin file. This file should follow the naming convention "vendor/namespace/view/frontend/web/js/mixin-name-mixin.js". This file will contain the code for your mixin.

Let's say my module vendor and namespace is Addeos_MyModule.

And I want to create a mixin for this core file : vendor/magento/module-checkout/view/frontend/web/js/model/shipping-save-processor/default.js

I am going to create this file:
I respect the same folder hierachy.

Here is the content of that file:

define(['jquery', 'mage/utils/wrapper'], function ($, wrapper) {
    'use strict';

    return function (defaultShippingSaveProcessor) {
        defaultShippingSaveProcessor.saveShippingInformation = wrapper.wrapSuper(
            function () {
                console.log('here, I can do want I want.');
                return this._super();
        return defaultShippingSaveProcessor;

Step 2: Apply the Mixin to the Target Module:

To apply the mixin to the target module, create a requirejs-config.js file in your module's view/frontend directory.

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/model/shipping-save-processor/default': {
                'Addeos_MyModule/js/checkout/model/shipping-save-processor/default-mixin': true,


Adding a mixin to an existing JavaScript module in Magento 2 is a powerful way to customize functionality without modifying core code. Drawing parallels to PHP plugins, mixins offer a clean and modular approach to extending JavaScript modules, ensuring maintainability and ease of future upgrades. Incorporate this technique into your Magento 2 development toolkit to create flexible and scalable solutions.


Magento 2 Security Best Practices

Safeguarding Your E-Commerce Store


In the ever-evolving landscape of e-commerce, ensuring the security of your Magento 2 store is paramount. This article will guide you through essential security best practices, helping you protect your online business and instill confidence in your customers.

1. Keep Magento 2 Updated

Regularly updating your Magento 2 installation is the first line of defense against potential vulnerabilities. Magento frequently releases security patches and updates to address known issues. Make it a practice to stay current with the latest versions.

Check the published versions of Adobe Commerce here. It contains the release dates of each minor, patch, and security release, as well as the end of support dates.

Take a look at the lifecycle policy here.

2. Secure Admin Access

  • Unique Admin URL: Change the default admin URL to reduce the risk of brute-force attacks.
  • Strong Passwords: Enforce strong password policies for admin accounts, including a combination of letters, numbers, and special characters.

3. SSL Implementation

Ensure that your Magento 2 store uses Secure Socket Layer (SSL) to encrypt data transmission. This is crucial for securing sensitive information such as customer details and payment transactions.

4. Regular Security Audits

Performing regular security audits is essential to identify vulnerabilities and address them promptly. Consider employing third-party security tools or services to conduct thorough assessments.

5. File Permissions and Ownership

Set appropriate file permissions and ownership for your Magento 2 installation. Limit access to critical files and directories, reducing the likelihood of unauthorized access or modification.

6. Web Application Firewall (WAF)

Implement a Web Application Firewall to protect your store from common web threats. A WAF can filter and monitor HTTP traffic between a web application and the Internet, providing an additional layer of security.

7. Two-Factor Authentication (2FA)

Enforce Two-Factor Authentication for admin accounts to add an extra layer of security. This ensures that even if login credentials are compromised, an additional verification step is required.

8. Regular Backups

Frequently back up your Magento 2 store, including databases and media files. In the event of a security breach or data loss, having recent backups can significantly reduce downtime and data loss.

9. Extension Security

Carefully vet and only install reputable extensions from trusted sources. Regularly update installed extensions to benefit from security patches and improvements.

10. Educate Your Team

Security is a collective effort. Educate your team members on security best practices, including recognizing phishing attempts, safeguarding login credentials, and reporting suspicious activities promptly.


By implementing these Magento 2 security best practices, you fortify your e-commerce store against potential threats and build a foundation of trust with your customers. Stay vigilant, stay secure, and keep your online business thriving in a secure digital environment.


Exciting News: My First Magento Extension is Now Live on the Marketplace!

I am thrilled to share some exciting news with you! Today marks a significant milestone for me as I proudly announce the deployment of my very first extension on the Adobe Magento Marketplace.

This extension empowers you to anonymize your database with a new CLI command, ensuring that sensitive customer privacy details are obfuscated for enhanced security and GDPR compliance.

I wrote an article in the past. Here it is : https://www.addeos.com/magento-2-database-anonymization-module

The module is still available on packagist here : https://packagist.org/packages/addeos/anonymize

And you can find it on the Adobe Magento Marketplace here: https://commercemarketplace.adobe.com/addeos-anonymize.html


Magento 2 – Adding Custom Configuration – Quick Tutorial

Welcome to our comprehensive Magento 2 custom configurations guide.

In this tutorial, we'll walk you through the essential steps to seamlessly integrate and manage personalized settings for your e-commerce store. Unlock the full potential of your Magento 2 experience with our expert insights and easy-to-follow instructions.

Follow these steps to integrate your custom configuration effortlessly:

Step 1: Create your custom module

Develop a custom module if you haven't already. This typically involves setting up the necessary files and directories. Check this post for creating your first module : https://www.addeos.com/magento-2-creating-a-magento-module-a-beginners-guide

Step 2: Create system.xml file

Inside your module's etc folder, create a system.xml file. This file will define your custom configuration fields.

Step 3: Define configuration fields

Within system.xml, define your custom configuration fields using XML tags like <section>, <group>, and <field>. Specify field types, labels, and other attributes.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
        <section id="custom_section" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Custom Section</label>
            <group id="custom_group" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Custom Group</label>
                <field id="custom_field" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Custom Field</label>
                    <comment>Some description for your custom field.</comment>

Step 4: Run setup upgrade command

After defining your configuration, run the setup upgrade command to apply changes:

php bin/magento setup:upgrade

Step 5: Access Configuration in the Admin Panel

Navigate to Stores > Configuration in the Admin Panel. Your custom configuration section and fields should be visible for modification.

Congratulations! You've successfully added custom configuration settings to Magento 2 through your custom module. Adjust these steps according to your specific requirements.


Magento 2 – Creating a Magento Module: A Beginner’s Guide

Magento's modular architecture empowers developers to customize and extend functionality. In this tutorial, we'll guide you through the essential steps to create a basic Magento module.

Here is our Magento module creation guide.

Step 1: Set Up Your Development Environment

Ensure you have a Magento instance for development. Familiarize yourself with Magento's file structure and basic module concepts.
If you need to set it up quickly check Mark Shust solution : https://github.com/markshust/docker-magento

Step 2: Create the Module Directory Structure

Navigate to the app/code directory and create the directory structure for your module. For instance, if your module is named MyModule, the path should be app/code/Vendor/MyModule.

Step 3: Define Module Configuration

Inside your module directory, create a registration.php file to register your module:

    \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_MyModule', __DIR__ 

Step 4: Create Module Configuration File

Create a module.xml file in app/code/Vendor/MyModule/etc:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_MyModule" setup_version="1.0.0"/>

Step 5: Enable the Module

Run the following command in the Magento root directory to enable your module:

php bin/magento module:enable Vendor_MyModule

Step 6: Verify Your Module

Check the enabled modules by running:

php bin/magento module:status

Your module, Vendor_MyModule, should appear in the list.

Congratulations! You've created a minimal Magento module using our Magento module creation guide. While this module doesn't include a custom controller, you can build upon this foundation to add more features and functionality as needed. Happy coding!


Magento 2 – New logging function compatible with version 2.4.3

Magento 2 debug log 

In a previous article, I explained how I add temporary debug logs with magento 2 in my code while coding. It can be very useful, it saves me time and does not require installing additional tools. You just have to remember that this solution is used temporarily and must not be committed in the code.

The complete post is here : https://www.addeos.com/magento-2-adding…n-when-debugging

Please the read the post again to understand how to add this as a live template in phpStorm which is the IDE I am using all the time.

With Magento version 2.4.3, I now use the following function which is still working.

The logging function has to be updated to :

private function log($str)
    $str = 'CLASS : ' . str_pad(__CLASS__, 50, ' ')
        . ' - LINE : ' . debug_backtrace()[0]['line']
        . ' - FUNCTION : ' . str_pad(debug_backtrace()[1]['function'], 15, ' ')
        . ' - STR : ' . $str;
    $filesystem = new \Magento\Framework\Filesystem\Driver\File();
    $handler = new \Magento\Framework\Logger\Handler\Base($filesystem, 'var/log/', 'custom_logs.log');
    $loggerHandlers = ['debug' => $handler];
    $logger = new \Monolog\Logger('customlogger', $loggerHandlers);


Magento 2 – Development environment

I just made available on github a project that allows you to install a local development environment with a working version of magento within it.

Here is the url of its repo : https://github.com/berliozd/magento-env


After cloning the project, you will have to execute two commands.

The first one should be executed from your local machine and will allow you to build the necessary docker containers which are described in the docker-compose.yml file.

6 docker containers will be needed:

  • php
  • nginx
  • mysql
  • redis
  • rabbitmq
  • elasticsearch

The second command must be executed from the php container.
It will create the magento project using composer. The latest version of magento (aka Adobe commerce) will be installed. At this time the latest version is 2.4.
As the magento source code is downloaded from the repository https://repo.magento.com/, you will be asked for access keys. To obtain these keys, you must have a magento developper account and access the magento marketplace at this page https://marketplace.magento.com/customer/accessKeys/.
Once the magento project is created, the script will continue with the magento installation itself.

Once this is finished, you will be able to access your new magento instance.

Step by step guide

  • clone the git projet
    git clone git@github.com:berliozd/magento-env.git .
  • run pre.sh from your local machine et the root of the git project
  • run bash inside the PHP container
    docker-compose -f docker-compose.mac.yml run php bash
  • run init.sh from the PHP container

That's all.

You can now use that development environment to test some tutorial I wrote : https://www.addeos.com/magento-2-tutorial-adding-a-new-model-part-1-creating-the-db-table


It is with this solution that I am currently working on my Magento projects.
It allows me to quickly install a new instance of Magento.
I would be interested to know what solutions are used by magento developers around the world. Feel free to share in the comments how you work and how you configure your work environment.


Magento 2 – Tutorial : new model – Part 2 – creating the PHP classes


This article is the 2nd part of a series in which I go through the procedure to create a new model in magento 2, with its own magento 2 admin grid in the Back Office.

You can go back to the first part if you wish.

As a preamble, I have to say that this tutorial series has been developed and tested with Magento version 2.4.2.

I remind you that for the purpose of the article I am going to create a "provider" model and that our code will be contained in an "Addeos_ModelTutorial" module.

In the first part I have explained how to create the DB table using declarative XML. In this second part, I will create the PHP classes :

  • the API data interface
  • the model that implements the interface
  • the resource model
  • the collection resource model

Creating the API data interface

If we want to respect the concept of service contracts which is a good thing and recommanded by Magento, I need to create some PHP interfaces first. Here is some more details about service contracts.

By convention, these PHP interfaces have to be in an Api folder and a Data folder for data interfaces.

The first interface to create is the ProviderInterface : Api/Data/ProviderInterface.php.

Here is the code :



namespace Addeos\ModelTutorial\Api\Data;

 * @api
interface ProviderInterface
    const ENTITY_ID = 'entity_id';
    const CREATED_AT = 'created_at';
    const UPDATED_AT = 'updated_at';
    const NAME = 'name';
    const DESCRIPTION = 'description';

    public function getEntityId(): ?int;

    public function setEntityId(int $entityId);

    public function getName(): ?string;

    public function setName(string $name);

    public function getDescription(): ?string;

    public function setDescription(string $description);

    public function getCreatedAt(): ?string;

    public function setCreatedAt(string $createdAt);

    public function getUpdatedAt(): ?string;

    public function setUpdatedAt(string $updatedAt);


Creating the PHP model

I then need to create the PHP model that will implement the interface we have just created. This PHP class will extend \Magento\Framework\Model\AbstractModel.

Here is the code :


namespace Addeos\ModelTutorial\Model;

use Addeos\ModelTutorial\Api\Data\ProviderInterface;
use Magento\Framework\Model\AbstractModel;

class Provider extends AbstractModel implements ProviderInterface

    public function getName(): ?string
        return $this->getData(self::NAME);

    public function setName(string $name)
        $this->setData(self::NAME, $name);

    public function getDescription(): ?string
        return $this->getData(self::DESCRIPTION);

    public function setDescription(string $description)
        $this->setData(self::DESCRIPTION, $description);

    public function getCreatedAt(): ?string
        return $this->getData(self::CREATED_AT);

    public function setCreatedAt(string $createdAt)
        $this->setData(self::CREATED_AT, $createdAt);

    public function getUpdatedAt(): ?string
        return $this->getData(self::CREATED_AT);

    public function setUpdatedAt(string $updatedAt)
        $this->setData(self::UPDATED_AT, $updatedAt);

Creating the resource model

I now need to create resource model.

The file is Model/ResourceModel/Provider.php.

Here is the code :


namespace Addeos\ModelTutorial\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class Provider extends AbstractDb
    protected function _construct()
        $this->_init('addeos_provider', 'entity_id');

Creating the collection resource model

I now need to create the provider collection resource model.

The file is ModelResourceModel/Provider/Collection.php.

Her is the code :


namespace Addeos\ModelTutorial\Model\ResourceModel\Provider;

use Addeos\ModelTutorial\Model\Provider;
use Addeos\ModelTutorial\Model\ResourceModel\Provider as ProviderResourceModel;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
    protected $_idFieldName = 'entity_id';
    protected $_eventPrefix = 'addeos_provider_collection';
    protected $_eventObject = 'addeos_provider_collection';

    protected function _construct()
        $this->_init(Provider::class, ProviderResourceModel::class);

And that's all. From that point we have all the necessary classes for now.

In next post, I will explain now how to create the grid in Back Office to visualize the data of our new table.