E se mudar o nome da imagem sem enviar uma nova imagem ?

julioff Criador 22/12/2019
julioff

Olá, professor

Pela regras não é possível editar imagem sem editar o nome do produto também, até aí tudo bem

Editando o nome do produto e a imagem, é  o que foi mostrado na aula, ok.

Mas se editar apenas o nome do produto sem editar a imagem, ocorre o cenario não desejado, que é o produto e imagem com nomes diferentes. Entende?

Eu pensei em criar um formRequest só pro update e deixar a imagem como required, mas creio que não seria interessante já que no cadastro a imagem é opcional

Também não consegui criar uma lógica onde o nome da imagem fosse alterado mesmo que não fosse selecionada nenhuma imagem, pois como não há arquivo, não há extensão, o que é necessario para formar o nome da imagem no banco.

Tem alguma sugestão ?

Criador julioff 22/12/2019
julioff

Errata: o título da dúvida deveria ser "E se mudar o nome do PRODUTO sem editar a imagem ?"

Criador julioff 22/12/2019
julioff

Professor, achei uma alternativa.

Em vez de basear o nome da imagem pelo do produto, eu baseei no id atraves do uniqid, fiz os testes de upload e edição e aparentemente tá tudo ok.

É uma boa alternativa ?

Manager Carlos Ferreira 22/12/2019
Carlos Ferreira

Olá, Julio!
Tudo bem?

Nesse caso você pode e deve atualizar o nome da imagem também:
Storage::move('caminho/nome-arquivo.jpg', 'caminho/nome-arquivo-atualizado.jpg');

Criador julioff 23/12/2019
julioff

Mas professor, como vou pegar a extensão se nenhum arquivo for selecionado ?

Manager Carlos Ferreira 26/12/2019
Carlos Ferreira

Olá amigo!

Nesse caso você pode mover o arquivo, com o novo nome.

Para isso pode usar a função rename() do PHP, ou usar a classe Storage do Laravel:
Storage::move (https://laravel.com/docs/6.x/filesystem)

Criador julioff 27/12/2019
julioff

Olá mestre,

Não consegui fazer atráves da maneira que me recomendou, mas consegui através do query builder. Não sei se é  "profisisonal" a forma que fiz, mas sanou completamente o que eu queria. Quando edito apenas o nome do produto, o nome da imagem também é editado e a sua extensão continua a mesma.

Gostaria que o senhor olhasse o código e me desse um feedback (a parte importante é o else). E também algum colega que possa ter a mesma dúvida pode dar uma olhada na minha solução


https://pastebin.com/Jni4YYVd

Criador julioff 27/12/2019
julioff

(é só juntar o link)
 https: //pastebin.com/ Jni4YYVd

Manager Carlos Ferreira 30/12/2019
Carlos Ferreira

Olá amigo!

Primeiro, sugiro que não faça isso, porque deixa o código muito poluído:
$extensao = DB::select("SELECT SUBSTRING_INDEX(imagem,'.',-1) AS extensao FROM produtos WHERE id = :id", ['id' => $id]);


Não testei o exemplo, teste:
[...]

if($request->hasFile('imagem') && $request->file('imagem')->isValid()) {
    [...]
} else {
    // Verifica se já tinha a imagem, e se mudou o nome
    if($produto->imagem && $produto->nome != $request->nome) {
        if(Storage::exists("produtos/{$produto->imagem}")) {
            // Define o nome do novo arquivo
            $newName = kebab_case($request->nome);

            // Pega a extensão do arquivo antigo
            $piecesOldName = explode('.', $produto->imagem);
            $extension = end($piecesName);

            // Define o novo nome do arquivo
            $newNameImage = "{$newName}.{$extension}";;

            // Renomeia o arquivo antigo
              Storage::move("produtos/{$produto->imagem}", "produtos/{$newNameImage}");
        }
    }
}

$produto->update($dados);

[...]

Criador julioff 30/12/2019
julioff

Olá, professor.

Sua solução não funciona. Muda o nome do arquivo mas não muda o nome da imagem.

Bom, de qualquer forma te agradeço.

Vou continuar com minha solução até achar uma que seja menos poluída.

Feliz ano novo pra você e sua familia.

Manager Carlos Ferreira 30/12/2019
Carlos Ferreira

Ah é verdade, faltou atualizar o nome da imagem:
$newNameImage = "{$newName}.{$extension}";
$data['imagem'] = $newNameImage;

Criador julioff 31/12/2019
julioff

Ah, verdade mestre. Me passei nisso.

Muito obrigado por toda atenção, seus cursos são show.

Abraço

Criador julioff 31/12/2019
julioff

Olá, professor, fiz alguns teste, sem efeito. O nome no banco não é alterado.

E acabei desobrindo mais um problema. Se editar apenas o nome e não a imagem, lá em storage/produtos o nome da imagem é modificado, como é esperado. Se eu modificar o nome do produto outra vez, o nome da imagem não é mais modificado, ou seja, só funciona uma vez.

está assim meu código

else {
            // Verifica se já tinha a imagem, e se mudou o nome
            if($produto->imagem && $produto->nome != $request->nome) {
                if(Storage::exists("produtos/{$produto->imagem}")) {
                    // Define o nome do novo arquivo
                    $newName = kebab_case($request->nome);
        
                    // Pega a extensão do arquivo antigo
                    $piecesOldName = explode('.'$produto->imagem);
                    $extension = end($piecesName);
        
                    // Define o novo nome do arquivo
                    $newNameImage = "{$newName}.{$extension}";;
                    $data['imagem'] = $newNameImage;
                    
                    // Renomeia o arquivo antigo
                      Storage::move("produtos/{$produto->imagem}""produtos/{$newNameImage}");
                }
            }
        }
Criador julioff 31/12/2019
julioff

p.s: no meu código eu uso o $dados = $request->all()

então mudei para $dados['imagem'] = $nemNameImage;  Mesmo assim sem sucesso.




Manager Carlos Ferreira 31/12/2019
Carlos Ferreira

Aqui um erro:
$piecesOldName = explode('.', $produto->imagem);
$extension = end($piecesName);

Deve ser:
$piecesOldName = explode('.', $produto->imagem);
$extension = end($piecesOldName);

 

Está entrando nesse if?
Faça um teste: dd('Aqui...');

Criador julioff 31/12/2019
julioff

Olá, professor...depois de quebrr muito a cabeça decidi fazer uma adaptação.  Salvar pelo id do produto, mas não da forma que fiz antes com o uniqid()
mas apenas com o id mesmo.

No banco fica assim.  A imagem do produto de ID 10, se chama imagem_10, fica visualmente melhor e sem poluição com "query bruta", fiz só com o eloquent. E no storage fica tudo certinho também. 

Acho que em um banco de milhares de registros fica até mais claro a imagem com o nome do id, pois se sabe exatamente onde encontra-la, ou será que estou equivocado ?

Bom é isso, obrigado pela paciência professor.

Aqui o link atualizado (tanto com o metodo store, quanto o update) pra caso algum colega queira dar uma olhada:  https://pastebin.com/Px5GjPx3

Criador julioff 31/12/2019
julioff

Vi agora sua última resposta, eu tinha visto aquele erro depois e corrigi tudo, também dei um dd() em cada variavel lá do else e tudo parecia ok, só não salvava no banco e nem mandava pro storage rsrs, mas cansei de quebrar a cabeça com isso. Se o senhor puder ver a nova adaptação que fiz (link na resposta anterior) eu te agradeço. Feliz ano novo!

Manager Carlos Ferreira 02/01/2020
Carlos Ferreira

Olá amigo!

O link atualizado é esse https://pastebin.com/Px5GjPx3 ?

O método update não tem a lógica de alterar o nome da imagem, caso atualize o nome do produto.

--------------------

Se não precisa de um trabalho de SEO, pode deixar a imagem até com o nome default que o Laravel cria:
$nameFilePath =  $request->imagem->store('produtos');
$dados['imagem'] = $nameFilePath;

Sabe a Solução? Ajude a resolver!

Precisa estar logado para conseguir responder a este ticket!

Clique Aqui Para Entrar!