public function select($selector, $selectKey = false) { if ($this->isConverted || $this->data instanceof Collection === false) { return parent::select($selector, $selectKey); } if ($selectKey !== false && $selectKey !== null) { if (\Sledgehammer\is_closure($selectKey) || empty($this->options['mapping'][$selectKey])) { // Key not in the mapping array? return parent::select($selector, $selectKey); } if ($this->hasReadFilter($selectKey)) { // Key requires a readFilter? return parent::select($selector, $selectKey); } $selectKeyMapped = $this->options['mapping'][$selectKey]; } else { $selectKeyMapped = $selectKey; } if (is_string($selector) && isset($this->options['mapping'][$selector])) { if ($this->hasReadFilter($selector)) { return parent::select($selector, $selectKey); } // Bypass Repository and return the resultset directly from the backend-collection. return $this->data->select($this->options['mapping'][$selector], $selectKeyMapped); } elseif (is_array($selector)) { $selectorMapped = []; foreach ($selector as $to => $from) { if (empty($this->options['mapping'][$from])) { // Field not in the mapping array? return parent::select($selector, $selectKey); } if ($this->hasReadFilter($from)) { return parent::select($selector, $selectKey); } $selectorMapped[$to] = $this->options['mapping'][$from]; } // Bypass Repository and return the resultset directly from the backend-collection. return $this->data->select($selectorMapped, $selectKeyMapped); } // Closure selector return parent::select($selector, $selectKey); }
/** * Return a new collection where each element is a subselection of the original element. * (Known as "collect" in Ruby or "pluck" in underscore.js). * * @param string|array $selector Path to the variable to select. Examples: "->id", "[message]", "customer.name", array('id' => 'message_id', 'message' => 'message_text') * @param string|null|false $selectKey (optional) The path that will be used as key. false: Keep the current key, null: create linear keys. * * @return Collection */ public function select($selector, $selectKey = false) { if ($this->data !== null || is_string($this->sql) || is_object($selector) && is_callable($selector)) { return parent::select($selector, $selectKey); } if (is_int($selector)) { $selector = (string) $selector; } $selectorPaths = is_string($selector) ? array($selector => $selector) : $selector; $hasKeySelector = $selectKey !== false && $selectKey !== null; if ($hasKeySelector) { \Sledgehammer\array_key_unshift($selectorPaths, $selectKey, $selectKey); } if (count($selectorPaths) === 0) { // empty selector? return parent::select($selector, $selectKey); } $isWildcardSelector = $this->sql->columns === '*' || $this->sql->columns == array('*' => '*'); if ($isWildcardSelector === false && (is_string($this->sql->columns) || count($selectorPaths) >= count($this->sql->columns))) { // The selector can't be a subsection of current columns. return parent::select($selector, $selectKey); } $columns = []; foreach ($selectorPaths as $to => $from) { $column = $this->convertPathToColumn($from); $alias = $this->convertPathToColumn($to); if ($column === false || $alias === false) { // Path can't be mapped to column return parent::select($selector, $selectKey); } if ($isWildcardSelector === false) { if (isset($this->sql->columns[$column])) { $column = $this->sql->columns[$column]; // Use the original column/calculation (just change the alias) } else { // @todo Use array_search() for support of indexed array of columns. return parent::select($selector, $selectKey); } } if ($hasKeySelector) { $alias = $column; // Don't alias in SQL, but (re)use the $selector. } $columns[$alias] = $column; } $collection = new self($this->sql->select($columns), $this->dbLink); if ($hasKeySelector || is_string($selector)) { // Does the $collection requires additional selecting? return $collection->select($selector, $selectKey); } return $collection; }