JAMES WEB
Aprenda como se faz.
Produtos CRUD (Editar)
Na página denominada “Lista de Produtos” no painel administrativo, observa-se a presença do botão “Editar” em cada entrada de produto exibida. Ao acionar tal botão, o sistema redireciona o usuário para o endereço “/admin/products_get/:idproduct”, onde se possibilita a modificação dos dados pertinentes ao produto selecionado.

Editando um produto
Na página denominada “Lista de Produtos” no painel administrativo, observa-se a presença do botão “Editar” em cada entrada de produto exibida. Ao acionar tal botão, o sistema redireciona o usuário para o endereço “/admin/products_get/:idproduct”, onde se possibilita a modificação dos dados pertinentes ao produto selecionado.
PHP: admin-products.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php // inicio código... //Rota Editar Produtos- Template products-update.html $app ->get( '/admin/products_get/:idproduct' , function ( $idproduct ) { User::verifyLogin(); $product = new Product(); $product ->get((int) $idproduct ); $page = new PageAdmin(); $page ->setTpl( "products-update" , [ 'product' => $product ->getValues() ]); }); ?> |
Explicação linha por linha:
- L 5 – $app->get(‘/admin/products_get/:idproduct’, function($idproduct) {:
Define uma rota para lidar com requisições HTTP do tipo GET no caminho /admin/products_get/:idproduct.- $app->get(): Indica que esta é uma rota que responde a requisições GET.
- /admin/products_get/:idproduct: Define o padrão da URL.: idproduct é um parâmetro dinâmico, que captura o valor do ID do produto na URL.
- function($idproduct) { … }: Define uma função anônima que será executada quando a rota for acessada. O parâmetro $idproduct recebe o valor capturado do parâmetro dinâmico na URL.
- L 6 – User::verifyLogin();:
Chama o método estático verifyLogin() da classe User. Este método verifica se o usuário está autenticado e logado. Se o usuário não estiver logado, o método pode redirecioná-lo para a página de login ou exibir uma mensagem de erro. - L 7 – $product = new Product();:
Cria uma nova instância da classe Product e a atribui à variável $product. Esta instância representará o produto a ser editado. - L 8 – $product->get((int)$idproduct);:
Chama o método get() do objeto $product, passando o valor de $idproduct convertido para um inteiro. Este método recupera os dados do produto do banco de dados com base no ID fornecido. - L 9 – $page = new PageAdmin();:
Cria uma nova instância da classe PageAdmin e a atribui à variável $page. Esta instância será usada para renderizar a página de edição do produto. - L 10 – $page->setTpl(“products-update”, [:
Chama o método setTpl() do objeto $page. Este método define o template (arquivo HTML) a ser usado para renderizar a página e passa os dados a serem exibidos no template.- “products-update”: Especifica o nome do arquivo de template (provavelmente products-update.html).
- [: Inicia um array associativo que contém os dados a serem passados para o template.
- L 11 – ‘product’ => $product->getValues():
Define um elemento no array associativo.- ‘product’: A chave do elemento, que estará disponível no template.
- $product->getValues(): Chama o método getValues() do objeto $product, que retorna um array associativo contendo os dados do produto. Este array será passado para o template.
Método get()
Na linha 8, “$product->get((int)$idproduct);”, nos referimos ao método get(), que recupera os dados do produto do banco de dados com base no ID fornecido. Ele deve ser inserido na classe “Product” conforme exemplos a seguir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php // Início do código public function get( $idproduct ) { $sql = new Sql(); $results = $sql ->select( "SELECT * FROM tb_products WHERE idproduct = :idproduct" , [ ':idproduct' => $idproduct ]); $this ->setData( $results [0]); } // resto do código ?> |
A função get pega um idproduct, consulta o banco de dados para encontrar o produto correspondente e, em seguida, armazena os dados desse produto no objeto atual. É uma função essencial para recuperar informações de produtos em um sistema que utiliza um banco de dados.
Veja a explicação linha por linha
- L4 – public function get($idproduct)
- public: Este modificador de acesso indica que a função get pode ser chamada de qualquer lugar, seja dentro da classe ou fora dela. É como abrir as portas da sua casa para receber visitas.
- function get($idproduct): Aqui, definimos uma função chamada get. Esta função tem um propósito específico: recuperar informações de um produto. O parâmetro $idproduct é o identificador único do produto que desejamos buscar. É como o número de matrícula de um aluno, que o identifica individualmente.
- L5 – {
Abre o bloco de código que contém as instruções da função get. É o início do “corpo” da função. - L6 – $sql = new Sql();
Aqui, criamos uma instância da classe Sql. Imagine a classe Sql como uma caixa de ferramentas especializada em interagir com o banco de dados. Ao criar um novo objeto $sql, estamos pegando essa caixa de ferramentas e preparando-a para uso. - L7 – $results = $sql->select(“SELECT * FROM tb_products WHERE idproduct = :idproduct”, [ ‘:idproduct’ => $idproduct ]);
Esta é a linha crucial, onde a magia acontece.- $sql->select(…): Chamamos o método select do objeto $sql. Este método é responsável por executar consultas SQL no banco de dados.
- “SELECT * FROM tb_products WHERE idproduct = :idproduct”: Esta é a consulta SQL em si. Traduzindo para o português, seria algo como “Selecione todas as colunas (*) da tabela tb_products onde o idproduct é igual a um valor específico”. O :idproduct é um marcador de posição, um “buraco” que será preenchido com o valor real do idproduct.
- [‘:idproduct’ => $idproduct]: Este é o array que fornece o valor para o marcador de posição. Estamos dizendo: “Substitua :idproduct pelo valor da variável $idproduct”. Isso evita ataques de injeção de SQL, uma prática de segurança fundamental.
- $results = …: O resultado da consulta SQL é armazenado na variável $results. Este resultado é um array de linhas, onde cada linha representa um registro do banco de dados.
- L5 – $this->setData($results[0]); Aqui, assumimos que a consulta SQL retornou pelo menos uma linha (o produto com o idproduct especificado).
- $results[0]: Acessamos o primeiro elemento do array $results, que corresponde à primeira linha retornada pela consulta.
- $this->setData(…): Chamamos o método setData da própria classe. O $this refere-se ao objeto atual. Este método pega os dados do produto (a linha do banco de dados) e os armazena em propriedades do objeto, tornando-os acessíveis para outras partes do código.
- L11 – } Fecha o bloco de código da função get.
Função getValues()
Na linha 11 em “admin-produts.php” temos a função getValues() que deve ser reproduzida na Classe Product. Veja o exemplo a seguir:
1 2 3 4 5 6 7 8 9 10 11 12 | <?php // Início do código public function getValues() { $this ->checkPhoto(); $values = parent::getValues(); return $values ; } // resto do código ?> |
Veja a seguir a explicação linha por linha do código. Observe que a função verifica a existência de uma imagem para o produto cadastrado:
- L4 : public function getValues()
- public: Novamente, o modificador public indica que essa função pode ser chamada de qualquer lugar.
- function getValues(): Definimos uma função chamada getValues. O nome sugere que ela retorna um conjunto de valores, provavelmente as propriedades de um objeto.
- L5 : {
Abre o bloco de código da função. - L6 : $this->checkPhoto();
Esta linha chama o método checkPhoto() dentro do objeto atual (representado por $this). CheckPhoto() realiza uma verificação se um arquivo de foto existe. Se sim ele retorna uma foto relacionada ao produto, se não retorna uma imagem padrão. - L7 : $values = parent::getValues();
Aqui, estamos chamando o método getValues() da classe pai (superclasse) do objeto atual. Isso sugere que a classe atual herda de outra classe que já possui um método getValues(). A classe pai define um conjunto básico de valores que são comuns a todas as classes filhas. O resultado desse método é armazenado na variável $values. Em outras palavras, ele busca os valores da classe pai, e armazena eles na variavel $values. - L8 : return $values;
Finalmente, a função retorna o valor armazenado em $values. Este valor contém os valores obtidos da classe pai. - L9 : }
Fecha o bloco de código da função.
Tratando as imagens dos produtos
A ausência de imagem no cadastro de produtos é permitida. A função checkPhoto() lida com essa eventualidade, exibindo um placeholder (painel cinza) quando necessário. Para permitir o upload de imagens personalizadas, o campo ‘Foto’ inclui o botão ‘Escolher Ficheiro’. Este processa e exibe imagens selecionadas localmente. Para implementar essa funcionalidade, insira os códigos abaixo na classe Products em Products.php.
Função checkPhoto()
Dentro do diretório ‘res/site/img/products/’, a função checkPhoto() busca uma imagem relacionada ao ID do produto. Se a busca falhar, uma imagem padrão é utilizada. O caminho da imagem resultante (armazenado na variável $url) é então definido como a foto do produto, através do método setdesphoto($url).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php // Início do código public function checkPhoto() { if ( file_exists ( $_SERVER [ 'DOCUMENT_ROOT' ] . DIRECTORY_SEPARATOR . "ecommerce" . DIRECTORY_SEPARATOR . "res" . DIRECTORY_SEPARATOR . "site" . DIRECTORY_SEPARATOR . "img" . DIRECTORY_SEPARATOR . "products" . DIRECTORY_SEPARATOR . $this ->getidproduct() . ".jpg" )) { $url = "/ecommerce/res/site/img/products/" . $this ->getidproduct() . ".jpg" ; } else { $url = "/ecommerce/res/site/img/product.jpg" ; } return $this ->setdesphoto( $url ); } // resto do código ?> |
Veja a explicação linha por linha do código:
- L4 : public function checkPhoto()
- public: Indica que a função checkPhoto() pode ser chamada de qualquer lugar, dentro ou fora da classe.
- function checkPhoto(): Define a função checkPhoto(), cujo propósito é verificar e definir a foto de um produto.
- L5 : {
Abre o bloco de código que contém as instruções da função. - L6 : if (file_exists(
Inicia uma estrutura condicional if. A função file_exists() verifica se um arquivo ou diretório existe. - L7 : $_SERVER[‘DOCUMENT_ROOT’] . DIRECTORY_SEPARATOR .
- $_SERVER[‘DOCUMENT_ROOT’]: Obtém o caminho absoluto do diretório raiz do servidor web.
- DIRECTORY_SEPARATOR: Constante que representa o separador de diretórios do sistema operacional (por exemplo, “/” em Linux/macOS e “” em Windows). Isso garante que o código seja compatível com diferentes sistemas.
- .: O operador de concatenação em PHP, que une as strings.
- L8 : “ecommerce” . DIRECTORY_SEPARATOR .
Adiciona o diretório “ecommerce” ao caminho. - L9 : “res” . DIRECTORY_SEPARATOR .
Adiciona o diretório “res” (recursos) ao caminho. - L10 : “site” . DIRECTORY_SEPARATOR .
Adiciona o diretório “site” ao caminho. - L10 : “img” . DIRECTORY_SEPARATOR .
Adiciona o diretório “img” (imagens) ao caminho. - L10 : “products” . DIRECTORY_SEPARATOR .
Adiciona o diretório “products” ao caminho. - L10 : $this->getidproduct() . “.jpg”
Chama o método getidproduct() do objeto atual ($this), que provavelmente retorna o ID do produto. “.jpg”: Concatena a extensão “.jpg” ao ID do produto, formando o nome completo do arquivo da imagem. - L15 : $url = “/ecommerce/res/site/img/products/” . $this->getidproduct() . “.jpg”;
Se o arquivo existir, constrói a URL da imagem com base no ID do produto. Essa URL será usada para exibir a imagem. - L16 : Linha 14: } else {
Inicia o bloco else, que será executado se o arquivo não existir. - L17 : $url = “/ecommerce/res/site/img/product.jpg”;
Se o arquivo não existir, define a URL para a imagem padrão “product.jpg”. - L18 : }
Fecha o bloco else. - L19 : return $this->setdesphoto($url);
Chama o método setdesphoto() do objeto atual, passando a URL da imagem ($url) como argumento. Esse método Retorna o resultado da chamada de setdesphoto(). - L20 : }
Fecha o bloco de código da função checkPhoto().
Persistência de Dados do Produto Editado
Após a modificação dos dados do produto, a etapa subsequente é a persistência dessas alterações. Isso é alcançado através do envio de uma requisição HTTP do tipo POST para o endpoint /admin/products/:idproduct. O :idproduct representa um parâmetro dinâmico, substituído pelo identificador único do produto em questão.
A implementação dessa funcionalidade requer a inserção do seguinte trecho de código no arquivo admin_products.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php /// início do código //Rota Salvar Edição Produtos- Template products-update.html $app ->post( '/admin/products_post/:idproduct' , function ( $idproduct ) { User::verifyLogin(); $product = new Product(); $product ->get((int) $idproduct ); $product ->setTpl( $_POST ); $product ->save(); $product ->setPhoto( $_FILES [ "file" ]); header( "Location: /ecommerce/admin/products" ); exit ; }); // restodo código ?> |
Veja a explicação linha por linha:
- L5: $app->post(‘/admin/products_post/:idproduct’, function($idproduct) {
Esta linha inicia a definição de uma rota no aplicativo web.- $app->post(): indica que esta rota responde a requisições HTTP do tipo POST. Este tipo de requisição é comumente usado para enviar dados para o servidor, como em formulários de envio.
- ‘/admin/products_post/:idproduct’: define o caminho da rota. :idproduct é um parâmetro dinâmico, ou seja, pode variar dependendo do ID do produto que está sendo processado.
- function($idproduct) {: inicia uma função anônima que será executada quando a rota for acessada. $idproduct é o parâmetro que recebe o valor dinâmico do ID do produto.
- L6: User::verifyLogin();
Esta linha chama um método estático verifyLogin() da classe User. Este método tem a responsabilidade de verificar se o usuário está autenticado e tem permissão para acessar esta rota. Trata-se de uma medida de segurança essencial para proteger áreas administrativas do sistema. - L7: $product = new Product();
Aqui, um novo objeto da classe Product é instanciado. A classe Product representa um produto no sistema e contém os atributos e métodos necessários para manipular os dados do produto. - L8: $product->get((int)$idproduct);
Este trecho chama o método get() do objeto $product, passando o $idproduct como argumento. O (int) garante que o $idproduct seja convertido para um número inteiro, prevenindo erros. O método get() recupera os dados do produto correspondente ao $idproduct do banco de dados e os armazena no objeto $product. - L9: $product->setTpl($_POST);
O método setTpl() do objeto $product é chamado, passando o array $_POST como argumento. $_POST contém os dados enviados pelo formulário na requisição POST. setTpl() atualiza os atributos do objeto $product com os valores recebidos do formulário. - L10: $product->save();
Este trecho invoca o método save() do objeto $product. save() persiste as alterações feitas no objeto $product no banco de dados. - L11: $product->setPhoto($_FILES[“file”]);
O método setPhoto() do objeto $product é chamado, passando o array $_FILES[“file”] como argumento.$_FILES[“file”] contém os dados do arquivo enviado pelo usuário, neste caso, uma foto. O método setPhoto() processa o arquivo e o associa ao produto. - L12:header(“Location: /ecommerce/admin/products”);
Esta linha redireciona o usuário para a página /ecommerce/admin/products. Após o processamento dos dados do produto, o usuário é redirecionado para a lista de produtos. - L13: exit;
A função exit encerra a execução do script. Esta linha garante que nenhum código adicional seja executado após o redirecionamento.
Função ‘setPhoto()’
PHP: Product.php (função setPhoto)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?php /// início do código public function setPhoto( $file ) { $extension = explode ( '.' , $file [ 'name' ]); $extension = end ( $extension ); switch ( $extension ) { case "jpg" : case "jpeg" : $image = imagecreatefromjpeg( $file [ "tmp_name" ]); break ; case "gif" : $image = imagecreatefromgif( $file [ "tmp_name" ]); break ; case "png" : $image = imagecreatefrompng( $file [ "tmp_name" ]); break ; } $dest = $_SERVER [ 'DOCUMENT_ROOT' ] . DIRECTORY_SEPARATOR . "ecommerce" . DIRECTORY_SEPARATOR . "res" . DIRECTORY_SEPARATOR . "site" . DIRECTORY_SEPARATOR . "img" . DIRECTORY_SEPARATOR . "products" . DIRECTORY_SEPARATOR . $this ->getidproduct() . ".jpg" ; imagejpeg( $image , $dest ); imagedestroy( $image ); $this ->checkPhoto(); } // restodo código ?> |
Veja a explicação do código linha por linha:
- L4: public function setPhoto($file)
Esta linha define uma função pública chamada setPhoto que recebe um parâmetro $file. O parâmetro $file espera receber um array associativo contendo informações sobre o arquivo enviado pelo usuário, tipicamente o array $_FILES associado a um campo de upload de arquivo. - L5: {
Início do bloco de código da função. - L6: $extension = explode(‘.’, $file[‘name’]);
Esta linha utiliza a função explode() para dividir o nome do arquivo em um array de strings, usando o ponto (.) como delimitador. O resultado é armazenado na variável $extension. Esta operação visa extrair a extensão do arquivo. - L7: $extension = end($extension);
A função end() é usada para obter o último elemento do array $extension, que corresponde à extensão do arquivo. O valor da extensão é então sobrescrito na variável $extension. - L8: switch ($extension) {
Esta linha inicia uma estrutura de controle switch que verifica o valor da variável $extension. - L9-L11: case “jpg”: case “jpeg”: $image = imagecreatefromjpeg($file[“tmp_name”]); break;
Este bloco case lida com arquivos de imagem JPEG. Se a extensão for “jpg” ou “jpeg”, a função imagecreatefromjpeg() é chamada para criar uma imagem a partir do arquivo temporário ($file[“tmp_name”]). O resultado é armazenado na variável $image. break; encerra a execução do switch. - L12-L14: case “gif”: $image = imagecreatefromgif($file[“tmp_name”]); break;
Este bloco case lida com arquivos de imagem GIF. Se a extensão for “gif”, a função imagecreatefromgif() é chamada para criar uma imagem a partir do arquivo temporário. O resultado é armazenado na variável $image.break; encerra a execução do switch. - L15-L17: case “png”: $image = imagecreatefrompng($file[“tmp_name”]); break;
Este bloco case lida com arquivos de imagem PNG. Se a extensão for “png”, a função imagecreatefrompng() é chamada para criar uma imagem a partir do arquivo temporário. O resultado é armazenado na variável $image.break; encerra a execução do switch. - L19-L25: $dest = $_SERVER[‘DOCUMENT_ROOT’] . DIRECTORY_SEPARATOR . “ecommerce” . DIRECTORY_SEPARATOR . “res” . DIRECTORY_SEPARATOR . “site” . DIRECTORY_SEPARATOR . “img” . DIRECTORY_SEPARATOR . “products” . DIRECTORY_SEPARATOR . $this->getidproduct() . “.jpg”; 1
Esta linha constrói o caminho completo para o arquivo de destino onde a imagem será salva.- $_SERVER[‘DOCUMENT_ROOT’]: obtém o diretório raiz do servidor web.
- DIRECTORY_SEPARATOR: garante a compatibilidade entre diferentes sistemas operacionais. A string concatena os diversos diretórios, e também o id do produto, obtido através do método $this->getidproduct(), e finaliza o nome do arquivo com a extensão “.jpg”.
- L26: imagejpeg($image, $dest);
Esta linha utiliza a função imagejpeg() para salvar a imagem criada anteriormente ($image) no caminho de destino ($dest). A imagem é salva no formato JPEG. - L27: imagedestroy($image);
A função imagedestroy() é chamada para liberar a memória utilizada pela imagem criada. Isso é importante para evitar o consumo excessivo de recursos do servidor. - L28: $this->checkPhoto();
Esta linha chama o método checkPhoto() do objeto atual ($this). Este método verifica se a foto foi salva com sucesso e pode realizar outras operações relacionadas à foto do produto. - L29: }
Fim do bloco de código da função.
Para Saber Mais…
- Função ‘verifyLogin’
- Função ‘setData’
- Função ‘save’
- Método ‘setTpl’
- Array
- Função file_exists()
- Função explode()
- Função end()
- Função imagejpeg()
- Função imagecreatefromjpeg()
- Função imagecreatefromgif()
- Função imagecreatefrompng()
- Função imagedestroy()