Sistema administrativo desenvolvido com programação estrutural em PHP
Tags: php, web
Published: 2023-09-04 17:34:59

## Introdução

A um tempo atras eu publiquei no meu LinkedIn falando que começaria um novo projeto onde eu pegaria um sistema feito no meu TCC e começaria 100% do 0 com o PHP, porém dessa vez começaria o projeto da forma mais amadora possível e aos poucos iria profissionalizando o projeto utilizando os recursos do PHP e desenvolvendo o PHP do jeito certo. E faria alguns posts por aqui documentando o projeto.
E nesse post irei mostrar como eu fiz utilizando apenas a programação estrutural do PHP, sem autoload, PSRs, composer, orientação a objetos e etc...


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77s897xvsbprsxokusj7.png)

## Sobre o projeto

Mas antes de mostrar como foi feito vamos falar sobre o sistema.

O sistema é basicamente um sistema de gerenciamento de quiosque, onde ele tem a parte administrativa e o app de fato. O app tem como objetivo auxiliar as atividades do garçom e da cozinha. Então o garçom poderá através do app selecionar a mesa que o cliente está, e criar um pedido e adicionar os produtos no pedido, ao adicionar o pedido ele irá diretamente para o histórico de pedidos, que a cozinha irá acompanhar e quando finalizar o pedido irá atualizar automaticamente no estoque a quantidade que tem daquele produto.

Já na parte administrativa o usuário poderá criar as mesas e colocar uma numeração, cadastrar os funcionários que trabalham no quiosque e cadastrar os produtos. Um sistema bem simples, porém que tem o objetivo de ajudar a gerenciar um quiosque com mais facilidade.

Obs: nesse post irei mostrar apenas a parte administrativa desenvolvido e nos próximos irei mostrar como foi feito o app.

## Sistema de login

Primeiro começarei mostrando como foi realizado o sistema de login.

### Cadastro do usuário

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohdyp1wx34bryaoa87zt.png)

Bom na parte do cadastro, como vocês podem ver na imagem, teremos esses campos.

Então para fazer os cadastro do usuário no sistema, criei um arquivo .php e comecei nele trazendo as configurações para fazer a conexão com o banco de dados.

```
<?php

define('DB_SERVER', '');
define('DB_USERNAME', '');
define('DB_PASSWORD', '');
define('DB_NAME', '');
 
try {
    $pdo = new PDO("mysql:host=" . DB_SERVER . ";dbname=" . DB_NAME, DB_USERNAME, DB_PASSWORD);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
    die("ERROR: Não foi possível conectar." . $e->getMessage());
}
```

Esse é o conteúdo do arquivo de configurações e ele será requirido em todos os meus arquivos .php que faz a conexão com o banco de dados, nesse caso se eu tivesse utilizando o autoload não seria necessário, eu colocaria esse arquivo no composer.json e iria fazer automaticamente, mas como disse, irei evoluindo o projeto ao longo dos posts.

Depois disso faço uma verificação se o method request é um POST e armazeno os dados que o usuário preenche nas variáveis.

```
if ($_SERVER["REQUEST_METHOD"] == "POST") {

    // limpa o input
    $name = htmlspecialchars($_POST["name"]);
    $phone = htmlspecialchars($_POST["phone"]);
    $username = htmlspecialchars($_POST["username"]);
    $accessLevel = htmlspecialchars($_POST["access_level"]);
    $email = htmlspecialchars($_POST["email"]);
    $password = htmlspecialchars($_POST["password"]);
    $confirmPassword = htmlspecialchars($_POST["confirm_password"]);

    // variaveis de erro
    $errors = [];
```

Após isso, faço algumas verificação em algumas variáveis para verificar se por exemplo, se os campos está vazio, ou se o campo está com a formatação correta, ou no caso do username, email e senha se ele já está em uso. Segue o exemplo de um dos campos abaixo.

```
// Validar nome de usuário
    if (empty($username)) {
        $errors[] = "Por favor coloque um nome de usuário.";
    } elseif (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
        $errors[] = "O nome de usuário pode conter apenas letras, números e sublinhados.";
    } else {

        // Prepare uma declaração selecionada
        $sql = "SELECT id FROM users WHERE user = :user";
        
        if ($stmt = $pdo->prepare($sql)) {
            // Vincule as variáveis à instrução preparada como parâmetros
            $stmt->bindParam(":user", $username, PDO::PARAM_STR);
            
            // Tente executar a declaração preparada
            if ($stmt->execute()) {
                if ($stmt->rowCount() == 1) {
                    $errors[] = "Este nome de usuário já está em uso.";
                }
            } else {
                echo "Ops! Algo deu errado. Por favor, tente novamente mais tarde.";
            }

            // Fechar declaração
            unset($stmt);
        }
    }
```

E caso alguma verificação de falso, salvo na variável de errors, após essas verificações verifico essa variável de errors que nesse caso fiz como um array, e se estiver vazio dou continuidade, fazendo assim de fato o cadastro do usuário.

```
// Verifique os erros de entrada antes de inserir no banco de dados
    if (empty($errors)) {
        
        // Prepare uma declaração de inserção
        $sql = "INSERT INTO users (name, phone, email, password, user, access_level) VALUES (:name, :phone, :email, :password, :user, :access_level)";

        $password = password_hash($password, PASSWORD_DEFAULT);
         
        if($stmt = $pdo->prepare($sql)){
            // Vincule as variáveis à instrução preparada como parâmetros
            $stmt->bindParam(":name", $name, PDO::PARAM_STR);
            $stmt->bindParam(":phone", $phone, PDO::PARAM_STR);
            $stmt->bindParam(":email", $email, PDO::PARAM_STR);
            $stmt->bindParam(":password", $password, PDO::PARAM_STR);
            $stmt->bindParam(":user", $username, PDO::PARAM_STR);
            $stmt->bindParam(":access_level", $accessLevel, PDO::PARAM_STR);

            // Tente executar a declaração preparada
            if ($stmt->execute()) {
                //Redirecionar para a página de login
                header("location: ../../src/index.html");
            } else {
                echo "Ops! Algo deu errado. Por favor, tente novamente mais tarde.";
            }

            // Fechar declaração
            unset($stmt);
        }
    }
    
    // Fechar conexão
    unset($pdo);
}
```

### Login


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r39c7cxiufk8zf3xn7bg.png)

Com o usuário cadastrado partiremos para o arquivo que faz algumas verificações e se tudo estiver certo fazendo o login no sistema.

Antes de tudo, inicio a sessão de variáveis globais e verifico se já existe a variável global de login como true, caso esteja true será redirecionado automaticamente para dentro do sistema.

```
// Inicialize a sessão
session_start();
 
// Verifique se o usuário já está logado, em caso afirmativo, redirecione-o para a página de boas-vindas
if (isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true) {
    header("location: ../../src/widgets/tables/tables.php");
    exit;
}
```

Após isso, faz algo bem parecido com o de registro, verifica o method request, captura os dados do input e salva na variável, verifica se eles estão vazios, caso esteja preenche o erro na variável de errors, depois verifica a variável, e se estiver vazio consulta o usuário e verifica se a senha está correto e se o usuário é um administrador(já que só o administrador tem permissão de entrar) e caso esteja, realiza o login e cria a variável global de login deixando como true.

```
// Processando dados do formulário quando o formulário é enviado
if ($_SERVER["REQUEST_METHOD"] == "POST") {

    // limpa o input
    $username = htmlspecialchars($_POST["username"]);
    $password = htmlspecialchars($_POST["password"]);

    $errors = [];
 
    // Verifique se o nome de usuário está vazio
    if (empty($username)) {
        $errors[] = "Por favor, insira o nome de usuário.";
    }
    
    // Verifique se a senha está vazia
    if (empty($password)) {
        $errors[] = "Por favor, insira sua senha.";
    }
    
    // Validar credenciais
    if (empty($errors)) {

        // Prepare uma declaração selecionada
        $sql = "SELECT id, user, password, access_level FROM users WHERE user = :user";
        
        if ($stmt = $pdo->prepare($sql)) {

            // Vincule as variáveis à instrução preparada como parâmetros
            $stmt->bindParam(":user", $username, PDO::PARAM_STR);
            
            // Tente executar a declaração preparada
            if ($stmt->execute()) {

                // Verifique se o nome de usuário existe, se sim, verifique a senha
                if ($stmt->rowCount() == 1) {

                    if ($row = $stmt->fetch()) {
                        $id = $row["id"];
                        $username = $row["user"];
                        $hashed_password = $row["password"];
                        $accessLevel = $row["access_level"];

                        if (password_verify($password, $hashed_password) && $accessLevel == "administrador") {

                            // A senha está correta, então inicie uma nova sessão
                            session_start();
                            
                            // Armazene dados em variáveis de sessão
                            $_SESSION["loggedin"] = true;
                            $_SESSION["id"] = $id;
                            $_SESSION["username"] = $username;                            
                            
                            // Redirecionar o usuário para a página de boas-vindas
                            header("location: ../../src/widgets/tables/tables.php");
                        } else {
                            // A senha não é válida, exibe uma mensagem de erro genérica
                            $errors[] = "Nome de usuário ou senha ou nivel de acesso inválidos.";
                        }
                    }
                } else {
                    // O nome de usuário não existe, exibe uma mensagem de erro genérica
                    $errors[] = "Nome de usuário ou senha inválidos.";
                }
            } else{
                echo "Ops! Algo deu errado. Por favor, tente novamente mais tarde.";
            }

            // Fechar declaração
            unset($stmt);
        }
    }
    
    // Fechar conexão
    unset($pdo);
}
```

### Logout

E por ultimo mostrarei o arquivo de logout, onde basicamente ele destrói todas as variáveis globais e redireciona para o login.

```
<?php
// Inicialize a sessão
session_start();
 
// Remova todas as variáveis de sessão
$_SESSION = array();
 
// Destrua a sessão.
session_destroy();
 
// Redirecionar para a página de login
header("location: ../../src/index.html");
exit;
```

## Conclusão

Bom esse basicamente foi um sistema de login feito apenas com o PHP utilizando a programação estrutural e o PDO. além do login fiz o crud básico de cadastro das mesas, listagens dos usuários e edição, e crud dos produtos, pórem como os arquivos basicamente eram bem parecidos com o que mostrei no sistema de login, apenas mudando as tabelas, os campos e claro o tipo de consulta, decide não colocar para não ficar muito grande o post(mais do que já está haha), mas caso queiram que eu faça um post mostrando o CRUD também, deixem nos comentários e também claro, sugestões, correções e etc...

Nos próximos post, mostrarei o projeto agora com algumas melhorias como por exemplo ele feito orientado a objeto e autoload/psr-4.