/** * loadComponent() * * Carrega o componente especificado. Se chamado manualmente, não * funcionarão os métodos beforeBeforeFilter, por exemplo. Portanto, * não chame manualmente o AuthComponent, por exemplo. * * @param string $componentName * @return bool */ public function loadComponent($valor, $options = array()) { include_once CORE_COMPONENTS_DIR . $valor . ".php"; $componentName = $valor . COMPONENT_CLASSNAME_SUFFIX; /** * Instancia compoment */ $componentParams = array("params" => $this->params, "data" => $this->data, "models" => $this->usedModels, "controller" => $this); ${$valor} = new $componentName($componentParams); /** * Envia o Component para a Action do Controller */ if (empty($options['as'])) { $loadedComponentName = StrTreament::firstToLower($valor); } else { $loadedComponentName = $options['as']; } $this->{$loadedComponentName} = ${$valor}; $this->loadedComponents[] = $loadedComponentName; return true; }
/** * SAVE() * * $data deve ter o seguinte formato: * [model]=>array([campo]=>valor), [modelFilho]=>array([campo]=>valor) * * @author Alexandre de Oliveira <*****@*****.**> * @since v0.1 * @param array $data Dados enviados para salvar no DB * @param array $options * @return bool Se salvou ou não */ public function save($data, $options = array()) { if (is_array($data)) { /** * Sanitize os dados */ $data = Security::Sanitize($data); $updateInstruction = false; $doUpdate = empty($options["doUpdate"]) ? false : $options["doUpdate"]; /** * VALIDATE */ if ($this->validate($data)) { /** * LOOP EM $DATA * * Loop por cada model dos valores enviados em $data. O formato * padrão é * * array( * [model] => array( * [campo] => valor * ) * ) * */ foreach ($data as $model => $campos) { /** * Verifica possíveis relacionamentos entre o model $this * atual e o model atual de $data */ if (get_class($this) == $model) { $tabela = $this->useTable; $modelPai = true; /** * Verifica se este Model pertence a outro */ /** * @todo - verificar integridade */ //pr($campos); if (!empty($this->belongsTo)) { /* * Percorre cada Model a qual o Model atual ($this) * pertence, verificando se um campo no formulário * foi especificado. * * Se foi especificado, cria um índice em $data * com o ID do model relacionado. * * Ex: * - Idade belongsTo Usuario * | * | Se o formulário é do model Idade e há um * | campo chamado Usuario.id, substitui por * | Idade.usuario_id * */ foreach ($this->belongsTo as $relationalModel => $propriedades) { if (array_key_exists($relationalModel, $data) and !empty($data[$relationalModel]["id"])) { $campos[$propriedades["foreignKey"]] = $data[$relationalModel]["id"]; } } } } else { $tabela = $this->{$model}->useTable; $modelPai = false; if (array_key_exists($model, $this->hasOne)) { $modelsFilhos[$model] = $campos; } else { if (array_key_exists($model, $this->hasMany)) { $modelsFilhos[$model] = $campos; } } } /** * MODEL PAI * * $data[model] == model objeto atual ? * * Verifica se o Model atual da array $data (está dentro de * um foreach) é o mesmo que get_class($this) ou se é um * model filho. * * [Se for o próprio Model pai] * Gera SQL para INSERT ou UPDATE posteriormente no * código * */ if ($modelPai) { /** * subModel * * Se esta é uma chamada a um subModel, ve qual o * registro deve ser modificado. */ if ($doUpdate and !empty($options["foreignKey"])) { $campoId = $options["foreignKey"]["id"]; /** * Se o tipo de relação é hasMany, o campo * foreignKey não deve ser a referência. */ if (!empty($options["relationType"]) and $options["relationType"] !== "hasMany") { $updateConditionField = $options["foreignKey"]["field"]; } else { if (!empty($options["relationType"]) and $options["relationType"] == "hasMany") { /** * VERIFICA FORMATO $DATA PARA HASMANY */ $dataItems = array_keys($data[get_class($this)]); } else { } } } // fim chamada subModel /* * Se a tabela atual existe de fato. */ if (in_array($tabela, $this->dbTables)) { /** * Loop por cada campo e seus valores para gerar uma * string com os campos a serem incluidos. */ foreach ($campos as $campo => $valor) { /* * Se o campo existe de fato na tabela * especificada. */ if (array_key_exists($campo, $this->tableDescribed)) { /** * Atualizando subModel (model filho) */ if ($campo == "id") { $doUpdate = true; $campoId = $valor; $updateConditionField = "id"; } else { $camposStr[] = $campo; /** * Checkbox? Tinyint? * * Verifica se o campo é do tipo checkbox. */ $type = StrTreament::getNameSubStr($this->tableDescribed[$campo]["Type"], "("); if (in_array($type, array("tinyint", "bool"))) { if (!empty($valor)) { $valor = '1'; } } $valorStr[] = $valor; } } else { /* * O campo não existe e não é um arquivo. */ if (!$this->_isFileField(array($campo => $valor))) { //showWarning("Campo inexistente configurado no formulário."); } } } if (!empty($camposStr)) { /** * @todo - comentar */ /** * com $doUpdate=true, verifica se realmente * deve ser feito um update, ou um insert */ if ($doUpdate and !empty($updateConditionField)) { //pr($campoId); if ($this->countRows(array("conditions" => array(get_class($this) . "." . $updateConditionField => $campoId))) == 0) { $doUpdate = false; } } else { if (empty($updateConditionField)) { $doUpdate = false; } } /* * Flag que indica se é insert ou update */ $insertInstruction = false; $updateInstruction = false; if (!$doUpdate) { $insertInstruction = true; $tempSql = "INSERT INTO\n " . $tabela . "\n (" . implode(",", $camposStr) . ")\n VALUES\n ('" . implode("','", $valorStr) . "')\n "; } else { for ($i = 0; $i < count($camposStr); $i++) { $camposUpdate[] = $camposStr[$i] . "='" . $valorStr[$i] . "'"; } /** * Instrução de atualização. */ $updateInstruction = true; $tempSql = "UPDATE\n " . $tabela . "\n SET\n " . implode(",", $camposUpdate) . "\n WHERE\n " . $updateConditionField . "='" . $campoId . "'\n "; } /** * SQL deste campo */ $sql[] = $tempSql; } unset($camposStr); unset($valorStr); } else { $debugMode = Config::read("debug"); if (Config::read("debug") > 0 or empty($debugMode)) { trigger_error("Alguma tabela especificada não existe", E_USER_ERROR); } } } // fim modelFather==true } // fim criação de SQLs /** * SALVA SQL CRIADO * * Executa o SQL do model principal * * Gera lastInsertId ao final */ /* * Se há uma SQL gerado nesta execução */ if (!empty($sql) and count($sql) > 0) { foreach ($sql as $instrucao) { /** * Salva dados na tabela deste Model */ $this->conn->exec($instrucao); unset($_SESSION["Sys"]["addToThisData"]); unset($_SESSION["Sys"]["options"]["addToThisData"]); if ($updateInstruction) { if (!empty($data[get_class($this)]["id"])) { $lastInsertId = $data[get_class($this)]["id"]; } else { $lastInsertId = $data[get_class($this)][$updateConditionField]; } } else { $lastInsertId = $this->conn->lastInsertId(); } //$modelsFilhos = array(); } } else { $lastInsertId = $data[get_class($this)]["id"]; } /* * Guarda lastInsertId. * * Esta variável é útil para se saber qual o id foi salvo e pode * ser acessada através de Model::lastInsertId */ $this->lastInsertId = $lastInsertId; /** * Se há dados de models filhas (relacionais), envia dados para * seus respectivos objetos ($model) para serem salvos * * [Se há models filhos com dados && lastInsertId existe] * */ if (!empty($modelsFilhos) and !empty($lastInsertId)) { /** * Loop por models filhos */ foreach ($modelsFilhos as $model => $campos) { $dataTemp[$model] = $campos; /** * FOREIGNKEY * * Pega as chaves estrangeiras (foreignKey) dos models * relacionados. */ if (array_key_exists($model, $this->hasOne)) { $foreignKey = $this->hasOne[$model]["foreignKey"]; $relationType = "hasOne"; } else { if (array_key_exists($model, $this->hasMany)) { $foreignKey = $this->hasMany[$model]["foreignKey"]; $relationType = "hasMany"; } else { if (array_key_exists($model, $this->belongsTo)) { $foreignKey = $this->belongsTo[$model]["foreignKey"]; $relationType = "hasBelongsTo"; } else { if (array_key_exists($model, $this->hasAndBelongsToMany)) { $foreignKey = $this->hasAndBelongsToMany[$model]["foreignKey"]; $relationType = "hasAndBelongsToMany"; } } } } /* * CHAMA MODEL::SAVE() FILHOS */ /* * hasMany * */ if ($relationType == "hasMany") { foreach ($dataTemp[$model] as $chave => $valor) { if (is_int($chave)) { $dataForHasMany[$model] = $valor; $dataForHasMany[$model][$foreignKey] = $lastInsertId; if ($insertInstruction and !empty($dataForHasMany[$model]["id"])) { unset($dataForHasMany[$model]["id"]); } /** * Chama os models filhos - save() * * Envia dados para Models relacionados salvarem. É * passado [foreignKey] para que o model filho saiba * qual é o registro que deve ser mexido, e qual * o relacionamento existe. * */ $this->{$model}->save($dataForHasMany, array("doUpdate" => $doUpdate, "relationType" => $relationType, "foreignKey" => array("field" => $foreignKey, "id" => $lastInsertId))); } } } else { $dataTemp[$model][$foreignKey] = $lastInsertId; /** * Chama os models filhos - save() * * Envia dados para Models relacionados salvarem. É * passado [foreignKey] para que o model filho saiba * qual é o registro que deve ser mexido, e qual * o relacionamento existe. * */ $this->{$model}->save($dataTemp, array("doUpdate" => $doUpdate, "relationType" => $relationType, "foreignKey" => array("field" => $foreignKey, "id" => $lastInsertId))); } unset($dataTemp); } } return true; } else { $this->invalidate($data); } } return false; }
/** * translateUrl() traduz uma URL * * @global Object $dispatcher Objeto inicializador do sistema * @param mixed $mixed Configuração de Url para criação de string final * @return string Retorna um endereço Url válido */ function translateUrl($mixed, $isFile = false) { $dispatcher = Dispatcher::getInstance(); /** * $mixed é array */ if (is_array($mixed)) { /* * Define APP */ if (isset($mixed["app"]) and is_string($mixed["app"])) { $app = $mixed["app"] . "/"; } else { $app = ""; } $controller = empty($mixed["controller"]) ? "" : $mixed["controller"]; $action = (empty($mixed["action"]) or empty($controller)) ? "" : $mixed["action"]; if (!empty($action)) { $action = '/' . $action; } $args = (empty($mixed[0]) or empty($action)) ? "" : $mixed[0]; if (isset($args[0]) and $args[0] != "/") { $args = "/" . $args; } /* * Se app é vazio mas existe, acessa app sem nome, que é automaticamente * levado para app/. */ if (!empty($app)) { $rootDir = ROOT; if ($app == "/") { $app = ""; } } else { $rootDir = WEBROOT; } $url = str_replace("//", "/", $rootDir . $app . $controller . $action . $args); } else { if (is_string($mixed)) { /* * A URL é uma string mas não contém nenhum dos termos a seguir, * ou seja, é um link para uma página interna. */ if (!in_array(StrTreament::getNameSubStr($mixed, ":"), array("http", "ftp", "ssh", "git", "https")) and !$isFile) { /* Strips webroot off the beginning of the url */ $pos = strpos($mixed, WEBROOT); if ($pos === 0) { $mixed = substr($mixed, mb_strlen(WEBROOT)); } $controller = ''; $url = explode("/", $mixed); $args = array(); $i = 0; foreach ($url as $chave => $valor) { if (empty($valor)) { unset($url[$chave]); } else { if ($i == 0) { $controller = $valor; } else { if ($i == 1) { $action = $valor; } else { $args[] = $valor; } } $i++; } } /* * Se não foi especificado um action */ if (!empty($action)) { $action = "/" . $action; } else { $action = ''; } $argsStr = implode("/", $args); if (!empty($argsStr)) { $argsStr = "/" . $argsStr; } $url = WEBROOT . $controller . $action . $argsStr; } else { if ($isFile) { $url = WEBROOT_ABSOLUTE . $mixed; } else { $url = $mixed; } } } } $url = str_replace("//", "/", $url); return $url; }