0

I want Magento (2.4) to set newly created products as new for specified period of time but only when product is created and not saved after being edited... So, I would need something very similar to what's answered in Magento 2 Set Product as New when new product is created but for different method: something like beforeCreate which doesn't seem to exist...?

2 Answers 2

1

This answer is very similar to previous one, but use another one observer. In Magento for create and update operations uses the single action save. If you want to check if is it new product on before_save, you can check if a product has id or not.

Better to use event in correct area

app/code/Acme/StackExchange/etc/adminhtml/events.xml

<?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="acme_stackexchange_observer_catalog_product_save_before"
                  instance="Acme\StackExchange\Observer\Catalog\ProductSaveBefore" />
    </event>
</config>

app/code/Acme/StackExchange/Observer/Catalog/ProductSaveBefore.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Observer\Catalog;

use Magento\Catalog\Model\Product;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class ProductSaveBefore implements ObserverInterface
{
    /**
     * @inheritDoc
     */
    public function execute(Observer $observer)
    {
        /** @var Product $product */
        $product = $observer->getEvent()->getData('product');

        if (!$product->getId()) {
            $newFromDate = date("m/d/Y");
            $newToDate   = date('m/d/Y', strtotime("+30 day"));

            $product->setNewsFromDate($newFromDate);
            $product->setNewsToDate($newToDate);
        }
    }
}

You don't need to double save product when you are using before_save logic

[Update]

Alternative way with to do the same but with plugin

As I've pointed in comment, ideally to have properly configured dependencies

app/code/Acme/StackExchange/etc/module.xml

<?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="Acme_StackExchange">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

app/code/Acme/StackExchange/etc/adminhtml/di.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\ResourceModel\Product">
        <plugin name="Acme_StackExchange_Plugin_Catalog_Model_ResourceModel_ProductPlugin"
                type="Acme\StackExchange\Plugin\Catalog\Model\ResourceModel\ProductPlugin" sortOrder="10"/>
    </type>
</config>

Acme/StackExchange/Plugin/Catalog/Model/ResourceModel/ProductPlugin.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Plugin\Catalog\Model\ResourceModel;

use Magento\Catalog\Model\ResourceModel\Product;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Psr\Log\LoggerInterface;

class ProductPlugin
{
    protected DateTime        $coreDate;
    protected LoggerInterface $logger;

    public function __construct(
        DateTime $coreDate,
        LoggerInterface $logger
    ) {
        $this->coreDate = $coreDate;
        $this->logger   = $logger;
    }

    public function beforeSave(Product $subject, AbstractModel $object): array
    {
        $this->logger->info('Before save product logic');
        if (!$object->getId()) {
            $this->logger->info('Set dates to new product');

            $dateFrom      = new \DateTime(date('Y-m-d H:i:s', $this->coreDate->timestamp()));
            $dateTo        = clone $dateFrom;
            // add one month to current date
            $dateTo->add(new \DateInterval('P1M'));
            // optional remove one date from current date
            $dateFrom->sub(new \DateInterval('P1D'));

            $object->setNewsFromDate($dateFrom->format('Y-m-d H:i:s'));
            $object->setNewsToDate($dateTo->format('Y-m-d H:i:s'));

            $this->logger->info('setNewsFromDate = ' . $dateFrom->format('Y-m-d H:i:s'));
            $this->logger->info('setNewsToDate = ' . $dateTo->format('Y-m-d H:i:s'));
        }

        return [$object];
    }
}

In this plugin you can see example how to work with log and more correct way of date manipulations

system.log

[2022-06-21T16:46:56.666743+00:00] report.INFO: Before save product logic [] []
[2022-06-21T16:46:56.667859+00:00] report.INFO: Set dates to new product [] []
[2022-06-21T16:46:56.668130+00:00] report.INFO: setNewsFromDate = 2022-06-20 16:46:56 [] []
[2022-06-21T16:46:56.668260+00:00] report.INFO: setNewsToDate = 2022-07-21 16:46:56 [] []

Any solution or code provided by myself are were tested before publish on one of latest Magento version

To be sure you've cleared cache and for new extension register it and run bin/magento setup:upgrade command.

For development purposes make sense to set your environment in developer mode with bin/magento deploy:mode:set developer command

I'm also suggest to check what data is saved in DB and verify any places with custom logic for those fields in other events/plugins

5
  • Thanks. But I've been trying a few times and still can't get it working at all - no dates are set (in contrary to quoted plugin which changes dates after every save of product). I have changed namespace and so on to reflect my naming convention so, I can't find anything else to correct... What else I would need to check? Jun 21 at 16:07
  • Ideally it's a sequence to Magento_Catalog in etc/modules.xml but it's not required. I don't have any concrete idea what's wrong, please double check all file names, namespaces and class names and to be sure they are corresponding to their locations. To be sure you don't have few observers with the same name to the same event. I will update answer with plugin alternative, but anyway, observer should work. Try to add logging in observer to be sure your observer is properly configured and logic called on save Jun 21 at 16:26
  • See updated comment Jun 21 at 16:53
  • Hi @victor-tihonchuk, thanks again and finally it works! I had a small issue caused by copying code of di.xml as config declaration (xlmns) in this file was broken into 2 lines. BTW, why di.xml needs to be placed in adminhtml subfolder instead of directly in etc folder? yesterday
  • adminhtml/di.xml - adminhtml scope only, frontend/di.xml - frontend scope only, di.xml - global scope. In Magento also present other scopes like api, crontab, etc yesterday
0

In this case, you can use the event like:

app/code/Vendor/Module/etc/events.xml:

<event name="catalog_product_save_after">
    <observer name="my_custom_product_save_observer" instance="Vendor\module\Observer\Productsaveafter" />
</event>  

And at this observer,you can get identify by below code

app/code/Vendor/Module/Observer/Productsaveafter.php

<?php
    
        namespace Vendor\Module\Observer;
    
        use Magento\Framework\Event\ObserverInterface;
    
        class Productsaveafter implements ObserverInterface
        {
           public function execute(\Magento\Framework\Event\Observer $observer)
            {
                 /** @var Product $product */
                $product = $observer->getEvent()->getProduct();
                if($product->isObjectNew() )
                {//new product
                     $new_from_date = date("m/d/Y"); 
                     $new_to_date = date('m/d/Y',strtotime("+30 day"));
    
                     $product->setNewsFromDate($new_from_date); 
                     $product->setNewsToDate($new_to_date); 
                     $product->save();
                }
            }
    }
    ?>
4
  • Thanks, but where shall I apply it? After amending content of Vendor\Module\Plugin\SetNew.php it doesn't work at all... Jun 14 at 14:59
  • its observer not plugin. check updated answer. Jun 14 at 17:04
  • I've changed it too but it doesn't work (set as new date isn't set at all) and also doesn't throw any errors... Jun 15 at 15:31
  • Check updated answer ...added product save code Jun 15 at 20:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.