├── .babelrc ├── .env-example ├── .gitignore ├── Readme.md ├── app ├── controllers │ ├── Contact.php │ ├── Home.php │ ├── Login.php │ ├── Maintenance.php │ ├── Password.php │ ├── User.php │ ├── UserImage.php │ └── Users.php ├── core │ └── controller.php ├── database │ ├── connect.php │ ├── no-query-builder │ │ ├── create.php │ │ ├── delete.php │ │ ├── read.php │ │ └── update.php │ ├── queries.php │ └── query-builder │ │ ├── execute.php │ │ ├── join.php │ │ ├── limit.php │ │ ├── order.php │ │ ├── paginate.php │ │ ├── read.php │ │ ├── search.php │ │ └── where.php ├── helpers │ ├── constants.php │ ├── csrf.php │ ├── email.php │ ├── flash.php │ ├── helpers.php │ ├── image.php │ ├── old.php │ ├── redirect.php │ ├── sessions.php │ ├── validate.php │ └── validations.php ├── router │ ├── router.php │ └── routes.php └── views │ ├── contact.php │ ├── create.php │ ├── edit.php │ ├── emails │ ├── contact.html │ └── password.html │ ├── home.php │ ├── login.php │ ├── maintenance.php │ ├── master.php │ └── partials │ └── header.php ├── composer.json ├── composer.lock ├── package-lock.json ├── package.json ├── public ├── .DS_Store ├── app.js ├── app.js.map ├── assets │ ├── .DS_Store │ ├── css │ │ └── styles.css │ └── js │ │ ├── alpine-components │ │ └── users.js │ │ ├── app.js │ │ ├── http.js │ │ ├── teste.js │ │ └── users.js ├── bootstrap.php ├── index.php └── maintenance.php └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.env-example: -------------------------------------------------------------------------------- 1 | MAINTENANCE= 2 | PRODUCTION= 3 | 4 | DATABASE_HOST= 5 | DATABASE_USER= 6 | DATABASE_PASSWORD= 7 | DATABASE_NAME= 8 | 9 | EMAIL_HOST= 10 | EMAIL_USERNAME= 11 | EMAIL_PASSWORD= 12 | EMAIL_PORT= 13 | 14 | TONAME= 15 | TOEMAIL= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .idea 3 | node_modules 4 | .DS_Store 5 | .env 6 | *.png 7 | *.jpeg 8 | *.jpg 9 | *.gif -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## Curso PHP Profissional do Clube Full-Stack 2 | 3 | ### 🚀 Links Importantes 4 | 5 | 1. [Youtube](https://www.youtube.com/c/AlexandreCardoso) 6 | 2. [Adquirir Curso](https://bit.ly/php-profissional-clube-fullstack) 7 | 8 | ### 🔥 Para rodar o projeto 9 | 10 | 1. composer install - Para instalar as dependências do composer 11 | 2. npm install - Para instalar as dependências do npm 12 | 3. php -S localhost:8000 - Para iniciar o servidor do php 13 | 4. npm run dev - Para rodar o webpack 14 | 5. Mudar o banco de dados no arquivo .env - Para mudar o bando de dados 15 | -------------------------------------------------------------------------------- /app/controllers/Contact.php: -------------------------------------------------------------------------------- 1 | 'contact', 13 | 'data' => ['title' => 'Contact',], 14 | ]; 15 | } 16 | 17 | public function store() 18 | { 19 | // $email = new stdClass(); 20 | // $email->fromName = 'Alexandre'; 21 | // $email->fromEmail = 'xandecar@hotmail.com'; 22 | // $email->toName = 'Joao'; 23 | // $email->toEmail = 'joao@email.com.br'; 24 | // $email->subject = 'teste de mensagem'; 25 | // $email->message = 'mensagem simples'; 26 | // $email->template = 'contact'; 27 | 28 | $validated = validate([ 29 | 'name' => 'required', 30 | 'email' => 'required|email', 31 | 'subject' => 'required', 32 | 'message' => 'required' 33 | ], persistInputs:true, checkCsrf:true); 34 | 35 | if (!$validated) { 36 | return redirect('/contact'); 37 | } 38 | 39 | $sent = send([ 40 | 'fromName' => $validated['name'], 41 | 'fromEmail' => $validated['email'], 42 | 'toName' => $_ENV['TONAME'], 43 | 'toEmail' => $_ENV['TOEMAIL'], 44 | 'subject' => $validated['subject'], 45 | 'message' => $validated['message'], 46 | 'template' => 'contact' 47 | ]); 48 | 49 | if ($sent) { 50 | return setMessageAndRedirect('contact_success', 'Enviado com sucesso', '/contact'); 51 | } 52 | return setMessageAndRedirect('contact_error', 'Ocorreu um erro ao enviar o email, tente novamente em alguns segundos', '/contact'); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/controllers/Home.php: -------------------------------------------------------------------------------- 1 | $search]); 15 | } 16 | 17 | paginate(5); 18 | 19 | // where('id', '<', 20); 20 | // whereIn('firstName', ['Alexandre','Prof. Lulu Ullrich','Loma Champlin']); 21 | 22 | // if ($search) { 23 | // search(['firstName' => $search,'lastName' => $search]); 24 | // } 25 | 26 | // limit(10); 27 | 28 | 29 | // select * from users where firstName like %alexandre% or lastName like %alexandre% or age 30 | 31 | $users = execute(); 32 | 33 | // dd($users); 34 | 35 | // dd($users); 36 | 37 | // dd($users); 38 | 39 | // select * from users order by id desc limit 10 offset 0 40 | 41 | // dd($users); 42 | 43 | return [ 44 | 'view' => 'home', 45 | 'data' => ['title' => 'Home', 'users' => $users,'links' => render()], 46 | ]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/controllers/Login.php: -------------------------------------------------------------------------------- 1 | 'login', 11 | 'data' => ['title' => 'Login'] 12 | ]; 13 | } 14 | 15 | public function store() 16 | { 17 | $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL); 18 | $password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING); 19 | 20 | if (empty($email) || empty($password)) { 21 | return setMessageAndRedirect('message', 'Usuário ou senha inválidos', '/login'); 22 | } 23 | 24 | // $user = findBy('users', 'email', $email); 25 | 26 | read('users', 'users.id,firstName,lastName,email,password,path'); 27 | tableJoin('photos', 'id', 'left'); 28 | where('email', $email); 29 | 30 | $user = execute(isFetchAll:false); 31 | 32 | // dd($user); 33 | 34 | if (!$user) { 35 | return setMessageAndRedirect('message', 'Usuário ou senha inválidos', '/login'); 36 | } 37 | 38 | if (!password_verify($password, $user->password)) { 39 | return setMessageAndRedirect('message', 'Usuário ou senha inválidos', '/login'); 40 | } 41 | 42 | unset($user->password); 43 | 44 | $_SESSION[LOGGED] = $user; 45 | 46 | return redirect('/'); 47 | } 48 | 49 | public function destroy() 50 | { 51 | unset($_SESSION[LOGGED]); 52 | 53 | return redirect('/'); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/controllers/Maintenance.php: -------------------------------------------------------------------------------- 1 | 'maintenance', 11 | 'data' => ['title' => 'Em manutenção'] 12 | ]; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/controllers/Password.php: -------------------------------------------------------------------------------- 1 | id) { 10 | return redirect('/'); 11 | } 12 | 13 | $validated = validate([ 14 | 'email' => 'required|confirmed', 15 | 'email_confirmation' => 'required' 16 | ], checkCsrf: true); 17 | 18 | 19 | if (!$validated) { 20 | return redirect('/user/edit/profile'); 21 | } 22 | 23 | dd($validated); 24 | $updated = update('users', [ 25 | 'password' => $validated['password'] 26 | ], ['id' => user()->id]); 27 | 28 | if ($updated) { 29 | $user = user(); 30 | send([ 31 | 'fromName' => 'Alexandre', 32 | 'fromEmail' => 'xandecar@hotmail.com', 33 | 'toName' => $user->firstName, 34 | 'toEmail' => $user->email, 35 | 'subject' => 'Senha alterada', 36 | 'message' => 'Senha alterada com sucesso', 37 | 'template' => 'password' 38 | ]); 39 | return setMessageAndRedirect('password_success', 'Senha alterada com sucesso', "/user/edit/profile"); 40 | } else { 41 | return setMessageAndRedirect('password_error', 'Ocorreu um erro ao atualizar a senha ', "/user/edit/profile"); 42 | } 43 | 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /app/controllers/User.php: -------------------------------------------------------------------------------- 1 | id); 27 | 28 | $user = execute(isFetchAll:false); 29 | 30 | return [ 31 | 'view' => 'edit', 32 | 'data' => ['title' => 'Edit','user' => $user] 33 | ]; 34 | } 35 | 36 | public function create():array 37 | { 38 | return [ 39 | 'view' => 'create', 40 | 'data' => ['title' => 'Create'] 41 | ]; 42 | } 43 | 44 | public function store() 45 | { 46 | $validate = validate([ 47 | 'firstName' => 'required', 48 | 'lastName' => 'required', 49 | 'email' => 'required|email|unique:users', 50 | 'password' => 'maxlen:5|required', 51 | ], persistInputs:true, checkCsrf:true); 52 | 53 | if (!$validate) { 54 | return redirect('/user/create'); 55 | } 56 | 57 | $validate['password'] = password_hash($validate['password'], PASSWORD_DEFAULT); 58 | 59 | $created = create('users', $validate); 60 | 61 | if (!$created) { 62 | setFlash('message', 'Ocorreu um erro ao cadastrar, tente novamente em alguns segundo'); 63 | return redirect('/user/create'); 64 | } 65 | 66 | return redirect('/'); 67 | } 68 | 69 | public function update($args) 70 | { 71 | if (!isset($args['user']) || $args['user'] !== user()->id) { 72 | return redirect('/'); 73 | } 74 | 75 | $validated = validate([ 76 | 'firstName' => 'required', 77 | 'lastName' => 'required', 78 | 'email' => 'required|email|uniqueUpdate:users,id='.$args['user'] 79 | ]); 80 | 81 | if (!$validated) { 82 | return redirect('/user/edit/profile'); 83 | } 84 | 85 | $updated = update('users', $validated, ['id' => user()->id]); 86 | 87 | if ($updated) { 88 | return setMessageAndRedirect('updated_success', 'Atualizado com sucesso', '/user/edit/profile'); 89 | } 90 | setMessageAndRedirect('updated_error', 'Ocorreu um erro ao atualizar', '/user/edit/profile'); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/controllers/UserImage.php: -------------------------------------------------------------------------------- 1 | id); 15 | 16 | $photoUser = execute(isFetchAll:false); 17 | 18 | if ($photoUser) { 19 | $updated = update('photos', [ 20 | 'path' => $path 21 | ], [ 22 | 'userId' => $auth->id 23 | ]); 24 | @unlink($photoUser->path); 25 | } else { 26 | $updated = create('photos', [ 27 | 'userId' => $auth->id, 28 | 'path' => $path 29 | ]); 30 | } 31 | 32 | if ($updated) { 33 | $auth->path = $path; 34 | setMessageAndRedirect('upload_success', 'Upload feito com sucesso', '/user/edit/profile'); 35 | return; 36 | } 37 | setMessageAndRedirect('upload_error', 'Ocorreu um erro ao fazer o upload', '/user/edit/profile'); 38 | } catch (\Exception $e) { 39 | setMessageAndRedirect('upload_error', $e->getMessage(), '/user/edit/profile'); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/controllers/Users.php: -------------------------------------------------------------------------------- 1 | $method($params); 20 | 21 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 22 | die(); 23 | } 24 | 25 | return $controller; 26 | } 27 | -------------------------------------------------------------------------------- /app/database/connect.php: -------------------------------------------------------------------------------- 1 | PDO::FETCH_OBJ 11 | ] 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /app/database/no-query-builder/create.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 17 | return $prepare->execute($data); 18 | } catch (PDOException $e) { 19 | var_dump($e->getMessage()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/database/no-query-builder/delete.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 17 | $prepare->execute($where); 18 | return $prepare->rowCount(); 19 | } 20 | -------------------------------------------------------------------------------- /app/database/no-query-builder/read.php: -------------------------------------------------------------------------------- 1 | query("select {$fields} from {$table}"); 9 | return $query->fetchAll(); 10 | } catch (PDOException $e) { 11 | var_dump($e->getMessage()); 12 | } 13 | } 14 | 15 | function findBy($table, $field, $value, $fields = '*') 16 | { 17 | try { 18 | $connect = connect(); 19 | $prepare = $connect->prepare("select {$fields} from {$table} where {$field} = :{$field}"); 20 | $prepare->execute([ 21 | $field => $value 22 | ]); 23 | 24 | return $prepare->fetch(); 25 | } catch (PDOException $e) { 26 | var_dump($e->getMessage()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/database/no-query-builder/update.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 25 | $prepare->execute($data); 26 | return $prepare->rowCount(); 27 | 28 | // dd($sql, $data); 29 | } 30 | -------------------------------------------------------------------------------- /app/database/queries.php: -------------------------------------------------------------------------------- 1 | prepare($query['sql']); 19 | $prepare->execute($query['execute'] ?? []); 20 | 21 | if ($rowCount) { 22 | $query['count'] = $prepare->rowCount(); 23 | return $query['count']; 24 | } 25 | 26 | if ($isFetchAll) { 27 | return (object)[ 28 | 'count' => $query['count'] ?? $prepare->rowCount(), 29 | 'rows' => $prepare->fetchAll() 30 | ]; 31 | } 32 | 33 | return $prepare->fetch(); 34 | } catch (Exception $e) { 35 | // $message = "Erro no arquivo {$e->getFile()} na linha {$e->getLine()} com a mensagem: {$e->getMessage()}"; 36 | // $message.= $query['sql']; 37 | $error = [ 38 | 'file' => $e->getFile(), 39 | 'line' => $e->getLine(), 40 | 'message' => $e->getMessage(), 41 | 'sql' => $query['sql'], 42 | ]; 43 | 44 | ddd($error); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/database/query-builder/join.php: -------------------------------------------------------------------------------- 1 | build(); 8 | $tableToSingular = $inflector->singularize($table); 9 | 10 | return $tableToSingular.ucfirst($field); 11 | } 12 | 13 | 14 | function tableJoin(string $table, string $fieldFK, string $typeJoin = 'inner') 15 | { 16 | global $query; 17 | 18 | if (isset($query['where'])) { 19 | throw new Exception("Nao posso colocar o where antes do join"); 20 | } 21 | 22 | $fkToJoin = fieldFK($query['table'], $fieldFK); 23 | 24 | $query['sql'] = "{$query['sql']} {$typeJoin} join {$table} on {$table}.{$fkToJoin} = {$query['table']}.{$fieldFK}"; 25 | } 26 | 27 | function tableJoinWithFK(string $table, string $fieldFK, string $typeJoin = 'inner') 28 | { 29 | global $query; 30 | 31 | if (isset($query['where'])) { 32 | throw new Exception("Nao posso colocar o where antes do join"); 33 | } 34 | 35 | $fkToJoin = fieldFK($table, $fieldFK); 36 | 37 | $query['sql'] = "{$query['sql']} {$typeJoin} join {$table} on {$table}.{$fieldFK} = {$query['table']}.{$fkToJoin}"; 38 | } 39 | -------------------------------------------------------------------------------- /app/database/query-builder/limit.php: -------------------------------------------------------------------------------- 1 | '; 39 | 40 | if ($currentPage > 1) { 41 | $previous = $currentPage - 1; 42 | $linkPage = http_build_query(array_merge($_GET, ['page' => $previous])); 43 | $first = http_build_query(array_merge($_GET, ['page' => 1])); 44 | $links.= "
  • Primeira
  • "; 45 | $links.= "
  • Anterior
  • "; 46 | } 47 | 48 | $class = ''; 49 | // 1 - 5 = -4 1 + 5 = 6 50 | // 7 - 5 = 2 . 7+5 = 12 51 | for ($i=$currentPage - $maxLinks; $i<=$currentPage + $maxLinks ; $i++) { 52 | // $page = "?page={$i}"; 53 | if ($i > 0 && $i <= $pageCount) { 54 | $class = $currentPage === $i ? 'active' : ''; 55 | $linkPage = http_build_query(array_merge($_GET, ['page' => $i])); 56 | $links.= "
  • {$i}
  • "; 57 | } 58 | } 59 | 60 | if ($currentPage < $pageCount) { 61 | $next = $currentPage + 1; 62 | $linkPage = http_build_query(array_merge($_GET, ['page' => $next])); 63 | $last = http_build_query(array_merge($_GET, ['page' => $pageCount])); 64 | $links.= "
  • Próxima
  • "; 65 | $links.= "
  • Última
  • "; 66 | } 67 | 68 | $links .= ''; 69 | 70 | return $links; 71 | } 72 | -------------------------------------------------------------------------------- /app/database/query-builder/read.php: -------------------------------------------------------------------------------- 1 | $searched) { 19 | $sql.= "{$field} like :{$field} or "; 20 | $execute[$field] = "%{$searched}%"; 21 | } 22 | 23 | $sql = rtrim($sql, ' or '); 24 | 25 | $query['sql'] = $sql; 26 | $query['execute'] = $execute; 27 | } 28 | -------------------------------------------------------------------------------- /app/database/query-builder/where.php: -------------------------------------------------------------------------------- 1 | 3) { 19 | throw new Exception('O where precisa de 2 ou 3 parâmetros'); 20 | } 21 | 22 | if ($numArgs === 2) { 23 | $field = $args[0]; 24 | $operator = '='; 25 | $value = $args[1]; 26 | } 27 | 28 | if ($numArgs === 3) { 29 | $field = $args[0]; 30 | $operator = $args[1]; 31 | $value = $args[2]; 32 | } 33 | 34 | $fieldWhere = $field; 35 | 36 | if (str_contains($field, '.')) { 37 | [, $fieldWhere] = explode('.', $field); 38 | } 39 | 40 | $query['where'] = true; 41 | $query['execute'] = array_merge($query['execute'], [$fieldWhere => $value]); 42 | $query['sql'] = "{$query['sql']} where {$field} {$operator} :{$fieldWhere}"; 43 | } 44 | 45 | 46 | function orWhere() 47 | { 48 | global $query; 49 | 50 | $args = func_get_args(); 51 | $numArgs = func_num_args(); 52 | 53 | 54 | if (!isset($query['read'])) { 55 | throw new Exception('Antes de chamar o where chame o read'); 56 | } 57 | 58 | if (!isset($query['where'])) { 59 | throw new Exception('Antes de chamar o orWhere chame o where'); 60 | } 61 | 62 | if ($numArgs < 2 || $numArgs > 4) { 63 | throw new Exception('O where precisa de 2 até 4 parâmetros'); 64 | } 65 | 66 | $data = match ($numArgs) { 67 | 2 => whereTwoParameters($args), 68 | 3 => whereThreeParameters($args), 69 | 4 => $args, 70 | }; 71 | 72 | [$field, $operator, $value, $typeWhere] = $data; 73 | 74 | // dd([$field => $value]); 75 | $query['where'] = true; 76 | $query['execute'] = array_merge($query['execute'], [$field => $value]); 77 | $query['sql'] = "{$query['sql']} {$typeWhere} {$field} {$operator} :{$field}"; 78 | } 79 | 80 | function whereTwoParameters(array $args): array 81 | { 82 | $field = $args[0]; 83 | $operator = '='; 84 | $value = $args[1]; 85 | $typeWhere = 'or'; 86 | 87 | return [$field,$operator,$value, $typeWhere]; 88 | } 89 | function whereThreeParameters(array $args): array 90 | { 91 | $operators = ['=','<','>','!==','<=','>=']; 92 | $field = $args[0]; 93 | $operator = in_array($args[1], $operators) ? $args[1] : '='; 94 | $value = in_array($args[1], $operators) ? $args[2] : $args[1]; 95 | $typeWhere = $args[2] === 'and' ? 'and' : 'or'; 96 | 97 | return [$field,$operator,$value, $typeWhere]; 98 | } 99 | 100 | function whereIn(string $field, array $data) 101 | { 102 | global $query; 103 | 104 | if (isset($query['where'])) { 105 | throw new Exception("Não poder ter chamado a função where com a função where in"); 106 | } 107 | 108 | $query['where'] = true; 109 | $query['sql'] = "{$query['sql']} where {$field} in (".'\''.implode('\',\'', $data).'\''.')'; 110 | } 111 | 112 | 113 | // function where(string $field, string $operator, string|int $value) 114 | // { 115 | // global $query; 116 | 117 | // if (!isset($query['read'])) { 118 | // throw new Exception('Antes de chamar o where chame o read'); 119 | // } 120 | 121 | // if (func_num_args() !== 3) { 122 | // throw new Exception('O where precisa de exatamente 3 parâmetros'); 123 | // } 124 | 125 | // $query['where'] = true; 126 | // $query['execute'] = array_merge($query['execute'], [$field => $value]); 127 | // $query['sql'] = "{$query['sql']} where {$field} {$operator} :{$field}"; 128 | // } 129 | 130 | // function orWhere(string $field, string $operator, string|int $value, string $typeWhere ='or') 131 | // { 132 | // global $query; 133 | 134 | // if (!isset($query['read'])) { 135 | // throw new Exception('Antes de chamar o where chame o read'); 136 | // } 137 | 138 | // if (!isset($query['where'])) { 139 | // throw new Exception('Antes de chamar o orWhere chame o where'); 140 | // } 141 | 142 | // if (func_num_args() < 3 or func_num_args() > 4) { 143 | // throw new Exception('O where precisa 3 ou 4 parâmetros'); 144 | // } 145 | 146 | // $query['where'] = true; 147 | // $query['execute'] = array_merge($query['execute'], [$field => $value]); 148 | // $query['sql'] = "{$query['sql']} {$typeWhere} {$field} {$operator} :{$field}"; 149 | // } 150 | -------------------------------------------------------------------------------- /app/helpers/constants.php: -------------------------------------------------------------------------------- 1 | "; 9 | } 10 | 11 | function checkCsrf() 12 | { 13 | $csrf = filter_input(INPUT_POST, 'csrf', FILTER_SANITIZE_STRING); 14 | 15 | if (!$csrf) { 16 | throw new Exception('Token inválido'); 17 | } 18 | 19 | if (!isset($_SESSION['csrf'])) { 20 | throw new Exception('Token inválido'); 21 | } 22 | 23 | if ($csrf !== $_SESSION['csrf']) { 24 | throw new Exception('Token inválido'); 25 | } 26 | 27 | unset($_SESSION['csrf']); 28 | } 29 | -------------------------------------------------------------------------------- /app/helpers/email.php: -------------------------------------------------------------------------------- 1 | isSMTP(); 9 | $phpmailer->Host = $_ENV['EMAIL_HOST']; 10 | $phpmailer->SMTPAuth = true; 11 | $phpmailer->Port = $_ENV['EMAIL_PORT']; 12 | $phpmailer->Username = $_ENV['EMAIL_USERNAME']; 13 | $phpmailer->Password = $_ENV['EMAIL_PASSWORD']; 14 | 15 | return $phpmailer; 16 | } 17 | 18 | function send(stdClass|array $emailData) 19 | { 20 | try { 21 | if (is_array($emailData)) { 22 | $emailData = (object) $emailData; 23 | } 24 | 25 | $body = (isset($emailData->template)) ? template($emailData) : $emailData->message; 26 | 27 | checkPropertiesEmail($emailData); 28 | 29 | $mail = config(); 30 | $mail->setFrom($emailData->fromEmail, $emailData->fromName); 31 | $mail->addAddress($emailData->toEmail, $emailData->toName); 32 | 33 | $mail->isHTML(true); 34 | $mail->CharSet = 'UTF-8'; 35 | $mail->Subject = $emailData->subject; 36 | $mail->Body = $body; 37 | $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; 38 | 39 | return $mail->send(); 40 | } catch (Exception $e) { 41 | dd($e->getMessage()); 42 | } 43 | } 44 | 45 | function checkPropertiesEmail($emailData) 46 | { 47 | $propertiesRequired = ['toName','toEmail','fromName','fromEmail','subject','message']; 48 | unset($emailData->template); 49 | 50 | $emailVars = get_object_vars($emailData); 51 | 52 | foreach ($propertiesRequired as $prop) { 53 | if (!array_key_exists($prop, $emailVars)) { 54 | throw new Exception("{$prop} é obrigatório para enviar o email"); 55 | } 56 | } 57 | } 58 | 59 | 60 | function template($emailData) 61 | { 62 | $templateFile = ROOT."/app/views/emails/{$emailData->template}.html"; 63 | 64 | if (!file_exists($templateFile)) { 65 | throw new Exception("O template {$emailData->template}.html não existe"); 66 | } 67 | 68 | $template = file_get_contents($templateFile); 69 | 70 | $emailVars = get_object_vars($emailData); 71 | 72 | $arr = array_map(function ($key) { 73 | return "@{$key}"; 74 | }, array_keys($emailVars)); 75 | 76 | // dd($arr); 77 | 78 | // $vars = []; 79 | 80 | // foreach ($emailVars as $key => $value) { 81 | // $vars["@{$key}"] = $value; 82 | // } 83 | 84 | return str_replace($arr, array_values($emailVars), $template); 85 | } 86 | -------------------------------------------------------------------------------- /app/helpers/flash.php: -------------------------------------------------------------------------------- 1 | $flash"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/helpers/helpers.php: -------------------------------------------------------------------------------- 1 | ['imagecreatefrompng', 'imagepng'], 12 | 'jpg', 'jpeg' => ['imagecreatefromjpeg', 'imagejpeg'], 13 | 'gif' => ['imagecreatefromgif', 'imagegif'], 14 | }; 15 | } 16 | 17 | function isFileToUpload($fieldName) 18 | { 19 | if (!isset($_FILES[$fieldName], $_FILES[$fieldName]['name']) || $_FILES[$fieldName]['name'] === '') { 20 | throw new Exception("O campo {$fieldName} não existe ou não foi escolhida uma imagem"); 21 | } 22 | } 23 | 24 | function isImage($extension) 25 | { 26 | $acceptedExtensions = ['jpeg', 'jpg', 'gif', 'png']; 27 | if (!in_array($extension, $acceptedExtensions)) { 28 | $extensions = implode(',', $acceptedExtensions); 29 | throw new Exception("O arquivo não é aceito, aceitamos somente {$extensions}"); 30 | } 31 | } 32 | 33 | function resize(int $width, int $height, int $newWidth, int $newHeight) 34 | { 35 | $ratio = $width / $height; 36 | 37 | ($newWidth / $newHeight > $ratio) ? 38 | $newWidth = $newHeight * $ratio : 39 | $newHeight = $newWidth / $ratio; 40 | 41 | return [$newWidth, $newHeight]; 42 | } 43 | 44 | function crop(int $width, int $height, int $newWidth, int $newHeight) 45 | { 46 | $thumbWidth = $newWidth; 47 | $thumbHeight = $newHeight; 48 | 49 | $srcAspect = $width / $height; 50 | $dstAspect = $thumbWidth / $thumbHeight; 51 | 52 | ($srcAspect >= $dstAspect) ? 53 | $newWidth = $width / ($height / $thumbHeight) : 54 | $newHeight = $height / ($width / $thumbWidth); 55 | 56 | return [$newWidth, $newHeight, $thumbWidth, $thumbHeight]; 57 | } 58 | 59 | function upload(int $newWidth, int $newHeight, string $folder, string $type = 'resize') 60 | { 61 | isFileToUpload('file'); 62 | 63 | $extension = getExtension($_FILES['file']['name']); 64 | 65 | isImage($extension); 66 | 67 | [$width, $height] = getimagesize($_FILES['file']['tmp_name']); 68 | 69 | [$functionCrateFrom, $saveImage] = getFunctionCreateFrom($extension); 70 | 71 | $src = $functionCrateFrom($_FILES['file']['tmp_name']); 72 | 73 | if ($type === 'resize') { 74 | [$newWidth, $newHeight] = resize($width, $height, $newWidth, $newHeight); 75 | $dst = imagecreatetruecolor($newWidth, $newHeight); 76 | imagecopyresampled($dst, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); 77 | } else { 78 | [$newWidth, $newHeight, $thumbWidth, $thumbHeight] = crop($width, $height, $newWidth, $newHeight); 79 | $dst = imagecreatetruecolor($thumbWidth, $thumbHeight); 80 | imagecopyresampled( 81 | $dst, 82 | $src, 83 | 0 - ($newWidth - $thumbWidth) / 2, 84 | 0 - ($newHeight - $thumbHeight) / 2, 85 | 0, 86 | 0, 87 | $newWidth, 88 | $newHeight, 89 | $width, 90 | $height 91 | ); 92 | } 93 | 94 | $path = $folder . DIRECTORY_SEPARATOR . rand() . '.' . $extension; 95 | 96 | $saveImage($dst, $path); 97 | 98 | return $path; 99 | } 100 | -------------------------------------------------------------------------------- /app/helpers/old.php: -------------------------------------------------------------------------------- 1 | $validate) { 12 | $result[$field] = (!str_contains($validate, '|')) ? 13 | singleValidation($validate, $field, $param) : 14 | multipleValidations($validate, $field, $param); 15 | } 16 | 17 | if ($persistInputs) { 18 | setOld(); 19 | } 20 | 21 | if (in_array(false, $result, true)) { 22 | return false; 23 | } 24 | 25 | return $result; 26 | } 27 | 28 | function singleValidation($validate, $field, $param) 29 | { 30 | if (str_contains($validate, ':')) { 31 | [$validate, $param] = explode(':', $validate); 32 | } 33 | return $validate($field, $param); 34 | } 35 | 36 | function multipleValidations($validate, $field, $param) 37 | { 38 | $explodePipeValidate = explode('|', $validate); 39 | $result = []; 40 | foreach ($explodePipeValidate as $validate) { 41 | if (str_contains($validate, ':')) { 42 | [$validate, $param] = explode(':', $validate); 43 | } 44 | 45 | $result[$field] = $validate($field, $param); 46 | 47 | if ($result[$field] === false || $result[$field] === null) { 48 | break; 49 | } 50 | } 51 | return $result[$field]; 52 | } 53 | -------------------------------------------------------------------------------- /app/helpers/validations.php: -------------------------------------------------------------------------------- 1 | $param) { 84 | setFlash($field, "Esse campo não pode passar de {$param} caracteres"); 85 | return false; 86 | } 87 | 88 | return $data; 89 | } 90 | 91 | function optional($field) 92 | { 93 | // $data = filter_input(INPUT_POST, $field, FILTER_SANITIZE_STRING); 94 | $data = strip_tags($_POST[$field]); 95 | 96 | if ($data === '') { 97 | return null; 98 | } 99 | 100 | return $data; 101 | } 102 | 103 | function confirmed($field){ 104 | 105 | if(!isset($_POST[$field], $_POST[$field.'_confirmation'])){ 106 | setFlash($field, "Os campos para atualizar a senha são obrigatórios"); 107 | return false; 108 | } 109 | 110 | $value = strip_tags($_POST[$field]); 111 | $value_confirmation = strip_tags($_POST[$field.'_confirmation']); 112 | 113 | if($value !== $value_confirmation){ 114 | setFlash($field, "Os dois campos tem que ser iguais"); 115 | return false; 116 | } 117 | 118 | if($field === 'password'){ 119 | return password_hash($value, PASSWORD_DEFAULT); 120 | } 121 | return $value; 122 | } -------------------------------------------------------------------------------- /app/router/router.php: -------------------------------------------------------------------------------- 1 | $routes[$uri]] : 8 | []; 9 | } 10 | 11 | function regularExpressionMatchArrayRoutes($uri, $routes) 12 | { 13 | return array_filter( 14 | $routes, 15 | function ($value) use ($uri) { 16 | $regex = str_replace('/', '\/', ltrim($value, '/')); 17 | return preg_match("/^$regex$/", ltrim($uri, '/')); 18 | }, 19 | ARRAY_FILTER_USE_KEY 20 | ); 21 | } 22 | 23 | function params($uri, $matchedUri) 24 | { 25 | if (!empty($matchedUri)) { 26 | $matchedToGetParams = array_keys($matchedUri)[0]; 27 | return array_diff( 28 | $uri, 29 | explode('/', ltrim($matchedToGetParams, '/')) 30 | ); 31 | } 32 | return []; 33 | } 34 | 35 | function paramsFormat($uri, $params) 36 | { 37 | $paramsData = []; 38 | foreach ($params as $index => $param) { 39 | $paramsData[$uri[$index - 1]] = $param; 40 | } 41 | 42 | return $paramsData; 43 | } 44 | 45 | 46 | function router() 47 | { 48 | $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); 49 | 50 | $routes = require 'routes.php'; 51 | $requestMethod = $_SERVER['REQUEST_METHOD']; 52 | 53 | $matchedUri = exactMatchUriInArrayRoutes($uri, $routes[$requestMethod]); 54 | 55 | $params = []; 56 | if (empty($matchedUri)) { 57 | $matchedUri = regularExpressionMatchArrayRoutes($uri, $routes[$requestMethod]); 58 | $uri = explode('/', ltrim($uri, '/')); 59 | $params = params($uri, $matchedUri); 60 | $params = paramsFormat($uri, $params); 61 | } 62 | 63 | if ($_ENV['MAINTENANCE'] === 'true') { 64 | $matchedUri = ['/maintenance' => 'Maintenance@index']; 65 | } 66 | 67 | // dd($matchedUri); 68 | 69 | 70 | if (!empty($matchedUri)) { 71 | return controller($matchedUri, $params); 72 | } 73 | 74 | 75 | throw new Exception('Algo deu errado'); 76 | } 77 | -------------------------------------------------------------------------------- /app/router/routes.php: -------------------------------------------------------------------------------- 1 | [ 5 | '/login' => 'Login@store', 6 | '/contact' => 'Contact@store', 7 | '/user/[0-9]+' => 'User@update', 8 | '/user/store' => 'User@store', 9 | '/user/image/update' => "UserImage@store", 10 | '/password/user/[0-9]+' => 'Password@update', 11 | ], 12 | 'GET' => [ 13 | '/' => 'Home@index', 14 | '/users' => 'Users@index', 15 | '/contact' => 'Contact@index', 16 | '/user/create' => 'User@create', 17 | '/user/edit/profile' => 'User@edit', 18 | '/user/[0-9]+' => 'User@show', 19 | '/login' => 'Login@index', 20 | '/logout' => 'Login@destroy', 21 | ] 22 | ]; 23 | -------------------------------------------------------------------------------- /app/views/contact.php: -------------------------------------------------------------------------------- 1 | layout('master', ['title' => $title]) ?> 2 | 3 |

    Contato

    4 | 5 | 6 | 7 | 8 |
    9 | 10 | 11 | 12 | 13 |
    14 | 15 |
    16 | 17 |
    18 | 19 | 20 |
    21 | 22 | 23 | 24 |
    25 | -------------------------------------------------------------------------------- /app/views/create.php: -------------------------------------------------------------------------------- 1 | layout('master', ['title' => $title]) ?> 2 | 3 |

    Create

    4 | 5 | 6 | 7 | 8 |
    9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 | 17 |
    18 | 19 | 20 |
    21 | 22 | 23 |
    24 | 25 |
    26 | -------------------------------------------------------------------------------- /app/views/edit.php: -------------------------------------------------------------------------------- 1 | layout('master', ['title' => $title]) ?> 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 | path) : ?> 33 | 34 | 35 | 36 |
    37 | 38 |
    39 | 40 | 41 |
    42 | 43 | 44 | 45 | 46 | 47 |
    48 | -------------------------------------------------------------------------------- /app/views/emails/contact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 | 15 | 16 |

    Você recebeu uma mensagem de @fromName

    17 | 18 |

    @message

    19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/views/emails/password.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Senha alterada 7 | 8 | 9 | 10 |

    Você recebeu uma mensagem de @fromName

    11 | 12 |

    @message

    13 | 14 |

    Caso não tenha sido você que tenha alterado a senha, entre em contato conosco.

    15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/views/home.php: -------------------------------------------------------------------------------- 1 | layout('master', ['title' => $title]) ?> 2 | 3 |

    Users count ?>

    4 | 5 |
    6 | 7 | 8 | 9 |
    10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/views/login.php: -------------------------------------------------------------------------------- 1 | layout('master', ['title' => $title]) ?> 2 | 3 | 4 |

    Login

    5 | 6 |
    7 | 8 | 9 | 10 |
    11 | 12 |

    Já está logado

    13 | -------------------------------------------------------------------------------- /app/views/maintenance.php: -------------------------------------------------------------------------------- 1 | layout('master', ['title' => $title]); ?> 2 | 3 | 4 | start('styles') ?> 5 | 6 | stop() ?> 7 | 8 |

    Em manutenção

    -------------------------------------------------------------------------------- /app/views/master.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <?php echo $this->e($title) ?> 7 | 8 | 9 | section('styles')?> 10 | 11 | 12 | 13 | 16 |
    17 | section('content')?> 18 |
    19 | 20 | section('scripts')?> 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/views/partials/header.php: -------------------------------------------------------------------------------- 1 | 8 | 9 |
    10 | Bem vindo, 11 | 12 | path) : ?> 13 | 14 | 15 | 16 | firstName; ?> | Logout | 17 | Edit profile 18 | 19 | visitante 20 | 21 |
    22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alexandreeduardocardoso/php-pro", 3 | "description": "php-profissional", 4 | "authors": [ 5 | { 6 | "name": "Alexandre Cardoso", 7 | "email": "alecar2007@gmail.com" 8 | } 9 | ], 10 | "require": { 11 | "symfony/var-dumper": "^5.3", 12 | "league/plates": "^3.4", 13 | "vlucas/phpdotenv": "^5.3", 14 | "doctrine/inflector": "^2.0", 15 | "phpmailer/phpmailer": "^6.5", 16 | "ext-pdo": "*" 17 | }, 18 | "autoload": { 19 | "files": [ 20 | "app/helpers/constants.php", 21 | "app/router/router.php", 22 | "app/core/controller.php", 23 | "app/database/connect.php", 24 | "app/database/queries.php", 25 | "app/helpers/redirect.php", 26 | "app/helpers/flash.php", 27 | "app/helpers/sessions.php", 28 | "app/helpers/validate.php", 29 | "app/helpers/validations.php", 30 | "app/helpers/helpers.php", 31 | "app/helpers/old.php", 32 | "app/helpers/csrf.php", 33 | "app/helpers/email.php", 34 | "app/helpers/image.php" 35 | ], 36 | "psr-4": { 37 | "app\\":"app" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "ef43146c8b326a53a2dfb453f8a49114", 8 | "packages": [ 9 | { 10 | "name": "doctrine/inflector", 11 | "version": "2.0.3", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/inflector.git", 15 | "reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/9cf661f4eb38f7c881cac67c75ea9b00bf97b210", 20 | "reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^7.2 || ^8.0" 25 | }, 26 | "require-dev": { 27 | "doctrine/coding-standard": "^7.0", 28 | "phpstan/phpstan": "^0.11", 29 | "phpstan/phpstan-phpunit": "^0.11", 30 | "phpstan/phpstan-strict-rules": "^0.11", 31 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" 32 | }, 33 | "type": "library", 34 | "extra": { 35 | "branch-alias": { 36 | "dev-master": "2.0.x-dev" 37 | } 38 | }, 39 | "autoload": { 40 | "psr-4": { 41 | "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" 42 | } 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "MIT" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Guilherme Blanco", 51 | "email": "guilhermeblanco@gmail.com" 52 | }, 53 | { 54 | "name": "Roman Borschel", 55 | "email": "roman@code-factory.org" 56 | }, 57 | { 58 | "name": "Benjamin Eberlei", 59 | "email": "kontakt@beberlei.de" 60 | }, 61 | { 62 | "name": "Jonathan Wage", 63 | "email": "jonwage@gmail.com" 64 | }, 65 | { 66 | "name": "Johannes Schmitt", 67 | "email": "schmittjoh@gmail.com" 68 | } 69 | ], 70 | "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", 71 | "homepage": "https://www.doctrine-project.org/projects/inflector.html", 72 | "keywords": [ 73 | "inflection", 74 | "inflector", 75 | "lowercase", 76 | "manipulation", 77 | "php", 78 | "plural", 79 | "singular", 80 | "strings", 81 | "uppercase", 82 | "words" 83 | ], 84 | "support": { 85 | "issues": "https://github.com/doctrine/inflector/issues", 86 | "source": "https://github.com/doctrine/inflector/tree/2.0.x" 87 | }, 88 | "funding": [ 89 | { 90 | "url": "https://www.doctrine-project.org/sponsorship.html", 91 | "type": "custom" 92 | }, 93 | { 94 | "url": "https://www.patreon.com/phpdoctrine", 95 | "type": "patreon" 96 | }, 97 | { 98 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", 99 | "type": "tidelift" 100 | } 101 | ], 102 | "time": "2020-05-29T15:13:26+00:00" 103 | }, 104 | { 105 | "name": "graham-campbell/result-type", 106 | "version": "v1.0.2", 107 | "source": { 108 | "type": "git", 109 | "url": "https://github.com/GrahamCampbell/Result-Type.git", 110 | "reference": "84afea85c6841deeea872f36249a206e878a5de0" 111 | }, 112 | "dist": { 113 | "type": "zip", 114 | "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/84afea85c6841deeea872f36249a206e878a5de0", 115 | "reference": "84afea85c6841deeea872f36249a206e878a5de0", 116 | "shasum": "" 117 | }, 118 | "require": { 119 | "php": "^7.0 || ^8.0", 120 | "phpoption/phpoption": "^1.8" 121 | }, 122 | "require-dev": { 123 | "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" 124 | }, 125 | "type": "library", 126 | "autoload": { 127 | "psr-4": { 128 | "GrahamCampbell\\ResultType\\": "src/" 129 | } 130 | }, 131 | "notification-url": "https://packagist.org/downloads/", 132 | "license": [ 133 | "MIT" 134 | ], 135 | "authors": [ 136 | { 137 | "name": "Graham Campbell", 138 | "email": "hello@gjcampbell.co.uk" 139 | } 140 | ], 141 | "description": "An Implementation Of The Result Type", 142 | "keywords": [ 143 | "Graham Campbell", 144 | "GrahamCampbell", 145 | "Result Type", 146 | "Result-Type", 147 | "result" 148 | ], 149 | "support": { 150 | "issues": "https://github.com/GrahamCampbell/Result-Type/issues", 151 | "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.2" 152 | }, 153 | "funding": [ 154 | { 155 | "url": "https://github.com/GrahamCampbell", 156 | "type": "github" 157 | }, 158 | { 159 | "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", 160 | "type": "tidelift" 161 | } 162 | ], 163 | "time": "2021-08-28T21:34:50+00:00" 164 | }, 165 | { 166 | "name": "league/plates", 167 | "version": "v3.4.0", 168 | "source": { 169 | "type": "git", 170 | "url": "https://github.com/thephpleague/plates.git", 171 | "reference": "6d3ee31199b536a4e003b34a356ca20f6f75496a" 172 | }, 173 | "dist": { 174 | "type": "zip", 175 | "url": "https://api.github.com/repos/thephpleague/plates/zipball/6d3ee31199b536a4e003b34a356ca20f6f75496a", 176 | "reference": "6d3ee31199b536a4e003b34a356ca20f6f75496a", 177 | "shasum": "" 178 | }, 179 | "require": { 180 | "php": "^7.0|^8.0" 181 | }, 182 | "require-dev": { 183 | "mikey179/vfsstream": "^1.6", 184 | "phpunit/phpunit": "^9.5", 185 | "squizlabs/php_codesniffer": "^3.5" 186 | }, 187 | "type": "library", 188 | "extra": { 189 | "branch-alias": { 190 | "dev-master": "3.0-dev" 191 | } 192 | }, 193 | "autoload": { 194 | "psr-4": { 195 | "League\\Plates\\": "src" 196 | } 197 | }, 198 | "notification-url": "https://packagist.org/downloads/", 199 | "license": [ 200 | "MIT" 201 | ], 202 | "authors": [ 203 | { 204 | "name": "Jonathan Reinink", 205 | "email": "jonathan@reinink.ca", 206 | "role": "Developer" 207 | }, 208 | { 209 | "name": "RJ Garcia", 210 | "email": "ragboyjr@icloud.com", 211 | "role": "Developer" 212 | } 213 | ], 214 | "description": "Plates, the native PHP template system that's fast, easy to use and easy to extend.", 215 | "homepage": "https://platesphp.com", 216 | "keywords": [ 217 | "league", 218 | "package", 219 | "templates", 220 | "templating", 221 | "views" 222 | ], 223 | "support": { 224 | "issues": "https://github.com/thephpleague/plates/issues", 225 | "source": "https://github.com/thephpleague/plates/tree/v3.4.0" 226 | }, 227 | "time": "2020-12-25T05:00:37+00:00" 228 | }, 229 | { 230 | "name": "phpmailer/phpmailer", 231 | "version": "v6.5.1", 232 | "source": { 233 | "type": "git", 234 | "url": "https://github.com/PHPMailer/PHPMailer.git", 235 | "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355" 236 | }, 237 | "dist": { 238 | "type": "zip", 239 | "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/dd803df5ad7492e1b40637f7ebd258fee5ca7355", 240 | "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355", 241 | "shasum": "" 242 | }, 243 | "require": { 244 | "ext-ctype": "*", 245 | "ext-filter": "*", 246 | "ext-hash": "*", 247 | "php": ">=5.5.0" 248 | }, 249 | "require-dev": { 250 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", 251 | "doctrine/annotations": "^1.2", 252 | "php-parallel-lint/php-console-highlighter": "^0.5.0", 253 | "php-parallel-lint/php-parallel-lint": "^1.3", 254 | "phpcompatibility/php-compatibility": "^9.3.5", 255 | "roave/security-advisories": "dev-latest", 256 | "squizlabs/php_codesniffer": "^3.6.0", 257 | "yoast/phpunit-polyfills": "^1.0.0" 258 | }, 259 | "suggest": { 260 | "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", 261 | "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", 262 | "league/oauth2-google": "Needed for Google XOAUTH2 authentication", 263 | "psr/log": "For optional PSR-3 debug logging", 264 | "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", 265 | "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" 266 | }, 267 | "type": "library", 268 | "autoload": { 269 | "psr-4": { 270 | "PHPMailer\\PHPMailer\\": "src/" 271 | } 272 | }, 273 | "notification-url": "https://packagist.org/downloads/", 274 | "license": [ 275 | "LGPL-2.1-only" 276 | ], 277 | "authors": [ 278 | { 279 | "name": "Marcus Bointon", 280 | "email": "phpmailer@synchromedia.co.uk" 281 | }, 282 | { 283 | "name": "Jim Jagielski", 284 | "email": "jimjag@gmail.com" 285 | }, 286 | { 287 | "name": "Andy Prevost", 288 | "email": "codeworxtech@users.sourceforge.net" 289 | }, 290 | { 291 | "name": "Brent R. Matzelle" 292 | } 293 | ], 294 | "description": "PHPMailer is a full-featured email creation and transfer class for PHP", 295 | "support": { 296 | "issues": "https://github.com/PHPMailer/PHPMailer/issues", 297 | "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.1" 298 | }, 299 | "funding": [ 300 | { 301 | "url": "https://github.com/Synchro", 302 | "type": "github" 303 | } 304 | ], 305 | "time": "2021-08-18T09:14:16+00:00" 306 | }, 307 | { 308 | "name": "phpoption/phpoption", 309 | "version": "1.8.0", 310 | "source": { 311 | "type": "git", 312 | "url": "https://github.com/schmittjoh/php-option.git", 313 | "reference": "5455cb38aed4523f99977c4a12ef19da4bfe2a28" 314 | }, 315 | "dist": { 316 | "type": "zip", 317 | "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/5455cb38aed4523f99977c4a12ef19da4bfe2a28", 318 | "reference": "5455cb38aed4523f99977c4a12ef19da4bfe2a28", 319 | "shasum": "" 320 | }, 321 | "require": { 322 | "php": "^7.0 || ^8.0" 323 | }, 324 | "require-dev": { 325 | "bamarni/composer-bin-plugin": "^1.4.1", 326 | "phpunit/phpunit": "^6.5.14 || ^7.0.20 || ^8.5.19 || ^9.5.8" 327 | }, 328 | "type": "library", 329 | "extra": { 330 | "branch-alias": { 331 | "dev-master": "1.8-dev" 332 | } 333 | }, 334 | "autoload": { 335 | "psr-4": { 336 | "PhpOption\\": "src/PhpOption/" 337 | } 338 | }, 339 | "notification-url": "https://packagist.org/downloads/", 340 | "license": [ 341 | "Apache-2.0" 342 | ], 343 | "authors": [ 344 | { 345 | "name": "Johannes M. Schmitt", 346 | "email": "schmittjoh@gmail.com" 347 | }, 348 | { 349 | "name": "Graham Campbell", 350 | "email": "hello@gjcampbell.co.uk" 351 | } 352 | ], 353 | "description": "Option Type for PHP", 354 | "keywords": [ 355 | "language", 356 | "option", 357 | "php", 358 | "type" 359 | ], 360 | "support": { 361 | "issues": "https://github.com/schmittjoh/php-option/issues", 362 | "source": "https://github.com/schmittjoh/php-option/tree/1.8.0" 363 | }, 364 | "funding": [ 365 | { 366 | "url": "https://github.com/GrahamCampbell", 367 | "type": "github" 368 | }, 369 | { 370 | "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", 371 | "type": "tidelift" 372 | } 373 | ], 374 | "time": "2021-08-28T21:27:29+00:00" 375 | }, 376 | { 377 | "name": "symfony/polyfill-ctype", 378 | "version": "v1.23.0", 379 | "source": { 380 | "type": "git", 381 | "url": "https://github.com/symfony/polyfill-ctype.git", 382 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" 383 | }, 384 | "dist": { 385 | "type": "zip", 386 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", 387 | "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", 388 | "shasum": "" 389 | }, 390 | "require": { 391 | "php": ">=7.1" 392 | }, 393 | "suggest": { 394 | "ext-ctype": "For best performance" 395 | }, 396 | "type": "library", 397 | "extra": { 398 | "branch-alias": { 399 | "dev-main": "1.23-dev" 400 | }, 401 | "thanks": { 402 | "name": "symfony/polyfill", 403 | "url": "https://github.com/symfony/polyfill" 404 | } 405 | }, 406 | "autoload": { 407 | "psr-4": { 408 | "Symfony\\Polyfill\\Ctype\\": "" 409 | }, 410 | "files": [ 411 | "bootstrap.php" 412 | ] 413 | }, 414 | "notification-url": "https://packagist.org/downloads/", 415 | "license": [ 416 | "MIT" 417 | ], 418 | "authors": [ 419 | { 420 | "name": "Gert de Pagter", 421 | "email": "BackEndTea@gmail.com" 422 | }, 423 | { 424 | "name": "Symfony Community", 425 | "homepage": "https://symfony.com/contributors" 426 | } 427 | ], 428 | "description": "Symfony polyfill for ctype functions", 429 | "homepage": "https://symfony.com", 430 | "keywords": [ 431 | "compatibility", 432 | "ctype", 433 | "polyfill", 434 | "portable" 435 | ], 436 | "support": { 437 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" 438 | }, 439 | "funding": [ 440 | { 441 | "url": "https://symfony.com/sponsor", 442 | "type": "custom" 443 | }, 444 | { 445 | "url": "https://github.com/fabpot", 446 | "type": "github" 447 | }, 448 | { 449 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 450 | "type": "tidelift" 451 | } 452 | ], 453 | "time": "2021-02-19T12:13:01+00:00" 454 | }, 455 | { 456 | "name": "symfony/polyfill-mbstring", 457 | "version": "v1.23.1", 458 | "source": { 459 | "type": "git", 460 | "url": "https://github.com/symfony/polyfill-mbstring.git", 461 | "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" 462 | }, 463 | "dist": { 464 | "type": "zip", 465 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", 466 | "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", 467 | "shasum": "" 468 | }, 469 | "require": { 470 | "php": ">=7.1" 471 | }, 472 | "suggest": { 473 | "ext-mbstring": "For best performance" 474 | }, 475 | "type": "library", 476 | "extra": { 477 | "branch-alias": { 478 | "dev-main": "1.23-dev" 479 | }, 480 | "thanks": { 481 | "name": "symfony/polyfill", 482 | "url": "https://github.com/symfony/polyfill" 483 | } 484 | }, 485 | "autoload": { 486 | "psr-4": { 487 | "Symfony\\Polyfill\\Mbstring\\": "" 488 | }, 489 | "files": [ 490 | "bootstrap.php" 491 | ] 492 | }, 493 | "notification-url": "https://packagist.org/downloads/", 494 | "license": [ 495 | "MIT" 496 | ], 497 | "authors": [ 498 | { 499 | "name": "Nicolas Grekas", 500 | "email": "p@tchwork.com" 501 | }, 502 | { 503 | "name": "Symfony Community", 504 | "homepage": "https://symfony.com/contributors" 505 | } 506 | ], 507 | "description": "Symfony polyfill for the Mbstring extension", 508 | "homepage": "https://symfony.com", 509 | "keywords": [ 510 | "compatibility", 511 | "mbstring", 512 | "polyfill", 513 | "portable", 514 | "shim" 515 | ], 516 | "support": { 517 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" 518 | }, 519 | "funding": [ 520 | { 521 | "url": "https://symfony.com/sponsor", 522 | "type": "custom" 523 | }, 524 | { 525 | "url": "https://github.com/fabpot", 526 | "type": "github" 527 | }, 528 | { 529 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 530 | "type": "tidelift" 531 | } 532 | ], 533 | "time": "2021-05-27T12:26:48+00:00" 534 | }, 535 | { 536 | "name": "symfony/polyfill-php80", 537 | "version": "v1.23.1", 538 | "source": { 539 | "type": "git", 540 | "url": "https://github.com/symfony/polyfill-php80.git", 541 | "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" 542 | }, 543 | "dist": { 544 | "type": "zip", 545 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", 546 | "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", 547 | "shasum": "" 548 | }, 549 | "require": { 550 | "php": ">=7.1" 551 | }, 552 | "type": "library", 553 | "extra": { 554 | "branch-alias": { 555 | "dev-main": "1.23-dev" 556 | }, 557 | "thanks": { 558 | "name": "symfony/polyfill", 559 | "url": "https://github.com/symfony/polyfill" 560 | } 561 | }, 562 | "autoload": { 563 | "psr-4": { 564 | "Symfony\\Polyfill\\Php80\\": "" 565 | }, 566 | "files": [ 567 | "bootstrap.php" 568 | ], 569 | "classmap": [ 570 | "Resources/stubs" 571 | ] 572 | }, 573 | "notification-url": "https://packagist.org/downloads/", 574 | "license": [ 575 | "MIT" 576 | ], 577 | "authors": [ 578 | { 579 | "name": "Ion Bazan", 580 | "email": "ion.bazan@gmail.com" 581 | }, 582 | { 583 | "name": "Nicolas Grekas", 584 | "email": "p@tchwork.com" 585 | }, 586 | { 587 | "name": "Symfony Community", 588 | "homepage": "https://symfony.com/contributors" 589 | } 590 | ], 591 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 592 | "homepage": "https://symfony.com", 593 | "keywords": [ 594 | "compatibility", 595 | "polyfill", 596 | "portable", 597 | "shim" 598 | ], 599 | "support": { 600 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" 601 | }, 602 | "funding": [ 603 | { 604 | "url": "https://symfony.com/sponsor", 605 | "type": "custom" 606 | }, 607 | { 608 | "url": "https://github.com/fabpot", 609 | "type": "github" 610 | }, 611 | { 612 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 613 | "type": "tidelift" 614 | } 615 | ], 616 | "time": "2021-07-28T13:41:28+00:00" 617 | }, 618 | { 619 | "name": "symfony/var-dumper", 620 | "version": "v5.3.7", 621 | "source": { 622 | "type": "git", 623 | "url": "https://github.com/symfony/var-dumper.git", 624 | "reference": "3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f" 625 | }, 626 | "dist": { 627 | "type": "zip", 628 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f", 629 | "reference": "3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f", 630 | "shasum": "" 631 | }, 632 | "require": { 633 | "php": ">=7.2.5", 634 | "symfony/polyfill-mbstring": "~1.0", 635 | "symfony/polyfill-php80": "^1.16" 636 | }, 637 | "conflict": { 638 | "phpunit/phpunit": "<5.4.3", 639 | "symfony/console": "<4.4" 640 | }, 641 | "require-dev": { 642 | "ext-iconv": "*", 643 | "symfony/console": "^4.4|^5.0", 644 | "symfony/process": "^4.4|^5.0", 645 | "twig/twig": "^2.13|^3.0.4" 646 | }, 647 | "suggest": { 648 | "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", 649 | "ext-intl": "To show region name in time zone dump", 650 | "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" 651 | }, 652 | "bin": [ 653 | "Resources/bin/var-dump-server" 654 | ], 655 | "type": "library", 656 | "autoload": { 657 | "files": [ 658 | "Resources/functions/dump.php" 659 | ], 660 | "psr-4": { 661 | "Symfony\\Component\\VarDumper\\": "" 662 | }, 663 | "exclude-from-classmap": [ 664 | "/Tests/" 665 | ] 666 | }, 667 | "notification-url": "https://packagist.org/downloads/", 668 | "license": [ 669 | "MIT" 670 | ], 671 | "authors": [ 672 | { 673 | "name": "Nicolas Grekas", 674 | "email": "p@tchwork.com" 675 | }, 676 | { 677 | "name": "Symfony Community", 678 | "homepage": "https://symfony.com/contributors" 679 | } 680 | ], 681 | "description": "Provides mechanisms for walking through any arbitrary PHP variable", 682 | "homepage": "https://symfony.com", 683 | "keywords": [ 684 | "debug", 685 | "dump" 686 | ], 687 | "support": { 688 | "source": "https://github.com/symfony/var-dumper/tree/v5.3.7" 689 | }, 690 | "funding": [ 691 | { 692 | "url": "https://symfony.com/sponsor", 693 | "type": "custom" 694 | }, 695 | { 696 | "url": "https://github.com/fabpot", 697 | "type": "github" 698 | }, 699 | { 700 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 701 | "type": "tidelift" 702 | } 703 | ], 704 | "time": "2021-08-04T23:19:25+00:00" 705 | }, 706 | { 707 | "name": "vlucas/phpdotenv", 708 | "version": "v5.3.0", 709 | "source": { 710 | "type": "git", 711 | "url": "https://github.com/vlucas/phpdotenv.git", 712 | "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56" 713 | }, 714 | "dist": { 715 | "type": "zip", 716 | "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/b3eac5c7ac896e52deab4a99068e3f4ab12d9e56", 717 | "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56", 718 | "shasum": "" 719 | }, 720 | "require": { 721 | "ext-pcre": "*", 722 | "graham-campbell/result-type": "^1.0.1", 723 | "php": "^7.1.3 || ^8.0", 724 | "phpoption/phpoption": "^1.7.4", 725 | "symfony/polyfill-ctype": "^1.17", 726 | "symfony/polyfill-mbstring": "^1.17", 727 | "symfony/polyfill-php80": "^1.17" 728 | }, 729 | "require-dev": { 730 | "bamarni/composer-bin-plugin": "^1.4.1", 731 | "ext-filter": "*", 732 | "phpunit/phpunit": "^7.5.20 || ^8.5.14 || ^9.5.1" 733 | }, 734 | "suggest": { 735 | "ext-filter": "Required to use the boolean validator." 736 | }, 737 | "type": "library", 738 | "extra": { 739 | "branch-alias": { 740 | "dev-master": "5.3-dev" 741 | } 742 | }, 743 | "autoload": { 744 | "psr-4": { 745 | "Dotenv\\": "src/" 746 | } 747 | }, 748 | "notification-url": "https://packagist.org/downloads/", 749 | "license": [ 750 | "BSD-3-Clause" 751 | ], 752 | "authors": [ 753 | { 754 | "name": "Graham Campbell", 755 | "email": "graham@alt-three.com", 756 | "homepage": "https://gjcampbell.co.uk/" 757 | }, 758 | { 759 | "name": "Vance Lucas", 760 | "email": "vance@vancelucas.com", 761 | "homepage": "https://vancelucas.com/" 762 | } 763 | ], 764 | "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", 765 | "keywords": [ 766 | "dotenv", 767 | "env", 768 | "environment" 769 | ], 770 | "support": { 771 | "issues": "https://github.com/vlucas/phpdotenv/issues", 772 | "source": "https://github.com/vlucas/phpdotenv/tree/v5.3.0" 773 | }, 774 | "funding": [ 775 | { 776 | "url": "https://github.com/GrahamCampbell", 777 | "type": "github" 778 | }, 779 | { 780 | "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", 781 | "type": "tidelift" 782 | } 783 | ], 784 | "time": "2021-01-20T15:23:13+00:00" 785 | } 786 | ], 787 | "packages-dev": [], 788 | "aliases": [], 789 | "minimum-stability": "stable", 790 | "stability-flags": [], 791 | "prefer-stable": false, 792 | "prefer-lowest": false, 793 | "platform": [], 794 | "platform-dev": [], 795 | "plugin-api-version": "2.1.0" 796 | } 797 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "php-pro", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "webpack.config.js", 6 | "scripts": { 7 | "dev": "NODE_ENV=development webpack --progress --watch", 8 | "prod": "NODE_ENV=production webpack --progress --watch" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/aleduca/php-profissional.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/aleduca/php-profissional/issues" 19 | }, 20 | "devDependencies": { 21 | "@babel/cli": "^7.10.5", 22 | "@babel/core": "^7.11.1", 23 | "@babel/polyfill": "^7.12.1", 24 | "@babel/preset-env": "^7.11.0", 25 | "babel-loader": "^8.1.0", 26 | "eslint": "^7.7.0", 27 | "webpack": "^4.44.1", 28 | "webpack-cli": "^3.3.12" 29 | }, 30 | "dependencies": { 31 | "alpinejs": "^3.3.3", 32 | "axios": "^0.21.4" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleduca/php-profissional/3504041e7b8eb58e0ad1ed88e83636fbbff99768/public/.DS_Store -------------------------------------------------------------------------------- /public/assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleduca/php-profissional/3504041e7b8eb58e0ad1ed88e83636fbbff99768/public/assets/.DS_Store -------------------------------------------------------------------------------- /public/assets/css/styles.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=PT+Sans:wght@400;700&display=swap'); 2 | 3 | html, 4 | body { 5 | font-family: 'PT Sans', sans-serif; 6 | } 7 | 8 | .container { 9 | margin: auto; 10 | width: 50%; 11 | border: 3px solid green; 12 | padding: 10px; 13 | } 14 | 15 | #box-login { 16 | margin: 0 auto; 17 | background: tomato; 18 | padding: 5px; 19 | width: 400px; 20 | color: white; 21 | text-align: center; 22 | } 23 | 24 | .button-green { 25 | background-color: green; 26 | border: none; 27 | color: white; 28 | } 29 | 30 | #header { 31 | display: flex; 32 | justify-content: space-between; 33 | width: 100%; 34 | align-items: center; 35 | } 36 | 37 | ul#menu_list { 38 | list-style: none; 39 | display: flex; 40 | padding: 0; 41 | justify-content: space-between; 42 | } 43 | 44 | ul#menu_list li { 45 | margin-right: 15px; 46 | } 47 | 48 | #status_login { 49 | background-color: #efefef; 50 | } 51 | 52 | ul#users-home { 53 | list-style: none; 54 | padding: 0; 55 | } 56 | 57 | ul#users-home li { 58 | background-color: aquamarine; 59 | padding: 5px; 60 | margin-bottom: 3px; 61 | } 62 | -------------------------------------------------------------------------------- /public/assets/js/alpine-components/users.js: -------------------------------------------------------------------------------- 1 | import http from "../http"; 2 | 3 | function users() { 4 | return { 5 | data: [], 6 | async loadUsers() { 7 | try { 8 | const { data } = await http.get("/users"); 9 | this.data = data; 10 | } catch (error) { 11 | console.log(error); 12 | } 13 | }, 14 | }; 15 | } 16 | 17 | export default users; 18 | -------------------------------------------------------------------------------- /public/assets/js/app.js: -------------------------------------------------------------------------------- 1 | import Alpine from "alpinejs"; 2 | import users from "./alpine-components/users"; 3 | 4 | window.Alpine = Alpine; 5 | window.users = users; 6 | 7 | Alpine.start(); 8 | -------------------------------------------------------------------------------- /public/assets/js/http.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const axiosConfig = axios.create({ 4 | headers: { 5 | 'Content-type': 'application/json', 6 | HTTP_X_REQUESTED_WITH: 'XMLHttpRequest', 7 | }, 8 | baseURL: 'http://localhost:8000', 9 | }); 10 | 11 | export default axiosConfig; 12 | -------------------------------------------------------------------------------- /public/assets/js/teste.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleduca/php-profissional/3504041e7b8eb58e0ad1ed88e83636fbbff99768/public/assets/js/teste.js -------------------------------------------------------------------------------- /public/assets/js/users.js: -------------------------------------------------------------------------------- 1 | import http from './http'; 2 | 3 | async function users() { 4 | try { 5 | const { data } = await http.get('/users'); 6 | console.log(data); 7 | } catch (error) { 8 | console.log(error); 9 | } 10 | } 11 | 12 | export default users; 13 | -------------------------------------------------------------------------------- /public/bootstrap.php: -------------------------------------------------------------------------------- 1 | load(); 8 | -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | render($data['view'], $data['data']); 39 | 40 | // extract($data['data']); 41 | 42 | // $view = $data['view']; 43 | 44 | // require VIEWS.'master.php'; 45 | } catch (Exception $e) { 46 | var_dump($e->getMessage()); 47 | } 48 | -------------------------------------------------------------------------------- /public/maintenance.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Em manutenção 8 | 9 | 10 |

    Site em manutenção

    11 | 12 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: process.env.NODE_ENV, 5 | devtool: process.env.NODE_ENV == 'development' ? 'source-map' : '', 6 | entry: { 7 | app: ['@babel/polyfill', './public/assets/js/app.js'], 8 | }, 9 | output: { 10 | path: path.resolve(__dirname, 'public'), 11 | filename: '[name].js', 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.js$/, 17 | exclude: /node_modules/, 18 | loader: 'babel-loader', 19 | }, 20 | ], 21 | }, 22 | }; 23 | --------------------------------------------------------------------------------