1

I'm trying to set some defaults for newly created products. That is, when a new product is created, I want to set some settings to specific default values, but users should be allowed to change those.

use craft\commerce\elements\Product;
use craft\events\ModelEvent;
use yii\base\Event;

Event::on(
    Product::class,
    Product::EVENT_BEFORE_SAVE,
    function (ModelEvent $e) {
        if (!$e->isNew) {
            return;
        }
        $e->sender->freeShipping = true;
        $e->sender->defaultVariant->hasUnlimitedStock = true;
    },
);

This is working, but the default values are only set when the product is first saved. This means that the user presses + New Product from the product index list, then sees the full product edit form without my defaults. Only after the users clicks Save is the hook triggered, and my default values are set. So if the user has already changed those options, they are overwritten.

I think the problem is that Commerce products don't have full draft support. For entries, the default values are set before the user sees the edit form for the first time, because pressing + New entry creates an unpublished draft in the database immediately, triggering the EVENT_BEFORE_SAVE hook. But products don't do this, they present an empty edit form with nothing saved in the database before the first save, so the hook isn't triggered.

This also presents another problem: If there are validation errors, the hook triggers multiple times, because the product is always new ($e->isNew) until it is saved successfully. So the default values will be set multiple times, overwriting the values set by the editor, until the product is saved successfully at least once.

Is there another hook I could use, or another way to solve this?

  • Craft 4.4.7.1
  • Craft Commerce 4.2.7
5
  • Let me know if you find a good solution for this, I need this functionality too! May be a good feature request - these two parameters should really be configurable imo. Apr 20 at 16:41
  • @JamesSmith Until someone can suggest a better way, I'll go with the imperfect solution mentioned above. A feature request will probably not be necessary – I've read somewhere on GitHub that full draft support for products is planned for Commerce 5. At this point this should resolve itself, since the hook will trigger immediately once new products are created as unpublished drafts immediately (same as entries).
    – MoritzLost
    Apr 20 at 16:45
  • Hmm, I still think we shouldn't need a plugin/module to achieve this. There's currently no way to opt-out of Commerce's inventory management other than to mark each product as "unlimited stock" every time you create one. It could be a simple tickbox in the same spot where you can turn off dimensions & weight fields. Apr 20 at 17:24
  • @JamesSmith Yeah, having more configuration options for the built-in fields would be great!
    – MoritzLost
    Apr 21 at 7:21
  • @JamesSmith I've added a a feature request discussion here: github.com/craftcms/commerce/discussions/3165
    – MoritzLost
    May 4 at 15:30

1 Answer 1

2

You're currently attaching this to the EVENT_BEFORE_SAVE which is working, in order for your values to appear in the form when the new product form is opened you'll need to create a custom module that injects the values into product form.

"Hmm, I still think we shouldn't need a plugin/module to achieve this."

I would recommend filing a feature request with Craft Commerce here: https://github.com/craftcms/commerce

Currently, this is not out-of-box functionality and does require custom coding via module/plugin.

I haven't attempted to do what you're trying, but I think you'll need to look into the other events available. Maybe try using the Event Code generator located at: https://craftcms.com/docs/commerce/4.x/extend/events.html#event-code-generator to explore some options.

It's not an answer, I know, but hopefully helps!

2
  • Thanks! I don't think there's any event that we can hook into that's earlier … the first time the edit form is displayed, no product exists yet, the form is just initialized with a totally empty product. I don't think this triggers an event at all – correct me if I'm wrong. Since those fields are in the sidebar and not part of the field layout, the field layout hooks won't work. I think the only way to solve this programmatically at the moment would be to insert some JS to the product form that sets the default values in the frontend, which … oof.
    – MoritzLost
    May 4 at 15:32
  • I've opened a feature request discussion here: github.com/craftcms/commerce/discussions/3165
    – MoritzLost
    May 4 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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