Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Não consigo executar relatorio-cursos-por-aluno.php

Na aula 06 do curso de Doctrine, vídeo 02.

Nós executamos o relatorio-cursos-por-aluno.php para receber a listagem de alunos.

No entanto eu não consigo fazer isso, me retona um erro.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Ele entra num loop na hora de procurar o Telefone dos Alunos.

Já revisei tudo.

Por favor, me ajudem!

Aqui meu GIT com o código completo https://github.com/zwinglio/doctrine-alura

Aluno.php

<?php


namespace Alura\Doctrine\Entity;

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

/**
 * @Entity
 */
class Aluno
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    private $id;

    /**
     * @Column(type="string")
     */
    private $nome;

    /**
     * @OneToMany(targetEntity="Telefone", mappedBy="aluno", cascade={"remove", "persist"}), fetch="EAGER")
     */
    private $telefones;
    /**
     * @ManyToMany(targetEntity="Curso", mappedBy="alunos")
     */
    private $cursos;

    public function __construct() {
        $this->telefones = new ArrayCollection();
        $this->cursos = new ArrayCollection();
    }

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

    public function getNome(): string
    {
        return $this->nome;
    }

    public function setNome($nome)
    {
        $this->nome = $nome;
        return $this;
    }

    public function addTelefone(Telefone $telefone)
    {
        $this->telefones->add($telefone);
        $telefone->setAluno($this);
        return $this;
    }

    public function getTelefones(): Collection
    {
        return $this->telefones;
    }

    public function addCurso(Curso $curso): self
    {

        if($this->cursos->contains($curso)){
            return $this;
        }

        $this->cursos->add($curso);
        $curso->addAluno($this);

        return $this;
    }

    public function getCurso(): Collection 
    {
        return $this->cursos;
    }
}

Telefone.php

<?php

namespace Alura\Doctrine\Entity;

/**
 * @Entity
 */
class Telefone
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    private $id;
    /**
     * @Column(type="string")
     */
    private $numero;
    /**
     * @ManyToOne(targetEntity="Aluno")
     */
    private $aluno;

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

    public function getNumero(): string
    {
        return $this->numero;
    }

    public function setNumero(string $numero): self
    {
        $this->numero = $numero;
        return $this;
    }

    public function getAluno(): Aluno
    {
        return $this->aluno;
    }

    public function setAluno(Aluno $aluno): self
    {
        $this->aluno = $aluno;
        return $this;
    }
}

relatorio-curso-por-aluno.php

<?php

use Alura\Doctrine\Entity\Aluno;
use Alura\Doctrine\Entity\Telefone;
use Alura\Doctrine\Helper\EntityManagerFactory;

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

$entityManagerFactory = new EntityManagerFactory();
$entityManager = $entityManagerFactory->getEntityManager();

$alunosRepository = $entityManager->getRepository(Aluno::class);

$alunos = $alunosRepository->findAll();

var_dump($alunos);
exit();

foreach ($alunos as $aluno) {
    $telefones = $aluno
        ->getTelefones()
        ->map(function(Telefone $telefone) {
            return $telefone->getNumero();
        })->toArray();

    echo "ID: { $aluno->getId() }\n";
    echo "Nome: { $aluno->getNome() }\n";
    echo "Telefones: " .implode(', ', $telefones);

    $cursos = $aluno->getCursos();

    foreach ($cursos as $curso) {
        echo "\tID Curso: { $curso->getId() }\n";
        echo "\tNome do Curso: { $curso->getNome() \n}";
        echo "\n";
    }
    echo "/n";
}
3 respostas
solução!

Encontrei alguns erros: primeiro no seu arquivo relatorio-curso-por-aluno.php, vc esta chamdno a função getCursos(), e na sua classe aluna o nome da funçao é getCurso. Segundo, é pq vc esta chamando uma função dentro da sua string deste jeito "ID: { $aluno->getId() }\n", eu alteriei para "ID: ".$aluno->getId()."\n" e deu tudo certo

O codigo ficou

<?php

use Alura\Doctrine\Entity\Aluno;
use Alura\Doctrine\Entity\Telefone;
use Alura\Doctrine\Helper\EntityManagerFactory;

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

$entityManagerFactory = new EntityManagerFactory();
$entityManager = $entityManagerFactory->getEntityManager();

$alunosRepository = $entityManager->getRepository(Aluno::class);

$alunos = $alunosRepository->findAll();

foreach ($alunos as $aluno) {

    $telefones = $aluno
        ->getTelefones()
        ->map(function(Telefone $telefone) {
            return $telefone->getNumero();
        })->toArray();

    echo "ID: ".$aluno->getId() ."\n";
    echo "Nome: ".$aluno->getNome() ."}\n";
    echo "Telefones: " .implode(', ', $telefones);

    $cursos = $aluno->getCursos();

    foreach ($cursos as $curso) {
        echo "\tID Curso: ". $curso->getId() ."\n";
        echo "\tNome do Curso: ". $curso->getNome() ."\n";
        echo "\n";
    }
    echo "/n";
}

e alterei o nome da função

<?php


namespace Alura\Doctrine\Entity;

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

/**
 * @Entity
 */
class Aluno
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    private $id;

    /**
     * @Column(type="string")
     */
    private $nome;

    /**
     * @OneToMany(targetEntity="Telefone", mappedBy="aluno", cascade={"remove", "persist"}), fetch="EAGER")
     */
    private $telefones;
    /**
     * @ManyToMany(targetEntity="Curso", mappedBy="alunos")
     */
    private $cursos;

    public function __construct() {
        $this->telefones = new ArrayCollection();
        $this->cursos = new ArrayCollection();
    }

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

    public function getNome(): string
    {
        return $this->nome;
    }

    public function setNome($nome)
    {
        $this->nome = $nome;
        return $this;
    }

    public function addTelefone(Telefone $telefone)
    {
        $this->telefones->add($telefone);
        $telefone->setAluno($this);
        return $this;
    }

    public function getTelefones(): Collection
    {
        return $this->telefones;
    }

    public function addCurso(Curso $curso): self
    {

        if($this->cursos->contains($curso)){
            return $this;
        }

        $this->cursos->add($curso);
        $curso->addAluno($this);

        return $this;
    }

 // ______________________ esta função que estava com o nome errado
    public function getCursos(): Collection 
    {
        return $this->cursos;
    }
}

resultado da execução

ID: 1
Nome: Samuel Zwinglio}
Telefones: 84 9 9666 6408    ID Curso: 1
    Nome do Curso: Doctrine

    ID Curso: 3
    Nome do Curso: Resetando o mindset

/nID: 2
Nome: Edyjancleide}
Telefones: 84 5555 44444, 84 99999 66666    ID Curso: 1
    Nome do Curso: Doctrine

/nID: 3
Nome: Jeremias Elegante}

Muito obrigado, Vinicius. Ele entrou num loop aqui não sei porque, mas realmente passou despercebido o uso da função errada da classe Aluno.

Me fala sobre o uso do { } ao invés do ""; Não existe uma forma de usar assim pra não precisar cocatenar?

Vc usa as chaves "{}" em alugns casos mais complexos tipo

$carro = "carro";

//ai vc quer escrever carros no plural
echo " existem 100 $carros estacionados"; // isso vai gerar um erro pq a variável $carros não exite

echo " existem 100 {$carro}s estacionados"; //assim vai dar certo.

já para executar uma função que nem vc estava querendo no seu código tem uma maneira também, mas não é muito bom não

<?php

function escreveNomeMaiusculo($nome){
    return ucfirst($nome);
}

$fn = 'escreveNomeMaiusculo'; // vc tem que atribuir o nome da função em uma váriavl

echo "Meu nome é: {$fn('vinicius')}".PHP_EOL; // e na hora de escrever chamar a variavel que tem o nome da função

$nome = escreveNomeMaiusculo('vinicius'); //essa seria a maneira mais noraml, que é armazenar o resultado da função em uma váriavel e depois escrever o resultado

echo "Meu nome é: {$nome}";

//resutaldo

    Meu nome é Vinicius
    Meu nome é Vinicius

?>