<?php
// Include da package DB da pear.php.net
include_once("DB.php");

/**
 * +++++++++++++++++++ CODE GENERATOR ++++++++++++++++++++++++++
 * 1. Pacote para criação de classes apartir da estrutura de uma
 *    tabela do banco de dados
 * 2. Compativel com PHP 5 ou superior
 * 3. Utilização packages da pear do grupo PHP.net utilizando-se
 *    para conexão de banco de dados a package DB e na utilização
 *    da fonte criada também.
 * 4. Primeiramente foi feito para MySQL
 *    Funções que devem ser observadas para outros Bancos de dados:
 *         + getTableStructure()
 *         + CodeGenConnect()
 *         + abrTypes()
 *         + addFieldType()
 * 
 * @package CodeGenerator
 * @author Rafael Stoever
 * @since 07.2006
 * @version 1.2
 * @copyright rstoever.com 
 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 */
class CodeGenerator {
    
/**
     * Variavel de debug em tempo de execução
     * setada inicialmente no modo off para não mostrar
     *
     * @var bool $_debug
     */
    
protected    $_debug            false;
    
/**
     * Variavel que recebe os valores do database
     *
     * @var array $_dbc
     */
    
protected    $_dbc              = array();
    
/**
     * Variavel que transporta a conexão com o banco de dados
     * Utilizando-se do padrao da 
     *
     * @var unknown_type
     */
    
protected    $_conn;

    
/**
     * Variavel com o nome da tabela que está gerando a classe
     *
     * @var string $_tablename
     */
    
protected    $_tablename       "";
    
/**
     * Variavel com o nome da classe que será gerado o fonte
     *
     * @var string $_classname
     */
    
protected    $_classname        "";
    
/**
     * Variavel contendo os nomes dos campos da estrutura da tabela
     *
     * @var array $_fieldsNames
     */
    
protected    $_fieldsNamesOriginal      = array();
    
/**
     * Variavel contendo os nomes dos campos da estrutura da tabela
     *
     * @var array $_fieldsNames
     */
    
protected    $_fieldsNames      = array();
    
/**
     * Variavel contendo os nomes dos campos e seus tipos de dados
     *
     * @var array $_fieldsTypes
     */
    
protected    $_fieldsTypes      = array();
    
/**
     * Variavel contendo os nomes dos campos e seus tamanhos de dados
     *
     * @var array $_fieldsLen
     */
    
protected    $_fieldsLen        = array();
    
/**
     * Variavel contendo os nomes dos campos e se este campo é nulo ou não
     *
     * @var array $_fieldsNullable
     */
    
protected    $_fieldsNullable   = array();
    
/**
     * Variavel contendo os nomes dos campos que são primary keys
     *
     * @var array $_fieldsPrimaryKey
     */
    
protected    $_fieldsPrimaryKey = array();
    
/**
     * Variavel que irá conter toda a string do codigo fonte
     *
     * @var string $_code
     */
    
protected    $_code             "";

    protected    
$_author           "";
    
/**
     * Construtor da classe CodeGenerator
     * E em seguida tenta conectar no banco
     * 
     * @access private
     * @param string $host
     * @param string $database
     * @param string $user
     * @param string $password
     * @param string $soft
     * @param bool   $debug
     */
    
public function __construct($host$database$user='root'$password=''$soft 'mysql'$debug false) {
        
$this->_dbc['host']     = $host;
        
$this->_dbc['database'] = $database;
        
$this->_dbc['user']     = $user;
        
$this->_dbc['password'] = $password;
        
$this->_dbc['software'] = $soft;
        
$this->_debug           $debug;
        
$this->codeGenConnect();
    }
    
/**
     * Função para adicionar um autor para a classe
     *
     * @param string $strAuthor
     */
    
public function setAuthor($strAuthor ""){
        
$this->_author $strAuthor;
    }
    
/**
     * Função que retorna o nome do autor da classe
     *
     * @return string
     */
    
protected function getAuthor(){
        return 
$this->_author;
    }
    
/**
     * Função para setar qual a tabela que será transformada em classe
     * 
     * @access public
     * @param string $strTable
     */
    
public function setTable($strTable) {
        if (!empty(
$strTable)) {
            
$this->debug("(setTable) Setando a tabela[".$strTable."] do banco de dados para classname!");
            
$this->_dbc['table'] = $strTable;
            
$this->_classname    ucfirst($this->rename($this->_dbc['table']));
            
$this->_tablename $this->_dbc['table'];
        } else {
            
$this->debug("(setTable) Favor informar uma tabela para criar uma classe!");
            exit(
0);
        }
    }

    
/**
     * Funcão que adicionar a PK do campo na estrutura
     *
     * @param string $strFieldName
     * @param bool $strFieldPrimaryKey
     */
    
private function addFieldPrimaryKey($strFieldName,$strFieldPrimaryKey false){
        
$this->debug("(addFieldPrimaryKey) Adicionando a estrutura aa Primary Key no campo[".$strFieldName."] ");
        if (
$this->existsFieldName($strFieldName)) {
            
$newPK = array($strFieldName=>$strFieldPrimaryKey);
            
$this->_fieldsPrimaryKey array_merge($this->_fieldsPrimaryKey,$newPK);
            
$this->debug("(addFieldPrimaryKey) Sucesso ao adicionar a PK no campo[".$strFieldName."] na estrutura.");
        } else {
            
$this->debug("(addFieldPrimaryKey) Campo inexistente na estrutura.",true);
        }
    }

    
/**
     * Função que adiciona o Null ou Not Null na estrutura do campo
     * » NullAble (Y/N)
     *   Y - É Nulo
     *   N - É Not Null
     * 
     * @param string $strFieldName
     * @param string $strFieldNullable (Y/N)
     */
    
private function addFieldNullable($strFieldName,$strFieldNullable "Y"){
        
$this->debug("(addFieldNullable) Adicionando a estrutura o Nullable[".$strFieldNullable."] do campo[".$strFieldName."] ");
        if (
$this->existsFieldName($strFieldName)) {
            
$newNullable = array($this->rename($strFieldName)=>$strFieldNullable);
            
$this->_fieldsNullable array_merge($this->_fieldsNullable,$newNullable);
            
$this->debug("(addFieldNullable) Sucesso ao adicionar o NullAble[".$strFieldNullable."] do campo[".$strFieldName."] na estrutura.");
        } else {
            
$this->debug("(addFieldNullable) Campo inexistente na estrutura.",true);
        }
    }

    
/**
     * Função que adiciona o tamanho do campo
     *
     * @access private
     * @param string $strFieldName
     * @param int    $strFieldLen
     */
    
private function addFieldLen($strFieldName,$strFieldLen 0){
        
$this->debug("(addFieldLen) Adicionando a estrutura o tamanho[".$strFieldLen."] do campo[".$strFieldName."] ");
        if (
$this->existsFieldName($strFieldName)) {
            
$newLen = array($this->rename($strFieldName)=>$strFieldLen);
            
$this->_fieldsLen array_merge($this->_fieldsLen,$newLen);
            
$this->debug("(addFieldLen) Sucesso ao adicionar o tamanho[".$strFieldLen."] do campo[".$strFieldName."] na estrutura.");
        } else {
            
$this->debug("(addFieldLen) Campo inexistente na estrutura.",true);
        }
    }
    
/**
     * Função que retorna o tamanho do campo solicitado
     *
     * @param string $strFieldName
     * @return int
     */
    
private function getFieldLen($strFieldName) {
        
$this->debug("(getFieldLen) Obtendo o tamanho do campo[".$strFieldName."]");
        return 
$this->_fieldsLen[$strFieldName];
    }
    
/**
     * Função que retorna o tipo do campo solicitado
     *
     * @param string $strFieldName
     * @return string
     */
    
protected function getFieldType($strFieldName) {
        
$this->debug("(getFieldType) Obtendo o tipo do campo[".$strFieldName."]");
        return 
$this->_fieldsTypes[$strFieldName];
    }

    
/**
     * Função que adiciona o tipo do campo
     *
     * @access private
     * @param string $strFieldName
     * @param string $strFieldType
     */
    
private function addFieldType($strFieldName,$strFieldType "string") {
        
$this->debug("(addFieldType) Adicionando a estrutura o tipo[".$strFieldType."] do campo[".$strFieldName."].");
        if (
$this->existsFieldName($strFieldName)) {
            switch (
strtolower($strFieldType)) {
                case 
'string':
                
$strType 'string';
                break;
                case 
'blob':
                
$strType 'blob';
                break;
                case 
'varchar2':
                
$strType 'string';
                break;
                case 
'char':
                
$strType 'string';
                break;
                case 
'int':
                
$strType 'int';
                break;
                case 
'number':
                
$strType 'int';
                break;
                default:
                
$strType 'string';
                break;
            }
            
$newType = array($this->rename($strFieldName)=>$strType);
            
$this->_fieldsTypes array_merge($this->_fieldsTypes,$newType);
            
$this->debug("(addFieldType) Sucesso ao adicionar o tipo[".$strFieldType."] ao campo[".$strFieldName."] na estrutura.");
        } else {
            
$this->debug("(addFieldType) Campo inexistente na estrutura.",true);
        }
    }

    
/**
     * Função para adicionar um campo na estrutura
     *
     * @access private
     * @param string $strFieldName
     */
    
private function addFieldName($strFieldName){
        if (!empty(
$strFieldName)) {
            
$this->debug("(addFieldName) Adicionando campo[".$strFieldName."] para controle da estrutura da classe.");
            if (!
$this->existsFieldName($strFieldName)) {
                
$this->debug("(addFieldName) Adicionado o campo a estrutura.");
                
array_push($this->_fieldsNames,$this->rename($strFieldName));
                
array_push($this->_fieldsNamesOriginal,$strFieldName);
            } else {
                
$this->debug("(addFieldName) Campo já existente na estrutura!");
            }
        } else {
            
$this->debug("(addFieldName) Não foi informado o nome do campo.",true);
        }
    }

    
/**
     * Verificação se já existe o campo na estrutura
     *
     * @access private
     * @param strin $strFieldName
     * @return bool
     */
    
private function existsFieldName($strFieldName){
        
$this->debug("(existsFieldName) Iniciando a busca do campo[".$this->rename($strFieldName)."] no array.");
        if (!empty(
$strFieldName)) {
            if (
count($this->_fieldsNames) > 0) {
                
$achou false;
                for (
$i=0;$i<count($this->_fieldsNames);$i++) {
                    if (
$this->_fieldsNames[$i] == $this->rename($strFieldName)) {
                        
$achou true;
                        break;
                    }
                }
                if (
$achou) {
                    
$this->debug("(existsFieldName) Campo encontrado.");
                    return 
true;
                } else {
                    
$this->debug("(existsFieldName) Campo inexistente!");
                    return 
false;
                }
            } else {
                
$this->debug("(existsFieldName) Campo inexistente!");
                return 
false;
            }
        } else {
            
$this->debug("(existsFieldName) Não foi passado um nome de campo para a busca.",true);
        }
        return 
false;
    }
    protected function 
cleanVar(){
        
$this->_code                = array();
        
$this->_tablename           '';
        
$this->_classname           '';
        
$this->_fieldsLen           = array();
        
$this->_fieldsNames         = array();
        
$this->_fieldsNamesOriginal = array();
        
$this->_fieldsNullable      = array();
        
$this->_fieldsPrimaryKey    = array();
        
$this->_fieldsTypes         = array();
    }
    
/**
     * Função que inicia o processo de geração do código fonte da classe.
     *
     * @param string[optional] $strTable
     */
    
public function run($strTable "") {
        
$this->cleanVar();
        if (!empty(
$strTable)) {
            
$this->setTable($strTable);
        }
        
$this->debug("(run) Iniciando programa.");
        
$this->getTableStructure();
        
$this->debug("(run) Iniciando a criação do código fonte da classe.");
        
$this->createCode();
        
$this->debug("(run) Finalizado a criação do código fonte da classe.");
        
$this->debug("(run) Gravando arquivo com o fonte da classe.");
        
$this->writeFile($this->_classname.'.class.php'$this->_code);
    }
    
/**
    * Função que grava num arquivo especificado o texto passado como parametro
    *
    * @param string $strFileName
    * @param string $strTexto
    */
    
protected function writeFile($strFileName$strTexto) {
        if (!
file_exists("class")) {
            
mkdir("./class");
        }
        
$fh = @fopen('./class/'.$strFileName'w');
        if (@
fwrite($fh$strTexto)) {
            
$this->debug("(writeFile) Arquivo[".$strFileName."] salvo com sucesso.");
        } else {
            
$this->debug("(writeFile) Problemas ao salvar o arquivo['.$strFileName.'].",true);
        }
        
fclose($fh);
        
$this->debug("<hr>");
    }

    private function 
abrTypes($strText) {
        switch (
strtolower($strText)) {
            case 
"string"  $res 'str';
            break;
            case 
"int"     $res 'int';
            break;
            case 
"integer" $res 'int';
            break;
            case 
"blob"    $res 'str';
            break;
            case 
"bool"    $res 'bool';
            break;
            case 
"varchar2"$res 'str';
            break;
            case 
"char"    $res 'str';
            break;
            default        :  
$res 'str';
            break;
        }
        return 
$res;
    }
    
/**
     * Função para verificação se o campo é Null ou Not Null
     *
     * @param string $field
     * @param string $strTrue
     * @param string $strFalse
     * @return string[bool]
     */
    
protected  function isRequired($strField,$strTrue true,$strFalse false) {
        
$this->debug("(isRequired) Iniciando a verificação se o campo[".$strField."] é null ou não");
        if (isset(
$this->_fieldsNullable)) {
            
$res $this->_fieldsNullable[$strField];
        }
        if (
$res == 'Y') {
            return 
$strTrue;
        } else {
            return 
$strFalse;
        }
    }

    
/**
     * Função de criação do codigo fonte da classe
     *
     */
    
protected function createCode() {
        
// 1. Cabeçalho do arquivo
        
$this->_code[] = '<?php';
        
$this->_code[] = '/**';
        
$this->_code[] = ' * Classe simples obtida do banco de dados ';
        
$this->_code[] = ' * 1. Lembrando que deve-se ser usado a classe DB do pacote PEAR';
        
$this->_code[] = ' * 2. Suportado pelas versões PHP >= 5';
        
$this->_code[] = ' * ';
        
$this->_code[] = ' * @since '.date('d/m/Y H:i:s');
        
$this->_code[] = ' * @package '.$this->_classname;
        
$aut $this->getAuthor();
        if (!empty(
$aut)) {
            
$this->_code[] = ' * @author '.$this->getAuthor();
        }
        
$this->_code[] = ' */';
        
// 2. Classe
        
$this->_code[] = 'class '.$this->_classname.' {';
        
// 3. Declaração das variáveis
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * @var array $_fieldsTypes';
        
$this->_code[] = '   * @access private';
        
$this->_code[] = '   */';
        
$this->_code[] = '   private $_fieldsTypes = array();';
        
$this->_code[] = '';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * @var array $_fieldsLen';
        
$this->_code[] = '   * @access private';
        
$this->_code[] = '   */';
        
$this->_code[] = '   private $_fieldsLen = array();';
        
$this->_code[] = '';
        foreach (
$this->_fieldsNames as $field) {
            
$this->_code[] = '  /**';
            
$this->_code[] = '   * @var '.$this->getFieldType($field).'['.$this->getFieldLen($field).'] $_'.$field;
            
$this->_code[] = '   * @access private';
            
$this->_code[] = '   */';
            
$this->_code[] = '   private $_'.$field.';';
        }
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * @var array $_fieldsRequired ';
        
$this->_code[] = '   * @access private';
        
$this->_code[] = '   */';
        
$this->_code[] = '   private $_fieldsRequired = array();';
        
// 4. Construtor da classe
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * @param bool[optional] $clear (default = true)';
        
$this->_code[] = '   *                              Parametro que ao criar o objeto já';
        
$this->_code[] = '   *                              limpar e setar algumas variáveis';
        
$this->_code[] = '   * @sice '.date('d/m/Y H:i:s');
        
$this->_code[] = '   */';
        
$this->_code[] = '   public function __construct($clearVariables = true) {';
        
$this->_code[] = '     if ($clearVariables === true) {';
        
$this->_code[] = '       $this->clearVariables(true);';
        
$this->_code[] = '     }';
        
$this->_code[] = '     $this->setFieldsTypes();';
        
$this->_code[] = '     $this->setFieldsLen();';
        
$this->_code[] = '   }';
        
$this->_code[] = '   ';
        
// 5. Métodos GETTERS e SETTERS
        
foreach ($this->_fieldsNames as $field) {
            
$this->_code[] = '   /**';
            
$this->_code[] = '    * Função para adquirir(GET) o valor do campo '.$field;
            
$this->_code[] = '    * @return '.$this->getFieldType($field).'['.$this->getFieldLen($field).'] '.$field;
            
$this->_code[] = '    */';
            
$this->_code[] = '    public function '.$this->rename($field,'get').'($posicao = 0) {';
            if (
$this->getFieldType($field) == 'int') {
                
$this->_code[] = '      if (empty($this->_'.$field.'[$posicao])) {';
                
$this->_code[] = '        $this->set'.ucfirst($field).'(0);';
                
$this->_code[] = '      }';
            }
            
$this->_code[] = '      return $this->_'.$field.'[$posicao];';
            
$this->_code[] = '    }';
            
$this->_code[] = '    ';
            
$this->_code[] = '   /**';
            
$this->_code[] = '    * Função para (SET)ar o valor do campo '.$field;
            
$this->_code[] = '    * @param '.$this->getFieldType($field).'['.$this->getFieldLen($field).'] '.$field;
            
$this->_code[] = '    * @param bool[optional] require Caso o campo for obrigatório no banco';
            
$this->_code[] = '    *                       T -> É obrigatório';
            
$this->_code[] = '    *                       F -> Não é obrigatório';
            
$this->_code[] = '    * @return '.$this->getFieldType($field).'['.$this->getFieldLen($field).'] '.$field;
            
$this->_code[] = '    */';
            
$this->_code[] = '    public function '.$this->rename($field,'set').'($'.$this->abrTypes($this->getFieldType($field)).ucfirst($field).',$require = "'.$this->isRequired($field,"T","F").'",$posicao=0) {';
            
$this->_code[] = '      $this->_'.$field.'[$posicao] = $'.$this->abrTypes($this->getFieldType($field)).ucfirst($field).';';
            
$this->_code[] = '      $this->setFieldRequire("'.$field.'",$require);';
            
$this->_code[] = '    }';
        }
        
$this->_code[] = '    ';
        
$this->_code[] = '  //################ FUNCOES DE CONTROLE #########################';
        
$this->_code[] = '    ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que irá setar os tipos dos campos';
        
$this->_code[] = '   * @access private';
        
$this->_code[] = '   * @return void';
        
$this->_code[] = '   */';
        
$this->_code[] = '  private Function setFieldsTypes() {                                        ';
        foreach (
$this->_fieldsNames as $field)    {
            
$this->_code[] = '    $this->_fieldsTypes = array_merge($this->_fieldsTypes,array("'.$field.'"=>"'.$this->getFieldType($field).'"));';
        }
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '  ';
        foreach (
$this->_fieldsNames as $field)    {
            
$this->_code[] = '  /**';
            
$this->_code[] = '   * Função que irá retornar o tipo do campo '.$field;
            
$this->_code[] = '   * @access public';
            
$this->_code[] = '   * @return string';
            
$this->_code[] = '   */';
            
$this->_code[] = '    public function get'.ucfirst(strtolower($field)).'FieldType(){';
            
$this->_code[] = '      return $this->_fieldsTypes["'.$field.'"];';
            
$this->_code[] = '    }';
        }
        
$this->_code[] = '  ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que irá setar os tipos dos campos';
        
$this->_code[] = '   * @access private';
        
$this->_code[] = '   * @return void';
        
$this->_code[] = '   */';
        
$this->_code[] = '  private Function setFieldsLen() {                                        ';
        foreach (
$this->_fieldsNames as $field)    {
            
$this->_code[] = '    $this->_fieldsLen = array_merge($this->_fieldsLen,array("'.$field.'"=>'.$this->getFieldLen($field).'));';
        }
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '  ';
        foreach (
$this->_fieldsNames as $field)    {
            
$this->_code[] = '  /**';
            
$this->_code[] = '   * Função que irá retornar o tamanho do campo '.$field;
            
$this->_code[] = '   * @access public';
            
$this->_code[] = '   * @return float';
            
$this->_code[] = '   */';
            
$this->_code[] = '    public function get'.ucfirst(strtolower($field)).'FieldLen(){';
            
$this->_code[] = '      return $this->_fieldsLen["'.$field.'"];';
            
$this->_code[] = '    }';
        }
        
$this->_code[] = '  ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que irá limpar as variáveis';
        
$this->_code[] = '   * @param string $strField';
        
$this->_code[] = '   * @access public';
        
$this->_code[] = '   */';
        
$this->_code[] = '  public Function clearVariable($strField) {                                        ';
        
$this->_code[] = '    if ($this->isRequired($strField)) { $required = "T"; } else { $required = "F"; }';
        
$this->_code[] = '    call_user_method("set".$strField, $this,"");                   ';
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '                                                                             ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Atalho para a função que irá limpar as variáveis locais somente';
        
$this->_code[] = '   * @access public';
        
$this->_code[] = '   */';
        
$this->_code[] = '  public Function clearThisVariablesOnly() {                                                       ';
        
$this->_code[] = '    $this->clearVariables(true,false);';
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '                                                                             ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que irá limpar as variáveis desta classe ou de classes pais(extends)';
        
$this->_code[] = '   * @param bool[optional] $boolThis (default = false)';
        
$this->_code[] = '   * @param bool[optional] $boolFieldsRequired (default = true)';
        
$this->_code[] = '   * @access public';
        
$this->_code[] = '   */';
        
$this->_code[] = '  public Function clearVariables($boolThis = false,$boolFieldsRequired = true) {                                  ';
        
$this->_code[] = '    if (!$boolThis) {                                                           ';
        
$this->_code[] = '      $biza = @get_parent_class(@get_parent_class(@get_parent_class($this)));';
        
$this->_code[] = '      if (!empty($biza)) {                                                    ';
        
$this->_code[] = '        if (method_exists($this,"clearVariables") ) {          ';
        
$this->_code[] = '          parent::clearVariables();         ';
        
$this->_code[] = '        }                                                                    ';
        
$this->_code[] = '      }                                                                      ';
        
$this->_code[] = '    }                                                                        ';
        
$this->_code[] = '    if (!$boolFieldsRequired) {';
        
$this->_code[] = '      $this->_fieldsRequired = array();';
        
$this->_code[] = '    }';
        foreach (
$this->_fieldsNames as $field)    {
            
$this->_code[] = '    $this->'.$this->rename($field'set').'("","'.$this->isRequired($field,"T","F").'");';
        }
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '                                                                             ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que seta os campos que são obrigatório para a classe/DB';
        
$this->_code[] = '   * @param string $strField Campo da tabela';
        
$this->_code[] = '   * @param bool $boolRequired Informativo se o campo é obrigatório ou não (default = "F")';
        
$this->_code[] = '   * @access private';
        
$this->_code[] = '   */';
        
$this->_code[] = '  private Function setFieldRequire($strField,$boolRequired = "F") {                                         ';
        
$this->_code[] = '    if ( (strtoupper($boolRequired) == "T") || ($boolRequired === 1) )  {                         ';
        
$this->_code[] = '      $ma = $this->_fieldsRequired;                                      ';
        
$this->_code[] = '      $c = count($ma);                                                       ';
        
$this->_code[] = '      $achou = false;                                                        ';
        
$this->_code[] = '      for ($i = 0; $i < $c; $i++ ) {                                         ';
        
$this->_code[] = '        if ($ma[$i] == trim($strField)) {                           ';
        
$this->_code[] = '          $achou = true;                                                     ';
        
$this->_code[] = '          break;                                                             ';
        
$this->_code[] = '        }                                                                    ';
        
$this->_code[] = '      }                                                                      ';
        
$this->_code[] = '      if (!$achou) {                                                         ';
        
$this->_code[] = '        $ma[++$c] = trim($strField);                                ';
        
$this->_code[] = '      }                                                                      ';
        
$this->_code[] = '      $this->_fieldsRequired = $ma;                                      ';
        
$this->_code[] = '    }                                                                        ';
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '                                                                             ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que verifica se o campo é obrigatório';
        
$this->_code[] = '   * @param string $strField';
        
$this->_code[] = '   * @return bool';
        
$this->_code[] = '   * @access protected';
        
$this->_code[] = '   */';
        
$this->_code[] = '  protected Function isRequired($strField) {                                           ';
        
$this->_code[] = '    $ma = $this->_fieldsRequired;                                        ';
        
$this->_code[] = '    $c = count($ma);                                                         ';
        
$this->_code[] = '    $achou = false;                                                          ';
        
$this->_code[] = '    if ($c > 0) {                                                            ';
        
$this->_code[] = '      foreach ($ma as $value) {                                              ';
        
$this->_code[] = '        if ($strField == $value) {                                              ';
        
$this->_code[] = '          $achou = true;                                                     ';
        
$this->_code[] = '          break;                                                             ';
        
$this->_code[] = '        }                                                                    ';
        
$this->_code[] = '      }                                                                      ';
        
$this->_code[] = '    }                                                                        ';
        
$this->_code[] = '    return $achou;                                                           ';
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '                                                                             ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que retornará se há campos não informados que são obrigatórios';
        
$this->_code[] = '   * @return bool';
        
$this->_code[] = '   * @access public';
        
$this->_code[] = '   */';
        
$this->_code[] = '  public Function haveErrors() {                                                      ';
        
$this->_code[] = '    $ma = $this->_fieldsRequired;                                        ';
        
$this->_code[] = '    $c = count($ma);                                                         ';
        
$this->_code[] = '    if ($c > 0) {                                                            ';
        
$this->_code[] = '      foreach ($ma as $value) {                                              ';
        
$this->_code[] = '        $var = call_user_method("get".$value, $this, "0") ;                   ';
        
$this->_code[] = '        if (empty($var)) {                                                   ';
        
$this->_code[] = '          return true;                                                       ';
        
$this->_code[] = '          break;                                                             ';
        
$this->_code[] = '        }                                                                    ';
        
$this->_code[] = '      }                                                                      ';
        
$this->_code[] = '    }                                                                        ';
        
$this->_code[] = '    return false;                                                            ';
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '                                                                             ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que retornará se o campo solicitado foi informado';
        
$this->_code[] = '   * @return bool/string Conforme o parametro';
        
$this->_code[] = '   * @param string $strField Campo/Variavel da classe';
        
$this->_code[] = '   * @param bool/string $res1 É o valor que irá retornar se tiver Error = TRUE ';
        
$this->_code[] = '   * @param bool/string $res2 É o valor que irá retornar se não tiver Error = FALSE';
        
$this->_code[] = '   * @access public';
        
$this->_code[] = '   */';
        
$this->_code[] = '  public Function haveError($strField = "",$res1 = true,$res2 = false) {                 ';
        
$this->_code[] = '    $ma = $this->_fieldsRequired;                                        ';
        
$this->_code[] = '    $c = count($ma);                                                         ';
        
$this->_code[] = '    if ($c > 0) {                                                            ';
        
$this->_code[] = '      foreach ($ma as $value) {                                              ';
        
$this->_code[] = '        $var = call_user_method("get".$value, $this, "0");                    ';
        
$this->_code[] = '        if (strtoupper(trim($strField)) == strtoupper($value) && (empty($var))) {     ';
        
$this->_code[] = '          return $res1;                                                      ';
        
$this->_code[] = '          break;                                                             ';
        
$this->_code[] = '        }                                                                    ';
        
$this->_code[] = '      }                                                                      ';
        
$this->_code[] = '      return $res2;                                                          ';
        
$this->_code[] = '    } else {                                                                 ';
        
$this->_code[] = '      return $res2;';
        
$this->_code[] = '    }                                                                        ';
        
$this->_code[] = '  }                                                                          ';
        
$this->_code[] = '                                                                             ';
        
$this->_code[] = '  /**';
        
$this->_code[] = '   * Função que retornará um array dos campos que não foram informados e são obrigatórios';
        
$this->_code[] = '   * @return array';
        
$this->_code[] = '   * @access public';
        
$this->_code[] = '   */';
        
$this->_code[] = '  public Function arrayErrors() {                                                    ';
        
$this->_code[] = '    $retorno = "";                                                           ';
        
$this->_code[] = '    $c = 0;                                                                  ';
        
$this->_code[] = '    if ($this->haveErrors())  {                                                ';
        
$this->_code[] = '      $ma = $this->_fieldsRequired;                                      ';
        
$this->_code[] = '      foreach ($ma as $value) {                                              ';
        
$this->_code[] = '        $var = call_user_method("get".$value, $this, "0") ;                   ';
        
$this->_code[] = '        if (empty($var)) {                                                   ';
        
$this->_code[] = '          $retorno[$c++] = $value;                                           ';
        
$this->_code[] = '        }                                                                    ';
        
$this->_code[] = '      }                                                                      ';
        
$this->_code[] = '      return $retorno;                                                       ';
        
$this->_code[] = '    } else { return array(); }                                                 ';
        
$this->_code[] = '  }';
        
$this->_code[] = '';
        
$this->_code[] = '    protected function rename($db_formatted_name, $prefix = "") {';
        
$this->_code[] = '        if ($prefix != ""){';
        
$this->_code[] = '            $db_formatted_name = $prefix."_".$db_formatted_name;';
        
$this->_code[] = '        }';
        
$this->_code[] = '';
        
$this->_code[] = '        $parts = split("_", $db_formatted_name);';
        
$this->_code[] = '        $result = "";';
        
$this->_code[] = '';
        
$this->_code[] = '        foreach ($parts as $p => $part)    {';
        
$this->_code[] = '            //    the first letter had to be lowercase';
        
$this->_code[] = '            if ($p == 0) {';
        
$this->_code[] = '                $result .= strtolower($part);';
        
$this->_code[] = '            } else {';
        
$this->_code[] = '                $result .= ucfirst(strtolower($part));';
        
$this->_code[] = '            }';
        
$this->_code[] = '        }';
        
$this->_code[] = '        return    $result;';
        
$this->_code[] = '    }';
        
$this->_code[] = '';
        
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        
$this->_code[] = '}';
        
$this->_code[] = '';
        
$this->_code[] = '/** Esta classe foi gerado automaticamente pelo Code-Gen rstoever.com **/';
        
$this->_code[] = '';
        
$this->_code[] = '?>';
        
$this->_code implode("\n"$this->_code);
    }

    
/**
     * Função onde adiquire todos os dados da estruta da tabela
     * para gerar a classe
     *
     * @access private
     */
    
protected function getTableStructure() {
        
$conn =& $this->_conn;
        
$res $conn->tableInfo($this->_dbc['table']);
        
$this->debug("(getTableStruture) Varendo a estrutura da tabela[".$this->_classname."] contendo (".count($res).") registros.");
        
$x=0;
        for (
$i=0;$i<count($res);$i++) {
            
$this->debug("<b>(getTableStruture)</b> ".++$x);
            
$this->addFieldName($res[$i]['name']);
            
$this->addFieldType($res[$i]['name'],$res[$i]['type']);
            
$this->addFieldLen($res[$i]['name'],$res[$i]['len']);
            if (!empty(
$res[$i]['flags'])) {
                
// Deve ser observado os campos not_null <---- Pode ser alterdo
                
preg_match('[[nN]ot.[nN]ull]',$res[$i]['flags'],$notnull);
                if (!empty(
$notnull[0])) {
                    
$this->addFieldNullable($res[$i]['name'],"Y");
                }
                
// Deve ser observado os campos primary_key <---- Pode ser alterdo
                
preg_match('[[pP]rimary.[kK]ey]',$res[$i]['flags'],$pk);
                if (!empty(
$pk[0])) {
                    
$this->addFieldPrimaryKey($res[$i]['name'],"Y");
                }
            }
        }
    }

    
/**
     * Esta função renomea o nome do banco para um className
     * 
     * @example acl_user_id => aclUserId
     * @access protected
     * @param string input string
     * @param string prefix like get, set or is
     * @return string output camel-case foramtted string
     */    
    
protected function rename($db_formatted_name$prefix '') {
        if (
$prefix != ''){
            
$db_formatted_name $prefix.'_'.$db_formatted_name;
        }

        
$parts split('_'$db_formatted_name);
        
$result '';

        foreach (
$parts as $p => $part)    {
            
//    the first letter had to be lowercase
            
if ($p == 0) {
                
$result .= strtolower($part);
            } else {
                
$result .= ucfirst(strtolower($part));
            }
        }
        return    
$result;
    }


    
/**
     * Code Generator Conect DB
     * Se ocorrer algum erro o programa aborta aqui mesmo
     *    senao ele continua
     * 
     * @access private
     */
    
protected function CodeGenConnect(){

        
$dsn = array(
        
'phptype'  => $this->_dbc['software'],
        
'username' => $this->_dbc['user'],
        
'password' => $this->_dbc['password'],
        
'hostspec' => $this->_dbc['host'],
        
'database' => $this->_dbc['database'],
        );

        
$options = array(
        
'debug'       => 2,
        
'portability' => DB_PORTABILITY_ALL,
        );

        
$conn =& DB::connect($dsn$options);
        if (
PEAR::isError($conn))
        {
            
$this->debug("(CodeGenConnect) Problemas na conexão do banco de dados: ".$conn->getMessage (),true );
        }
        
$conn->autoCommit(false);
        
$this->debug("(CodeGenConnect) Sucesso ao conectar ao Banco de dados!");
        
$this->_conn =& $conn;
    }

    
/**
     * 1. Função que verifica se a opção de debug está habilitada e mostra as
     *    mensagem passo a passo para debug
     * 2. Caso for informado o abort como true o programa para de executar.
     * 
     * @access private
     * @param string $strDebug
     * @param bool   $abort
     */
    
protected function debug($strDebug ""$abort false){
        if (
$this->_debug) {
            echo 
'DEBUG: '$strDebug." <br />\n";
        }
        if (
$abort) {
            echo 
"Programa abortado \n";
            exit(
0);
        }
    }
}
?>