0

Aware that there is a lot of information around the net regarding this, I am still having a lot of trouble getting this to work.

I have created a custom service:

<?php

namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;
use App\Entity\AccommodationType;
use App\Entity\Night;

class AvailabilityChecks {

    private $em;

     public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function nightAvailable(string $RoomCode, string $NightDate) {


        $GetRoom = $this->em->getDoctrine()->getRepository(AccommodationType::class)->findOneBy([
                'RoomCode' => $RoomCode
            ]);

        $RoomQnt = $GetRoom->getNightlyQnt();

        $GetNight = $this->em->getDoctrine()->getRepository(Night::class)->findOneBy([
                'RoomCode' => $RoomCode,
                'NightDate' => $NightDate
            ]);

        $NumberOfNights = $GetNight->count();

        if($NumberOfNights<$RoomQnt) {
            return true;
        }
        else {
            return false;
        }

    }


}

and have put this in services.yaml:

AvailabilityChecks.service:
  class: App\Service\AvailabilityChecks
  arguments: ['@doctrine.orm.entity_manager']

So when I try and use this in my controller, I get this error:

Too few arguments to function App\Service\AvailabilityChecks::__construct(), 0 passed in /mypath/src/Controller/BookController.php on line 40 and exactly 1 expected

I just can't figure out why it's not injecting the ORM stuff into the constructor! Any help greatly appreciated

Jordan S
  • 31
  • 8
  • 1
    Can you post the code using the service (eg. BookController)? It looks like you're trying to instantiate it yourself? – ccKep Feb 24 '19 at 22:49
  • Also: `$this->em->getDoctrine()->getRepository(...)` is not going to work, the EntityManager doesn't have a method called `getDoctrine`. It should probably be `$this->em->getRepository(...)` – ccKep Feb 24 '19 at 22:51
  • try to inject DoctrineManager instead interface – AythaNzt Feb 25 '19 at 00:13

4 Answers4

3

The problem is in your BookController. Even though you didn't posted its code I can assume you create new AvailabilityChecks in it (on line 40).

In Symfony every service is intantiated by service container. You should never intantiate service objects by yourself. Instead BookController must ask service container for AvailabilityChecks service. How should it do it ?

In Symfony <3.3 we used generally :

use Symfony\Bundle\FrameworkBundle\Controller\Controller;


class MyController extends Controller 
{
    public function myAction() 
    {
        $em = $this->get('doctrine.orm.entity_manager');
        // ...
    }
}

Nowadays services can be injected in controllers using autowiring which is way easier:

use Doctrine\ORM\EntityManagerInterface;

class MyController extends Controller 
{
    public function myAction(EntityManagerInterface $em) 
    {
        // ...
    }
}
VladRia
  • 1,475
  • 3
  • 20
  • 32
0

You are using the wrong service for what you want to do. The alias doctrine that is used, e.g. in the AbstractController when you call getDoctrine() is bound to the service Doctrine\Common\Persistence\ManagerRegistry.

So the code you wrote fits better with that and you should either add @doctrine or @Doctrine\Common\Persistence\ManagerRegistry to the service definition.

Both with your current configuration or the changed one, you don't have to call $this->em->getDoctrine(), because $this->em is already equivalent to $this->getDoctrine() from your controller. Instead you could create a (private) method to make it look more like that code, e.g.:

private function getDoctrine()
{
    return $this->em;
}

Then you can call $this->getDoctrine()->getRepository(...) or use $this->em->getRepository(...) directly.

dbrumann
  • 16,803
  • 2
  • 42
  • 58
0

In SF4, you no longer need to specify dependencies required by your custom service in the service.yaml file. All you have to do is to use dependency injection.

So remove config lines, and call your service directly in the controller method :

<?php

namespace App\Controller;

use App\Service\AvailabilityChecks ;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class AppController extends AbstractController
{
    public function index(AvailabilityChecks $service)
    {
        ...
    }
}

Having said that, i think you don't need custom service to do simple operations on database. Use repository instead.

Adrien Rosi
  • 132
  • 5
0

In Symfony 4, you dont need to create it as services. This is automatically now. Just inject the dependencies what you need in the constructor. Be sure that you have autowire property with true value in services.yml (it is by default)

Remove this from services.yml:

AvailabilityChecks.service:
  class: App\Service\AvailabilityChecks
  arguments: ['@doctrine.orm.entity_manager']

You dont need EntityManagerInterface because you are not persisting anything, so inject repositories only.

<?php

namespace App\Service;

use App\Entity\AccommodationType;
use App\Entity\Night;
use App\Repository\AccommodationTypeRepository;
use App\Repository\NightRepository;

class AvailabilityChecks {

    private $accommodationTypeRepository;
    private $nightRepository

     public function __construct(
          AcommodationTypeRepository  $acommodationTypeRepository,
          NightRepository $nightRepository
    )
    {
        $this->acommodationTypeRepository = $acommodationTypeRepository;
        $this->nightRepository = $nightRepository;
    }

    public function nightAvailable(string $RoomCode, string $NightDate) {


        $GetRoom = $this->acommodationTypeRepository->findOneBy([
                'RoomCode' => $RoomCode
            ]);

        $RoomQnt = $GetRoom->getNightlyQnt();

        $GetNight = $this->nightRepository->findOneBy([
                'RoomCode' => $RoomCode,
                'NightDate' => $NightDate
            ]);

        $NumberOfNights = $GetNight->count();

        if($NumberOfNights<$RoomQnt) {
            return true;
        }
        else {
            return false;
        }

    }
}
AythaNzt
  • 1,057
  • 6
  • 14