Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15404665
D20149.id48122.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D20149.id48122.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 19, 8:35 AM (3 d, 11 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7224231
Default Alt Text
D20149.id48122.diff (6 KB)
Attached To
Mode
D20149: Introduce new PhutilURI API methods to move away from the ambiguity of the "set" operation
Attached
Detach File
Event Timeline
Log In to Comment