} public static function newFromVector($vector) { if ($vector instanceof PhabricatorQueryOrderVector) { return (clone $vector); } if (!is_array($vector)) { throw new Exception( pht( 'An order vector can only be constructed from a list of strings or '. 'another order vector.')); } if (!$vector) { throw new Exception( pht( 'An order vector must not be empty.')); } $items = array(); foreach ($vector as $key => $scalar) { if (!is_string($scalar)) { throw new Exception( pht( 'Value with key "%s" in order vector is not a string (it has '. 'type "%s"). An order vector must contain only strings.', $key, gettype($scalar))); } $item = PhabricatorQueryOrderItem::newFromScalar($scalar); // Orderings like "id, id, id" or "id, -id" are meaningless and invalid. if (isset($items[$item->getOrderKey()])) { throw new Exception( pht( 'Order vector "%s" specifies order "%s" twice. Each component '. 'of an ordering must be unique.', implode(', ', $vector), $item->getOrderKey())); } $items[$item->getOrderKey()] = $item; } $obj = new PhabricatorQueryOrderVector(); $obj->items = $items; $obj->keys = array_keys($items); return $obj; } public function getAsString() { $scalars = array(); foreach ($this->items as $item) { $scalars[] = $item->getAsScalar(); } return implode(', ', $scalars); } public function containsKey($key) { return isset($this->items[$key]); } /* -( Iterator Interface )------------------------------------------------- */ public function rewind() { $this->cursor = 0; } public function current() { return $this->items[$this->key()]; } public function key() { return $this->keys[$this->cursor]; } public function next() { ++$this->cursor; } public function valid() { return isset($this->keys[$this->cursor]); } }