Example #1
0
 protected function _get($params)
 {
     // Get a list of fields convert it to a count if that is what is needed
     if ($params["type"] == "count") {
         $fields = "COUNT(*)";
     } else {
         // If a count is not needed get a list of all the fields in the model
         $description = $this->model->describe();
         if ($params["fields"] == null) {
             $requestedFields = array_keys($description["fields"]);
         } else {
             $requestedFields = is_array($params["fields"]) ? $params["fields"] : explode(",", $params["fields"]);
         }
         $fields = array();
         $hasManyFields = array();
         $belongsToFields = array();
         foreach ($requestedFields as $index => $field) {
             if ($params["fetch_related"] === true || $params["fetch_belongs_to"] === true) {
                 $modelName = Model::extractModelName($field);
                 if ($modelName != '') {
                     $relationShip = $this->model->getRelationshipWith($modelName);
                     if ($relationShip == Model::RELATIONSHIP_HAS_MANY) {
                         $hasManyFields[$modelName][] = $field;
                         continue;
                     } else {
                         if ($relationShip == Model::RELATIONSHIP_BELONGS_TO) {
                             $belongsToFields[$modelName][] = Model::extractFieldName($field);
                             continue;
                         }
                     }
                 }
             }
             $fields[$index] = $this->resolveName($field, true, $description);
             if ($params["fetch_belongs_to"] && $description["fields"][$field]["foreign_key"] && $description["fields"][$field]["alias"] != '') {
                 $fields[$index] .= " AS {$description["fields"][$field]["alias"]}";
             }
         }
         $fields = implode(", ", is_array($fields) ? $fields : explode(",", $fields));
     }
     // Generate joins
     $joins = "";
     // Related joins from the model description
     if ($params["fetch_related"] === true || $params["fetch_belongs_to"] === true) {
         $numRequestedBelongsTo = count($belongsToFields);
         foreach ($this->model->belongsTo as $relatedModel) {
             if (is_array($relatedModel) && isset($relatedModel["through"])) {
                 $firstRelatedModel = Model::load(Model::getBelongsTo($relatedModel[0]));
                 $firstDatastore = $firstRelatedModel->dataStore;
                 $secondRelatedModel = Model::load($relatedModel["through"]);
                 $secondDatastore = $secondRelatedModel->dataStore;
                 $joins .= " LEFT JOIN {$firstDatastore->table} ON {$firstDatastore->table}.id = {$secondDatastore->table}." . Ntentan::singular($firstDatastore->table) . "_id ";
                 $joinedModelDescription = $firstRelatedModel->describe();
                 $joinedModelFields = array_keys($joinedModelDescription["fields"]);
                 foreach ($joinedModelFields as $index => $field) {
                     $joinedModelFields[$index] = $this->quote($firstDatastore->table) . "." . $this->quote($field) . " AS " . $this->quote($firstRelatedModel->getRoute() . ".{$field}");
                 }
                 if ($params['type'] != 'count') {
                     $fields = $fields . ", " . implode(", ", $joinedModelFields);
                 }
             } else {
                 $alias = null;
                 $as = null;
                 if (is_array($relatedModel)) {
                     $alias = isset($relatedModel['alias']) ? $relatedModel['alias'] : $relatedModel["as"];
                     $as = $relatedModel['as'];
                     $relatedModel = $relatedModel[0];
                 }
                 // If the related belongs to field was not queried then skip this whole step entirely
                 if ($numRequestedBelongsTo > 0 & isset($belongsToFields[$relatedModel])) {
                     $model = Model::load(Model::getBelongsTo($relatedModel));
                     $datastore = $model->dataStore;
                     $joinedModelDescription = $model->describe();
                     $joinedModelFields = $belongsToFields[$relatedModel];
                 } else {
                     if (is_array($requestedFields)) {
                         $array = explode('.', $relatedModel);
                         if ($alias != null && array_search($alias, $requestedFields) === false) {
                             continue;
                         } else {
                             if ($alias == null && array_search(Ntentan::singular(end($array)) . "_id", $requestedFields) === false) {
                                 continue;
                             }
                         }
                     }
                     $model = Model::load(Model::getBelongsTo($relatedModel));
                     $datastore = $model->dataStore;
                     $joinedModelDescription = $model->describe();
                     $joinedModelFields = array_keys($joinedModelDescription["fields"]);
                 }
                 if ($alias == null) {
                     $joinedTable = $joinedModelDescription["name"];
                 } else {
                     $joinedTable = "{$datastore->table}_as_" . str_replace('.', '_', $alias);
                 }
                 foreach ($joinedModelFields as $index => $field) {
                     $joinedModelFields[$index] = $datastore->resolveName($field, true, $joinedModelDescription, false) . " AS " . $this->quote($alias == '' ? "{$model->getRoute()}.{$field}" : "{$alias}.{$field}");
                 }
                 if ($params['type'] != 'count') {
                     $fields = $fields . ", " . implode(", ", $joinedModelFields);
                 }
                 $table = $alias == '' ? $datastore->table : $joinedTable;
                 //"{$datastore->table}_as_" $alias);
                 $joins .= " LEFT JOIN " . ($datastore->schema == "" ? '' : "{$datastore->schema}.") . $datastore->table . " " . ($alias == '' ? '' : "{$table} ") . " ON {$table}.id = {$this->table}." . ($alias != null ? $as : Ntentan::singular($datastore->table) . "_id ");
             }
         }
     }
     /**
      * @todo write a test case for this
      */
     if (isset($params["through"])) {
         if (is_array($params["through"])) {
             $through = $params['through'];
         } else {
             if (is_string($params['through'])) {
                 $through = explode(',', $params['through']);
             }
         }
         $previousTable = $this->table;
         foreach ($through as $relatedModel) {
             $modelInstance = Model::load($relatedModel);
             $currentTable = $modelInstance->dataStore->table;
             $foreignKey = Ntentan::singular($previousTable) . "_id";
             $joins .= " JOIN {$currentTable} ON {$previousTable}.id = {$currentTable}.{$foreignKey} ";
             $previousTable = $currentTable;
         }
     }
     // Generate the base query
     $query = "SELECT {$fields} FROM " . ($this->schema != '' ? $this->quotedSchema . "." : '') . $this->quotedTable . " {$joins} ";
     // Generate conditions
     $parserResults = $this->parseConditions($params['conditions'], $params);
     $hasManyConditions = $parserResults['has_many_conditions'];
     $query .= $parserResults['query'];
     // Add the sorting queries
     if (isset($params['sort'])) {
         if (is_array($params['sort'])) {
             $query .= " ORDER BY " . implode(", ", $params['sort']);
         } else {
             $query .= " ORDER BY {$params["sort"]} ";
         }
     }
     // Add the limiting clauses
     if ($params["type"] == 'first') {
         $query .= $this->limit(array("limit" => '1'));
         //" LIMIT 1";
     } else {
         if (is_numeric($params["type"])) {
             $query .= $this->limit(array("limit" => $params['type'], "offset" => $params['offset']));
         }
     }
     $results = $this->query($query);
     // Retrieve all related data
     if ($params["fetch_related"] === true || $params["fetch_belongs_to"] === true) {
         if (count($this->model->belongsTo) > 0) {
             foreach ($results as $index => $result) {
                 $modelizedFields = array();
                 foreach ($result as $field => $value) {
                     if (strpos($field, ".") !== false) {
                         $fieldNameArray = explode(".", $field);
                         $fieldName = array_pop($fieldNameArray);
                         $modelName = Ntentan::singular(implode(".", $fieldNameArray));
                         if (is_string($results[$index][$modelName])) {
                             $results[$index][$modelName] = array();
                         }
                         if ($params['use_dots']) {
                             $results[$index]["{$modelName}.{$fieldName}"] = $value;
                         } else {
                             $results[$index][$modelName][$fieldName] = $value;
                         }
                         $modelizedFields[] = $modelName;
                         unset($results[$index][$field]);
                     }
                 }
                 $modelizedFields = array_unique($modelizedFields);
                 foreach ($modelizedFields as $modelizedField) {
                     if ($description["fields"][$modelizedField]["alias"]) {
                         $wrapperModelName = $description["fields"][$modelizedField]["model"];
                     } else {
                         $wrapperModelName = Ntentan::plural($modelizedField);
                     }
                     $wrapperModel = Model::load($wrapperModelName);
                     $wrapperModel->setData($results[$index][$modelizedField], true);
                     $results[$index][$this->formatRelatedModelName($modelizedField, $params)] = $wrapperModel;
                 }
             }
         }
     }
     if ($params["fetch_related"] === true || $params["fetch_has_many"] === true) {
         if (count($this->model->hasMany) > 0) {
             foreach ($this->model->hasMany as $hasMany) {
                 foreach ($results as $index => $result) {
                     $model = Model::load($hasMany);
                     $relatedData = $model->get('all', array("conditions" => array_merge(array(Ntentan::singular($this->model->getName()) . "_id" => $result["id"]), is_array($hasManyConditions[$hasMany]) ? $hasManyConditions[$hasMany] : array()), "fields" => $hasManyFields[$hasMany], 'sort' => $params["{$hasMany}_sort"], 'fetch_related' => $params['fetch_related'], 'fetch_has_many' => $params['fetch_has_many']));
                     $results[$index][$this->formatRelatedModelName($hasMany, $params)] = $relatedData;
                 }
             }
         }
     }
     // Generate the data to be returned
     if ($params["type"] == 'first') {
         $return = $results[0];
     } else {
         if ($params["type"] == 'count') {
             $return = reset($results[0]);
         } else {
             $return = $results;
         }
     }
     return $return;
 }