3
respostas

Erro AtualizaBaseadoEm

Quando tento listar os produtos minha aplicação está retornando o erro: "Fatal error: Call to a member function atualizaBaseadoEm() on null in D:\wamp64\www\loja\class\ProdutoDao.php on line 25"

Abaixo código da Classe Produto.php:

<?php 
class Produto{
    private $id;
    private $nome;
    protected $preco;
    private $descricao;
    private $categoria;
    private $usado;
    //private $tipoProduto;

        function __construct($nome, $preco, $descricao, Categoria $categoria, $usado){
            $this->nome = $nome;
            $this->preco = $preco;
            $this->descricao = $descricao;
            $this->categoria = $categoria;
            $this->usado = $usado;
        }

        public function precoComDesconto($valor = 0.1){
            if($valor > 0 && $valor <= 0.5){
                $this->preco -= $this->preco * $valor;
            }
            return $this->preco;
        }

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

        public function setId($id){
            $this->id = $id;
        }

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


        public function getPreco(){
            return $this->preco;
        }


        public function getDescricao(){
            return $this->descricao;
        }


        public function getCategoria(){
            return $this->categoria;
        }


        public function isUsado(){
            return $this->usado;
        }

        public function setUsado($usado){
            $this->usado = $usado;
        }

        public function __toString(){
            return $this->nome.": R$".$this->preco;
        }

        //Retirado essa parte do código pq o tipo de produto agora é representado pela classe;
        /*
        public function getTipoProduto(){
            return $this->tipoProduto;
        }

        //Função para verificar se o tipo de produto é um Livro
        public function setTipoProduto($tipoProduto){
            $this->tipoProduto = $tipoProduto;
        }*/

        public function temIsbn(){
            //instanceof= Se for uma instancia de livro ele retorna true
            return $this instanceof Livro;
        }

        public function calculaImposto(){
            return $this->getPreco() * 0.195;
        }

        public function temTaxaImpressao() {
                return $this instanceof LivroFisico;
        }

        public function temWaterMark() {
            return $this instanceof Ebook;
        }

        public function atualizaBaseadoEm($params) {
            if ($this->temIsbn()) {
                $this->setIsbn($params["isbn"]);
            }
            if ($this->temWaterMark()) {
                $this->setWaterMark($params["waterMark"]);
            }
            if ($this->temTaxaImpressao()) {
                $this->setTaxaImpressao($params["taxaImpressao"]);
            }
        }

}

 ?>

Código do ProdutoDao.php

<?php 

class ProdutoDao {

    private $conexao;

    function __construct($conexao) {
        $this->conexao = $conexao;
    }

    function listaProdutos() {

        $produtos = array();
        $resultado = mysqli_query($this->conexao, "select p.*,c.nome as categoria_nome 
            from produtos as p join categorias as c on c.id=p.categoria_id");

        while($produto_array = mysqli_fetch_assoc($resultado)) {

            $tipoProduto = $produto_array['tipoProduto'];
            $produto_id = $produto_array['id'];
            $categoria_nome = $produto_array['categoria_nome'];

            $factory = new ProdutoFactory();
            $produto = $factory->criaPor($tipoProduto, $produto_array);
            $produto->atualizaBaseadoEm($produto_array);

            $produto->setId($produto_id);
            $produto->getCategoria()->setNome($categoria_nome);

            array_push($produtos, $produto);
        }

        return $produtos;
    }

    function insereProduto(Produto $produto) {

        $isbn = "";
        if($produto->temIsbn()) {
            $isbn = $produto->getIsbn();
        }

        $waterMark = "";
        if($produto->temWaterMark()) {
            $waterMark = $produto->getWaterMark();
        }

        $taxaImpressao = "";
        if($produto->temTaxaImpressao()) {
            $taxaImpressao = $produto->getTaxaImpressao();
        }

        $tipoProduto = get_class($produto);

        $query = "insert into produtos (nome, preco, descricao, categoria_id, 
                usado, isbn, tipoProduto, waterMark, taxaImpressao) 
                    values ('{$produto->getNome()}', {$produto->getPreco()}, 
                        '{$produto->getDescricao()}', 
                            {$produto->getCategoria()->getId()}, 
                                {$produto->isUsado()}, '{$isbn}', '{$tipoProduto}', 
                                    '{$waterMark}', '{$taxaImpressao}')";

        return mysqli_query($this->conexao, $query);
    }

    function alteraProduto(Produto $produto) {

        $isbn = "";
        if($produto->temIsbn()) {
            $isbn = $produto->getIsbn();
        }

        $waterMark = "";
        if($produto->temWaterMark()) {
            $waterMark = $produto->getWaterMark();
        }

        $taxaImpressao = "";
        if($produto->temTaxaImpressao()) {
            $taxaImpressao = $produto->getTaxaImpressao();
        }

        $tipoProduto = get_class($produto);

        $query = "update produtos set nome = '{$produto->getNome()}', 
            preco = {$produto->getPreco()}, descricao = '{$produto->getDescricao()}', 
                categoria_id= {$produto->getCategoria()->getId()}, 
                    usado = {$produto->isUsado()}, isbn = '{$isbn}', 
                        tipoProduto = '{$tipoProduto}', waterMark = '{$waterMark}', 
                            taxaImpressao = '{$taxaImpressao}' 
                                where id = '{$produto->getId()}'";

        return mysqli_query($this->conexao, $query);
    }

    function buscaProduto($id) {

        $query = "select * from produtos where id = {$id}";
        $resultado = mysqli_query($this->conexao, $query);
        $produto_buscado = mysqli_fetch_assoc($resultado);

        $tipoProduto = $produto_buscado['tipoProduto'];
        $produto_id = $produto_buscado['id'];
        $categoria_id = $produto_buscado['categoria_id'];

        $factory = new ProdutoFactory();
        $produto = $factory->criaPor($tipoProduto, $produto_buscado);
        $produto->atualizaBaseadoEm($produto_buscado);

        $produto->setId($produto_id);
        $produto->getCategoria()->setId($categoria_id);

        return $produto;
    }

    function removeProduto($id) {

        $query = "delete from produtos where id = {$id}";

        return mysqli_query($this->conexao, $query);
    }
}

?>
3 respostas

Não sou especialista em php, mas pela mensagem do erro, meu chute é que o problema está na ProdutoFactory(); Confere se o método realmente ta retornando um produto? Parece que ele ta retornando nulo...

O método atualizaBaseadoEm() está descrito na Classe Produto. Segue código da classe ProdutoFactory para conferência:

<?php 
class ProdutoFactory{
    private $classes = array("Produto", "LivroFisico", "Ebook");

    //A função tem que receber o tipo produto como parametro
    //o $params serve para receber todos os atributos dos produtos em um array (nome, preço...)
    public function CriaPor($tipoProduto, $params){

        $nome = $params ['nome'];
        $preco = $params ['preco'];
        $descricao = $params ['descricao'];
        $categoria = new Categoria;
        $usado = $params ['usado'];

        if(in_array($tipoProduto, $this->classes)){
        //utilizando a variavel tipo produto não precisa ficar fazendo vários Ifs para cada nova classe;
            $produto = new $tipoProduto($nome, $preco, $descricao, $categoria, $usado);
        } else{
            $produto = new LivroFisico($nome, $preco, $descricao, $categoria, $usado);
        }
    }
}

 ?>

A função "CriaPor" que você chamou não retorna nada para a variável $produto. E a partir da variável $produto você tenta chamar a função "atualizaBaseadoEm". Você é quem conhece melhor o código, mas eu colocaria um return adequado na função "CriaPor".