Another solution without influencing Magento Core functionality (which happens when using a plugin) would be to inject a custom OrderIdentity
that will always return true for isEnabled
.
I tried out the solution on Magento OSS ver. 2.4.2-p1.
First, you extend \Magento\Sales\Model\Order\Email\Container\OrderIdentity
and just return true for isEnabled
. Alhtough, extending should be kept to a minimum, I think it is ok in this case, as we won't override the original class with a preference. We will just use it as a argument in di.xml.
app/code/Vendor/YourModule/Model/Order/Email/Container/EnabledOrderIdentity.php:
<?php
declare(strict_types=1);
namespace Vendor\YourModule\Model\Order\Email\Container;
/**
* An order identity that will ignore the configuration for sales_email/order/enabled.
*/
class EnabledOrderIdentity extends \Magento\Sales\Model\Order\Email\Container\OrderIdentity
{
/**
* Always return true and do not consider config options
*
* @return bool
*/
public function isEnabled(): bool
{
return true;
}
}
Now, as we have our custom identity that won't care when sales_email/order/enabled
is disabled, we can create a virtual type that replaces the identityContainer
argument for OrderSender
with our custom one.
This virtual type can be used as argument for places where the injected OrderSender should be able to send emails without paying attention to the sales_email/order/enabled` setting.
app/code/Vendor/YourModule/etc/di.xml:
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!-- Virtual OrderSender type that ignores order email disable setting -->
<virtualType name="Vendor\YourModule\Model\Order\Email\Sender\OrderSender"
type="Magento\Sales\Model\Order\Email\Sender\OrderSender">
<arguments>
<argument name="identityContainer" xsi:type="object">Vendor\YourModule\Model\Order\Email\Container\EnabledOrderIdentity</argument>
</arguments>
</virtualType>
<!-- Example usage -->
<type name="Class\Where\You\Want\Custom\OrderSender\Test">
<arguments>
<argument name="orderSender" xsi:type="object">Vendor\YourModule\Model\Order\Email\Sender\OrderSender</argument>
</arguments>
</type>
</config>
In the class where you want to programmatically send the email while sales_email/order/enabled
is set to disabled, must use constructor injection (instead of ObjectManager) to inject your custom OrderSender.
This can look like the following example:
<?php
declare(strict_types=1);
namespace Class\Where\You\Want\Custom\OrderSender;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order\Email\Sender\OrderSender;
class Test {
/**
* @var OrderRepositoryInterface
*/
private OrderRepositoryInterface $orderRepository;
/**
* @var OrderSender
*/
private OrderSender $orderSender;
/**
* Index constructor.
*
* @param OrderRepositoryInterface $orderRepository
* @param OrderSender $orderSender
*/
public function __construct(
OrderRepositoryInterface $orderRepository,
OrderSender $orderSender
) {
$this->orderRepository = $orderRepository;
$this->orderSender = $orderSender;
}
public function someFunction() {
$order = $this->orderRepository->get(8); // Your logic to get the order
$this->orderSender->send($order); // Order sender has custom identity that ignores settings
}
}