:::: MENU ::::

Magento Tutorial | Magento Blog | Learn Magento 2

Cookies Consent Popup

Cron jobs are essential in Magento 2 for automating repetitive tasks such as reindexing, sending emails, generating reports, and cleaning logs. Sometimes, you may need to create a custom cron job for your own module to perform scheduled operations. In this guide, we’ll walk through the steps to set up a custom cron in Magento 2.

Step 1: Create cron.xml

Inside your custom module, create a etc/cron.xml file. This file defines the cron job and its schedule.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/cron.xsd">

    <group id="default">
        <job name="vendor_module_custom_cron"
             instance="Vendor\Module\Cron\Custom"
             method="execute">
            <schedule>*/5 * * * *</schedule>
        </job>
    </group>

</config>

Here, the cron job runs every 5 minutes (*/5 * * * *).

Step 2: Create Cron Class

Next, create the PHP class that will be executed by the cron job.

<?php
namespace Vendor\Module\Cron;

class Custom
{
    public function execute()
    {
        // Your custom logic here
        // Example: log a message
        file_put_contents(BP . '/var/log/custom_cron.log', "Cron executed at " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
    }
}

This class contains the execute() method, which Magento calls when the cron job runs.

Step 3: Enable and Test Cron

Ensure Magento’s cron is properly set up on your server. Run:

bin/magento cron:run

Check var/log/custom_cron.log to confirm your cron job executed successfully.

Step 4: Configure System Cron

Magento relies on the server’s cron daemon. Add the following to your server’s crontab:

* * * * * php /path/to/magento/bin/magento cron:run | grep -v "Ran jobs by schedule" >> /path/to/magento/var/log/magento.cron.log
* * * * * php /path/to/magento/update/cron.php >> /path/to/magento/var/log/update.cron.log
* * * * * php /path/to/magento/bin/magento setup:cron:run >> /path/to/magento/var/log/setup.cron.log

This ensures Magento’s cron system runs continuously.

Advanced Usage

  • Groups → You can define jobs under different groups (e.g., index, default).
  • Schedules → Use cron expressions to control frequency (e.g., 0 0 * * * for midnight daily).
  • Dependency Injection → Inject services into your cron class for database operations, API calls, etc.

Troubleshooting

  • Check var/log/magento.cron.log for errors.
  • Ensure your server’s cron daemon is running (service cron status).
  • Verify file permissions for var/log and bin/magento.
  • Run bin/magento setup:upgrade after adding new cron jobs.

Best Practices

  • Keep cron jobs lightweight; avoid long‑running tasks.
  • Use queues or background processes for heavy operations.
  • Log outputs for debugging and monitoring.
  • Test cron jobs in development before deploying to production.

Conclusion

Setting up a custom cron job in Magento 2 allows you to automate repetitive tasks and extend your module’s functionality. By defining cron.xml, creating a cron class, and configuring the system cron, you can ensure your jobs run reliably. Following best practices will keep your store efficient and maintainable.

Happy Coding & Automating!

Magento 2 is built on a powerful event-driven architecture. This means you can hook into specific events and perform custom actions before or after certain operations. One common requirement is to run logic before inserting data into the database, such as modifying product attributes, validating customer data, or logging changes.

Understanding Events in Magento 2

Magento dispatches events at key points in its workflow. Developers can listen to these events using observers. For example:

  • catalog_product_save_before → Triggered before a product is saved.
  • customer_save_before → Triggered before a customer record is saved.
  • sales_order_place_before → Triggered before an order is placed.

By listening to these events, you can run custom logic before Magento inserts or updates records.

Step 1: Define events.xml

Inside your module, create etc/events.xml to register the observer:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">

    <event name="catalog_product_save_before">
        <observer name="vendor_module_product_before_save"
                  instance="Vendor\Module\Observer\ProductBeforeSave" />
    </event>

</config>

This tells Magento to call your observer before a product is saved.

Step 2: Create the Observer Class

Now create the observer class in Vendor/Module/Observer/ProductBeforeSave.php:

<?php
namespace Vendor\Module\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class ProductBeforeSave implements ObserverInterface
{
    public function execute(Observer $observer)
    {
        $product = $observer->getEvent()->getProduct();

        // Example: Add prefix to product name before saving
        $name = $product->getName();
        $product->setName('[Custom] ' . $name);

        // Example: Log action
        file_put_contents(BP . '/var/log/product_before_save.log',
            "Product " . $product->getSku() . " modified before save at " . date('Y-m-d H:i:s') . "\n",
            FILE_APPEND
        );
    }
}

This observer modifies the product name and logs the action before Magento inserts/updates the product record.

Other Useful Events

  • customer_save_before → Validate or modify customer data before insert.
  • sales_order_place_before → Add custom logic before order placement.
  • checkout_cart_product_add_after → Run logic after a product is added to cart.

Best Practices

  • Keep observer logic lightweight; avoid heavy operations that slow down saves.
  • Use dependency injection for services instead of direct file_put_contents.
  • Log actions for debugging, but disable verbose logging in production.
  • Test observers in development before deploying to production.

Conclusion

Magento 2’s event/observer system makes it easy to perform actions before inserting or saving data. By registering events in events.xml and writing observer classes, you can customize Magento’s behavior in a clean, upgrade‑safe way. This approach is ideal for adding validations, modifying attributes, or logging changes before data is persisted.

Happy Coding & Customizing!

When working with Magento 2, many developers encounter a common issue: database backups missing tables. This usually happens when running Magento’s built‑in backup commands or when exporting the database manually. Missing tables can lead to broken restores, incomplete migrations, or errors during upgrades.

Understanding the Issue

Magento’s database is large and complex, with hundreds of tables and views. One of the most common problems after restoring a backup is the inventory_stock_1 view being missing. This view is part of Magento’s Multi‑Source Inventory (MSI) system and is required for product salability checks.

Step 1: Verify Missing View

Run the following command to check if inventory_stock_1 exists:

mysql -u username -p -e "SHOW FULL TABLES WHERE Table_type = 'VIEW';" magento_db

If inventory_stock_1 is missing, you’ll need to recreate it.

Step 2: Recreate inventory_stock_1 View

Use the following SQL query to recreate the missing view:

CREATE OR REPLACE VIEW `inventory_stock_1` AS
SELECT DISTINCT
    `legacy_stock_status`.`product_id` AS `product_id`,
    `legacy_stock_status`.`website_id` AS `website_id`,
    `legacy_stock_status`.`stock_id` AS `stock_id`,
    `legacy_stock_status`.`qty` AS `quantity`,
    `legacy_stock_status`.`stock_status` AS `is_salable`,
    `product`.`sku` AS `sku`
FROM
    `cataloginventory_stock_status` AS `legacy_stock_status`
JOIN
    `catalog_product_entity` AS `product`
ON
    `legacy_stock_status`.`product_id` = `product`.`entity_id`;

This query rebuilds the inventory_stock_1 view by joining cataloginventory_stock_status with catalog_product_entity, ensuring Magento can correctly calculate product salability.

Step 3: Flush Cache and Reindex

After recreating the view, run the following commands:

bin/magento cache:flush
bin/magento indexer:reindex

This ensures Magento recognizes the restored view and updates product stock data.

Troubleshooting Tips

  • Check var/log/system.log for errors after restoring backups.
  • Ensure your MySQL user has privileges to create views (CREATE VIEW).
  • If multiple inventory views are missing (inventory_stock_2, etc.), recreate them using similar queries.

Best Practices

  • Always use mysqldump with --routines --triggers to include views in backups.
  • Test restores regularly to confirm views are included.
  • Document custom fixes like this for your team.

Conclusion

The “database backup missing table/view” issue in Magento 2 is common, especially with MSI views like inventory_stock_1. By recreating the view with the correct SQL query and reindexing, you can restore functionality quickly. Following best practices for backups will help prevent this issue in the future.

Happy Coding & Safe Backups!