如何在 Symfony 命令中注入带有邮件程序和日期时间的服务?

How to inject a service with mailer and datetime in a Symfony Command?

我想在库存对象有效期结束前 4 周向所有用户发送电子邮件。我的问题是我不知道如何在 ValidityReminderCommand class.

中 运行 我的服务

这是我的 ValidityReminderCommand:

namespace App\Command;


use App\Entity\Inventory;
use App\Repository\InventoryRepository;
use App\Service\ValidityEndHandler;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ValidityReminderCommand extends Command
{

    protected static $defaultName = 'app:validity-reminder';

    private $validityEndHandler;


    public function __construct(ValidityEndHandler $validityEndHandler)
    {
        $this->validityEndHandler = $validityEndHandler;




        parent::__construct();
    }


    protected function configure()
    {
        $this->setDescription('Sendet 4 Wochen vor Gültigkeitsende eine Mail an alle Admins');

    }


    protected function execute(InputInterface $input, OutputInterface $output, Inventory $inventory, \Swift_Mailer $mailer, InventoryRepository $repository)
    {
        $this->validityEndHandler->sendReminderMail($inventory, $mailer, $repository);


        $output->writeln('Emails werden gesendet');

    }
}

这是我的 ValidityEndHandler 即服务:

namespace App\Service;


use App\Entity\Inventory;
use App\Entity\User;
use App\Repository\InventoryRepository;


class ValidityEndHandler
{
    public function sendReminderMail (Inventory $inventory, \Swift_Mailer $mailer, InventoryRepository $repository)
    {

        $itemsToRemind = $repository
            ->createQueryBuilder('i')
            ->where('i.validityEnd - 2419200 <= :now')
            ->setParameter('now', new \DateTime('now'))
            ->where('i.remindedAt is null')->getQuery()->execute();

        foreach ($itemsToRemind as $itemToRemind) {

            $endDate = $itemToRemind->$inventory->getValidityEnd();
            $fourweeks = 2419200;

            $endDateTimestamp = strtotime($endDate);

            $difference = $endDateTimestamp - $fourweeks;
            $now = time();


            $title = $inventory->getTitle();
            $admins = $repository
                ->createQueryBuilder('q')
                ->where('q.roles like :adminrole')
                ->setParameter('adminrole', '%ROLE_ADMIN%')
                ->getQuery()
                ->execute();

            if ($difference == $now) {
                /** @var User $admin */
                foreach ($admins as $admin) {

                    $message = (new \Swift_Message('Eine Lizenz läuft in 4 Wochen ab.'))
                        ->setFrom('noreply@validityEndLBX.com')
                        ->setTo($admin->getEmail())
                        ->setBody(
                            "Das Inventarobjekt . $title . läuft in 4 Wochen ab",
                            'text/html'
                        );
                    $mailer->send($message);
                }
            }

        }

    }

}

这是我在控制台中尝试时收到的一些错误消息:

Warning: Declaration of App\Command\ValidityReminderCommand::execute(Symfony\Component\Console\Input\InputInterface $input, Symfony  
  \Component\Console\Output\OutputInterface $output, App\Entity\Inventory $inventory, Swift_Mailer $mailer, App\Repository\InventoryR  
  epository $repository) should be compatible with Symfony\Component\Console\Command\Command::execute(Symfony\Component\Console\Input  
  \InputInterface $input, Symfony\Component\Console\Output\OutputInterface $output)

问题是您在 ValidityReminderCommand 中对 execute 方法的声明与 Command 的声明不兼容。

除了前两个参数,你不应该传递任何东西:InputInterface $input, OutputInterface $output

像传递 ValidityHandler 参数一样通过构造函数传递其他参数

    public function __construct(ValidityEndHandler $validityEndHandler, InventoryRepository $repository)
    {
        $this->validityEndHandler = $validityEndHandler;            
        $this->repository = $repository;
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $inventory = $this->repository->yourRequest();
        // pass the mailer service you need directly to ValidityHandler and send only $inventory as a parameter
        $this->validityEndHandler->sendReminderMail($inventory);      
        $output->writeln('Emails werden gesendet');

    }