0

I am using a service within twig like this

{{ count_service.getCount(term.getId) }}

I want the service to use a repository function, repository function

<?php

namespace AppBundle\Repository;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping;

class SynonymRepository extends EntityRepository
{

    public function getCount($termId)
    {
        $qbSynonymType = $this->getEntityManager()->createQueryBuilder();
        $synonymTypes = $qbSynonymType->select('synonymType.id, synonymType.type')
            ->from('AppBundle:SynonymType', 'synonymType')
            ->getQuery()->getResult();

        $qb = $this->getEntityManager()->createQueryBuilder();
        $count = [];

        $qb->select('count(synonym.synonymId)')
            ->from('AppBundle:Synonym','synonym');

        foreach($synonymTypes as $type) {
            $count[$type['type']] = $qb
                ->where('synonym.term = :termId')
                ->andWhere('synonym.synonymType = :type')
                ->setParameter('termId', $termId)
                ->setParameter('type', $type['id'])
                ->getQuery()->getSingleScalarResult();
        }

        $qbTerm = $this->getEntityManager()->createQueryBuilder()->from('AppBundle:Term', 'term');


        $count['parent'] = "NaN";
        $count['children'] = "NaN";

        return $count;
    }
 }

My service.yml looks like this

synonymrepository:
    class: Doctrine\ORM\EntityRepository
    factory: ["@doctrine.orm.entity_manager", getRepository]
    arguments:
        - AppBundle\Entity\SynonymType

term_count:
    class: AppBundle\Services\TermCount
    arguments:
        - "@synonymrepository"

And finally my service looks like this

<?php

namespace AppBundle\Services;

use AppBundle\Repository\SynonymRepository;

class TermCount
{
    private $repository;

    public function __construct()
    {
        $this->repository = new SynonymRepository();
    }

    public function getCount($termId)
    {
        return $this->repository->getCount($termId);
    }
}

When running this I am getting the following error

Type error: Too few arguments to function Doctrine\ORM\EntityRepository::__construct(), 0 passed in /var/www/html/src/AppBundle/Services/TermCount.php on line 15 and exactly 2 expected

I assume this is happening because extending SynonymRepository with the EntityRepository requires EntityManagerInterface $em and Mapping\ClassMetadata $class. But I am not sure how pass them to EntityRepository.

I was using this answer to get me here, lost on how to actually implement the finall bit. Thanks for helping.

UPDATE

Entity

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Table(name="synonym")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\SynonymRepository")
 */
class Synonym
{
    /**
     * @var int
     * @ORM\Id()
     * @ORM\Column(name="synonym_id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $synonymId;

    /**
     * @var Term
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Term", inversedBy="synonyms")
     */
    protected $term;

    /**
     * @var SynonymType[]
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\SynonymType", inversedBy="synonyms")
     */
    protected $synonymType;

    /**
     * @var int
     * @ORM\Column(name="language_id", type="integer")
     */
    protected $languageId;

    /**
     * @var string
     * @ORM\Column(name="synonym", type="string", length=255)
     */
    protected $synonym;

    public function __construct()
    {
       // $this->synonymType = new ArrayCollection();
    }

    /**
     * @return int
     */
    public function getSynonymId(): int
    {
        return $this->synonymId;
    }

    /**
     * @return Term
     */
    public function getTerm(): Term
    {
        return $this->term;
    }

    /**
     * @param int $termId
     * @return Term
     */
    public function setTerm(int $termId): Term
    {
        $this->term = $termId;
        return $this->term;
    }

    /**
     * @return SynonymType[]
     */
    public function getSynonymType()
    {
        return $this->synonymType;
    }

    /**
     * @param SynonymType $synonymType
     * @return SynonymType
     */
    public function setSynonymType(SynonymType $synonymType): SynonymType
    {
        $this->synonymType = $synonymType;
        return $this->synonymType;
    }

    /**
     * @return int
     */
    public function getLanguageId(): int
    {
        return $this->languageId;
    }

    /**
     * @param int $languageId
     * @return Synonym
     */
    public function setLanguageId(int $languageId): Synonym
    {
        $this->languageId = $languageId;
        return $this;
    }

    /**
     * @return string
     */
    public function getSynonym(): string
    {
        return $this->synonym;
    }

    /**
     * @param string $synonym
     * @return Synonym
     */
    public function setSynonym(string $synonym): Synonym
    {
        $this->synonym = $synonym;
        return $this;
    }

}
Vladimir Szabo
  • 448
  • 4
  • 18
  • The answer below points you in the right direction but I'm curious as to what Symfony version you are using? If it is Symfony 2 then fine. But if you are using anything later then you can save yourself a considerable amount of work. – Cerad Jan 23 '20 at 16:12
  • Symfony 3.4. I am listening – Vladimir Szabo Jan 23 '20 at 17:09
  • 2
    Start by reading docs about the wonders of [autowire](https://symfony.com/doc/3.4/service_container/autowiring.html). With autowire you can drastically reduce the size of your services.yml file. And then switch over to the Doctrine section and see how to extend from the ServiceEntityRepository class instead of EntityRepository. Just be sure to always pick the 3.4 version while reading the docs. – Cerad Jan 23 '20 at 17:14

1 Answers1

1

You need to use DI (Dependency injection) in your construct insted of using new cause as i see the erreur your SynonymRepository depends on other services

<?php

namespace AppBundle\Services;

use AppBundle\Repository\SynonymRepository;

class TermCount
{
    private $repository;

    public function __construct(SynonymRepository $synonymRepository)
    {
        $this->repository = $synonymRepository;
    }

    public function getCount($termId)
    {
        return $this->repository->getCount($termId);
    }
}
Youssef Saoubou
  • 591
  • 4
  • 11
  • This gives the following error: Type error: Argument 1 passed to AppBundle\Services\TermCount::__construct() must be an instance of AppBundle\Repository\SynonymRepository, instance of Doctrine\ORM\EntityRepository given, called in /var/www/html/var/cache/dev/ContainerDhvlegw/appDevDebugProjectContainer.php on line 2661 – Vladimir Szabo Jan 23 '20 at 17:12
  • Found this question that looks exactly like mine but the solution was applicable to me @Youssef Saoubou any ides? https://stackoverflow.com/questions/38542747/symfony-3-argument-1-passed-to-some-service-construct-must-be-an-instance – Vladimir Szabo Jan 23 '20 at 17:25
  • Verify that your Synonym entity is correctly mapped to your SynonymRepository – Cerad Jan 23 '20 at 17:45
  • @VladimirSabo Are you still having trouble with this? Make sure you don't have any old doctrine mapping files hanging out under AppBundler/Resources/doctrine. They will interfere with your mappings. You can also debug with $repo = $entityManager->getRepository(Synonym::class) just to verify your are getting your custom repo. – Cerad Jan 24 '20 at 15:29
  • Found my issue, in service.yml I used the wrong argument for the repository – Vladimir Szabo Jan 24 '20 at 15:38
  • Happy to hear that but the DI is obligatory in your construct if you found my answer usefull thumbs up :) – Youssef Saoubou Jan 24 '20 at 16:06