Page MenuHomePhabricator

D20149.id.diff
No OneTemporary

D20149.id.diff

diff --git a/src/parser/PhutilURI.php b/src/parser/PhutilURI.php
--- a/src/parser/PhutilURI.php
+++ b/src/parser/PhutilURI.php
@@ -27,7 +27,7 @@
const TYPE_URI = 'uri';
const TYPE_GIT = 'git';
- public function __construct($uri) {
+ public function __construct($uri, $params = array()) {
if ($uri instanceof PhutilURI) {
$this->protocol = $uri->protocol;
$this->user = $uri->user;
@@ -38,10 +38,13 @@
$this->query = $uri->query;
$this->fragment = $uri->fragment;
$this->type = $uri->type;
+
+ $this->initializeQueryParams(phutil_string_cast($uri), $params);
+
return;
}
- $uri = (string)$uri;
+ $uri = phutil_string_cast($uri);
$type = self::TYPE_URI;
@@ -134,6 +137,8 @@
$this->fragment = idx($parts, 'fragment', '');
$this->type = $type;
+
+ $this->initializeQueryParams($uri, $params);
}
public function __toString() {
@@ -200,6 +205,9 @@
return $prefix.$path.$query.$fragment;
}
+ /**
+ * @deprecated
+ */
public function setQueryParam($key, $value) {
// To set, we replace the first matching key with the new value, then
// remove all other matching keys. This replaces the old value and retains
@@ -245,6 +253,9 @@
return $this;
}
+ /**
+ * @deprecated
+ */
public function setQueryParams(array $params) {
$this->query = array();
@@ -297,6 +308,43 @@
return $this->insertQueryParam($key, $value);
}
+ public function removeAllQueryParams() {
+ $this->query = array();
+ return $this;
+ }
+
+ public function removeQueryParam($remove_key) {
+ list($remove_key) = phutil_http_parameter_pair($remove_key, '');
+
+ foreach ($this->query as $idx => $pair) {
+ list($key, $value) = $pair;
+
+ if ($key !== $remove_key) {
+ continue;
+ }
+
+ unset($this->query[$idx]);
+ }
+
+ $this->query = array_values($this->query);
+
+ return $this;
+ }
+
+ public function replaceQueryParam($replace_key, $replace_value) {
+ if ($replace_value === null) {
+ throw new InvalidArgumentException(
+ pht(
+ 'Value provided to "replaceQueryParam()" for key "%s" is NULL. '.
+ 'Use "removeQueryParam()" to remove a query parameter.',
+ $replace_key));
+ }
+
+ $this->removeQueryParam($replace_key);
+ $this->appendQueryParam($replace_key, $replace_value);
+ return $this;
+ }
+
private function insertQueryParam($key, $value, $idx = null) {
list($key, $value) = phutil_http_parameter_pair($key, $value);
@@ -309,6 +357,34 @@
return $this;
}
+ private function initializeQueryParams($uri, array $params) {
+ $have_params = array();
+ foreach ($this->query as $pair) {
+ list($key) = $pair;
+ $have_params[$key] = true;
+ }
+
+ foreach ($params as $key => $value) {
+ if (isset($have_params[$key])) {
+ throw new InvalidArgumentException(
+ pht(
+ 'You are trying to construct an ambiguous URI: query parameter '.
+ '"%s" is present in both the string argument ("%s") and the map '.
+ 'argument.',
+ $key,
+ $uri));
+ }
+
+ if ($value === null) {
+ continue;
+ }
+
+ $this->appendQueryParam($key, $value);
+ }
+
+ return $this;
+ }
+
public function setProtocol($protocol) {
$this->protocol = $protocol;
return $this;
@@ -410,7 +486,7 @@
public function alter($key, $value) {
$altered = clone $this;
- $altered->setQueryParam($key, $value);
+ $altered->replaceQueryParam($key, $value);
return $altered;
}
diff --git a/src/parser/__tests__/PhutilURITestCase.php b/src/parser/__tests__/PhutilURITestCase.php
--- a/src/parser/__tests__/PhutilURITestCase.php
+++ b/src/parser/__tests__/PhutilURITestCase.php
@@ -292,12 +292,12 @@
'http://www.example.com/?x=1&x=2&x=3',
(string)$uri);
- $uri->setQueryParam('x', '4');
+ $uri->replaceQueryParam('x', '4');
$this->assertEqual(
'http://www.example.com/?x=4',
(string)$uri);
- $uri->setQueryParam('x', null);
+ $uri->removeQueryParam('x');
$this->assertEqual(
'http://www.example.com/',
(string)$uri);
@@ -311,13 +311,12 @@
'http://www.example.com/?a=a&b=b&c=c&b=d',
(string)$uri);
- $uri->setQueryParam('b', 'e');
+ $uri->replaceQueryParam('b', 'e');
$this->assertEqual(
- 'http://www.example.com/?a=a&b=e&c=c',
+ 'http://www.example.com/?a=a&c=c&b=e',
(string)$uri,
pht(
- 'Replacing a parameter should retain position and overwrite other '.
- 'instances of the key.'));
+ 'Replacing a parameter should overwrite other instances of the key.'));
}
public function testBadHTTPParameters() {
@@ -325,7 +324,7 @@
$caught = null;
try {
- $uri->setQueryParam(array(), 'x');
+ $uri->replaceQueryParam(array(), 'x');
} catch (Exception $ex) {
$caught = $ex;
}
@@ -336,7 +335,7 @@
$caught = null;
try {
- $uri->setQueryParam('x', array());
+ $uri->replaceQueryParam('x', array());
} catch (Exception $ex) {
$caught = $ex;
}
@@ -358,18 +357,18 @@
'http://www.example.com/?0=a&0=b',
(string)$uri);
- $uri->setQueryParam(0, 'c');
+ $uri->replaceQueryParam(0, 'c');
$this->assertEqual(
'http://www.example.com/?0=c',
(string)$uri);
- $uri->setQueryParam(0, 'a');
+ $uri->replaceQueryParam(0, 'a');
$uri->appendQueryParam('0', 'b');
$this->assertEqual(
'http://www.example.com/?0=a&0=b',
(string)$uri);
- $uri->setQueryParam('0', 'c');
+ $uri->replaceQueryParam('0', 'c');
$this->assertEqual(
'http://www.example.com/?0=c',
(string)$uri);
@@ -388,4 +387,31 @@
$this->assertTrue((bool)$caught);
}
+ public function testQueryURIConstruction() {
+ $uri = new PhutilURI('http://example.com/', array('y' => '1'));
+ $this->assertEqual(
+ 'http://example.com/?y=1',
+ (string)$uri);
+
+ $uri = new PhutilURI('http://example.com/?x=2', array('y' => '1'));
+ $this->assertEqual(
+ 'http://example.com/?x=2&y=1',
+ (string)$uri);
+
+ $caught = null;
+ try {
+ $uri = new PhutilURI('http://example.com/?y=3', array('y' => '1'));
+ } catch (InvalidArgumentException $ex) {
+ $caught = $ex;
+ }
+ $this->assertTrue((bool)$caught);
+
+ $uri = new PhutilURI('http://example.com/?a=1', array('b' => '2'));
+ $uri = new PhutilURI($uri, array('c' => '3'));
+
+ $this->assertEqual(
+ 'http://example.com/?a=1&b=2&c=3',
+ (string)$uri);
+ }
+
}
diff --git a/src/utils/utils.php b/src/utils/utils.php
--- a/src/utils/utils.php
+++ b/src/utils/utils.php
@@ -1623,7 +1623,7 @@
$ex);
}
- $key = (string)$key;
+ $key = phutil_string_cast($key);
try {
assert_stringlike($value);
@@ -1635,7 +1635,7 @@
$ex);
}
- $value = (string)$value;
+ $value = phutil_string_cast($value);
return array($key, $value);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 9:03 AM (1 d, 18 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7224231
Default Alt Text
D20149.id.diff (6 KB)

Event Timeline