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 testQueryOrderItem()
 {
     $item = PhabricatorQueryOrderItem::newFromScalar('id');
     $this->assertEqual('id', $item->getOrderKey());
     $this->assertEqual(false, $item->getIsReversed());
     $item = PhabricatorQueryOrderItem::newFromScalar('-id');
     $this->assertEqual('id', $item->getOrderKey());
     $this->assertEqual(true, $item->getIsReversed());
 }