Modelo.php

<< Click to Display Table of Contents >>

Navigation:  Outros > CRUD com persistencia Orientada Objeto > persistencia >

Modelo.php

Previous pageReturn to chapter overviewNext page

<?php
 
namespace persistencia;
 
abstract class Modelo {
 
    private $mensagemValidacao;
 
    // array das propriedades publicas que foram implementadas
    private function getPublicVars() {
        $publicVars = create_function('$obj''return get_object_vars($obj);');
        return $publicVars($this);
    }
 
    public function __toString() {
        return get_called_class();
    }
 
    private function isPossuiAnotacao($nomeProp$anotacao): bool {
        $propriedade = new \ReflectionProperty(get_called_class(), $nomeProp);
        return strpos($propriedade->getDocComment(), "@" . $anotacao) !== false;
    }
 
    private function isKey($prop): bool {
        return $this->isPossuiAnotacao($prop"pk");
    }
 
    private function isAutoInc($prop): bool {
        return $this->isPossuiAnotacao($prop"autoinc");
    }
 
    private function isNull($prop): bool {
        return $this->isPossuiAnotacao($prop"null");
    }
 
    private function isOnlyInsert($prop): bool {
        return $this->isPossuiAnotacao($prop"onlyinsert");
    }
 
    private function isOnlyUpdate($prop): bool {
        return $this->isPossuiAnotacao($prop"onlyupdate");
    }
 
    public function getCampoValores(): array {
 
        $update = $this->isKeyContemValor();
 
        $propriedades = $this->getPublicVars();
        $saida = array();
 
        foreach ($propriedades as $k => $v) {
 
            if ($update) {
                // se for update, ignora os campos only-insert
                if ($this->isOnlyInsert($k)) {
                    continue;
                }
            } else {
                // se for insert, ignora auto-inc e only-update
                if ($this->isOnlyUpdate($k) || $this->isAutoInc($k)) {
                    continue;
                }
            }
 
            $saida[$k] = $v;
        }
 
        return $saida;
    }
 
    public function getMensagemValidacao() {
        return $this->mensagemValidacao;
    }
 
    /**
     * Valida se todas as propriedades que são NOT null estão preenchidas
     * @return string
     */
    public function isTodasPropriedadesValidas($modo_update): bool {
 
        $this->mensagemValidacao = "";
        $modo_insert = !$modo_update;
 
        // pega todas as propriedades publicas e seus valores
        $propriedades = $this->getPublicVars();
 
        foreach ($propriedades as $k => $v) {
 
            // valor não tá nulo, ignora?
            if (isset($v)) {
                continue;
            }
 
            // campo permite nulo? então ignora
            if ($this->isNull($k)) {
                continue;
            }
 
            // se estamos no modo update 
            if ($modo_update) {
 
                // se o campo é somente insert, ignora
                if ($this->isOnlyInsert($k)) {
                    contineu;
                }
 
                $this->mensagemValidacao = "Campo '{$k}' está vazio (" . get_called_class() . ")u";
                break;
            }
 
            // se estamos no modo insert
            if ($modo_insert) {
 
                // se é campo somente insert ou auto-inc ignora
                if ($this->isOnlyUpdate($k) || $this->isAutoInc($k)) {
                    continue;
                }
 
                $this->mensagemValidacao = "Campo '{$k}' está vazio (" . get_called_class() . ")i";
                break;
            }
        }
        return (empty($this->mensagemValidacao));
    }
 
    public function getTabela(): string {
        $prop = new \ReflectionClass($this);
 
        // pega o comentário
        $comentario = $prop->getDocComment();
 
        // separa por espaço
        $p = explode(" "$comentario);
 
        // tem 2 itens e o segundo item começa com @ ?
        if (count($p) > 1 && $p[1][0] == "@") {
            // copia do segundo caracter até o fim
            return substr($p[1], 1);
        } else {
            return "";
        }
    }
 
    /** retorna TRUE se o campo chave não é nulo */
    public function isKeyContemValor(): bool {
 
        $propriedades = $this->getPublicVars();
 
        foreach ($propriedades as $k => $v) {
            if ($this->isKey($k)) {
                return !($v == null || $v == 0);
            }
        }
 
        return false;
    }
 
    public function getCampoChave(): string {
 
        $propriedades = $this->getPublicVars();
 
        // pega só as chaves
        $keys = array_keys($propriedades);
 
        foreach ($keys as $k) {
            if ($this->isKey($k)) {
                return $k;
            }
        }
 
        throw new Exception("Campo chave não localizado (" . get_called_class() . ")");
    }
 
    public function getInsertSQL() {
        $sql_campos = "INSERT INTO " . $this->getTabela() . " (";
        $sql_valores = ") VALUES (";
 
        // $propriedades retorna nome_propriedade => valor;  nome_propriedade => valor;  ...
        $propriedades = $this->getPublicVars();
 
        // pega só as chaves
        $keys = array_keys($propriedades);
 
        foreach ($keys as $k) {
 
            // se não é para entrar no insert e se é autoinc ignora
            if ($this->isOnlyUpdate($k) || $this->isAutoInc($k)) {
                continue;
            }
 
            $sql_campos .= $k . ",";
            $sql_valores .= ":{$k},";
        }
        return rtrim($sql_campos',') . rtrim($sql_valores',') . ")";
    }
 
    public function getUpdateSQL() {
        $sql = "UPDATE " . $this->getTabela() . " SET ";
        $sql_where = " WHERE ";
 
        // $propriedades retorna nome_propriedade => valor;  nome_propriedade => valor;  ...
        $propriedades = $this->getPublicVars();
 
        // pega só as chaves
        $keys = array_keys($propriedades);
 
        foreach ($keys as $k) {
 
            if ($this->isOnlyInsert($k)) {
                continue;
            }
 
            if ($this->isKey($k)) {
                $sql_where .= "{$k}=:{$k}";
            } else {
                $sql .= "{$k}=:{$k},";
            }
        }
        return rtrim($sql',') . $sql_where;
    }
 
    private function getSelectDelete($id): string {
        $sql = " FROM " . $this->getTabela() . " WHERE ";
 
        $propriedades = $this->getPublicVars();
 
        // pega só as chaves
        $keys = array_keys($propriedades);
 
        foreach ($keys as $k) {
 
            if ($this->isKey($k)) {
                $sql .= "{$k}=:{$k}";
                break;
            }
        }
        return $sql;
    }
 
    public function getSelectSQL($id) {
        return "SELECT *" . $this->getSelectDelete($id);
    }
 
    public function getDeleteSQL($id) {
        return "DELETE" . $this->getSelectDelete($id);
    }
 
    public function getSelectSQLSemWhere() {
        return "SELECT * FROM " . $this->getTabela() . " ";
    }
 
    // isso aqui vai mostrar um erro sempre que for tentado
    // setar uma propriedade que não existe -- é importante
    // para enviar erro de digitação
    public function __set($name$value) {
        $this->naoEncontrado(__FUNCTION__$name);
        echo "Valor: {$value}";
    }
 
    // se tentar obter uma propriedade que não existe
    // esse método é executado informando erro
    public function __get($name) {
        $this->naoEncontrado(__FUNCTION__$name);
    }
 
    // é chamado sempre que é testado uma propriedade
    // com o método isset($class->prop)
    public function __isset($name) {
        $this->naoEncontrado(__FUNCTION__$name);
    }
 
    // se chamar uma função que não existe ou não é pública
    // isso aqui será chamado
    public function __call($name$arguments) {
        $this->naoEncontrado(__FUNCTION__$name);
        var_dump($arguments);
    }
 
    // esse é executado quando chama o unset($var) com propridade
    // inválida ou privado
    public function __unset($name) {
        $this->naoEncontrado(__FUNCTION__$name);
    }
 
    private function naoEncontrado($metodo$nome) {
        throw new \Exception("{$metodo}: A propriedade {$nome} não existe em " . __CLASS__);
    }
 
}