mirror of
https://github.com/processwire/processwire.git
synced 2025-08-14 02:34:24 +02:00
Update WireInput with a a queryStringClean() method that provides a useful alternative to the existing queryString() method
This commit is contained in:
@@ -928,18 +928,27 @@ class WireInput extends Wire {
|
||||
*
|
||||
* #pw-group-URLs
|
||||
*
|
||||
* @param bool $withQueryString Include the query string as well? (if present, default=false)
|
||||
* @param array|bool $options Specify `withQueryString` (bool) option, or in 3.0.167+ you can also use an options array:
|
||||
* - `withQueryString` (bool): Include the query string as well? (if present, default=false)
|
||||
* - `page` (Page): Page object to use, if different from $page (default=$page)
|
||||
* @return string
|
||||
* @see WireInput::httpUrl(), Page::url()
|
||||
*
|
||||
*/
|
||||
public function url($withQueryString = false) {
|
||||
public function url($options = array()) {
|
||||
|
||||
$defaults = array(
|
||||
'withQueryString' => is_bool($options) ? $options : false,
|
||||
'page' => $this->wire('page'),
|
||||
);
|
||||
|
||||
$options = is_array($options) ? array_merge($defaults, $options) : $defaults;
|
||||
|
||||
$url = '';
|
||||
/** @var Page $page */
|
||||
$page = $this->wire('page');
|
||||
$page = $options['page'];
|
||||
$config = $this->wire('config');
|
||||
$sanitizer = $this->wire('sanitizer');
|
||||
$url = '';
|
||||
|
||||
if($page && $page->id) {
|
||||
// pull URL from page
|
||||
@@ -982,7 +991,7 @@ class WireInput extends Wire {
|
||||
}
|
||||
}
|
||||
|
||||
if($withQueryString) {
|
||||
if($options['withQueryString']) {
|
||||
$queryString = $this->queryString();
|
||||
if(strlen($queryString)) {
|
||||
$url .= "?$queryString";
|
||||
@@ -1010,13 +1019,15 @@ class WireInput extends Wire {
|
||||
*
|
||||
* #pw-group-URLs
|
||||
*
|
||||
* @param bool $withQueryString Include the query string? (default=false)
|
||||
* @param array|bool $options Specify `withQueryString` (bool) option, or in 3.0.167+ you can also use an options array:
|
||||
* - `withQueryString` (bool): Include the query string as well? (if present, default=false)
|
||||
* - `page` (Page): Page object to use, if different from $page (default=$page)
|
||||
* @return string
|
||||
* @see WireInput::url(), Page::httpUrl()
|
||||
*
|
||||
*/
|
||||
public function httpUrl($withQueryString = false) {
|
||||
return $this->httpHostUrl() . $this->url($withQueryString);
|
||||
public function httpUrl($options = array()) {
|
||||
return $this->httpHostUrl() . $this->url($options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1024,13 +1035,15 @@ class WireInput extends Wire {
|
||||
*
|
||||
* See httpUrl() method for argument and usage details.
|
||||
*
|
||||
* @param bool $withQueryString
|
||||
* @param array|bool $options Specify `withQueryString` (bool) option, or in 3.0.167+ you can also use an options array:
|
||||
* - `withQueryString` (bool): Include the query string as well? (if present, default=false)
|
||||
* - `page` (Page): Page object to use, if different from $page (default=$page)
|
||||
* @return string
|
||||
* @see WireInput::httpUrl()
|
||||
*
|
||||
*/
|
||||
public function httpsUrl($withQueryString = false) {
|
||||
return $this->httpHostUrl(true) . $this->url($withQueryString);
|
||||
public function httpsUrl($options = array()) {
|
||||
return $this->httpHostUrl(true) . $this->url($options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1282,12 +1295,184 @@ class WireInput extends Wire {
|
||||
*
|
||||
* @param array $overrides Optional assoc array for overriding or adding GET params
|
||||
* @return string Returns the unsanitized query string
|
||||
* @see WireInput::queryStringClean()
|
||||
*
|
||||
*/
|
||||
public function queryString($overrides = array()) {
|
||||
return $this->get()->queryString($overrides);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a cleaned query string that was part of this request, or blank if none
|
||||
*
|
||||
* Note: it is recommended that you always specify $options with this method as the defaults
|
||||
* may or may not be consistent with your needs.
|
||||
*
|
||||
* #pw-group-URLs
|
||||
*
|
||||
* @param array $options
|
||||
* - `values` (array): Optional associative array of [name=value] to use in query string rather than current GET vars. (default=[])
|
||||
* - `overrides` (array): Array of values to override or add to current request values. (default=[])
|
||||
* - `validNames` (array): Only include query string variables with these names, and omit any others. (default=[])
|
||||
* - `maxItems` (int): Maximum number of variables/items to include in the query string or 0 for no max. (default=20)
|
||||
* - `maxLength` (int): Max overall length of returned query string or 0 for no max. (default=1024)
|
||||
* - `maxNameLength` (int): Max length of any “name” in the “name=value” portion of a query string or 0 for no max. (default=50)
|
||||
* - `maxValueLength` (int): Max length of any “value” in the “name=value” portion of a query string or 0 for no max. (default=255)
|
||||
* - `maxArrayDepth` (int): Maximum depth for arrays, or 0 to disallow arrays. (default=0)
|
||||
* - `maxArrayItems` (int): Maximum number of items allowed in arrays or 0 for no max. (default=20)
|
||||
* - `associative` (bool): Allow associative arrays? (default=false)
|
||||
* - `sanitizeName` (string): Sanitize query string variable names with this sanitizer method or blank to ignore. (default='fieldName')
|
||||
* - `sanitizeValue` (string): Sanitize query string variable values with this sanitizer method or blank to ignore. (default='line')
|
||||
* - `sanitizeRemove` (bool): Remove any variables from query string that are changed as the result of sanitization? (default=true)
|
||||
* - `entityEncode` (bool): Should returned query string be entity encoded for HTML output? (default=true)
|
||||
* - `encType` (int): Use PHP_QUERY_RFC3986 for spaces encoded to '%20' or PHP_QUERY_RFC1738 for spaces as '+'. (default=PHP_QUERY_RFC3986)
|
||||
* - `separator` (string): Character(s) that separate each “name=value” in query string. (default='&')
|
||||
* @return string
|
||||
* @since 3.0.167
|
||||
*
|
||||
*/
|
||||
public function queryStringClean(array $options = array()) {
|
||||
|
||||
$defaults = array(
|
||||
'values' => array(),
|
||||
'overrides' => array(),
|
||||
'validNames' => array(),
|
||||
'maxItems' => 20,
|
||||
'maxLength' => 1024, // max overall length
|
||||
'maxNameLength' => 50,
|
||||
'maxValueLength' => 255,
|
||||
'allowArrays' => false,
|
||||
'maxArrayDepth' => 0,
|
||||
'maxArrayItems' => 20,
|
||||
'sanitizeName' => 'fieldName',
|
||||
'sanitizeValue' => 'line',
|
||||
'sanitizeRemove' => true,
|
||||
'entityEncode' => true,
|
||||
'encType' => PHP_QUERY_RFC3986, // Spaces are '%20', for '+' use PHP_QUERY_RFC1738
|
||||
'separator' => '&',
|
||||
);
|
||||
|
||||
$options = array_merge($defaults, $options);
|
||||
$values = empty($options['values']) ? $this->get()->getArray() : $options['values'];
|
||||
$sanitizer = $this->wire()->sanitizer;
|
||||
$separator = $options['separator'];
|
||||
$maxArrayDepth = $options['maxArrayDepth'];
|
||||
|
||||
if(count($options['overrides'])) {
|
||||
$values = array_merge($values, $options['overrides']);
|
||||
}
|
||||
|
||||
// only allow specific names/keys from the array
|
||||
if(!empty($options['validNames'])) {
|
||||
$a = array();
|
||||
foreach($values as $name => $value) {
|
||||
if(in_array($name, $options['validNames'], true)) $a[$name] = $value;
|
||||
}
|
||||
$values = $a;
|
||||
}
|
||||
|
||||
// limit to a max quantity of items
|
||||
if($options['maxItems'] && count($values) > $options['maxItems']) {
|
||||
$values = array_slice($values, 0, $options['maxItems']);
|
||||
}
|
||||
|
||||
// sanitize or remove arrays
|
||||
foreach($values as $name => $value) {
|
||||
if(!is_array($value)) continue;
|
||||
if($options['allowArrays']) {
|
||||
$a = $sanitizer->arrayVal($value, array(
|
||||
'maxItems' => $options['maxArrayItems'],
|
||||
'maxDepth' => $maxArrayDepth,
|
||||
'sanitizer' => $options['sanitizeValue'],
|
||||
'keySanitizer' => $options['sanitizeName'],
|
||||
));
|
||||
if($options['sanitizeRemove'] && $a != $value) {
|
||||
unset($values[$name]);
|
||||
} else {
|
||||
$values[$name] = $a;
|
||||
}
|
||||
} else {
|
||||
unset($values[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
// sanitize names
|
||||
if($options['sanitizeName'] || $options['maxNameLength']) {
|
||||
$method = $options['sanitizeName'];
|
||||
$max = $options['maxNameLength'];
|
||||
$a = array();
|
||||
foreach($values as $name => $value) {
|
||||
$newName = $method ? $sanitizer->$method($name) : $name;
|
||||
if($max && strlen($newName) > $max) {
|
||||
$newName = substr($newName, 0, $max);
|
||||
}
|
||||
if($newName === $name) {
|
||||
$a[$name] = $value;
|
||||
} else if(!$options['sanitizeRemove']) {
|
||||
$a[$newName] = $value;
|
||||
}
|
||||
}
|
||||
$values = $a;
|
||||
}
|
||||
|
||||
// sanitize values
|
||||
if($options['sanitizeValue'] || $options['maxValueLength']) {
|
||||
$method = $options['sanitizeValue'];
|
||||
$max = $options['maxValueLength'];
|
||||
$a = array();
|
||||
foreach($values as $name => $value) {
|
||||
if(is_array($value) && $options['allowArrays']) {
|
||||
// arrays already handled earlier
|
||||
$a[$name] = $value;
|
||||
continue;
|
||||
}
|
||||
$newValue = $method ? $sanitizer->$method($value) : $value;
|
||||
if($max && strlen($newValue) > $max) {
|
||||
$newValue = substr($newValue, 0, $max);
|
||||
}
|
||||
if($newValue === $value) {
|
||||
$a[$name] = $value;
|
||||
} else if(!$options['sanitizeRemove']) {
|
||||
$a[$name] = $newValue;
|
||||
}
|
||||
}
|
||||
$values = $a;
|
||||
}
|
||||
|
||||
if(!count($values)) return '';
|
||||
|
||||
// prevent double encoding if an encoded & was provided in $options
|
||||
if(strtolower($separator) === '&' && $options['entityEncode']) {
|
||||
$separator = '&';
|
||||
}
|
||||
|
||||
// build the query string
|
||||
$queryString = http_build_query($values, '', $separator, $options['encType']);
|
||||
|
||||
// %5Bfoobar%5D => [foobar]
|
||||
// if(strpos($queryString, '%5D=')) {
|
||||
// $queryString = preg_replace('/%5B([-_.a-zA-Z0-9]+)%5D=/', '[$1]=', $queryString);
|
||||
// }
|
||||
|
||||
// entity encode if requested
|
||||
if($options['entityEncode']) {
|
||||
$queryString = $sanitizer->entities($queryString);
|
||||
$separator = $sanitizer->entities($separator);
|
||||
}
|
||||
|
||||
// if query string exceeds max allowed length then truncate it
|
||||
if($options['maxLength'] && strlen($queryString) > $options['maxLength']) {
|
||||
while(strlen($queryString) > $options['maxLength'] && strpos($queryString, $separator)) {
|
||||
$a = explode($separator, $queryString);
|
||||
array_pop($a);
|
||||
$queryString = implode($separator, $queryString);
|
||||
}
|
||||
if(strlen($queryString) > $options['maxLength']) $queryString = '';
|
||||
}
|
||||
|
||||
return $queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current access scheme/protocol
|
||||
*
|
||||
|
Reference in New Issue
Block a user