Implementing services

97 views Asked by At

I'm quite new to Laminas API tools, i'd like to understand how inject properly a service into my rest service.

Example:

namespace account\V1\Rest\Users;

use Laminas\ApiTools\DbConnectedResource;

class UsersResource extends DbConnectedResource {
    /**
     * Create a resource
     *
     * @param  mixed $data
     * @return ApiProblem|mixed
     */
    public function create($data) {
        $dataFiltered = $this->retrieveData($data);
        $this->table->createUser($dataFiltered);
        $id = $this->table->getLastInsertValue();
        $user = $this->fetch($id);
        // send email to user
        return $user;
    }

I need to implement something in // send email to user to call the send method of the next class


namespace account\Core\Mail;

class Mail {

    protected $service;
    protected $message;
    protected $body;

    public function __construct(MailgunService $service) {
        $this->service = $service;
        $this->message = new \Laminas\Mail\Message();
        $this->body = new \Laminas\Mime\Message();
    }

    private function updateBody() {
        $this->message->setBody($this->body);
    }

    public function addPart($part, $partType) {
        $mailPart = new \Laminas\Mime\Part($part);
        $mailPart->type = $partType;

        $this->body->addPart($mailPart);

        $this->updateBody();
    }

    public function setMessage($to, $from, $subj) {
        $this->message
                ->setTo($to)
                ->setFrom($from)
                ->setSubject($subj);
    }

    public function send() {
        $this->service->send($message);
    }

}

(The Mail class has a factory like below (Also UsersResource but i dont know if its important))

namespace account\Core\Mail;

use Psr\Container\ContainerInterface;

class MailFactory
{
    public function __invoke(ContainerInterface $container)
    {
        return new Mail(
                $container->get(\SlmMail\Service\MailgunService::class)
                );
    }
}

I checked the laminas-servicemanager but dont know how to proceed, any hints?

1

There are 1 answers

0
j4g0 On

If I understand you correctly you want to inject a service into the mail class?

That would be exactly what the factory is for:

class Mail {

    protected $service;
    protected $anotherService // new service
    protected $message;
    protected $body;

    public function __construct(
        MailgunService $service,
        AnotherService $anotherService // new service
    ) {
        $this->service = $service;
        $this->anotherService = $anotherService; // new service
        $this->message = new \Laminas\Mail\Message();
        $this->body = new \Laminas\Mime\Message();
    }

// ... rest of class
}

And in your factory you inject the service like so:

class MailFactory
{
    public function __invoke(ContainerInterface $container)
    {
        return new Mail(
            $container->get(\SlmMail\Service\MailgunService::class),
            $container->get(AnotherService::class) // new Service
        );
    }
}

In order for this to work the ServiceManager needs to know about the new Service. and that the Mail class should be built using the MailFactory