Andrey Knupp Vital 136 Denunciar post Postado Julho 22, 2011 Nopz, vamos a um exemplo. UsuariosModel.php, considere esse código um VO( Value Object ) <?php class UsuariosModel{ /** * Guarda as informações do usuario * @var String|Integer */ private $nome, $sobrenome, $login, $senha; /** * Recupera o nome setado * @return String */ public function getNome(){ return $this->nome; } /** * Seta um nome * @param String $nome */ public function setNome($nome){ $this->nome = $nome; } /** * Recupera o sobrenome do usuário * @return String */ public function getSobrenome(){ return $this->sobrenome; } /** * Seta o sobrenome do usuário * @param String $sobrenome */ public function setSobrenome( $sobrenome ){ $this->sobrenome = $sobrenome; } /** * Recupera o login do usuário * @return String|Integer */ public function getLogin(){ return $this->login; } /** * Seta o login do usuário * @param String|Integer $login */ public function setLogin( $login ){ $this->login = $login; } /** * Recupera a senha do usuário * @return String|Integer */ public function getSenha(){ return $this->senha; } /** * Seta a senha do usuário * @param String|Integer $senha */ public function setSenha( $senha ){ $this->senha = $senha; } } UsuariosDAO.php <?php class UsuariosDataObject{ /** * Guarda as respostas dos métodos executados * @var String */ public $resposta; /** * Insere um usuário * @param Usuario sModel $UsuariosModel * @return String */ public function insert( UsuariosModel $UsuariosModel ){ $this->resposta[] = sprintf( 'Estamos inserindo os dados %s, %s, %s, %s ...', $UsuariosModel->getLogin(), $UsuariosModel->getNome(), $UsuariosModel->getSenha(), $UsuariosModel->getSobrenome() ); } /** * Seleciona um usuário * @param UsuariosModel $UsuariosModel * @return String */ public function select( UsuariosModel $UsuariosModel ){ $this->resposta[] = sprintf( 'Selecionando o usuário de login e senha %s/%s', $UsuariosModel->getLogin(), $UsuariosModel->getSenha() ); } /** * Deleta o usuário * @param UsuariosModel $UsuariosModel * @return String */ public function delete( UsuariosModel $UsuariosModel ){ $this->resposta[] = sprintf( 'Deletando o usuário de login %s', $UsuariosModel->getLogin() ); } } UsuariosView.php <?php class UsuariosView{ /** * Recupera as respostas * @param UsuariosDataObject $DataObject */ public function getRespostas( UsuariosDataObject $DataObject ){ if( count( $DataObject->resposta ) > 1 ){ foreach( $DataObject->resposta as $Resposta ){ echo $Resposta, '<br />'; } }else{ echo $DataObject->resposta; } } } UsuariosController.php <?php /** * .... */ require_once 'UsuariosDAO.php'; require_once 'UsuariosModel.php'; require_once 'UsuariosView.php'; $UsuariosModel = new UsuariosModel(); $UsuariosModel->setLogin( '123' ); $UsuariosModel->setSenha( '456' ); $UsuariosModel->setNome( 'Andrey' ); $UsuariosModel->setSobrenome( 'Knupp Vital' ); $UsuariosDataObject = new UsuariosDataObject(); $UsuariosDataObject->insert( $UsuariosModel ); $UsuariosDataObject->select( $UsuariosModel ); $UsuariosDataObject->delete( $UsuariosModel ); $UsuariosView = new UsuariosView(); $UsuariosView->getRespostas( $UsuariosDataObject ); Saída Estamos inserindo os dados 123, Andrey, 456, Knupp Vital ... Selecionando o usuário de login e senha 123/456 Deletando o usuário de login 123 No caso, no controlador, você pode fazer um switch, e verificar qual ação que o usuário deseja executar, se é logar, se é cadastrar, se é excluir .. etc Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 22, 2011 Valeu Andrey. o exemplo que dei logo acima, de login, está correto também? A logica pelo menos? Compartilhar este post Link para o post Compartilhar em outros sites
Andrey Knupp Vital 136 Denunciar post Postado Julho 22, 2011 Não amigo, as regras do negócio ficam na Model, o seu controlador é cego, ele não sabe de onde entra e sai dados, ele apenas controla. Então, na View você pega as respostas de uma transação, na Model você armazena os Dados, no controlador, você chama os objetos responsáveis por manipular a requisição Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 22, 2011 Então no login, eu pegaria os dados informados, via html, pelo usuario e mandaria para o controlador, esse pegaria esses dados e passaria para a camada de modelo, esta validaria tudo, junto ao bd e mostraria o erro pro usuário direto, acessando o html usado para pegar os dados no começo, ou até mesmo outro, ou, se tudo estiver ok, redirecionaria o usuário. Seria isso? Caso esteja errado, pode indicar meu erro e me exemplificar melhor esse esquema do login? Obrigado Por favor, vejam se estou no caminho. Estou bem perdido. Controle: //Um arquivo php irá ter um action para essa classe na hora de cadastrar um administrador require_once(DIRETORIO_DAO."/AdministradorDAO.php"); require_once(DIRETORIO_MODELO."/Administrador.php"); require_once(DIRETORIO_VISAO."/AdministradorView.php"); class AdministradorControle{ private $view; private $model; private $dao; private $nome; private $login; private $senha; private $email; public function __contruct(){ $this->model = new Administrador(); $this->view = new AdministradorView(); $this->dao = new AdministradorDAO(); $this->nome = $_POST["nome"]; $this->login = $_POST["login"]; $this->senha = $_POST["senha"]; $this->email = $_POST["email"]; } function salvar(){ $this->model->setNome($this->nome); $this->model->setLogin($this->login); $this->model->setSenha($this->senha); $this->model->setEmail($this->email); $this->dao->salvar($this->model); $UsuariosView = new UsuariosView(); $UsuariosView->getRespostas( $UsuariosDataObject ); } } DAO: class AdministradorDAO extends BancoDeDadosModelo { public function __contruct(){ } public function salvar(Administrador $administrador) { parent::conectar(); try { $sql = "INSERT INTO administrador(nome, login, senha, email) VALUES ( '".$administrador->getNome()."', '".$administrador->getLogin()."', '".md5($administrador->getSenha())."', '".$administrador->getEmail()."' )"; $retorno = parent::executarQuery($sql); if($retorno != null) { return true; } } catch(Exception $e) { echo "Erro: ".$e->getMessage(); return false; } parent::desconectar(); } Modelo class Administrador { private $id; private $nome; private $login; private $senha; private $email; private $ultimoAcesso; public function __construct() { } public function getId() { return $this->id; } public function setId($id) { $this->id = $id; } ... A minha dúvida está em criar a classe view, como vou mostrar o retorno do model no html, essas coisas Tambem não sei se fiz a classe de controle corretamente, recebendo os parametros via post e colocando no construct da classe. Compartilhar este post Link para o post Compartilhar em outros sites
André Severino 3 Denunciar post Postado Julho 22, 2011 Olá Jefferson o ideal do controller é que ele seria um pai para as subacoes, desta forma que você fez, teria que ter um controller para cada requisição do site o ideal seria algo parecido com isso abaixo: http://www.site.com.br/administrador/index <?php // faz os includes igual você fez acima... class AdministradorControle { private $view; private $model; private $dao; private $login; private $senha; public function __contruct() { $this->model = new Administrador(); $this->view = new AdministradorView(); $this->dao = new AdministradorDAO(); } /** * metodo default, assim que o usuário digitar /administrador ele carrega o controller e o metodo index */ function index() { // aqui você apenas faria uma requisição para mostrar a view INDEX(com o formulario de login) como apresentado na URL $this->view->carrega('admin/login.php'); // uma pasta chamada admin e dentro dela um form de login } function logar() { $this->login = protege($_POST['login']); $this->senha = protege($_POST['senha']); // Faz validações para verificar se o campo está vazio e blablabla... $this->model->setLogin($this->login); $this->model->setSenha($this->senha); // o dao não seria melhor apenas para fazer as conexões com o(s) banco(s) de dados // e deixa a parte de abstração com o MODEL em si ? #$this->dao->salvar($this->model); $qtd = $this->model->verificaLogin(); if($qtd > 0) { $data['erro'] = 'Usuario ou senha invalidos'; // cria a variavel erro, e envia para a paginadeerro.php $this->view->carrega('admin/paginadeerro.php', $data); } else { $UsuariosView = new UsuariosView(); $UsuariosView->getRespostas($UsuariosDataObject); // salva os valores em sessoes e etc... // e chama a view principal $this->view->carrega('admin/principal.php'); } } } ?> Neste seu formulario admin/login.php // Olhe a ação, para onde ele está apontando <form method="post" action="http://www.site.com.br/administrador/logar"> // CAMPOS DO FORMULARIO </form> Agora pensando na pagina principal e nos menus, vamos lá <ul> <li><a href="http://www.site.com.br/administrador/principal/">Home</a></li> <li><a href="http://www.site.com.br/administrador/novo_cliente/">Cadastrar cliente</a></li> <li><a href="http://www.site.com.br/administrador/logoff/">Sair</a></li> </ul> Perceba que para adicionar um novo_cliente ele chama o metodo novo_cliente do controller administrador, este método novo_cliente seria responsável apenas por carregar a view com o formulario, então você teria que adicionar ele na classe AdministradorController.php <?php // faz os includes igual você fez acima... class AdministradorControle { // ... function novo_cliente(){ // carrega a view cad_cliente.php que contem o formulario html com os inputs e etc... $this->view->carrega('admin/cad_cliente.php'); } // este metodo seria a ação do formulario da view cad_cliente.php (igual do login) // você receberia os valores da view e inseria no model, pegaria o retorno do model e exibiria a mensagem para o usuario se foi cadastrado com sucesso(false) ou se deu erro(false) :P function inserircliente(){ $nome = protege($_POST['nomecliente']); // recebe os outros campos e faz as validações necessarias // caso de algum erro na validação exibe a mensagem igual no logar() // você poderia utilizar um array para enviar os dados direto seria bem melhor // fica a criterio da modelagem da sua classe e estrutura :P $this->model->inserirCliente($nome,$email,$endereco,....); } // ... } ?> caiowind essa é minha duvida tambem, uso include ou extends? Então no caso desse escopo você pode utilizar o include, não precisa herdar os metodos/atributos da classe DAO, mas das 2 formas iria rodar, agora precisaria ver qual a 'certa' :thumbsup: Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 22, 2011 Valeu pela ajuda André. Olá Jefferson o ideal do controller é que ele seria um pai para as subacoes, desta forma que você fez, teria que ter um controller para cada requisição do site o ideal seria algo parecido com isso abaixo: http://www.site.com.br/administrador/index Eu estava achando que era um controlador para cada entidade do meu sistema, nesse exemplo que dei o administrador, nada mais é que um usuário do sistema. Pelo que você falou eu não precisaria de um UsuarioController ou AdminController, basta ter um controller geral, como você exemplificou? Neste seu formulario admin/login.php // Olhe a ação, para onde ele está apontando <form method="post" action="http://www.site.com.br/administrador/logar"> // CAMPOS DO FORMULARIO </form> Seguindo o exemplo que deu, basta eu colocar no action o nome da minha classe controller e depois o nome do metodo, no seu exemplo logar? É só isso, tipo action="controller/logar". Como ele vai saber onde encontrar essa classe controller e esse método, basta dar include no topo do form? Seguindo esse seu exemplo vou conseguir verificar o login? Como vou pegar os dados informados no form, coloco POST e pego no controller? No seu exemplo voce chama um função chamada carrega, da classe view, como implemento essa função? Agradeço, mais uma vez, sua ajuda. Desculpa pelas dúvidas e quantidade de perguntas, mas é que sói estou achando porcaria na internet e estou cheio de dúvidas. Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 22, 2011 Então pessoal, dei uma pesquisa aqui e achei um exemplo bem simples e facil de entender. Queria ver com vocês se esse exemplo está seguindo o padrão MVC A logica do exemplo é mais ou menos essa: Se o usuario digitar site.com.br/admin, abre o arquivo admin/index.php, esse arquivo instancia um controlador geral e informar para esse controlador que a ação é logar. O controlador então recebe essa ação e chama uma action para o login, essa action, por sua vez, inclui o arquivo login.php, esse arquivo, pega os dados e manda para o index.php a ação oculta e os dados informados, o index então chama o controlador informando que quer validar os dados e assim continua. É mais ou menos isso? Deu pra entender? Posso fazer assim? Compartilhar este post Link para o post Compartilhar em outros sites
André Severino 3 Denunciar post Postado Julho 22, 2011 Na verdade você teria que trabalhar com um index.php default, também conhecido como bootstrap por gerenciar essas requisiçoes e nao precisar ficar toda hora dando includes e + includes, mas a idéia é essa mesma Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 22, 2011 Então, acho que esse exemplo que achei faz isso sim. Vou segui-lo então. Muito obrigado pela ajuda de sempre Abraços Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 24, 2011 Pessoal, Só uma duvida basica: Validar o formulario não precisa ter um controle e um modelo? Ou precisa/ Quero só validar se o usuario digitou todos os campos obrigatorios, hoje em dia, tenho uma classe Validacao, que é responsavel só por isso. Eu passo para essa classe os campos e valido, caso esteja errado ou vazio eu retorno erro e mostra a mensagem na tela. DEsse jeito está certo? Da view enviando para uma classe e mostrando o erro? Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 25, 2011 Pessoal, Gostaria da opinião de voces sobre o que eu estou fazendo, só pra eu saber se estou no caminho certo e seguindo um pouco o padrao MVC Estou fazendo assim: View: <form action="<?=URL_ADMIN."/index.php";?>" method="post" id="loginForm" name="LoginForm"> <br /> <fieldset class="quadro_login"> <legend> Acesso ao sistema </legend> <br /> <table> <tr> <td rowspan="3"> <img src="<?=URL_IMAGENS_ADMIN;?>/login.png" width="60" /> </td> </tr> <tr> <td> <label for="login" accesskey="l">Login:</label> </td> <td> <input type="text" maxlength="80" name="login" id="login" title="Por favor, informe o login" /> </td> </tr> <tr> <td> <label for="senha" accesskey="s">Senha:</label> </td> <td> <input type="password" name="senha" id="senha" title="Por favor, digite a senha" /> </td> </tr> <tr> <td colspan="3"> <input type="hidden" name="acao" value="ValidarLoginAdmin" /> <input type="submit" name="logar" value=" Entrar " /> </td> </tr> <tr> <td colspan="3" align="center"> <br /> <? $erro = $_REQUEST['erro']; if($erro != "") { echo 'Por favor, preencha o campo '.$erro; } ?> <br /><br /> </td> </tr> </table> </fieldset> <br /> </form> Controller: class AdminController { private $acaoPadrao; private $acao; private $arquivo; private $diretorioActions = '../actions/'; //private $diretorioActions = DIRETORIO_ACTIONS; private $parametroAcao = 'acao'; public function AdminController($acaoPadrao){ $this->acaoPadrao = $acaoPadrao; } public function executarAcao(){ //Verifica se foi passado alguma ação, pela url ou por campo oculto do formulario if(isset($_REQUEST[$this->parametroAcao])){ $this->setAcao($_REQUEST[$this->parametroAcao]); } //Se nada foi passada cria a ação padrão, que é login else{ $this->setAcao($this->acaoPadrao); } $this->setArquivo($this->acao); if(!is_file($this->diretorioActions.$this->arquivo)){ $this->setAcao($this->acaoPadrao); } $this->setArquivo($this->acao); @require_once($this->diretorioActions.$this->arquivo); $action = new $this->acao(); $action->executa(); } public function setAcaoPadrao($acaoPadrao){ $this->acaoPadrao = $acaoPadrao; } private function setArquivo($acao){ $this->arquivo = $acao.'.php'; } private function setAcao($acao){ $this->acao = $acao.'Action'; } } Actions (acho que equivale a model) class ValidarLoginAdminAction { public function executa(){ $conexao = $_REQUEST['conexao']; $adminstradorDao = new AdministradorDAO($conexao); if($_REQUEST['login'] == ""){ header('Location: login.php?erro=login'); } else if($_REQUEST['senha'] == ""){ header('Location: login.php?erro=senha'); } else{ /*$administrador = new Administrador(); $administrador = $adminstradorDao->validarLogin($_REQUEST['login'], $_REQUEST['senha']);*/ /* if($administrador->getId() == '') { header('Location: login.php?erro=loginInvalido'); }*/ /*$contato = new Contato(); $contato->setNome($_REQUEST['nome']); $contato->setEmail($_REQUEST['email']); $contato->setEndereco($_REQUEST['endereco']); $contato->setNascimento(new Date($_REQUEST['nascimento'])); $contatoDao->insere($contato); header('Location: index.php');*/ } /*else{ //include('login.php'); echo "login ok"; }*/ } } DAO: public function inserir(Administrador $administrador){ try{ $query = "INSERT INTO administrador(nome, login, senha, email) VALUES (?, ?, ?, ?)"; $stmt = $this->conexao->prepare($query); $stmt->bindValue(1, $administrador->getNome()); $stmt->bindValue(2, $administrador->getLogin()); $stmt->bindValue(3, md5($administrador->getSenha())); $stmt->bindValue(4, $administrador->getEmail()); $stmt->execute(); } catch (PDOException $ex){ print "Erro: ".$ex->getMessage(); //die(); } } public function validarLogin($login, $senha){ try{ $query = "SELECT * FROM administrador WHERE login = ? AND senha = ?"; $stmt = $this->conexao->prepare($query); $stmt->bindValue(1, $login); $stmt->bindValue(2, md5($senha)); $stmt->execute(); $line = $stmt->fetch(PDO::FETCH_ASSOC); $administrador = new Administrador(); $administrador->setId($line["id"]); $administrador->setNome($line["nome"]); $administrador->setLogin($line["login"]); $administrador->setSenha($line["senha"]); $administrador->setEmail($line["email"]); $administrador->setUltimoAcesso(new Date($line["ultimo_acesso"])); return $administrador; } catch (PDOException $ex){ echo "Erro: ".$ex->getMessage(); //die(); } } Eu peguei esse exemplo na internet e comecei a adapta-lo a minha necessidade, mas estou com algumas duvidas ainda e nao sei se estou seguindo muito bem o MVC. A minha maior duvida esta na classe action, pois estou, nessa classe, validando se o usuario digitou tudo na view e dou um location, caso tenha erro, pode ser assim? Estou no caminho, fazendo do jeito mostrado acima? Obrigado Compartilhar este post Link para o post Compartilhar em outros sites
André Severino 3 Denunciar post Postado Julho 25, 2011 Só na view já se percebe que está errado, pq você está enviando os dados para a index (@bootstrap) ? <form action="<?=URL_ADMIN."/index.php";?>" method="post" id="loginForm" name="LoginForm"> No MVC você tem que trabalhar com controller e ações deste controlador, header('Location: login.php?erro=login'); O ideal seria criar uma parada assim(caso queira usar da forma tradicional, sem url amigável): header('Location: c=administrador&a=login&p=erro'); Compartilhar este post Link para o post Compartilhar em outros sites
Andrey Knupp Vital 136 Denunciar post Postado Julho 25, 2011 André, desnecessário isso no seu código: $this->model = new Administrador(); $this->view = new AdministradorView(); $this->dao = new AdministradorDAO(); Em uma situação, um dos métodos dispara um exception, ou faz um exit inesperado, você vai ter criado objetos que não serão usados !. O Legal de usar Type Hinting é o oposto disso, você vai esperar um objeto na sua ordem de uso. Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 25, 2011 Só na view já se percebe que está errado, pq você está enviando os dados para a index (@bootstrap) ? <form action="<?=URL_ADMIN."/index.php";?>" method="post" id="loginForm" name="LoginForm"> Como conserto isso. Na verdade esse arquivo index, nem recebe nada nem pega nada. Nem eu entendi direito porque envia para essa index. Eu pego os dados depois, no controller, via request. O que voce aconselharia eu mudar aqui? Colocar o action pro controller? No MVC você tem que trabalhar com controller e ações deste controlador, header('Location: login.php?erro=login'); O ideal seria criar uma parada assim(caso queira usar da forma tradicional, sem url amigável): header('Location: c=administrador&a=login&p=erro'); Fazendo isso, que voce falou, eu tenho que da action enviar para o controller? Só que aí teria um controller para cada action, seria isso? Eu quero usar url amigavel sim. Compartilhar este post Link para o post Compartilhar em outros sites
Andrey Knupp Vital 136 Denunciar post Postado Julho 25, 2011 Fazendo isso, que voce falou, eu tenho que da action enviar para o controller? Só que aí teria um controller para cada action, seria isso? Não, controlador é um só !, você consegue jogar vídeo game com 4 manetes, 1 com x outra com quadrado .. ? Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 25, 2011 Então, o certo é eu enviar da action para um controlador. Essa linha aqui iria para o controlador então? header('Location: c=administrador&a=login&p=erro'); Mas como eu faria um controlador unico, como ia pegar esses dados e mostra o erro na tela? Seguindo esse meu codigo: class AdminController { private $acaoPadrao; private $acao; private $arquivo; private $diretorioActions = '../actions/'; //private $diretorioActions = DIRETORIO_ACTIONS; private $parametroAcao = 'acao'; public function AdminController($acaoPadrao){ $this->acaoPadrao = $acaoPadrao; } public function executarAcao(){ //Verifica se foi passado alguma ação, pela url ou por campo oculto do formulario if(isset($_REQUEST[$this->parametroAcao])){ $this->setAcao($_REQUEST[$this->parametroAcao]); } //Se nada foi passada cria a ação padrão, que é login else{ $this->setAcao($this->acaoPadrao); } $this->setArquivo($this->acao); if(!is_file($this->diretorioActions.$this->arquivo)){ $this->setAcao($this->acaoPadrao); } $this->setArquivo($this->acao); @require_once($this->diretorioActions.$this->arquivo); $action = new $this->acao(); $action->executa(); } public function setAcaoPadrao($acaoPadrao){ $this->acaoPadrao = $acaoPadrao; } private function setArquivo($acao){ $this->arquivo = $acao.'.php'; } private function setAcao($acao){ $this->acao = $acao.'Action'; } } Essa é meu controlador unico Compartilhar este post Link para o post Compartilhar em outros sites
André Severino 3 Denunciar post Postado Julho 25, 2011 Jefferson, de uma olhada nas VA's do Matheus, são 8 video aulas, depois você procura entre as páginas acho que na quinta ou quarta ele disponibiliza o link para download dos arquivos, acredito que seja melhor do que ficar 'adaptando' os códigos :thumbsup: Clique aqui Se você for usar url amigável, o location seria assim: header('Location: administrador/login/erroaologar'); Compartilhar este post Link para o post Compartilhar em outros sites
Jefferson NF 0 Denunciar post Postado Julho 25, 2011 Beleza, Valeu mesmo. Vou dar uma olhada sim. Brigadao. Compartilhar este post Link para o post Compartilhar em outros sites
Andrey Knupp Vital 136 Denunciar post Postado Julho 25, 2011 Amigo, veja se entende o seguinte diagrama: As setas azuis representam uma associação, ou seja o controlador vai estar associado com a view, model, mas não com o banco de dados. Porque na verdade, esse é o objetivo da Model, estamos usando o Model em forma de um Value Object, ou seja, estamos guardando toda informação enviada lá na camada da Model, ou seja, o Controlador vai chamar o banco, mas não se associar a ele. As setas pontilhadas, representam uma dependência. ou seja, o View depende da resposta do banco de dados para exibir a informação que o banco emitiu, se for sucesso ou falha, etc. Compartilhar este post Link para o post Compartilhar em outros sites
caio wind 0 Denunciar post Postado Julho 25, 2011 Galera, então pra cada pagina eu vou ter que criar um Model, um Controller, um DAO e um View? eu chamo tudo no controller é isso? Compartilhar este post Link para o post Compartilhar em outros sites