Esempio n. 1
0
 /**
  * checa se o objeto possui relacionamentos e remove os objetos relacionados ou restringe.
  * Se houver relacionamentos no modo RESTRICT (ao menos um), Lumine não irá remover.
  * Se todos forem CASCADE, Lumine irá remover todos.
  * Se o relacionamento no mapeameanto for definido de qualquer outra forma a não ser RESTRICT ou CASCADE,
  * será interpretado como RESTRICT.
  * @author Hugo Ferreira da Silva
  * @access public
  * @param LumineBase $obj Um objeto que extende a classe LumineBase
  * @return array
  * @static 
  */
 function removeAll(&$obj)
 {
     if (is_a($obj, 'luminebase') == false) {
         LumineLog::logger(2, 'O objeto não extende a classe LumineBase', __FILE__, __LINE__);
         return false;
     }
     LumineLog::logger(1, 'Recuperando relacionamentos de ' . get_class($obj), __FILE__, __LINE__);
     $fks = $obj->oTable->getForeignKeys();
     // var que diz q passa
     $pass = true;
     // para cada um encontrado
     foreach ($fks as $fkname => $prop) {
         // para as que são OTM
         if ($prop['type'] == LUMINE_OTM) {
             // recupera a classe relacionada
             $o = Util::Import($prop['class']);
             // pega as fk's da outra classe
             $fko = $o->oTable->getForeignKeys();
             // se for restrict
             if (isset($fko['ondelete']) && strtolower($fko['ondelete']) != 'cascade') {
                 // pega o valor do relacionamento
                 $v = $obj->{$fko[$prop['linkOn']]['linkOn']};
                 // se o valor for nulo, passa para a próxima iteração
                 if ($v == '') {
                     continue;
                 }
                 $o->{$prop}['linkOn'] = $v;
                 // se o valor não for nulo, procura por elementos
                 $total = $o->count();
                 // se encontrar
                 if ($total > 0) {
                     LumineLog::logger(1, 'Objeto relacionado encontrado em ' . $prop['class'] . ': parando remoção', __FILE__, __LINE__);
                     // pára o loop e não deixa remover
                     $pass = false;
                     break;
                 }
             }
         }
         // olhando pelas many-to-many
         if ($prop['type'] == LUMINE_MTM) {
             if (!isset($prop['ondelete']) || strtolower($prop['ondelete']) != 'cascade') {
                 // tenta recuperar o link
                 $x = $obj->getLink($fkname);
                 // se estiver vazio
                 if (count($x) == 0) {
                     LumineLog::logger(1, 'Objeto relacionado encontrado em ' . $prop['class'] . ': parando remoção', __FILE__, __LINE__);
                     // passa para a próxima iteração
                     continue;
                 }
                 // diz que não pode remover
                 $pass = false;
                 // pára o loop
                 break;
             }
         }
     }
     // se passou
     if ($pass) {
         // remove todos os objetos relacionados a este
         reset($fks);
         foreach ($fks as $fkname => $prop) {
             if ($prop['type'] == LUMINE_OTM) {
                 LumineLog::logger(1, 'Removendo objetos de ' . $prop['class'], __FILE__, __LINE__);
                 $o = Util::Import($prop['class']);
                 $fko = $o->oTable->getForeignKeys();
                 $v = $obj->{$fko}[$prop['linkOn']]['linkOn'];
                 if ($v != '') {
                     $o->{$prop}['linkOn'] = $v;
                     $o->delete();
                 }
             }
             if ($prop['type'] == LUMINE_MTM) {
                 LumineLog::logger(1, 'Removendo objetos de ' . $prop['class'], __FILE__, __LINE__);
                 $obj->removeAll($fkname);
             }
         }
         return true;
     }
     return false;
 }
 /**
  * Decriptografa um valor vindo do banco de dados
  * @param array $prop Array contendo as propriedades do campo
  * @param string $value O valor a ser decriptografado
  * @return string Valor decriptografado
  * @author Hugo Ferreira da Silva
  */
 function _getDecryptValue($prop, $value)
 {
     if (isset($prop['crypt']) && $prop['crypt'] == 'true') {
         LumineLog::Logger(1, 'Decriptografando o campo ' . $prop['name'], __FILE__, __LINE__);
         $value = Util::decrypt($value, $this);
         // o valor foi "escapado" antes de inserir/atualizar... tempos que retirar as contra-barras
         if (isset($this->oTable->config->config['escape']) && $this->oTable->config->config['escape'] == 1) {
             $value = stripslashes($value);
         }
     }
     return $value;
 }
 function CreateControls($xmlfile)
 {
     LumineLog::setLevel(3);
     LumineLog::setOutput('browser');
     $this->conf = new LumineConfiguration($xmlfile);
 }
 /></td>
		</tr>
		<tr>
			<td align="right">&nbsp;</td>
			<td><input name="acao" type="submit" id="acao" value="Iniciar" />
				<input name="create-classes" type="hidden" id="create-classes" value="1" />
				<input name="create-maps" type="hidden" id="create-maps" value="1" />
				<input name="escape" type="hidden" id="escape" value="1" />
				<input name="empty-as-null" type="hidden" id="empty-as-null" value="1" /></td>
		</tr>
	</table>
</form>
	<?php 
if (@$_POST['acao'] == 'Iniciar') {
    echo '<div class="result">';
    LumineLog::setLevel(4);
    LumineLog::setOutput();
    if ($_POST['use-cache'] != '') {
        $_POST['use-cache'] = $_POST['class-path'] . '/' . $_POST['use-cache'];
    } else {
        unset($_POST['use-cache']);
    }
    $obj = new LumineReverse($_POST);
    $obj->doReverse();
    echo '</div>';
}
?>

</body>
</html>
 /**
  * Get's the entity by tablename or false if no entity with provided name was found
  *
  * @param string $table Tablename of desired entity
  * @access public
  * @return mixed False on failure, Entity on success
  */
 function getEntityByTable($table)
 {
     for ($i = 0, $max = count($this->tables); $i < $max; $i++) {
         if ($this->tables[$i]->tablename == $table) {
             LumineLog::logger(1, 'Retornando a entidade para a tabela <b>' . $table . '</b>', __FILE__, __LINE__);
             return $this->tables[$i];
         }
     }
     LumineLog::logger(2, 'Não foram encontradas entidades para a tabela ' . $table, __FILE__, __LINE__);
     return false;
 }
Esempio n. 6
0
 /**
  * Import a class from the current class-path and return a new instance of it
  *
  * @author Hugo Ferreira da Silva
  * @return mixed A  new instance of class or false on failure
  * @access public
  * @param string $class A class to import (like my.package.Classname)
  */
 function Import($class)
 {
     $listConf =& $GLOBALS['__LumineConf'];
     // primeiro, vemos se é uma entidade
     foreach ($listConf as $conf) {
         for ($j = 0; $j < count($conf->tables); $j++) {
             // achamos a entidade relacionada
             if ($conf->tables[$j]->class == $class) {
                 $file = $conf->config['class-path'] . "/" . str_replace(".", "/", $class) . ".php";
                 if (file_exists($file)) {
                     require_once $file;
                     $className = array_pop(explode(".", $class));
                     $x = new $className();
                     return $x;
                 } else {
                     LumineLog::logger(3, 'O arquivo não existe', __FILE__, __LINE__);
                     return false;
                 }
             }
         }
     }
     // ok, não é uma entidade, então vamos procurar simplesmente por uma classe dentro de todas as
     // class-paths definidas e usaremos a primeira que encontrar
     reset($listConf);
     foreach ($listConf as $conf) {
         $file = $conf->config['class-path'] . "/" . str_replace(".", "/", $class) . ".php";
         // se existir
         if (file_exists($file)) {
             // importa a classe
             require_once $file;
             $className = array_pop(explode(".", $class));
             $x = new $className();
             return $x;
         }
     }
     return false;
 }
 function getColumnProperties($entity, $column)
 {
     if (isset($entity['many-to-one']) && is_array($entity['many-to-one'])) {
         foreach ($entity['many-to-one'] as $mto) {
             if ($mto['column'] == $column) {
                 LumineLog::logger(1, 'Retornando many-to-one para ' . $column, __FILE__, __LINE__);
                 return $mto;
             }
         }
     }
     // agora nos campos
     foreach ($entity['fields'] as $field) {
         // se for igual
         if ($field['name'] == $column) {
             //retorna
             LumineLog::logger(1, 'Retornando campo para ' . $column, __FILE__, __LINE__);
             return $field;
         }
     }
     return false;
 }
Esempio n. 8
0
 /**
  * Parse the XML file provided in the contructor of class
  * This entity will be stocked in the LumineConfiguration Object created
  * @param String $xmlMap XML file that describe this entity
  * @author Hugo Ferreira da Silva
  */
 function parse($xmlMap, &$conf)
 {
     if (!file_exists($xmlMap)) {
         LumineLog::logger(1, 'Arquivo não existente (' . $xmlMap . ')');
         return;
     }
     $conf =& new DOMIT_Document();
     $conf->resolveErrors(true);
     if (!$conf->loadXML($xmlMap)) {
         echo "<pre><strong>Erro no XML de Classe:</strong> " . $conf->getErrorString() . " (" . $conf->getErrorCode() . ")<br>";
         echo "Classe: {$xmlMap}</pre>";
         exit;
     }
     $cfg = $conf->getElementsByPath('/lumine-map');
     if ($cfg->getLength() == 0) {
         LumineLog::logger(1, 'XML incorreto (não foi encontrado o elemento lumine-map)');
         return;
     }
     if (!$cfg->arNodeList[0]->hasAttribute('table')) {
         LumineLog::logger(1, 'nome da tabela não informado');
         return;
     }
     if (!$cfg->arNodeList[0]->hasAttribute('class')) {
         LumineLog::logger(1, 'Classe não informada)');
         return;
     }
     $this->tablename = $cfg->arNodeList[0]->getAttribute('table');
     $this->class = $cfg->arNodeList[0]->getAttribute('class');
     $this->extends = $cfg->arNodeList[0]->getAttribute('extends');
     // pega o campo de ID
     $idNode =& $conf->getElementsByPath('/lumine-map/id', 1);
     if ($idNode != null) {
         $id = array();
         if (!$idNode->hasAttribute('name')) {
             LumineLog::logger(1, 'Você deve informar o attributo name');
             return;
         }
         if (!$idNode->hasAttribute('column')) {
             $id['column'] = $idNode->getAttribute('name');
         } else {
             $id['column'] = $idNode->getAttribute('column');
         }
         $this->sequence_key = $idNode->getAttribute("name");
         $gen =& $conf->getElementsByPath('/lumine-map/id/generator');
         if ($gen->getLength() > 0) {
             $gen = $gen->item(0);
             $this->sequence_generator = $gen->getAttribute('class');
             $this->sequence_generator_method = $gen->getAttribute('method');
         } else {
             $this->sequence_generator = 'default';
         }
         // verifica se linka com algum campo caso esteja extendendo uma classe
         if ($idNode->hasAttribute("linkOn")) {
             $id['linkOn'] = $idNode->getAttribute("linkOn");
         }
         //if($idNode->getAttribute('primary-key') == 'true') {
         $this->primary_keys[] = $idNode->getAttribute('name');
         //}
         $id['primary_key'] = true;
         $this->columns[$idNode->getAttribute('name')] = $id;
     }
     // pega os campos normais
     $columns =& $conf->getElementsByPath('/lumine-map/property');
     if ($columns->getLength() > 0) {
         $total = $columns->getLength();
         for ($i = 0; $i < $total; $i++) {
             $node = $columns->item($i);
             if ($node->hasAttribute('name') == false) {
                 LumineLog::logger(1, 'Você deve informar o attributo name para (tabela ' . $this->tablename . ')');
                 break;
             }
             if ($node->hasAttribute('type') == false) {
                 LumineLog::logger(1, 'Você deve informar o attributo type para (tabela ' . $this->tablename . ', campo ' . $node->getAttribute('name') . ')');
                 break;
             }
             $fName = $node->getAttribute('name');
             while (list($att, $value) = each($node->attributes->arNodeMap)) {
                 if ($att != 'name') {
                     $this->columns[$fName][$att] = $value->nodeValue;
                 }
                 if ($att == 'primary-key' && $value->nodeValue == 'true') {
                     $this->columns[$fName]['primary_key'] = true;
                     $this->primary_keys[] = $fName;
                 }
             }
             if (($c = $node->getAttribute('column')) != '') {
                 $this->columns[$fName]['column'] = $c;
             } else {
                 $this->columns[$fName]['column'] = $node->getAttribute('name');
             }
         }
     }
     // relacionamentos one-to-many
     $otm = $conf->getElementsByPath('/lumine-map/many-to-one');
     for ($i = 0, $max = $otm->getLength(); $i < $max; $i++) {
         $fk = $otm->arNodeList[$i]->getAttribute('name');
         $this->foreign_keys[$fk]['type'] = 'many-to-one';
         $this->foreign_keys[$fk]['class'] = $otm->arNodeList[$i]->childNodes[0]->getAttribute('name');
         $this->foreign_keys[$fk]['column'] = $otm->arNodeList[$i]->childNodes[0]->getAttribute('column');
         $this->foreign_keys[$fk]['ondelete'] = $otm->arNodeList[$i]->childNodes[0]->getAttribute('ondelete');
         $this->foreign_keys[$fk]['onupdate'] = $otm->arNodeList[$i]->childNodes[0]->getAttribute('onupdate');
         $this->foreign_keys[$fk]['linkOn'] = $otm->arNodeList[$i]->childNodes[0]->getAttribute('linkOn');
         $this->foreign_keys[$fk]['lazy'] = $otm->arNodeList[$i]->getAttribute('lazy');
         $this->foreign_keys[$fk]['foreign'] = true;
         $this->foreign_keys[$fk]['name'] = $fk;
         if ($otm->arNodeList[$i]->getAttribute('primary-key') == 'true') {
             $this->primary_keys[] = $fk;
         }
         $this->columns[$fk] =& $this->foreign_keys[$fk];
     }
     // relacionamentos many-to-one
     $mto = $conf->getElementsByPath('/lumine-map/one-to-many');
     for ($i = 0, $max = $mto->getLength(); $i < $max; $i++) {
         $fk = $mto->arNodeList[$i]->getAttribute('name');
         $this->foreign_keys[$fk]['name'] = $fk;
         $this->foreign_keys[$fk]['type'] = 'one-to-many';
         $this->foreign_keys[$fk]['class'] = $mto->arNodeList[$i]->childNodes[0]->getAttribute('name');
         $this->foreign_keys[$fk]['column'] = $mto->arNodeList[$i]->childNodes[0]->getAttribute('column');
         $this->foreign_keys[$fk]['linkOn'] = $mto->arNodeList[$i]->childNodes[0]->getAttribute('linkOn');
         $this->foreign_keys[$fk]['lazy'] = $mto->arNodeList[$i]->getAttribute('lazy');
         $this->foreign_keys[$fk]['foreign'] = true;
         $this->columns[$fk] =& $this->foreign_keys[$fk];
     }
     // relacionamentos many-to-many
     $mtm = $conf->getElementsByPath('/lumine-map/many-to-many');
     for ($i = 0, $max = $mtm->getLength(); $i < $max; $i++) {
         $node = $mtm->item($i);
         $fk = $node->getAttribute('name');
         $this->foreign_keys[$fk]['name'] = $fk;
         $this->foreign_keys[$fk]['type'] = 'many-to-many';
         $this->foreign_keys[$fk]['linkOn'] = $node->firstChild->hasAttribute('linkOn') ? $node->firstChild->getAttribute('linkOn') : $node->getAttribute('name');
         $this->foreign_keys[$fk]['table'] = $node->getAttribute('table');
         $this->foreign_keys[$fk]['foreign'] = true;
         $this->foreign_keys[$fk]['class'] = $node->firstChild->getAttribute('name');
         $this->foreign_keys[$fk]['lazy'] = $node->getAttribute('lazy');
         //$this->columns[$fk] = &$this->foreign_keys[$fk];
     }
 }
 /**
  * Sets the log level
  * 
  * @param number $level The level o log
  * @param mixed $output Where to put the output
  * @author Hugo Ferreira da Silva
  * @access public
  */
 function setLevel($level, $output = false)
 {
     $GLOBALS['__LumineLog']['log-level'] = $level;
     if ($output !== false) {
         LumineLog::setOutput($output);
     }
 }
 /**
  * Create the database tables
  * <code>
  * require_once 'pah_to_lumine/LumineSchema.php';
  * $schema = new LumineSchema('your-conf-file.xml');
  * $schema->createSchema();
  * </code>
  * @author Hugo Ferreira da Silva
  * @access public
  * @return boolean True on success
  */
 function createSchema()
 {
     LumineLog::logger(1, 'Criando nova instancia do XML DOMIT', __FILE__, __LINE__);
     $doc =& new DOMIT_Document();
     $doc->resolveErrors(true);
     if (!$doc->loadXML($this->xml)) {
         LumineLog::logger(3, 'Arquivo de configuração com erros: ' . $doc->getErrorString(), __FILE__, __LINE__);
         $this->dienice("Erro no XML: " . $doc->getErrorString());
     }
     // item de configração
     LumineLog::logger(1, 'Verificando o bloco de configuração', __FILE__, __LINE__);
     $item =& $doc->getElementsByPath("/lumine-configuration/configuration", 1);
     if (!$item) {
         LumineLog::logger(3, 'Bloco de configuração não encontrado', __FILE__, __LINE__);
         $this->dienice("Elemento de configuração (<strong>configuration</strong>) não encontrado!");
     }
     // pega as configurações
     LumineLog::logger(1, 'Analisando itens da configuração', __FILE__, __LINE__);
     $config = array();
     for ($i = 0; $i < count($item->childNodes); $i++) {
         if ($item->childNodes[$i]->nodeType == 1) {
             $key = $item->childNodes[$i]->nodeName;
             $config[$key] = $item->childNodes[$i]->firstChild->nodeValue;
         }
     }
     // mapeamentos
     LumineLog::logger(1, 'Analisando mapeamentos', __FILE__, __LINE__);
     $maplist =& $doc->getElementsByPath("/lumine-configuration/mapping", 1);
     if (!$maplist) {
         LumineLog::logger(3, 'Bloco de mapeamentos não encontrado', __FILE__, __LINE__);
         $this->dienice("Bloco de mapemaento de entidades não encontrado");
     }
     // checa os itens do mapeamento
     LumineLog::logger(1, 'Solicitando itens dos mapeamentos', __FILE__, __LINE__);
     $maps =& $maplist->getElementsByPath("item");
     if ($maps->getLength() == 0) {
         LumineLog::logger(3, 'Não há mapeamentos para serem criados no banco', __FILE__, __LINE__);
         $this->dienice("Não há mapeamentos dentro da lista de mapas");
     }
     // checa se os arquivos informados existem
     LumineLog::logger(1, 'Checando existencia de itens', __FILE__, __LINE__);
     $files = array();
     for ($i = 0; $i < $maps->getLength(); $i++) {
         $it =& $maps->item($i);
         $file = $config['class-path'] . "/" . str_replace(".", "/", $it->getAttribute("src")) . ".xml";
         if (!file_exists($file)) {
             LumineLog::logger(3, 'Arquivo de mapeamento ' . $file . ' não existe!', __FILE__, __LINE__);
             $this->dienice("O arquivo de confiração do mapeamento <strong>{$file}</strong> não existe");
         }
         // checa o xml do mapeamento para ver se não há erros
         LumineLog::logger(1, 'Checando mapeamento: ' . $file, __FILE__, __LINE__);
         $xmlMap =& new DOMIT_Document();
         $xmlMap->resolveErrors(true);
         if (!$xmlMap->loadXML($file)) {
             LumineLog::logger(3, 'Arquivo de configuração ' . $file . ' com erros: ' . $xmlMap->getErrorString(), __FILE__, __LINE__);
             $this->dienice("Erro no arquivo de configuração <strong>{$file}</strong>: " . $xmlMap->getErrorString());
         }
         // carrega o xml de cada um e coloca numa matriz
         $files[$file] =& $xmlMap;
     }
     // recupera os tipo
     require_once LUMINE_INCLUDE_PATH . '/LumineTypes.php';
     LumineTypes::start($config['dialect']);
     // checa se o dialeto não foi informado
     if ($config['dialect'] == '') {
         LumineLog::logger(3, 'Dialeto não informado para conexão com o banco', __FILE__, __LINE__);
         $this->dienice("Dialeto não informado");
     }
     // checa se o dialeto existe
     LumineLog::logger(1, 'Incluindo arquivo de conexão com o banco: ' . $config['dialect'] . '.php', __FILE__, __LINE__);
     // importa a classe ADODB
     include_once LUMINE_INCLUDE_PATH . '/adodb/adodb.inc.php';
     // se não conseguir criar a instância do banco
     if (!($conn =& ADONewConnection($config['dialect']))) {
         LumineLog::logger(3, 'Classe de conexão <i>' . $config['dialect'] . '</i> não encontrada!', __FILE__, __LINE__);
         exit;
     }
     $this->cn =& $conn;
     $this->cn->SetFetchMode(ADODB_FETCH_ASSOC);
     if (!defined('LUMINE_RANDOM_FUNC')) {
         define('LUMINE_RANDOM_FUNC', $this->cn->random);
     }
     $ifschema = '';
     // verifica se foi informado o schema
     if (isset($config['schema']) && $config['schema'] != '') {
         // então cria o schema no banco
         $this->cn->query("CREATE SCHEMA " . $config['schema']);
         $ifschema = $config['schema'] . '.';
     } else {
         if (isset($config['schema-authorization']) && $config['schema-authorization'] != '') {
             // verifica se foi informado o schema-authorization
             // então cria o schema no banco
             $this->cn->query("CREATE SCHEMA AUTHORIZATION " . $config['schema-authorization']);
             $ifschema = $config['schema-authorization'] . '.';
         }
     }
     // se o schema foi informado, mudamos para ele
     if ($ifschema != '') {
         $this->cn->query("SET search_path TO " . substr($ifschema, 0, strlen($ifschema) - 1));
     }
     // inicia a escrita das tabelas
     $td =& $this->classes;
     foreach ($files as $file => $entity) {
         $first =& $entity->getElementsByPath("/lumine-map", 1);
         if (!$first) {
             $this->dienice("Elemento de definição incorreto para <strong>{$file}</strong>");
         }
         // table definition
         $table = $first->getAttribute("table");
         $td[$table]['class'] = $first->getAttribute("class");
         $td[$table]['tablename'] = $table;
         $td[$table]['extends'] = $first->getAttribute("extends");
         $id =& $first->getElementsByPath("id", 1);
         if ($id) {
             if ($id->getAttribute("name") == '') {
                 $this->dienice("O atributo <strong>name</strong> deve ser informado na definição da chave de sequencia do arquivo <strong>{$file}</strong>");
             }
             $generator =& $id->getElementsByPath("generator", 1);
             $column = @$id->getAttribute("column") == '' ? $id->getAttribute("name") : $id->getAttribute('column');
             $name = $id->getAttribute("name");
             //**********************************************************
             //** classes extendidas
             //**********************************************************
             if (!$generator && $id->hasAttribute("linkOn")) {
                 $td[$table]['primary-keys'][] = $column;
                 $fk =& $this->_getDefinitionByClass($td[$table]['extends']);
                 $fd =& $this->_getFieldDefinition($fk, $id->getAttribute('linkOn'));
                 $td[$table]['foreign-keys'][$name]['linkOn'] = $fd['column'];
                 $td[$table]['foreign-keys'][$name]['references'] = $fk['tablename'];
                 $td[$table]['foreign-keys'][$name]['ondelete'] = 'cascade';
                 $td[$table]['foreign-keys'][$name]['onupdate'] = 'cascade';
                 $td[$table]['foreign-keys'][$name]['not-null'] = true;
             } else {
                 if ($generator) {
                     $td[$table]['sequence-key']['column'] = $column;
                     $td[$table]['sequence-key']['name'] = $id->getAttribute('name');
                     $td[$table]['sequence-key']['generator'] = $generator->getAttribute("class");
                     $td[$table]['primary-keys'][] = $column;
                 } else {
                     LumineLog::logger(3, "Erro de definição de {$file}", __FILE__, __LINE__);
                     $this->dienice("não foi informado se a classe extende outra ou ao menos o gerador de sequencia desta classe");
                 }
             }
         }
         // propriedades
         $prop =& $first->getElementsByPath("property");
         for ($i = 0; $i < $prop->getLength(); $i++) {
             $node =& $prop->item($i);
             $name = $node->getAttribute("name");
             $type = $node->getAttribute("type");
             $notnull = $node->getAttribute("not-null") == 'true' ? true : false;
             $primary = $node->getAttribute("primary-key") == 'true' ? true : false;
             $default = $node->getAttribute("default");
             $column = $node->getAttribute("column") == '' ? $name : $node->getAttribute("column");
             if ($name == '') {
                 $this->dienice("O atributo <strong>name</strong> deve ser informado no elemento {$i} do arquivo <strong>{$file}</strong>");
             }
             if ($type == '') {
                 $this->dienice("Você deve informa o tipo da coluna");
             }
             $td[$table]['columns'][$name]['column'] = $column;
             $td[$table]['columns'][$name]['type'] = $type;
             if ($default != '') {
                 $td[$table]['columns'][$name]['default'] = $default;
             }
             if ($notnull == true) {
                 $td[$table]['columns'][$name]['not-null'] = true;
             }
             if ($primary == true) {
                 $td[$table]['primary-keys'][] = $column;
             }
         }
     }
     // reinicia a matriz, para procurarmos por chaves estrangeiras
     reset($files);
     // many-to-many relationships
     $many_to_many = array();
     $chaves = array_keys($files);
     foreach ($files as $file => $entity) {
         // procura many-to-one
         $first =& $entity->getElementsByPath("/lumine-map", 1);
         $table = $first->getAttribute("table");
         // chaves many-to-one
         $mto =& $first->getElementsByPath("many-to-one");
         for ($i = 0; $i < $mto->getLength(); $i++) {
             $node =& $mto->item($i);
             $class =& $node->getElementsByPath("class", 1);
             //echo "$file: " . $class->getAttribute("name") . "<br>";
             if (!$class) {
                 $this->dienice("A classe para a chave estrangeira <strong>{$name}</strong> não foi informada no arquivo <strong>{$file}</strong>");
             }
             $fk = $this->_getDefinitionByClass($class->getAttribute("name"));
             $name = $node->getAttribute("name");
             $reftable = $fk['tablename'];
             $linkOn = $class->getAttribute("linkOn");
             $column = $class->getAttribute("column");
             $ondelete = $class->getAttribute("ondelete");
             $onupdate = $class->getAttribute("onupdate");
             $notnull = $class->getAttribute("not-null") == 'true';
             //echo "$table, $name, $reftable, $linkOn, $column, $ondelete, $onupdate, $notnull<br>";
             if ($node->getAttribute("primary-key") == 'true') {
                 $td[$table]['primary-keys'][] = $column;
             }
             $td[$table]['foreign-keys'][$name]['column'] = $column;
             if ($linkOn == $fk['sequence-key']['column'] || $linkOn == $fk['sequence-key']['name']) {
                 $td[$table]['foreign-keys'][$name]['type'] = SEQUENCE_TYPE;
                 $linkOn = $fk['sequence-key']['column'];
             } else {
                 $td[$table]['foreign-keys'][$name]['type'] = $fd['type'];
                 $linkOn = $fd['column'];
             }
             $td[$table]['foreign-keys'][$name]['linkOn'] = $linkOn;
             $td[$table]['foreign-keys'][$name]['references'] = $reftable;
             $td[$table]['foreign-keys'][$name]['ondelete'] = $ondelete;
             $td[$table]['foreign-keys'][$name]['onupdate'] = $onupdate;
             $td[$table]['foreign-keys'][$name]['not-null'] = $notnull;
         }
         // procurando por chaves many-to-many
         $mtm = $first->getElementsByPath("many-to-many");
         for ($i = 0; $i < $mtm->getLength(); $i++) {
             $node =& $mtm->item($i);
             $class = $node->getElementsByPath("class", 1);
             if (!$class) {
                 $this->dienice("O elemento <strong>class</strong> necessário para chaves many-to-many não foi encontrado no arquivo <strong>{$file}</strong>");
             }
             $name = $node->getAttribute("name");
             $classname = $class->getAttribute("name");
             $linkOn = $class->getAttribute("linkOn");
             $reftable = $node->getAttribute("table");
             if ($name == '') {
                 $this->dienice("O atributo <strong>name</strong> para criação da chave many-to-many no arquivo <strong>{$file}</strong> deve ser informado");
             }
             if ($classname == '') {
                 $this->dienice("O atributo <strong>class.name</strong> para criação da chave many-to-many no arquivo <strong>{$file}</strong> deve ser informado");
             }
             if ($linkOn == '') {
                 $this->dienice("O atributo <strong>class.linkOn</strong> para criação da chave many-to-many no arquivo <strong>{$file}</strong> deve ser informado");
             }
             if ($reftable == '') {
                 $this->dienice("O atributo <strong>class.table</strong> para criação da chave many-to-many no arquivo <strong>{$file}</strong> deve ser informado");
             }
             $fk = $this->_getDefinitionByClass($classname);
             $c = array();
             $c['column'] = $fk['sequence-key']['column'] || $column == $fk['sequence-key']['name'] ? $fk['sequence-key']['column'] : $linkOn;
             // if($linkOn == $fk['sequence-key']['column'] || $linkOn == $fk['sequence-key']['name']) {
             $c['type'] = SEQUENCE_TYPE;
             // } else {
             //$c['type'] = $fk['columns'][$column]['type'];
             // }
             $c['references'] = $fk['tablename'];
             $c['ondelete'] = $class->getAttribute("ondelete");
             $c['onupdate'] = $class->getAttribute("onupdate");
             $many_to_many[$reftable][] = $c;
         }
     }
     // agora começaremos a criar as tabelas
     $tables = array();
     $alters = array();
     foreach ($this->classes as $name => $def) {
         $sql = "CREATE TABLE {$ifschema}{$name} (";
         // sequence key
         if (isset($def['sequence-key']) && $def['sequence-key']) {
             $sql .= $def['sequence-key']['column'] . ' ' . SEQUENCE_DEFINITION . ', ';
         }
         // foreign keys
         if (isset($def['foreign-keys']) && is_array($def['foreign-keys'])) {
             foreach ($def['foreign-keys'] as $fkname => $fkp) {
                 if (isset($fkp['column'])) {
                     $sql .= $fkp['column'] . ' ' . $fkp['type'];
                 } else {
                     if (isset($fkp['linkOn']) && isset($def['primary-keys']) && in_array($fkname, $def['primary-keys'])) {
                         $class_tmp = $this->classes[$fkp['references']];
                         $fk_tmp = $this->_getFieldDefinition($class_tmp, $fkp['linkOn']);
                         $sql .= $fkname . ' ' . SEQUENCE_TYPE;
                     }
                 }
                 if (isset($fkp['not-null']) && $fkp['not-null']) {
                     $sql .= ' not null';
                 }
                 $sql .= ', ';
             }
         }
         // campos
         if (is_array($def['columns'])) {
             foreach ($def['columns'] as $cname => $cdef) {
                 $sql .= $cdef['column'] . ' ' . $cdef['type'];
                 if (isset($cdef['not-null']) && $cdef['not-null'] == true) {
                     $sql .= ' not null';
                 }
                 $sql .= ', ';
             }
         }
         // colocando os INDEX para chaves estrangeiras
         if (isset($def['foreign-keys']) && is_array($def['foreign-keys'])) {
             reset($def['foreign-keys']);
             foreach ($def['foreign-keys'] as $fname => $fkp) {
                 if (CREATE_INDEX_FOR_FK) {
                     $sql .= "INDEX `FK_" . strtoupper(substr(md5(rand(0, time())), 0, 10)) . "`({$fkp['column']})";
                     $sql .= ', ';
                 }
                 $c = strtoupper(substr(md5(rand(0, time())), 0, 15));
                 if (!isset($fkp['column'])) {
                     $fkp['column'] = $fname;
                 }
                 $alter = "ALTER TABLE {$ifschema}{$name} ADD FOREIGN KEY({$fkp['column']}) REFERENCES {$ifschema}{$fkp['references']}({$fkp['linkOn']})";
                 if ($fkp['ondelete'] != '') {
                     $alter .= " ON DELETE {$fkp['ondelete']}";
                 }
                 if ($fkp['onupdate'] != '') {
                     $alter .= " ON UPDATE {$fkp['onupdate']}";
                 }
                 $alters[] = $alter;
             }
         }
         // colocando as primary keys
         if (isset($def['primary-keys']) && is_array($def['primary-keys'])) {
             $sql .= "PRIMARY KEY(";
             foreach ($def['primary-keys'] as $pname) {
                 $sql .= $pname . ", ";
             }
             $sql = substr($sql, 0, strlen($sql) - 2);
             $sql .= ")";
         }
         if (substr($sql, strlen($sql) - 2) == ', ') {
             $sql = substr($sql, 0, strlen($sql) - 2);
         }
         $sql .= ") " . TABLE_DEFINITION;
         $tables[$name] = $sql;
     }
     // agora, as many-to-many
     foreach ($many_to_many as $name => $def) {
         $sql = "CREATE TABLE {$ifschema}{$name} (";
         foreach ($def as $d) {
             $sql .= $d['column'] . ' ' . $d['type'] . ' not null, ';
         }
         $sql .= "PRIMARY KEY(";
         reset($def);
         foreach ($def as $d) {
             $sql .= $d['column'] . ', ';
         }
         $sql = substr($sql, 0, strlen($sql) - 2);
         $sql .= "), ";
         reset($def);
         foreach ($def as $d) {
             $x = strtoupper(substr(md5(rand(0, time())), 0, 15));
             if (CREATE_INDEX_FOR_FK) {
                 $sql .= "INDEX ({$d['column']}), ";
             }
             $alter = "ALTER TABLE " . $ifschema . $name . " ADD FOREIGN KEY({$d['column']}) REFERENCES {$ifschema}{$d['references']}({$d['column']})";
             if ($d['ondelete'] != '') {
                 $alter .= " ON DELETE {$d['ondelete']}";
             }
             if ($d['onupdate'] != '') {
                 $alter .= " ON UPDATE {$d['onupdate']}";
             }
             $alters[] = $alter;
         }
         $sql = substr($sql, 0, strlen($sql) - 2);
         $sql .= ") " . TABLE_DEFINITION;
         $tables[$name] = $sql;
     }
     // agora, cria no banco de dados
     /////// PARA MYSQL (POR ENQUANTO)
     $this->cn->connect($config['host'], $config['user'], $config['password'], $config['database']);
     $fkc = LumineTypes::disableForeignKeys($config['dialect']);
     if ($fkc != '') {
         $this->cn->query($fck);
     }
     $TablesInDatabase = $this->cn->MetaTables();
     foreach ($tables as $name => $sql) {
         if (in_array($name, $TablesInDatabase)) {
             LumineLog::logger(1, 'Dropando tabela existente: ' . $ifschema . $name, __FILE__, __LINE__);
             $this->cn->query("DROP TABLE " . $name);
         }
         LumineLog::logger(1, 'Executando SQL: ' . $sql, __FILE__, __LINE__);
         $this->cn->query($sql);
     }
     foreach ($alters as $sql) {
         LumineLog::logger(1, 'Executando SQL: ' . $sql, __FILE__, __LINE__);
         $this->cn->query($sql);
     }
     // se optou por criar as classes
     if ($config['create-classes'] == 1) {
         LumineLog::logger(1, 'Chamando rotina de criação das classes', __FILE__, __LINE__);
         $this->_createClasses($maps, $config);
     }
     // terminado
     return true;
 }
 /**
  * Validate a given class
  * A static method to validate your classes<br>
  * <code>
  * require_once 'path_to_lumine_package/LumineValidation.php';
  * $person = new Person;
  * $results = LumineValidation::validate($person);
  * if($results === true) {
  *     $person->save();
  * } else {
  *     print_r( $results );
  * }
  * </code>
  * or
  * <code>
  * require_once 'path_to_lumine_package/LumineValidation.php';
  * $person = new Person;
  * $results = $person->validate();
  * </code>
  * @return mixed True on sucess, false if $class is not a LumineBase object and associative array of field with errors
  * @author Hugo Ferreira da Silva
  * @access public
  * @param object $class A class that extends LumineBase
  */
 function validate(&$class)
 {
     // não é da classe LumineBase
     if (!is_a($class, "luminebase")) {
         return false;
     }
     //pega os campos da classe
     $table = $class->table();
     $table = array_merge($table, $class->oTable->getForeignKeys());
     // procura pelo arquivo de validaçao classname-validation.xml dentro do diretorio de mapeamentos
     $maps = $class->oTable->config->config['maps'];
     $maps = str_replace(".", "/", $maps);
     $xml = $class->oTable->config->config['class-path'] . '/' . $maps;
     $xml .= '/' . array_pop(explode(".", $class->oTable->class)) . '-validation.xml';
     // erros
     $errors = array();
     // se encontrou o arquivo, iremos fazer a validaçao pelo arquivo
     if (file_exists($xml)) {
         LumineLog::logger(1, "XML encontrado: " . $xml, __FILE__, __LINE__);
         // criamos uma nova instancia do DOMIT_Document
         $val =& new DOMIT_Document();
         $val->resolveErrors(true);
         if (!$val->loadXML($xml)) {
             // erro no XML
             LumineLog::logger(1, "XML com erro: " . $val->getErrorString(), __FILE__, __LINE__);
             return false;
         }
         // pega o primeiro nó
         $first = $val->getElementsByPath("/lumine-validator", 1);
         if ($first) {
             $filename = $first->getAttribute("messages_file");
             $fileparts = explode('.', $filename);
             $ext = array_pop($fileparts);
             $file = implode('/', $fileparts) . '.' . $ext;
             $file = $class->oTable->config->config['class-path'] . '/' . $file;
             if (file_exists($file) && is_file($file)) {
                 Messages::parseFile($file);
             }
         }
         // Pega os validator
         $validator_list = $val->getElementsByPath("/lumine-validator/field");
         // para cada validator
         for ($i = 0; $i < $validator_list->getLength(); $i++) {
             $node = $validator_list->item($i);
             $itens = $node->getElementsByPath("validator");
             // pega o nome do campo a ser validado
             $key = $node->getAttribute("name");
             // se não encontrar
             if ($key == '') {
                 LumineLog::logger(1, "Informe o nome do campo para validação no arquivo <b>{$xml}</b>");
                 return false;
             }
             // se o campo no validator não existe na entidade
             if (!array_key_exists($key, $table)) {
                 continue;
             }
             // pega o valor na entidade
             $value = $class->{$key};
             // para cada validator encontrado para este campo
             for ($j = 0; $j < $itens->getLength(); $j++) {
                 $vnode = $itens->item($j);
                 $type = $vnode->getAttribute("type");
                 $msg_key = Messages::getMessage($vnode->getAttribute("msg-key"));
                 $msg = $msg_key == false ? $vnode->getAttribute("msg") : $msg_key;
                 $rule = $vnode->getAttribute("rule");
                 $cname = $vnode->getAttribute("name");
                 $cmethod = $vnode->getAttribute("method");
                 $minlength = $vnode->getAttribute("minlength");
                 $maxlength = $vnode->getAttribute("maxlength");
                 $minvalue = $vnode->getAttribute("minvalue");
                 $maxvalue = $vnode->getAttribute("maxvalue");
                 // faz um switch no tipo
                 switch ($type) {
                     case "requiredString":
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             if ($class->{$key} == '') {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                             if ($minlength != '' && strlen($class->{$key}) < $minlength) {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                             if ($maxlength != '' && strlen($class->{$key}) > $maxlength) {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                             $errors[$key] = true;
                         }
                         break;
                     case "requiredNumber":
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             if (!is_numeric($class->{$key})) {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                             if ($minvalue != '' && $class->{$key} < $minvalue) {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                             if ($maxvalue != '' && $class->{$key} > $maxvalue) {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                             $errors[$key] = true;
                         }
                         break;
                     case 'unique':
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             $testClass = Util::Import($class->oTable->class);
                             // se não encontrou a classe
                             if ($testClass === false) {
                                 $erros[$key] = $msg;
                                 continue;
                             }
                             // se já existir um registro com este valor
                             $testClass->{$key} = $class->{$key};
                             if ($testClass->find() > 0) {
                                 // pega as chaves primárias
                                 $pks = $testClass->oTable->getPrimaryKeys();
                                 $todos = true;
                                 while ($testClass->fetch()) {
                                     // para cada pk
                                     foreach ($pks as $p => $prop) {
                                         // se ao menos UMA chave primária for diferente
                                         if ($testClass->{$p} != $class->{$p}) {
                                             // não passou na validação
                                             $todos = false;
                                             break;
                                         }
                                     }
                                     if ($todos == false) {
                                         break;
                                     }
                                 }
                                 // se houver uma chave diferente
                                 if ($todos == false) {
                                     // não passou
                                     $errors[$key] = $msg;
                                     continue;
                                 }
                             }
                             $errors[$key] = true;
                         }
                         break;
                     case "rule":
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             if ($rule != '') {
                                 // coloca os valores para a regra
                                 $regra = preg_replace("/#(.*?)#/e", "\$class->\\1", $rule);
                                 // executa o código
                                 $x = eval('if(' . $regra . ') return true;');
                                 // se for falso, significa que não passou no teste
                                 if (!$x) {
                                     $errors[$key] = $msg;
                                     continue;
                                 } else {
                                     $errors[$key] = true;
                                     continue;
                                 }
                             } else {
                                 $errors[$key] = '-- You must provide a rule to validate this field (' . $key . ')';
                             }
                         }
                         break;
                     case "class":
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             if ($cname != '') {
                                 $classname = array_pop(explode(".", $cname));
                                 if (!class_exists($classname)) {
                                     Util::Import($cname);
                                 }
                                 $x = new $classname();
                                 if (method_exists($x, $cmethod)) {
                                     $r = $x->{$cmethod}($class->{$key});
                                     if ($r === true) {
                                         $errors[$key] = true;
                                         continue;
                                     } else {
                                         $errors[$key] = $msg;
                                         continue;
                                     }
                                 } else {
                                     $errors[$key] = '-- You must provida a valid method for class ' . $classname . ' to validate the field ' . $key;
                                     continue;
                                 }
                             } else {
                                 $errors[$key] = '-- You must provide a class to validate this field(' . $key . ')';
                                 continue;
                             }
                         }
                         break;
                     case "requiredEmail":
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             if (Util::validateEmail($class->{$key})) {
                                 $errors[$key] = true;
                                 continue;
                             } else {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                         }
                         break;
                     case 'requiredDate':
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             $reg = array();
                             if (preg_match('@^([0-9]{2})/([0-9]{2})/([0-9]{4})$@', $class->{$key}, $reg)) {
                                 if (checkdate($reg[2], $reg[1], $reg[3]) || checkdate($reg[1], $reg[2], $reg[3])) {
                                     $errors[$key] = true;
                                     continue;
                                 } else {
                                     $errors[$key] = $msg;
                                     continue;
                                 }
                             } else {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                         }
                         break;
                     case 'requiredISODate':
                         if (!array_key_exists($key, $errors) || $errors[$key] === true) {
                             $reg = array();
                             if (preg_match('@^([0-9]{4})-([0-9]{2})-([0-9]{2})$@', $class->{$key}, $reg)) {
                                 if (checkdate($reg[2], $reg[3], $reg[1])) {
                                     $errors[$key] = true;
                                     continue;
                                 } else {
                                     $errors[$key] = $msg;
                                     continue;
                                 }
                             } else {
                                 $errors[$key] = $msg;
                                 continue;
                             }
                         }
                         break;
                 }
             }
         }
         // checa validações na classse
         foreach ($table as $key => $prop) {
             $m = "validate" . ucfirst($key);
             if (method_exists($class, $m)) {
                 $x = $class->{$m}();
                 if ($x !== true) {
                     if (is_bool($x)) {
                         $errors[$key] = Messages::getMessage($class->tablename() . "." . $key);
                     } else {
                         $errors[$key] = $x;
                     }
                 } else {
                     $errors[$key] = true;
                 }
             }
         }
         foreach ($errors as $key => $msg) {
             if ($msg !== true) {
                 $_REQUEST[$key . '_error'] = $msg;
             }
         }
         reset($errors);
         // terminou a validação dessa classe, porém verificamos se ela é uma classe extendida
         if (isset($class->oTable->extends) && $class->oTable->extends != '') {
             $x = Util::Import($class->oTable->extends);
             if ($x !== false) {
                 $x->setFrom($class->toArray());
                 $r = $x->validate();
                 if ($r !== true) {
                     $errors = array_merge($errors, $r);
                 }
             }
         }
         foreach ($errors as $key => $msg) {
             if (isset($errors[$key]) && $errors[$key] !== true) {
                 return $errors;
             }
         }
         return true;
     }
     LumineLog::logger(1, "XML não encontrado: " . $xml, __FILE__, __LINE__);
     /* somente entrará nesta parte se não encontrar o arquivo de validação */
     // para cada campo (não sendo chaves many-to-many e one-to-many)
     $errors = array();
     foreach ($table as $field => $prop) {
         if (isset($prop['not-null']) && $prop['not-null'] == 'true' && $field != $class->oTable->sequence_key) {
             if (!isset($class->{$field}) || $class->{$field} == '') {
                 $errors[$field] = false;
             }
         } else {
             $errors[$field] = true;
         }
         /*
         if(isset($prop['foreign'])) {
         	if($prop['foreign'] == false || ($prop['foreign'] && $prop['type'] == 'many-to-one')) {
         		
         	}
         }
         */
     }
     foreach ($errors as $key => $value) {
         if ($value === false) {
             reset($errors);
             return $errors;
         }
     }
     return true;
 }