Пример #1
0
    $crap = set_error_handler('PresciaErrorHandler');
    unset($crap);
}
# ab -n50 total mean: 19ms 16ms
$core->domainLoad();
// locks domain, load config and start i18n
define("CONS_FMANAGER", CONS_PATH_PAGES . $_SESSION['CODE'] . "/files/");
if (CONS_CACHE) {
    $core->cacheControl->startCaches();
}
// detects which cache to use from auto-throttle system
# -- database and metadata load
if (!$core->dbconnect()) {
    $core->offlineMode = true;
}
if (!$core->loadMetadata()) {
    $core->errorControl->raise(1, "metamodel fault");
}
// loadMetadata loads dimconfig
if ($core->debugmode) {
    $core->applyMetaData();
}
// only in debug. Executes onMeta's and save metadata/sql changes
# ab -n50 total mean: 546ms 28ms
# -- start parsing the request
require CONS_PATH_INCLUDE . "getBrowser.php";
# this will also detect if we are on mobile
$core->parseRequest();
# ab -n50 total mean: 557ms 29ms (27ms with cache enabled)
# -- which page I want and context are ready on parseRequest, load template, so get the template core (in case we need to dump an error, we can do it with the template)
require CONS_PATH_INCLUDE . "template/tc.php";
Пример #2
0
 function loadMetadata()
 {
     if (!$this->debugmode) {
         return parent::loadMetadata();
     }
     $this->errorControl->raise(1000);
     $this->log = array();
     // we don't want the above "log" to cause an abort (yes, this function uses the log size to confirm an error - lame but extremelly effective)
     $this->allModulesLoaded = true;
     # initial clean up and check
     if (!is_dir(CONS_PATH_TEMP)) {
         safe_mkdir(CONS_PATH_TEMP);
     }
     if (!is_dir(CONS_PATH_CACHE)) {
         safe_mkdir(CONS_PATH_CACHE);
     }
     if (!is_dir(CONS_PATH_DINCONFIG)) {
         safe_mkdir(CONS_PATH_DINCONFIG);
     }
     if (!is_dir(CONS_PATH_CACHE . "locale/")) {
         safe_mkdir(CONS_PATH_CACHE . "locale/");
     }
     if (!is_dir(CONS_PATH_LOGS)) {
         safe_mkdir(CONS_PATH_LOGS);
     }
     if (!is_dir(CONS_PATH_LOGS . $_SESSION['CODE'] . "/")) {
         safe_mkdir(CONS_PATH_LOGS . $_SESSION['CODE'] . "/");
     }
     if (!is_dir(CONS_PATH_DINCONFIG . $_SESSION['CODE'] . "/")) {
         safe_mkdir(CONS_PATH_DINCONFIG . $_SESSION['CODE'] . "/");
     }
     if (!is_dir(CONS_PATH_CACHE . $_SESSION['CODE'] . "/")) {
         safe_mkdir(CONS_PATH_CACHE . $_SESSION['CODE'] . "/");
     }
     if (!is_dir(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/")) {
         safe_mkdir(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/");
     }
     if (!is_dir(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/locale")) {
         safe_mkdir(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/locale/");
     }
     if (!is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/")) {
         safe_mkdir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/");
     }
     if (!is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions/")) {
         safe_mkdir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/actions");
     }
     if (!is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/content/")) {
         safe_mkdir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/content");
     }
     if (!is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/_config/locale/")) {
         safe_mkdir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/_config/locale");
     }
     if (!is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/files/")) {
         safe_mkdir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/files");
     }
     if (!is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/template/")) {
         safe_mkdir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/template");
         copy(CONS_PATH_SETTINGS . "defaults/basefile.html", CONS_PATH_PAGES . $_SESSION['CODE'] . "/template/basefile.html");
         copy(CONS_PATH_SETTINGS . "defaults/index.html", CONS_PATH_PAGES . $_SESSION['CODE'] . "/template/index.html");
     }
     if (!is_dir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/mail/")) {
         safe_mkdir(CONS_PATH_PAGES . $_SESSION['CODE'] . "/mail");
     }
     # Dimconfig
     if (is_file(CONS_PATH_DINCONFIG . $_SESSION['CODE'] . "/din.dat")) {
         $this->dimconfig = unserialize(cReadFile(CONS_PATH_DINCONFIG . $_SESSION['CODE'] . "/din.dat"));
     }
     if ($this->dimconfig === false) {
         $this->dimconfig = array();
     }
     # Error on load
     $this->checkConfig();
     # clear the meta cache
     if (!$this->offlineMode) {
         $files = listFiles(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/");
         foreach ($files as $file) {
             if (is_file(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/" . $file)) {
                 @unlink(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/" . $file);
             }
         }
         if (!$this->checkinstall()) {
             $this->errorControl->raise(118, array_unshift($this->log));
         }
         if (isset($_REQUEST['nocache'])) {
             recursive_del(CONS_PATH_CACHE . $_SESSION['CODE'] . "/pages/", true);
             recursive_del(CONS_PATH_CACHE . $_SESSION['CODE'] . "/", false, 'cache');
         }
     }
     # If no database, we are done
     if ($this->dbless) {
         return count($this->log) == 0;
     }
     # Search all necessary model files
     $parseXMLparams = array(C_XML_RAW => true, C_XML_AUTOPARSE => true, C_XML_REMOVECOMMENTS => true);
     $xml = new xmlHandler();
     $model = is_file(CONS_PATH_SETTINGS . "default.xml") ? cReadFile(CONS_PATH_SETTINGS . "default.xml") . "\n" : '';
     foreach ($this->loadedPlugins as $scriptName => $scriptObj) {
         if (is_file(CONS_PATH_SYSTEM . "plugins/" . $scriptName . "/meta.xml")) {
             $model .= cReadFile(CONS_PATH_SYSTEM . "plugins/" . $scriptName . "/meta.xml") . "\n";
         }
     }
     unset($scriptName);
     unset($scriptObj);
     if (is_file(CONS_PATH_PAGES . $_SESSION['CODE'] . "/_config/meta.xml")) {
         $model .= cReadFile(CONS_PATH_PAGES . $_SESSION['CODE'] . "/_config/meta.xml") . "\n";
     }
     $model = $xml->parseXML($model, $parseXMLparams, true);
     unset($xml);
     if ($model === false) {
         $this->errorControl->raise(119);
     }
     # browses the XML and loads modules
     $model =& $model->getbranch(0);
     $total = $model->total();
     $relation = array();
     # foreign keys are only created later
     $lastLoad = "";
     for ($c = 0; $c < $total; $c++) {
         # for each module ...
         $thisbranch =& $model->getbranch($c);
         $total_campos = $thisbranch->total();
         # creates the module as from XML settings
         $module = strtolower($thisbranch->data[0]);
         $param =& $thisbranch->data[1];
         $dbname = strtolower(isset($param['dbname']) ? $param['dbname'] : '');
         foreach ($this->modules as $name => $otherModule) {
             if ($otherModule->dbname == $dbname && $dbname != "" && $module != $otherModule->name) {
                 $this->errorControl->raise(120, $otherModule->name, $name, $dbname);
             }
         }
         if ($module == '') {
             $this->errorControl->raise(107, $dbname, "XML error", "Module after {$lastLoad} is corrupt");
         }
         $this->loadModule($module, $dbname);
         #MODULE CREATE
         $lastLoad = $module;
         # loads standard data from this object ---------------------------------------------------------------------
         # read parameters for the MODULE
         foreach ($this->moduleOptions as $mo) {
             $this->modules[$module]->options[$mo[0]] = $mo[3] != '' ? array() : '';
         }
         if (is_array($param)) {
             foreach ($param as $pkey => $pcontent) {
                 $pkey = strtolower($pkey);
                 switch ($pkey) {
                     case "key":
                     case "keys":
                         # will use default auto_increment "id" if none specified. If you specify more than one, none will be auto_increment and the system will use auto-numbering
                         $this->modules[$module]->keys = explode(",", $pcontent);
                         break;
                     case "title":
                         $this->modules[$module]->title = strtolower($pcontent);
                         break;
                     case "volatile":
                         # this module can be deleted as a stand-alone volatile item
                         $this->modules[$module]->options[CONS_MODULE_VOLATILE] = strtolower($pcontent) == "true";
                         break;
                     case "parent":
                         $this->modules[$module]->options[CONS_MODULE_PARENT] = strtolower($pcontent);
                         // field which denotes parenthood
                         break;
                     case "plugins":
                     case "plugin":
                         $this->modules[$module]->plugins = explode(",", strtolower($pcontent));
                         break;
                     case "order":
                         $this->modules[$module]->order = trim(strtolower($pcontent));
                         break;
                     case "permissionoverride":
                         if (strlen($pcontent) >= 9) {
                             $this->modules[$module]->permissionOverride = substr(strtolower($pcontent), 0, 9);
                         }
                         break;
                     case "linker":
                         $this->modules[$module]->linker = true;
                         break;
                     case "systemmodule":
                         $this->modules[$module]->options[CONS_MODULE_SYSTEM] = true;
                         break;
                     case "autoclean":
                         $this->modules[$module]->options[CONS_MODULE_AUTOCLEAN] = $pcontent;
                         break;
                     case "meta":
                         $this->modules[$module]->options[CONS_MODULE_META] = $pcontent;
                         break;
                     case "disallowmultiple":
                         if (strtolower($pcontent) == "true") {
                             $this->modules[$module]->options[CONS_MODULE_DISALLOWMULTIPLE] = true;
                         } else {
                             unset($this->modules[$module]->options[CONS_MODULE_DISALLOWMULTIPLE]);
                         }
                         break;
                     case "noundo":
                         if (strtolower($pcontent) == "true") {
                             $this->modules[$module]->options[CONS_MODULE_NOUNDO] = true;
                         } else {
                             unset($this->modules[$module]->options[CONS_MODULE_NOUNDO]);
                         }
                     default:
                         if ($pkey != "name" && $pkey != "dbname") {
                             $isMO = false;
                             foreach ($this->moduleOptions as $mo) {
                                 if ($mo[1] == $pkey) {
                                     $isMO = true;
                                     if ($mo[2]) {
                                         $pcontent = strtolower($pcontent);
                                     }
                                     if ($mo[3] != '') {
                                         $pcontent = explode($mo[3], $pcontent);
                                     }
                                     $this->modules[$module]->options[$mo[0]] = $pcontent;
                                     break;
                                 }
                             }
                             if (!$isMO) {
                                 $this->modules[$module]->options[$pkey] = $pcontent;
                             }
                         }
                         break;
                 }
             }
             #foreach
             unset($pkey);
             unset($pcontent);
         }
         if ($this->modules[$module]->options[CONS_MODULE_PARENT] != '' && strpos($this->modules[$module]->order, $this->modules[$module]->options[CONS_MODULE_PARENT]) === false) {
             # in tree mode, the field that defines parenthood must be in the order clause, the first if possible
             $this->modules[$module]->order = $this->modules[$module]->options[CONS_MODULE_PARENT] . "+" . ($this->modules[$module]->order != '' ? "," . $this->modules[$module]->order : '');
         }
         # -- ok on reading parameters
         $campos = array();
         $mandatory = 0;
         # browse FIELDS ---------------------------------------------------------------------------------
         for ($campo = 0; $campo < $total_campos; $campo++) {
             $thiscampo =& $thisbranch->getbranch($campo);
             ## processParameters #########################################
             $campos = $this->processParameters($thiscampo, $campos, $module);
             ##############################################################
             $nomecampo = strtolower($thiscampo->data[0]);
             if ($campos[$nomecampo][CONS_XML_TIPO] == CONS_TIPO_LINK) {
                 array_push($relation, array($module, $nomecampo, $campos[$nomecampo][CONS_XML_MODULE]));
                 // if this is a non-mandatory link to myself, called "id_parent", and I don't have parent ... well .. obviously this is it
                 if ($campos[$nomecampo][CONS_XML_MODULE] == $module && !isset($campos[$nomecampo][CONS_XML_MANDATORY]) && $nomecampo == "id_parent" && $this->modules[$module]->options[CONS_MODULE_PARENT] == '') {
                     $this->modules[$module]->options[CONS_MODULE_PARENT] = $nomecampo;
                 }
             } else {
                 if ($campos[$nomecampo][CONS_XML_TIPO] == CONS_TIPO_SERIALIZED) {
                     // browse fields looking for links
                     foreach ($campos[$nomecampo][CONS_XML_SERIALIZEDMODEL] as $exname => &$exfield) {
                         if ($exfield[CONS_XML_TIPO] == CONS_TIPO_LINK) {
                             array_push($relation, array($module, $nomecampo . ":" . $exname, $exfield[CONS_XML_MODULE]));
                         }
                     }
                 }
             }
             # checks if this field can be NULL or NOT depending on options and mandatory setting
             if (isset($campos[$nomecampo][CONS_XML_SQL]) && $campos[$nomecampo][CONS_XML_SQL] != "") {
                 # relation will not be set
                 if (isset($campos[$nomecampo][CONS_XML_MANDATORY]) || $campos[$nomecampo][CONS_XML_TIPO] == CONS_TIPO_OPTIONS || isset($campos[$nomecampo][CONS_XML_DEFAULT])) {
                     $campos[$nomecampo][CONS_XML_SQL] .= " NOT NULL";
                     $mandatory++;
                 } else {
                     $campos[$nomecampo][CONS_XML_SQL] .= " NULL";
                 }
                 if (isset($campos[$nomecampo][CONS_XML_DEFAULT])) {
                     $campos[$nomecampo][CONS_XML_SQL] .= " DEFAULT '" . $campos[$nomecampo][CONS_XML_DEFAULT] . "'";
                 }
             }
         }
         # this module has a database (it's possible to have modules without a database)
         if ($this->modules[$module]->dbname != "") {
             # checks standard key "id" if no key specified
             if (in_array("id", $this->modules[$module]->keys) && !isset($this->modules[$module]->fields['id']) && !isset($campos['id'])) {
                 if ($this->modules[$module]->linker) {
                     $this->modules[$module]->keys = array();
                     $keys = 0;
                     foreach ($campos as $fieldname => $fieldobj) {
                         if (isset($fieldobj[CONS_XML_MODULE])) {
                             $keys++;
                             $this->modules[$module]->keys[] = $fieldname;
                             if ($keys == 2) {
                                 break;
                             }
                         }
                     }
                     unset($fieldname);
                     unset($fieldobj);
                 } else {
                     $campos['id'][CONS_XML_SQL] = "INT (11) UNSIGNED NOT NULL" . (count($this->modules[$module]->keys) <= 1 ? " AUTO_INCREMENT" : "");
                     $campos['id'][CONS_XML_TIPO] = CONS_TIPO_INT;
                     if (count($this->modules[$module]->keys) > 1) {
                         $campos['id'][CONS_XML_RESTRICT] = 99;
                     }
                 }
             }
             # -- keys (this is done to prevent repeated keys)
             $chave = $this->modules[$module]->keys;
             $this->modules[$module]->keys = array();
             foreach ($chave as $x => $di) {
                 if (!in_array($di, $this->modules[$module]->keys) && $di != "") {
                     array_push($this->modules[$module]->keys, $di);
                 }
             }
             unset($x);
             unset($di);
             # if this is a re-definition, will TOTALLY overright the fields (you can redefine fields from the default.xml on the meta.xml)
             $this->modules[$module]->fields = array_merge($this->modules[$module]->fields, $campos);
             # -- makes sure all keys are mandatory and present
             foreach ($this->modules[$module]->keys as $x => $chave) {
                 if (!isset($this->modules[$module]->fields[$chave])) {
                     array_push($this->log, "Key not defined, considering INT 11, please fix the XML: {$module}.{$chave}");
                     $this->modules[$module]->fields[$chave] = array("CONS_XML_SQL" => "INT (11) UNSIGNED NOT NULL", "CONS_XML_TIPO" => CONS_TIPO_INT);
                 }
                 $this->modules[$module]->fields[$chave][CONS_XML_MANDATORY] = true;
                 // vc keys without case specified, force ucase
                 if ($this->modules[$module]->fields[$chave][CONS_XML_TIPO] == CONS_TIPO_VC && !isset($this->modules[$module]->fields[$chave][CONS_XML_SPECIAL])) {
                     $this->modules[$module]->fields[$chave][CONS_XML_SPECIAL] = "ucase";
                 }
             }
             unset($x);
             unset($chave);
         }
     }
     # -- foreach module
     $total_relacoes = count($relation);
     # check our relationship counts and build proper fields or support tables -------------
     for ($c = 0; $c < $total_relacoes; $c++) {
         $rel = $relation[$c];
         # relation: MODULE => FIELD => MODULE or MODULE => SFIELD:FIELD => MODULE for serialized fields
         if (!isset($this->modules[$rel[0]]) || !isset($this->modules[$rel[2]])) {
             array_push($this->log, "Error (pass 1) trying to build foreign keys from '" . $rel[0] . "' to '" . $rel[2] . "' at " . $rel[1] . ": one of the modules do not exist, ignoring relation");
         } else {
             $sfield = "";
             if (strpos($rel[1], ":") !== false) {
                 #serialized field
                 $field = explode(":", $field);
                 $sfield = $field[0];
                 $field = $field[1];
             } else {
                 $field = $rel[1];
             }
             if (substr($field, 0, 3) != "id_") {
                 array_push($this->log, "All relations to another modules MUST start with id_ on " . $rel[0] . "' to '" . $rel[2] . "' at " . $rel[1] . ": should be id_" . $field . " ?");
             }
             if ($sfield == '') {
                 $this->modules[$rel[2]]->volatile = false;
             }
             # keeps volatile if linked from serialized (a.k.a. serialized links are not safe, because they are meant to be dinamic)
             foreach ($this->modules[$rel[2]]->keys as $x => $chave) {
                 # will create required keys for foreign table, except any one in common with this table
                 if ($chave == "id" || !isset($this->modules[$rel[0]]->fields[$chave])) {
                     # only standard id exists (always link it), or it's not a standard key ... still have to test if it's not a key to this table
                     # basically, this will create the second+ keys on multikey relations
                     if (!($this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] == CONS_TIPO_LINK && $this->modules[$rel[2]]->fields[$chave][CONS_XML_MODULE] == $rel[0])) {
                         # ok not a key to this table (the FOREING key is not this table, pay attention! this will still be true for id_parent)
                         if ($sfield == "") {
                             # normal
                             if ($chave == "id") {
                                 # uses the name that came in the XML model
                                 if (!isset($this->modules[$rel[0]]->fields[$field])) {
                                     $this->modules[$rel[0]]->fields[$field] = array();
                                 }
                                 $this->modules[$rel[0]]->fields[$field][CONS_XML_SQL] = str_replace("AUTO_INCREMENT", "", $this->modules[$rel[2]]->fields[$chave][CONS_XML_SQL]);
                                 $this->modules[$rel[0]]->fields[$field][CONS_XML_TIPO] = CONS_TIPO_LINK;
                                 $this->modules[$rel[0]]->fields[$field][CONS_XML_LINKTYPE] = $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] != CONS_TIPO_LINK ? $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] : CONS_TIPO_INT;
                                 $this->modules[$rel[0]]->fields[$field][CONS_XML_MODULE] = $rel[2];
                                 # the creation system might have added this already, that's why testing before resetting the array
                                 if (isset($this->modules[$rel[0]]->fields[$field][CONS_XML_JOIN]) && $this->modules[$rel[0]]->fields[$field][CONS_XML_JOIN] == "inner" || isset($this->modules[$rel[0]]->fields[$field][CONS_XML_MANDATORY])) {
                                     // is set join to INNER or is explicitly mandatory, make sure both are set
                                     $this->modules[$rel[0]]->fields[$field][CONS_XML_MANDATORY] = true;
                                     if ($x == 0) {
                                         $this->modules[$rel[0]]->fields[$field][CONS_XML_JOIN] = "inner";
                                     }
                                 } else {
                                     // no join mode set (defaults to left), set to left, and no explicit mandatory tag
                                     if ($x == 0) {
                                         $this->modules[$rel[0]]->fields[$field][CONS_XML_JOIN] = "left";
                                     }
                                     $this->modules[$rel[0]]->fields[$field][CONS_XML_SQL] = str_replace("NOT NULL", "NULL", $this->modules[$rel[0]]->fields[$field][CONS_XML_SQL]);
                                 }
                             } else {
                                 if ($x == 0) {
                                     $nome = $field;
                                     # first key keeps the original name
                                     $this->modules[$rel[0]]->fields[$field][CONS_XML_LINKTYPE] = $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] != CONS_TIPO_LINK ? $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] : CONS_TIPO_INT;
                                 } else {
                                     $nome = $field . "_" . str_replace("id_", "", $chave);
                                 }
                                 # creates a composition with the model name and the foreign name
                                 $this->modules[$rel[0]]->fields[$nome][CONS_XML_SQL] = str_replace("AUTO_INCREMENT", "", $this->modules[$rel[2]]->fields[$chave][CONS_XML_SQL]);
                                 $this->modules[$rel[0]]->fields[$nome][CONS_XML_TIPO] = $x == 0 ? CONS_TIPO_LINK : $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO];
                                 $this->modules[$rel[0]]->fields[$nome][CONS_XML_MODULE] = isset($this->modules[$rel[2]]->fields[$chave][CONS_XML_MODULE]) ? $this->modules[$rel[2]]->fields[$chave][CONS_XML_MODULE] : $rel[2];
                                 if (isset($this->modules[$rel[0]]->fields[$field][CONS_XML_JOIN]) && $this->modules[$rel[0]]->fields[$field][CONS_XML_JOIN] == "inner" || isset($this->modules[$rel[0]]->fields[$nome][CONS_XML_MANDATORY])) {
                                     $this->modules[$rel[0]]->fields[$nome][CONS_XML_MANDATORY] = true;
                                     if ($x == 0) {
                                         $this->modules[$rel[0]]->fields[$nome][CONS_XML_JOIN] = "inner";
                                     }
                                 } else {
                                     if ($x == 0) {
                                         $this->modules[$rel[0]]->fields[$nome][CONS_XML_JOIN] = "left";
                                     }
                                     unset($this->modules[$rel[0]]->fields[$nome][CONS_XML_MANDATORY]);
                                     $this->modules[$rel[0]]->fields[$nome][CONS_XML_SQL] = str_replace("NOT NULL", "NULL", $this->modules[$rel[0]]->fields[$nome][CONS_XML_SQL]);
                                 }
                             }
                         } else {
                             # serialized
                             if ($chave == "id") {
                                 # uses the name that came in the XML model
                                 if (!isset($this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field])) {
                                     $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field] = array();
                                 }
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_SQL] = str_replace("AUTO_INCREMENT", "", $this->modules[$rel[2]]->fields[$chave][CONS_XML_SQL]);
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_TIPO] = CONS_TIPO_LINK;
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_LINKTYPE] = $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] != CONS_TIPO_LINK ? $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] : CONS_TIPO_INT;
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_MODULE] = $rel[2];
                                 # serialized links cannot be "inner"
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_JOIN] = "left";
                                 if (isset($this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_MANDATORY])) {
                                     $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_MANDATORY] = true;
                                 } else {
                                     $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_SQL] = str_replace("NOT NULL", "NULL", $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_SQL]);
                                 }
                             } else {
                                 if ($x == 0) {
                                     $nome = $field;
                                     # first key keeps the original name
                                     $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$field][CONS_XML_LINKTYPE] = $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] != CONS_TIPO_LINK ? $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO] : CONS_TIPO_INT;
                                 } else {
                                     $nome = $field . "_" . str_replace("id_", "", $chave);
                                 }
                                 # creates a composition with the model name and the foreign name
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_SQL] = str_replace("AUTO_INCREMENT", "", $this->modules[$rel[2]]->fields[$chave][CONS_XML_SQL]);
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_TIPO] = $x == 0 ? CONS_TIPO_LINK : $this->modules[$rel[2]]->fields[$chave][CONS_XML_TIPO];
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_MODULE] = isset($this->modules[$rel[2]]->fields[$chave][CONS_XML_MODULE]) ? $this->modules[$rel[2]]->fields[$chave][CONS_XML_MODULE] : $rel[2];
                                 # serialized links cannot be "inner"
                                 $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_JOIN] = "left";
                                 if (isset($this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_MANDATORY])) {
                                     $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_MANDATORY] = true;
                                 } else {
                                     $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_SQL] = str_replace("NOT NULL", "NULL", $this->modules[$rel[0]]->fields[$sfield][CONS_XML_SERIALIZEDMODEL][$nome][CONS_XML_SQL]);
                                 }
                             }
                         }
                         # sfield?
                     }
                 }
                 # secondary (multikey)?
             }
             # foreach
             unset($x);
             unset($chave);
             if (!isset($this->modules[$rel[0]]->fields[$field][CONS_XML_SQL])) {
                 array_push($this->log, "Error (pass 2) trying to build foreing keys from " . $rel[0] . " to " . $rel[2] . " at " . $field . ": ignoring relation");
             }
         }
     }
     # foreach for relations
     // now some automatic settings since all modules are loaded, and consistency check on build, partOf, etc ---------------------
     $cacheLinkNum = array();
     // module => modules which link to this
     foreach ($this->modules as $mname => &$module) {
         $links = 0;
         $fieldsRequiredToLinks = 0;
         foreach ($module->fields as $name => $field) {
             // check for linker modules
             if ($field[CONS_XML_TIPO] == CONS_TIPO_LINK && $field[CONS_XML_MODULE] != $mname) {
                 // links to OTHER link not myself
                 $links++;
                 # do not count PARENTS as links
                 $fieldsRequiredToLinks += count($this->modules[$field[CONS_XML_MODULE]]->keys);
                 # a module can have more than one key, thus to know if this module is a linker module, we need to check if ALL THIS HAVE are the keys for 2 modules
                 // vc links that have no case specified, force to upper
                 if ($field[CONS_XML_TIPO] == CONS_TIPO_LINK && $field[CONS_XML_LINKTYPE] == CONS_TIPO_VC && !isset($field[CONS_XML_SPECIAL])) {
                     $this->modules[$mname]->fields[$name][CONS_XML_SPECIAL] = "ucase";
                 }
             }
             if (isset($field[CONS_XML_FILTEREDBY])) {
                 foreach ($field[CONS_XML_FILTEREDBY] as $fbname) {
                     if (!isset($module->fields[$fbname])) {
                         $this->log[] = "Error on filteredby for {$mname}.{$name}: {$fbname} does not exist";
                     } else {
                         if (!isset($this->modules[$module->fields[$fbname][CONS_XML_MODULE]])) {
                             $this->log[] = "Error on filteredby for {$mname}.{$name}: module defined in {$fbname} does not exist";
                         }
                     }
                 }
             }
         }
         if ($links == 2 && count($module->fields) == $fieldsRequiredToLinks || $this->modules[$mname]->linker) {
             # this is a linker module!
             $this->modules[$mname]->linker = true;
         }
         if ($this->modules[$mname]->title == "" && !$this->modules[$mname]->options[CONS_MODULE_SYSTEM] && !$this->modules[$mname]->linker) {
             $this->modules[$mname]->title = $this->modules[$mname]->keys[0];
             // first key
         }
     }
     # here we finished the automatic settings
     # load plugins that are defined by METADATA
     foreach ($this->modules as $name => &$module) {
         foreach ($module->plugins as $sname) {
             if (!isset($this->loadedPlugins[$sname])) {
                 $this->addPlugin($sname, $name);
             } else {
                 $this->loadedPlugins[$sname]->moduleRelation = $name;
             }
         }
     }
     foreach ($this->loadedPlugins as $sname => $obj) {
         if ($obj->name == '' || $obj->name != $sname) {
             $this->errorControl->raise(9, $obj->name, $sname);
         }
     }
     # DIE FREAKING THUMBS.DB, DIE!
     function dieFreakingThumbs($folder)
     {
         if ($folder[strlen($folder) - 1] != '/') {
             $folder .= "/";
         }
         foreach (glob($folder . "*") as $file) {
             if (is_dir($file)) {
                 dieFreakingThumbs($file);
             } else {
                 $arf = explode(".", $file);
                 if (array_pop($arf) == 'db') {
                     @unlink($file);
                 }
             }
         }
     }
     dieFreakingThumbs(CONS_PATH_PAGES . $_SESSION['CODE'] . "/");
     $customxml = is_file(CONS_PATH_PAGES . $_SESSION["CODE"] . "/_config/custom.xml") ? cReadFile(CONS_PATH_PAGES . $_SESSION["CODE"] . "/_config/custom.xml") : '';
     # All plugins are loaded, check their manifest and customs
     foreach ($this->loadedPlugins as $sname => $plugin) {
         if (is_file(CONS_PATH_SYSTEM . "plugins/{$sname}/payloadmanifest.php")) {
             $copyFiles = (include CONS_PATH_SYSTEM . "plugins/{$sname}/payloadmanifest.php");
             foreach ($copyFiles as $from => $to) {
                 if ($from[strlen($from) - 1] == "/" && is_dir($from) && (!is_dir($to) || !CONS_ONSERVER && isset($_REQUEST['nocache']))) {
                     // FOLDER
                     if (!function_exists('recursive_copy')) {
                         include_once CONS_PATH_INCLUDE . "recursive_copy.php";
                     }
                     recursive_copy($from, $to);
                 } else {
                     if (is_file($from) && (!is_file($to) || !CONS_ONSERVER && isset($_REQUEST['nocache']))) {
                         // FILE
                         $path = explode("/", $to);
                         array_pop($path);
                         // bye file
                         $path = implode("/", $path);
                         makeDirs($path);
                         copy($from, $to);
                     }
                 }
             }
         }
         if (is_file(CONS_PATH_SYSTEM . "plugins/{$sname}/custom.xml")) {
             $customxml .= cReadFile(CONS_PATH_SYSTEM . "plugins/{$sname}/custom.xml");
         }
     }
     # Read custom metadata for dimconfig
     if ($customxml != '') {
         $parseXMLparams = array(C_XML_RAW => true, C_XML_AUTOPARSE => true, C_XML_REMOVECOMMENTS => true);
         $xml = new xmlHandler();
         $customxml = $xml->parseXML($customxml, $parseXMLparams, true);
         if ($customxml === false) {
             $this->errorControl->raise(180);
         }
         unset($xml);
         $customxml =& $customxml->getbranch(0);
         $total = $customxml->total();
         $dimconfigMD = array();
         // MetaData -------------------------------------
         for ($c = 0; $c < $total; $c++) {
             # for each module ...
             $thisbranch =& $customxml->getbranch($c);
             $configname = strtolower($thisbranch->data[0]);
             if (!isset($this->dimconfig[$configname])) {
                 $this->dimconfig[$configname] = '';
             }
             $dimconfigMD = $this->processParameters($thisbranch, $dimconfigMD, '');
         }
         foreach ($dimconfigMD as $name => $field) {
             if ($field[CONS_XML_TIPO] == CONS_TIPO_UPLOAD && (!isset($field['location']) || $field['location'][0] == '/')) {
                 $this->errorControl->raise(181, $name, 'dimconfig');
             }
             if ($field[CONS_XML_TIPO] != CONS_TIPO_ENUM) {
                 unset($dimconfigMD[$name][CONS_XML_SQL]);
             }
         }
         cWriteFile(CONS_PATH_CACHE . $_SESSION['CODE'] . "/meta/_dimconfig.dat", serialize($dimconfigMD));
         // this defines the type of each item on dimconfig
     }
     # Apply and raise metadata
     $this->applyMetaData();
     # no log = no error
     return $sucess = count($this->log) == 0;
 }