/** * Fetch results from a model * * @param array $options Various fetching options (e.g. limit, sorting, etc.) * @return array */ public function fetch(array $options = null) { try { $this->_checkAcl('fetch'); } catch (Garp_Auth_Exception $e) { $this->_checkAcl('fetch_own'); } if ($this->_model instanceof Garp_Model_Db) { $options = $options instanceof Garp_Util_Configuration ? $options : new Garp_Util_Configuration($options); $options->setDefault('sort', array())->setDefault('start', null)->setDefault('limit', null)->setDefault('fields', null)->setDefault('query', false)->setDefault('group', array())->setDefault('rule', null)->setDefault('bindingModel', null)->setDefault('bidirectional', false)->setDefault('filterForeignKeys', false); $options['sort'] = (array) $options['sort']; $options['fields'] = (array) $options['fields']; $tableName = $this->_getTableName($this->_model); $options = (array) $options; $modelInfo = $this->_model->info(); $referenceMap = $modelInfo['referenceMap']; // SELECT // ============================================================ $select = $this->_model->select(); $select->setIntegrityCheck(false); // FILTER WHERES AND JOINS // ============================================================ $related = array(); if ($options['query'] && !empty($options['query'])) { /** * Check for other model names in the conditions. * These are indicated by a dot (".") in the name. * If available, add these models as joins to the Select object. * The format is <related-model-name>.<primary-key> => <value>. */ foreach ($options['query'] as $column => $value) { if (strpos($column, '.') !== false) { $related[$column] = $value; unset($options['query'][$column]); } } } // FROM // ============================================================ if ($options['fields']) { $fields = $options['fields']; } elseif (count($related)) { // When using a join filter (used for the relationpanel), it's more performant to // specify only a model's list fields, otherwise the query can get pretty heavy for // tables with 100.000+ records. $primary = array_values($this->_model->info(Zend_Db_Table_Abstract::PRIMARY)); $fields = array_merge($this->_model->getListFields(), $primary); } else { $fields = Zend_Db_Table_Select::SQL_WILDCARD; } // If filterForeignKeys is true, filter out the foreign keys if ($options['filterForeignKeys']) { $fields = $this->_filterForeignKeyColumns($fields, $referenceMap); } $select->from($tableName, $fields); // JOIN // ============================================================ if (count($related)) { $this->_addJoinClause($select, $related, $options['rule'], $options['bindingModel'], $options['bidirectional']); } // WHERE // Add WHERE clause if there still remains something after // filtering. // ============================================================ if ($options['query']) { $select->where($this->_createWhereClause($options['query'])); } // GROUP // ============================================================ $select->group($options['group']); // ORDER // ============================================================ // Prefix native columns with the table name (e.g. "id" becomes // "Thing.id") // Note that we create a mock table object based on the joint view // to collect column info. // This should be more accurate than reading that info from the table. $mockTable = new Zend_Db_Table(array(Zend_Db_Table_Abstract::NAME => $tableName, Zend_Db_Table_Abstract::PRIMARY => $this->_model->info(Zend_Db_Table_Abstract::PRIMARY))); $nativeColumns = $mockTable->info(Zend_Db_Table_Abstract::COLS); $select->order(array_map(function ($s) use($tableName, $nativeColumns) { $nativeColTest = preg_replace('/(ASC|DESC)$/', '', $s); $nativeColTest = trim($nativeColTest); if (in_array($nativeColTest, $nativeColumns) && strpos($s, '.') === false) { $s = $tableName . '.' . $s; } return $s; }, $options['sort'])); // LIMIT // ============================================================ // Do not limit when a COUNT(*) is performed, this skews results. $isCountQuery = count($fields) == 1 && !empty($fields[0]) && strtolower($fields[0]) == 'count(*)'; if (!$isCountQuery) { $select->limit($options['limit'], $options['start']); } $results = $this->_model->fetchAll($select)->toArray(); } else { $results = $this->_model->fetchAll(); } foreach ($results as &$result) { foreach ($result as $column => $value) { if (strpos($column, '.') !== false) { $keyParts = explode('.', $column, 2); $newKey = $keyParts[1]; $relModelKey = Garp_Util_String::strReplaceOnce($this->_model->getNameWithoutNamespace(), '', $keyParts[0]); $result['relationMetadata'][$relModelKey][$newKey] = $value; unset($result[$column]); } } } return $results; }
public function testStrReplaceOnce() { $this->assertEquals('that should be replaced', Garp_Util_String::strReplaceOnce('this', 'that', 'this should be replaced')); $this->assertEquals('thoff online ./.on>>', Garp_Util_String::strReplaceOnce('on', 'off', 'thon online ./.on>>')); $this->assertEquals('thoff offline ./.on>>', Garp_Util_String::strReplaceOnce('on', 'off', 'thoff online ./.on>>')); $this->assertEquals('thoff offline ./.off>>', Garp_Util_String::strReplaceOnce('on', 'off', 'thoff offline ./.on>>')); }
/** * Store targetUrl in session. After login the user is redirected * back to this url. * @return Void */ protected function _storeTargetUrl() { $request = $this->getRequest(); // Only store targetUrl when method = GET. A redirect to a POST request is useless. if (!$request->isGet()) { return; } // Allow ?targetUrl=/path/to/elsewhere on any URL if (!($targetUrl = $request->getParam('targetUrl'))) { $targetUrl = $request->getRequestUri(); $baseUrl = $request->getBaseUrl(); /** * Remove the baseUrl from the targetUrl. This is neccessary * when Garp is installed in a subfolder. */ $targetUrl = Garp_Util_String::strReplaceOnce($baseUrl, '', $targetUrl); } if ($targetUrl !== '/favicon.ico' && !$request->isXmlHttpRequest()) { $store = Garp_Auth::getInstance()->getStore(); $store->targetUrl = $targetUrl; } }