Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Undefined method 'fetchCoursesByStudent'.

Fazendo uma varredura aqui pelo código eu cheguei a conclusão de que esse erro deve estar vinculado a IDE e gostaria de saber se alguém com mais experiência poderia me ajudar nessa questão. Estou usando o VS-Code e quando eu mapeio o repository na classe Student pra que eu possa usar o método fetchCoursesByStudent() tudo funciona normal como previsto, o código funciona, da os retornos esperados mas a IDE fica acusando que o método fetchCoursesByStudent() não existe. É como se durante a execução o sistema entende que agora o repository que deve ser executado é o que eu criei mas a IDE não. Alguém sabe como corrigir isso? PS: Meu código está em inglês.

Classe Student.php:

<?php

namespace Alura\Doctrine\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * @Entity(repositoryClass="Alura\Doctrine\Repository\StudentRepository")
 */
class Student
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    private int $id;
    /**
     * @Column(type="string")
     */
    private string $name;
    /**
     * @OneToMany(targetEntity="Phone", mappedBy="student", cascade={"remove", "persist"}, fetch="EAGER")
     */
    private $phones;
    /**
     * @ManyToMany(targetEntity="Course", mappedBy="students")
     */
    private $courses;

    public function __construct()
    {
        $this->phones = new ArrayCollection();
        $this->courses = new ArrayCollection();
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName($name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function addPhone(Phone $phone): self
    {
        $this->phones->add($phone);
        $phone->setStudent($this);
        return $this;
    }

    public function getPhones(): Collection
    {
        return $this->phones;
    }

    public function getCourses(): Collection
    {
        return $this->courses;
    }

    public function addCourse(Course $course): self
    {
        if ($this->courses->contains($course)) {
            return $this;
        }

        $this->courses->add($course);
        $course->addStudent($this);

        return $this;
    }
}

Classe StudentRepository.php:

<?php

namespace Alura\Doctrine\Repository;

use Alura\Doctrine\Entity\Student;
use Doctrine\ORM\EntityRepository;

class StudentRepository extends EntityRepository
{
    public function fetchCoursesByStudent()
    {
        $entityManager = $this->getEntityManager();
        $studentClass = Student::class;
        $dql = "SELECT s, p, c FROM $studentClass s JOIN s.phones p JOIN s.courses c";
        $query = $entityManager->createQuery($dql);
        return $query->getResult();
    }
}

Aqurivo report-course-by-student-repository.php que executa o código:

<?php

use Alura\Doctrine\Entity\Phone;
use Alura\Doctrine\Entity\Student;
use Alura\Doctrine\Helper\EntityManagerFactory;
use Doctrine\DBAL\Logging\DebugStack;

require_once __DIR__ . '/../vendor/autoload.php';

$entityManagerFactory = new EntityManagerFactory();
$entityManager = $entityManagerFactory->getEntityManager();
$studentsRepository = $entityManager->getRepository(Student::class);

$debugStack = new DebugStack();
$entityManager->getConfiguration()->setSQLLogger($debugStack);

/** @var Student[] $students */
$students = $studentsRepository->fetchCoursesByStudent();

foreach ($students as $student) {
    $phones = $student->getPhones()
        ->map(function (Phone $phone) {
            return $phone->getNumber();
        })
        ->toArray();

    echo "ID: {$student->getId()}\n";
    echo "Name: {$student->getName()}\n";
    echo "Phones: " . implode(",", $phones) . "\n";

    $cursos = $student->getCourses();

    foreach ($cursos as $curso) {
        echo "ID Course: {$curso->getId()}\n";
        echo "\tCourse: {$curso->getName()}";
        echo "\n";
    }
    echo "\n";
}

echo "\n";

foreach ($debugStack->queries as $queryInfo) {
    echo $queryInfo['sql'] . "\n";
}
1 resposta
solução!

Descobri o problema. O VS Code não faz ideia do que seja o objeto $studentsRepository. Precisei adicionar um docblock /** @var EntityRepository $studentsRepository */encima da variável especificando o que ela é.

/** @var EntityRepository $studentsRepository */
$studentsRepository = $entityManager->getRepository(Student::class);

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software