<?php
abstract class Model {
/**
* Tabela representativa.
* @var [array]
*/
private $_Table;
/**
* Meta-Descrições dos Campos.
* @var [array]
*/
protected $_Meta;
/**
* Listagem dos Campos.
* @var [array]
*/
protected $_Fields;
/**
* Listagem de Campos que não são podem ser Nulos.
* @var [array]
*/
protected $_NotNull;
/**
* Instância de banco de dados Singleton.
* @var [PDO]
*/
private static $db;
/**
* Listagem de todas as instâncias.
* @var [array][array]
*/
private static $_Cache;
public static function _Instance() {
self::$db = new db();
}
/**
* Define a tabela que será usada no objeto.
* @param [string] $table Tabela representativa.
*/
private function setTable($table) {
# Verifica se a entrada é válida.
if(empty($table))
throw new Exception("A tabela não pode ser vazia.");
# Define a tabela na classe.
$this->_Table = $table;
}
public function Insert() {
try
{
Validate::Run($this);
foreach($this->_Fields as $Field)
$binds[':' . $Field] = $this->{$Field};
$values = implode(', ', keys($binds));
$fields = $this->_Fields;
unset($fields[0]);
$fields = implode(', ', $this->_Fields);
$query = "INSERT INTO ". $this->_Table ."(". $fields .") VALUES(". $values .")";
self::e($query, $binds);
$this->Select(self::$db->lastInsertId());
}
catch(Exception $e)
{
echo $e->getMessage();
return false;
}
}
public function Select($id = NULL) {
if(is_null($id)) {
$id = $this->{$this->_Fields[0]};
if(is_null($id))
throw new Exception("Impossível realizar select com id nulo da tabela ". $this->_Table .".");
}
$fields = implode(', ', $this->_Fields);
$query = "SELECT ". $fields ." FROM ". $this->_Table ." WHERE ". $this->_Fields[0] ." = ?";
$stmt = self::e($query , array($id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($row) {
$this->_ResetFields();
foreach($this->_Fields as $Field)
$this->{$Field} = $row[$Field];
# $this->{'Hash'} = Bcrypt::hash($id . $this->_Table);
self::$_Cache[$this->_Table][$this->_Fields[0]] = $this;
}
else
throw new Exception("Id ". $id ." não existe na tabela ". $this->_Table);
}
public function Delete($id = NULL) {
if(is_null($id)) {
$id = $this->{$this->_Fields[0]};
if(is_null($id))
throw new Exception("Impossível deletar um id nulo da tabela ". $this->_Table .".");
}
$query = "SELECT ". $fields ." FROM ". $this->_Table ." WHERE ". $this->_Fields[0] ." = ?";
$stmt = self::e($query , array($id));
if($stmt->fetch()) {
if(Db::$VirtualDeletion['on']) {
$query = "UPDATE ". $this->_Table ." SET ". Db::$VirtualDeletion['Field'] ." = '". Db::$VirtualDeletion['Value'] ."' WHERE ". $this->_Fields[0] ." = ?";
self::e($query, array($id));
}
else {
$query = "DELETE FROM ". $this->_Table ." WHERE ". $this->_Fields[0] ." = ?";
self::e($query, array($id));
}
return true;
}
else
throw new Exception("O id ". $id ." não pode ser excluído da tabela ". $this->_Table ." pois não existe.");
}
public function Update($id = NULL) {
if(is_null($id)) {
$id = $this->{$this->_Fields[0]};
if(is_null($id))
throw new Exception("Impossível realizer update em um id nulo da tabela ". $this->_Table .".");
}
Validate::Run($this);
foreach($this->_Fields as $Field)
$binds[':' . $Field] = $this->{$Field};
$fields = $this->_Fields;
unset($fields[0]);
foreach($fields as $Field)
$values[] = $Field .' = '. $this->{$Field};
$values[] = implode(', ', $values);
$query = "UPDATE ". $this->_Table ." SET ". $values ." WHERE ". $this->_Fields[0] ." = :" . $this->_Fields[0];
self::e($query, $binds);
unset(
self::$_Cache[$this->_Table][$this->_Fields[0]]
);
$this->Select($id);
}
/**
* Limpa os objetos da memória cache.
*/
public static function Clear() {
unset(self::$_Cache);
}
protected static function e($query, $binds) {
$_stmt = self::$db->prepare($query);
$_stmt->execute($binds);
return $_stmt;
}
protected static function q($query) {
return self::$db->query($query);
}
public function __destruct() {
self::$db = null;
unset(self::$_Cache);
}
}
/**
* Developer: Felipe Francisco
* Reference: admin@felipefrancisco.com.br
* Date: 10/10/2012
*/
class o extends Model {
/**
* Tipo de saída como HTML.
* @var [boolean]
*/
protected $_HtmlOut = false;
/**
* Contagem de Atributos reais (previamente declarados) existentes.
* @var [int]
*/
protected $_RealAttrs;
/**
* Inicia o objeto.
* @param [string] $table [Nome da tabela que será carregada em um objeto]
* @param [int] $id [Id para ser carregado juntamente, na criação da tabela.]
*/
function __construct($table, $id = NULL) {
# Inicia a instância de banco de dados.
if(!Model::db)
parent::_Instance();
# Verfica na memória se o objeto já foi iniciado anteriormente. Se sim, retorne-o.
if(self::$_Cache[$table][$id] instanceof o)
return self::$_Cache[$table][$id];
# Armazena o nome da tabela.
$this->setTable($table);
# Conta os atributos reais da classe para efeito de cálculo de campos posteriormente.
$this->_realAttrs();
# Gera os atributos virtuais;
$this->_virtAttrs();
if(!is_null($id))
$this->Select($id);
}
/**
* Valida as saídas da classe, sempre impimindo em formato HTML.
* @param [string] $var Representa um atributo virtual da tabela.
* @return [mixed] Valor correspondente ao atributo selecionado.
*/
public function __get($var) {
# Verifica se o atributo existe dentro dos atributos virutais.
if(in_array($var, $this->_Fields)) {
# Caso a saída HTML seja verdadeira, formataremos a variável.
if($this->_HtmlOut)
return Format::HTML($this->{$var});
else
return $this->{$var};
}
else
throw new Exception("Atributo ". $var ." da tabela ". $this->_Table ." não encontrado.");
}
/**
* Conta os atributos reais da classe para efeito de cálculo de campos posteriormente.
*/
private function _realAttrs() {
# Procura atributos previamente declarados e define a quantidade de atributos previamente declarados na classe.
foreach(get_object_vars($this) as $vars)
$this->_RealAttrs++;
}
/**
* Define os atributos virtuais da classe.
*/
private function _virtAttrs() {
# Consulta para exibir os campos da tabela em questão.
$query = "SHOW COLUMNS FROM ". $this->table;
# Execução da Consulta de exibição de campos da tabela.
$result = self::q($query);
# Caso existam campos na tabela, prossiga:
if ($result) {
# Enquanto existirem colunas, faça:
foreach ($result as $row) {
# Cria atributo virtual.
$this->{$row['Field']} = null;
# Acha a posição que representa o fim do nome do Tipo do Campo.
$strpos = strpos($row['Type'],'(');
# Define as Meta-características do campo.
$this->_Meta[$row['Field']] = ($strpos) ? substr($row['Type'], 0, $strpos) : $row['Type'];
# Armazena o campo na lista de Campos.
$this->_Fields[] = $row['Field'];
if($row['Null'] == 'YES');
$this->_NotNull[] = $row['Field'];
}
}
else
throw new Exception("Tabela ". $this->_Table ." não encontrada.");
}
/**
* Reseta a classe.
*/
private function _ResetAll() {
$this->_ResetFields();
$this->HtmlOutput(false);
unset(
$this->_Table,
$this->_RealAttrs,
$this->_Meta,
$this->_NotNull,
$this->_Fields
);
}
/**
* Define o tipo de saída de dados da classe como HTML
* @param [boolean] $mode ativa ou desativa a saída HTML
*/
public function HtmlOutput($mode = true) {
# Valida o modo de saída.
if(!is_bool($mode))
throw new Exception('Modo de HTML inválido');
# Define a saída de variáveis no modo HTML.
$this->_HtmlOut = $mode;
}
/**
* Reseta os campos virtuais.
*/
protected function _ResetFields() {
if(is_array($this->_Fields))
foreach($this->_Fields as $Field)
$this->{$Field} = null;
else
throw new Exception('Não há campos para limpar neste objeto: ' . var_export($this, true));
}
}
?>