Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
15
respostas

PHP - altera produto

Pessoal, estou com um problema na hora de alterar os dados do produto. Quando chamo a pagina de altera produto ele carrega todos os dados, incluindo a imagem, mas no submit para alterar os dados do produto, o caminho da imagem é deletado do BD e a imagem permanece na pasta. Se escolho uma nova foto ele cria um novo caminho e guarda uma nova foto. Como posso alterar meu codigo para que durante a alteração, sem alterar a foto, eu consiga manter o caminho e a foto que já existia no BD?

segue pagina de alteração onde exibe a foto e se quiser altera a foto também

<div class="form-group">
        <label>Imagem do Produto:</label>
        <img width="177px" height="177px" width="auto" height="auto" img src="fotos/<?=$produto->getFoto() ?>" alt="Sem Imagem"/>
    </div>

    <div class="form-group">
        <label>Alterar Imagem:</label>
            <input type="file" name="foto" class="form-control"  
                value="foto">

segue abaixo a classe produto nos get e set foto:

public function getFoto()
{
return $this->foto;
}

public function carregaCaminhoFoto($foto)  {
        $this->foto = $foto;
}

    public function gerarNovoNome( $nomeAntigo )
    {
        // Pega extensão da imagem
        preg_match("/\.(gif|bmp|png|jpg|jpeg){1}$/i", $nomeAntigo, $ext);
        // Gera um nome único para a imagem
        $nome_imagem = md5(uniqid(time())) . "." . $ext[1];

        return $nome_imagem;
    }

    public function setFoto($foto)
    {

        // esta variavel precisa existir, mesmo que vazia
        $nome_imagem = null;

        // armazena erros se houver
        $error = array();

        // Se a foto estiver sido selecionada
        if (!empty($foto["name"]))
        {
            // Largura máxima em pixels
            $largura = 1200;
            // Altura máxima em pixels
            $altura = 1200;
            // Tamanho máximo do arquivo em bytes
            $tamanho = 1500000;
            // Verifica se o arquivo é uma imagem
            if(!preg_match("/^image\/(pjpeg|jpeg|png|gif|bmp)$/", $foto["type"]))
            {
                $error[1] = "Isso não é uma imagem.";
            }

            // Pega as dimensões da imagem
            $dimensoes = getimagesize($foto["tmp_name"]);

            // Verifica se a largura da imagem é maior que a largura permitida
            if($dimensoes[0] > $largura)
            {
                $error[2] = "A largura da imagem não deve ultrapassar ".$largura." pixels";
            }

            // Verifica se a altura da imagem é maior que a altura permitida
            if($dimensoes[1] > $altura)
            {
                $error[3] = "Altura da imagem não deve ultrapassar ".$altura." pixels";
            }

            // Verifica se o tamanho da imagem é maior que o tamanho permitido
            if($foto["size"] > $tamanho)
            {
                $error[4] = "A imagem deve ter no máximo ".$tamanho." bytes";
            }
// Se não houver nenhum erro
            if (count($error) == 0)
            {
                $nome_imagem = $this->gerarNovoNome($foto["name"]);

                // caso o diretório não exista
                if( !is_dir("fotos") )
                    mkdir("fotos", "0777", true);

                // Caminho de onde ficará a imagem
                $caminho_imagem = "fotos" . DIRECTORY_SEPARATOR . $nome_imagem;
                // Faz o upload da imagem para seu respectivo caminho
                move_uploaded_file($foto["tmp_name"], $caminho_imagem);
                $this->foto = $foto;
            }
          if (!count($error) == 0)
            {
                echo "<pre>";
                echo "Opa!, foto com os seguintes problemas: <br>";
                echo implode("<br>", $error);
                exit;
            }
            else{
                  $this->foto = $nome_imagem;
}
            return $nome_imagem;
}

segue o arquivo de altera produto na parte de setFoto

<?php
require_once 'conecta.php';
require_once 'banco-produto.php';
require_once 'produto.php';
require_once 'categoria.php';
require_once 'subcategoria.php';
require_once 'marca.php';

$nome_imagem = $produto->setFoto( $_FILES["foto"]);
15 respostas

Falta uma } no trecho de código colado acima, ao final da setFoto(). O original deve estar certo pois executou.


Assumindo que exista um return ao final da setFoto($foto) fora do if:

No começo do setFoto, você determina que:

// esta variavel precisa existir, mesmo que vazia`
 $nome_imagem = null;

Mas no caso de uma foto não tiver sido selecionada:

// Se a foto estiver sido selecionada
if (!empty($foto["name"]))

Seu script vai direto para:

return $nome_imagem;

Que está null nesse momento.

Obrigado Ricardo, esse if (!empty($foto["name"])) não existia é um teste que eu fiz para que o script não deletasse o caminho da foto no caso de uma alteração do produto, mas não obtive sucesso. O $nome_imagem é necessario para cadastrar novo nome do caminho da foto. Segue o codigo

public function gerarNovoNome( $nomeAntigo )
    {
        // Pega extensão da imagem
        preg_match("/\.(gif|bmp|png|jpg|jpeg){1}$/i", $nomeAntigo, $ext);
        // Gera um nome único para a imagem
        $nome_imagem = md5(uniqid(time())) . "." . $ext[1];

        return $nome_imagem;
    }

Outra coisa que fiz foi colocar um imput file hidden na exibição da foto para que quando fizesse alteração nos dados do produto o caminho da foto seria alterado para o que já existe. Mas também não consegui sucesso.

O maior problema que eu tenho é que o codigo como está contempla uma inclusão da foto em um produto já cadastrado. Mas na hora de alterar os dados do produto não sei como manter o caminho da foto no BD

Pode postar a linha que realiza a inclusão / alteração do produto ? Nesta parte do código é possível fazer um condicional para checar se o nome da foto está definido dentro do objeto produto e a partir deste ponto montar a query adequadamente para a inserção ou atualização.

obrigado Gabriel segue o formulário de alteração do produto com inclusão de nova foto e também exibe foto:

<main class="container">
    <article class="principal">

<?php

$categorias = listaCategorias($conexao);
$marcas = listaMarcas($conexao);
$subcategorias = listaSubcategorias($conexao);

$produto = new Produto();
$produto->setCategoria(new Categoria());
$produto->setSubcategoria(new Subcategoria());
$produto->setMarca(new Marca());
$ehAlteracao = false;
$action = "adiciona-produto.php";
$id = "";

//Campos do formulario
//Inserir os demais campos do formulario

if (array_key_exists('id', $_GET)) {
    $id = $_GET['id'];
    if ($id <> ""){
        $produto = buscaProduto($conexao, $id);
        $ehAlteracao = true;
        $nome = $produto->getNome() ;
        //Carrega os demais campos do formulário

        $action = "altera-produto.php";
    }
}

?>
<h1><?=$ehAlteracao ? "Alterar" : "Cadastrar" ?> produto</h1>
<form action="<?=$action ?>" method="post" enctype="multipart/form-data">

   <!-- Adicionar os demais campos do formulário -->

    <input type="hidden" name="id" value="<?=$id; ?>" />


    <br>
 <div class="form-group">
        <label>Imagem do Produto:</label>
           <img width="177px" height="177px" width="auto" height="auto" img src="fotos/<?=$produto->getFoto() ?>" alt="Sem Imagem"/>
            <input type="hidden" value="<?=$produto->getFoto() ?>" />
    </div>

    <div class="form-group">
        <label>Alterar Imagem:</label>
            <input type="file" name="foto" class="form-control"  
                value="foto">
<br>

        <button class="btn btn-primary" type="submit">Salvar</button>
</form>

este é o alteraproduto

<?php
require_once 'conecta.php';
require_once 'banco-produto.php';
require_once 'produto.php';
require_once 'categoria.php';
require_once 'subcategoria.php';
require_once 'marca.php';


$produto = new Produto();
$produto->setId( $_POST['id'] );
$produto->setCodigo( $_POST['codigo'] );
$produto->setReferencia( $_POST['referencia'] );
$produto->setPeso( $_POST['peso'] );
$produto->setNome( $_POST['nome'] );
$produto->setDescricao( $_POST['descricao'] );
$produto->setPreco( $_POST['preco'] );
$produto->setMedida( $_POST['medida'] );
$produto->setNcm( $_POST['ncm'] );
$produto->setMarca(new Marca());
$produto->getMarca()->setId( $_POST['marca_id'] );
$produto->setCategoria(new Categoria());
$produto->getCategoria()->setId( $_POST['categoria_id'] );
$produto->setSubcategoria(new Subcategoria());
$produto->getSubcategoria()->setId( $_POST['subcategoria_id'] );
$produto->setDestaque( $_POST['destaque'] );
$nome_imagem = $produto->setFoto( $_FILES["foto"]);

Faltou somente a SQL (INSERT ou UPDATE). É neste ponto que a alteração deve ser feita. Pode postar ?

obrigado Gabriel, segue

function alteraProduto($conexao, $produto, $nome_imagem) {
$query = "update produtos set nome = '{$produto->getNome()}',
codigo = {$produto->getCodigo()}, referencia = '{$produto->getReferencia()}', preco = {$produto->getPreco()}, peso = {$produto->getPeso()}, medida = '{$produto->getMedida()}', ncm = {$produto->getNcm()}, descricao = '{$produto->getDescricao()}', marca_id = {$produto->getMarca()->getId()}, categoria_id = {$produto->getCategoria()->getId()}, subcategoria_id = {$produto->getSubcategoria()->getId()}, destaque = {$produto->getDestaque()}, foto = '" .$nome_imagem. "' where id = {$produto->getId()}";

return mysqli_query($conexao, $query);

}

esse é o busca produto

function buscaProduto($conexao, $id) {
$query = "select p.*, c.nome as categoria_nome, sc.nome as subcategoria_nome, m.nome as marca_nome 
from produtos p 
inner join categorias c on(p.categoria_id = c.id)
inner join subcategorias sc on(p.subcategoria_id = sc.id)
inner join marcas m on(p.marca_id = m.id) 
where p.id = {$id}";

$resultado = mysqli_query($conexao, $query);
$array = mysqli_fetch_assoc($resultado);

$produto = new Produto();
$produto->setId( $array['id'] );
$produto->setCodigo($array['codigo']);
$produto->setReferencia($array['referencia']);
$produto->setPeso($array['peso']);
$produto->setNome( $array['nome'] );
$produto->setDescricao( $array['descricao'] );
$produto->setPreco( $array['preco'] );
$produto->setMedida($array['medida']);
$produto->setNcm($array['ncm']);
$produto->setMarca( new Marca() );
$produto->getmarca()->setId( $array['marca_id'] );
$produto->getMarca()->setNome( $array['marca_nome'] );
$produto->setCategoria( new Categoria() );
$produto->getCategoria()->setId( $array['categoria_id'] );
$produto->getCategoria()->setNome( $array['categoria_nome'] );
$produto->setSubcategoria( new Subcategoria() );
$produto->getSubcategoria()->setId( $array['subcategoria_id'] );
$produto->getSubcategoria()->setNome( $array['subcategoria_nome'] );
$produto->setDestaque($array['destaque']);
$produto->carregaCaminhoFoto($array['foto']);

return $produto;
}

Uma possível solução

function alteraProduto($conexao, $produto, $nome_imagem) {
    $query = "update produtos set nome = '{$produto->getNome()}',".
    $query .= " codigo = {$produto->getCodigo()},";
    $query .= " referencia = '{$produto->getReferencia()}',";
    $query .=  " preco = {$produto->getPreco()},";
    $query .=  " peso = {$produto->getPeso()},";
    $query .=  " medida = '{$produto->getMedida()}',";
    $query .=  " ncm = {$produto->getNcm()},";
    $query .=  " descricao = '{$produto->getDescricao()}',";
    $query .= " marca_id = {$produto->getMarca()->getId()},";
    $query .= " categoria_id = {$produto->getCategoria()->getId()},";
    $query .= " subcategoria_id = {$produto->getSubcategoria()->getId()},";
    $query .= " destaque = {$produto->getDestaque()},";
    if ( $nome_imagem <> "" ) $query .=  " foto = '" .$nome_imagem. "'";
    $query .= " where id = {$produto->getId()}";
    return mysqli_query($conexao, $query);

}

Oi Gabriel, funcionou o caminho da foto ficou no BD. Mas agora não consigo alterar nenhum dado do produto. Fiz um teste e olha o erro apresentado, o que poderá ser?

Notice: Undefined variable: query in C:\Bitnami\wampstack-5.6.19-0\apache2\htdocs\cadastro\banco-produto.php on line 89
O produto Batedeira planetario orbitalnão foi alterado: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where id = 26' at line 1

esta é o codigo alterado na linha 89

function alteraProduto($conexao, $produto, $nome_imagem) {
    $query = "update produtos set nome = '{$produto->getNome()}',".
 89   $query .= " codigo = {$produto->getCodigo()},";
 90  $query .= " referencia = '{$produto->getReferencia()}',";
91    $query .=  " preco = {$produto->getPreco()},";
    $query .=  " peso = {$produto->getPeso()},";
    $query .=  " medida = '{$produto->getMedida()}',";
    $query .=  " ncm = {$produto->getNcm()},";
    $query .=  " descricao = '{$produto->getDescricao()}',";
    $query .= " marca_id = {$produto->getMarca()->getId()},";
    $query .= " categoria_id = {$produto->getCategoria()->getId()},";
    $query .= " subcategoria_id = {$produto->getSubcategoria()->getId()},";
    $query .= " destaque = {$produto->getDestaque()},";
    if ( $nome_imagem <> "" ) $query .=  " foto = '" .$nome_imagem. "'";
    $query .= " where id = {$produto->getId()}";
    return mysqli_query($conexao, $query);

}

Faltou um ponto e vírgula na linha 88

function alteraProduto($conexao, $produto, $nome_imagem) {
    $query = "update produtos set nome = '{$produto->getNome()}',"; // faltava um ponto-e-vírgula aqui
   $query .= " codigo = {$produto->getCodigo()},";
   $query .= " referencia = '{$produto->getReferencia()}',";
    $query .=  " preco = {$produto->getPreco()},";
    $query .=  " peso = {$produto->getPeso()},";
    $query .=  " medida = '{$produto->getMedida()}',";
    $query .=  " ncm = {$produto->getNcm()},";
    $query .=  " descricao = '{$produto->getDescricao()}',";
    $query .= " marca_id = {$produto->getMarca()->getId()},";
    $query .= " categoria_id = {$produto->getCategoria()->getId()},";
    $query .= " subcategoria_id = {$produto->getSubcategoria()->getId()},";
    $query .= " destaque = {$produto->getDestaque()},";
    if ( $nome_imagem <> "" ) $query .=  " foto = '" .$nome_imagem. "'";
    $query .= " where id = {$produto->getId()}";
    return mysqli_query($conexao, $query);

}

Oi Gabriel, realmente resolveu uma parte mas ainda tem mais alguma coisa, podes me ajudar a encontrar?

O produto Batedeira planetario orbitalnão foi alterado: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where id = 26' at line 1

Acrescente algo antes da execução para checar a SQL que está sendo gerada e veja se tem algum erro.

$query .= " where id = {$produto->getId()}";
echo $query; exit;  // acrescente esta linha
 return mysqli_query($conexao, $query);

Lembre-se que o espaço depois da aspas de abertura é necessário.

Gabriel parece em ordem olha só mas não altera

update produtos set nome = 'Batedeira planetario orbital', codigo = 7893456378111, referencia = '368', preco = 150.00, peso = 11, medida = '11x11x11', ncm = 456, descricao = 'essa é uma ótima batedeira', marca_id = 1, categoria_id = 1, subcategoria_id = 3, destaque = 1, where id = 26
solução!

o código é numérico ? se não for tem que ficar entre aspas.

codigo = 7893456378111

Tem uma vírgula a mais depois de destaque. precisa ser removida.

destaque = 1, where id = 26

Pra evitar este erro, mude a ordem na query:

function alteraProduto($conexao, $produto, $nome_imagem) {
    $query = "update produtos set nome = '{$produto->getNome()}',"; // faltava um ponto-e-vírgula aqui
   $query .= " codigo = {$produto->getCodigo()},";
   $query .= " referencia = '{$produto->getReferencia()}',";
    $query .=  " preco = {$produto->getPreco()},";
    $query .=  " peso = {$produto->getPeso()},";
    $query .=  " medida = '{$produto->getMedida()}',";
    $query .=  " ncm = {$produto->getNcm()},";
    $query .=  " descricao = '{$produto->getDescricao()}',";
    $query .= " marca_id = {$produto->getMarca()->getId()},";
    $query .= " categoria_id = {$produto->getCategoria()->getId()},";
    $query .= " subcategoria_id = {$produto->getSubcategoria()->getId()},";
    if ( $nome_imagem <> "" ) $query .=  " foto = '" .$nome_imagem. "',";
    $query .= " destaque = {$produto->getDestaque()}";
    $query .= " where id = {$produto->getId()}";
    return mysqli_query($conexao, $query);

}

Perfeito Gabriel funcionou!!!! Exatamente como deve ser. Muito obrigado mais uma vez .

aeeeee bom que conseguiram