mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-10-30 19:04:10 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			434 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			434 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
 | |
| 
 | |
| namespace Icinga\Web;
 | |
| 
 | |
| use Icinga\Exception\MissingParameterException;
 | |
| 
 | |
| class UrlParams
 | |
| {
 | |
|     protected $separator = '&';
 | |
| 
 | |
|     protected $params = array();
 | |
| 
 | |
|     protected $index = array();
 | |
| 
 | |
|     public function isEmpty()
 | |
|     {
 | |
|         return empty($this->index);
 | |
|     }
 | |
| 
 | |
|     public function setSeparator($separator)
 | |
|     {
 | |
|         $this->separator = $separator;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get the given parameter
 | |
|      *
 | |
|      * Returns the last URL param if defined multiple times, $default if not
 | |
|      * given at all
 | |
|      *
 | |
|      * @param string $param   The parameter you're interested in
 | |
|      * @param string $default An optional default value
 | |
|      *
 | |
|      * @return mixed
 | |
|      */
 | |
|     public function get($param, $default = null)
 | |
|     {
 | |
|         if (! $this->has($param)) {
 | |
|             return $default;
 | |
|         }
 | |
| 
 | |
|         return rawurldecode($this->params[ end($this->index[$param]) ][ 1 ]);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Require a parameter
 | |
|      *
 | |
|      * @param   string  $name               Name of the parameter
 | |
|      * @param   bool    $strict             Whether the parameter's value must not be the empty string
 | |
|      *
 | |
|      * @return  mixed
 | |
|      *
 | |
|      * @throws  MissingParameterException   If the parameter was not given
 | |
|      */
 | |
|     public function getRequired($name, $strict = true)
 | |
|     {
 | |
|         if ($this->has($name)) {
 | |
|             $value = $this->get($name);
 | |
|             if (! $strict || strlen($value) > 0) {
 | |
|                 return $value;
 | |
|             }
 | |
|         }
 | |
|         $e = new MissingParameterException(t('Required parameter \'%s\' missing'), $name);
 | |
|         $e->setParameter($name);
 | |
|         throw $e;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get all instances of the given parameter
 | |
|      *
 | |
|      * Returns an array containing all values defined for a given parameter,
 | |
|      * $default if none.
 | |
|      *
 | |
|      * @param string $param   The parameter you're interested in
 | |
|      * @param string $default An optional default value
 | |
|      *
 | |
|      * @return mixed
 | |
|      */
 | |
|     public function getValues($param, $default = array())
 | |
|     {
 | |
|         if (! $this->has($param)) {
 | |
|             return $default;
 | |
|         }
 | |
| 
 | |
|         $ret = array();
 | |
|         foreach ($this->index[$param] as $key) {
 | |
|             $ret[] = rawurldecode($this->params[$key][1]);
 | |
|         }
 | |
|         return $ret;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Whether the given parameter exists
 | |
|      *
 | |
|      * Returns true if such a parameter has been defined, false otherwise.
 | |
|      *
 | |
|      * @param string $param The parameter you're interested in
 | |
|      *
 | |
|      * @return boolean
 | |
|      */
 | |
|     public function has($param)
 | |
|     {
 | |
|         return array_key_exists($param, $this->index);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get and remove the given parameter
 | |
|      *
 | |
|      * Returns the last URL param if defined multiple times, $default if not
 | |
|      * given at all. The parameter will be removed from this object.
 | |
|      *
 | |
|      * @param string $param   The parameter you're interested in
 | |
|      * @param string $default An optional default value
 | |
|      *
 | |
|      * @return mixed
 | |
|      */
 | |
|     public function shift($param = null, $default = null)
 | |
|     {
 | |
|         if ($param === null) {
 | |
|             if (empty($this->params)) {
 | |
|                 return $default;
 | |
|             }
 | |
|             $ret = array_shift($this->params);
 | |
|             $ret[0] = rawurldecode($ret[0]);
 | |
|             $ret[1] = rawurldecode($ret[1]);
 | |
|         } else {
 | |
|             if (! $this->has($param)) {
 | |
|                 return $default;
 | |
|             }
 | |
|             $key = reset($this->index[$param]);
 | |
|             $ret = rawurldecode($this->params[$key][1]);
 | |
|             unset($this->params[$key]);
 | |
|         }
 | |
| 
 | |
|         $this->reIndexAll();
 | |
|         return $ret;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Require and remove a parameter
 | |
|      *
 | |
|      * @param   string  $name               Name of the parameter
 | |
|      * @param   bool    $strict             Whether the parameter's value must not be the empty string
 | |
|      *
 | |
|      * @return  mixed
 | |
|      *
 | |
|      * @throws  MissingParameterException   If the parameter was not given
 | |
|      */
 | |
|     public function shiftRequired($name, $strict = true)
 | |
|     {
 | |
|         if ($this->has($name)) {
 | |
|             $value = $this->get($name);
 | |
|             if (! $strict || strlen($value) > 0) {
 | |
|                 $this->shift($name);
 | |
|                 return $value;
 | |
|             }
 | |
|         }
 | |
|         $e = new MissingParameterException(t('Required parameter \'%s\' missing'), $name);
 | |
|         $e->setParameter($name);
 | |
|         throw $e;
 | |
|     }
 | |
| 
 | |
|     public function addEncoded($param, $value = true)
 | |
|     {
 | |
|         $this->params[] = array($param, $this->cleanupValue($value));
 | |
|         $this->indexLastOne();
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     protected function urlEncode($value)
 | |
|     {
 | |
|         return rawurlencode((string) $value);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add the given parameter with the given value
 | |
|      *
 | |
|      * This will add the given parameter, regardless of whether it already
 | |
|      * exists.
 | |
|      *
 | |
|      * @param string $param The parameter you're interested in
 | |
|      * @param string $value The value to be stored
 | |
|      *
 | |
|      * @return $this
 | |
|      */
 | |
|     public function add($param, $value = true)
 | |
|     {
 | |
|         return $this->addEncoded($this->urlEncode($param), $this->urlEncode($value));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Adds a list of parameters
 | |
|      *
 | |
|      * This may be used with either a list of values for a single parameter or
 | |
|      * with a list of parameter / value pairs.
 | |
|      *
 | |
|      * @param string $param Parameter name or param/value list
 | |
|      * @param string $value The value to be stored
 | |
|      *
 | |
|      * @return $this
 | |
|      */
 | |
|     public function addValues($param, $values = null)
 | |
|     {
 | |
|         if ($values === null && is_array($param)) {
 | |
|             foreach ($param as $k => $v) {
 | |
|                 $this->add($k, $v);
 | |
|             }
 | |
|         } else {
 | |
|             foreach ($values as $value) {
 | |
|                 $this->add($param, $value);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     protected function clearValues()
 | |
|     {
 | |
|         $this->params = array();
 | |
|         $this->index = array();
 | |
|     }
 | |
| 
 | |
|     public function mergeValues($param, $values = null)
 | |
|     {
 | |
|         if ($values === null && is_array($param)) {
 | |
|             foreach ($param as $k => $v) {
 | |
|                 $this->set($k, $v);
 | |
|             }
 | |
|         } else {
 | |
|             if (! is_array($values)) {
 | |
|                 $values = array($values);
 | |
|             }
 | |
|             foreach ($values as $value) {
 | |
|                 $this->set($param, $value);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function setValues($param, $values = null)
 | |
|     {
 | |
|         $this->clearValues();
 | |
|         return $this->addValues($param, $values);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add the given parameter with the given value in front of all other values
 | |
|      *
 | |
|      * This will add the given parameter in front of all others, regardless of
 | |
|      * whether it already exists.
 | |
|      *
 | |
|      * @param string $param The parameter you're interested in
 | |
|      * @param string $value The value to be stored
 | |
|      *
 | |
|      * @return $this
 | |
|      */
 | |
|     public function unshift($param, $value)
 | |
|     {
 | |
|         array_unshift($this->params, array($this->urlEncode($param), $this->urlEncode($value)));
 | |
|         $this->reIndexAll();
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the given parameter with the given value
 | |
|      *
 | |
|      * This will set the given parameter, and override eventually existing ones.
 | |
|      *
 | |
|      * @param string $param The parameter you want to set
 | |
|      * @param string $value The value to be stored
 | |
|      *
 | |
|      * @return $this
 | |
|      */
 | |
|     public function set($param, $value)
 | |
|     {
 | |
|         if (! $this->has($param)) {
 | |
|             return $this->add($param, $value);
 | |
|         }
 | |
| 
 | |
|         while (count($this->index[$param]) > 1) {
 | |
|             $remove = array_pop($this->index[$param]);
 | |
|             unset($this->params[$remove]);
 | |
|         }
 | |
| 
 | |
|         $this->params[$this->index[$param][0]] = array(
 | |
|             $this->urlEncode($param),
 | |
|             $this->urlEncode($this->cleanupValue($value))
 | |
|         );
 | |
|         $this->reIndexAll();
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function remove($param)
 | |
|     {
 | |
|         $changed = false;
 | |
| 
 | |
|         if (! is_array($param)) {
 | |
|             $param = array($param);
 | |
|         }
 | |
| 
 | |
|         foreach ($param as $p) {
 | |
|             if ($this->has($p)) {
 | |
|                 foreach ($this->index[$p] as $key) {
 | |
|                     unset($this->params[$key]);
 | |
|                 }
 | |
|                 $changed = true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if ($changed) {
 | |
|             $this->reIndexAll();
 | |
|         }
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function without($param)
 | |
|     {
 | |
|         $params = clone $this;
 | |
|         return $params->remove($param);
 | |
|     }
 | |
| 
 | |
|     // TODO: push, pop?
 | |
| 
 | |
|     protected function indexLastOne()
 | |
|     {
 | |
|         end($this->params);
 | |
|         $key = key($this->params);
 | |
|         $param = $this->params[$key][0];
 | |
|         $this->addParamToIndex($param, $key);
 | |
|     }
 | |
| 
 | |
|     protected function addParamToIndex($param, $key)
 | |
|     {
 | |
|         if (! $this->has($param)) {
 | |
|             $this->index[$param] = array();
 | |
|         }
 | |
|         $this->index[$param][] = $key;
 | |
|     }
 | |
| 
 | |
|     protected function reIndexAll()
 | |
|     {
 | |
|         $this->index = array();
 | |
|         $this->params = array_values($this->params);
 | |
|         foreach ($this->params as $key => & $param) {
 | |
|             $this->addParamToIndex($param[0], $key);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     protected function cleanupValue($value)
 | |
|     {
 | |
|         return is_bool($value) ? $value : (string) $value;
 | |
|     }
 | |
| 
 | |
|     protected function parseQueryString($queryString)
 | |
|     {
 | |
|         $parts = preg_split('~&~', $queryString, -1, PREG_SPLIT_NO_EMPTY);
 | |
|         foreach ($parts as $part) {
 | |
|             $this->parseQueryStringPart($part);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     protected function parseQueryStringPart($part)
 | |
|     {
 | |
|         if (strpos($part, '=') === false) {
 | |
|             $this->addEncoded($part, true);
 | |
|         } else {
 | |
|             list($key, $val) = preg_split('/=/', $part, 2);
 | |
|             $this->addEncoded($key, $val);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Return the parameters of this url as sequenced or associative array
 | |
|      *
 | |
|      * @param   bool    $sequenced
 | |
|      *
 | |
|      * @return  array
 | |
|      */
 | |
|     public function toArray($sequenced = true)
 | |
|     {
 | |
|         if ($sequenced) {
 | |
|             return $this->params;
 | |
|         }
 | |
| 
 | |
|         $params = array();
 | |
|         foreach ($this->params as $param) {
 | |
|             if ($param[1] === true) {
 | |
|                 $params[] = $param[0];
 | |
|             } else {
 | |
|                 $params[$param[0]] = $param[1];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $params;
 | |
|     }
 | |
| 
 | |
|     public function toString($separator = null)
 | |
|     {
 | |
|         if ($separator === null) {
 | |
|             $separator = $this->separator;
 | |
|         }
 | |
|         $parts = array();
 | |
|         foreach ($this->params as $p) {
 | |
|             if ($p[1] === true) {
 | |
|                 $parts[] = $p[0];
 | |
|             } else {
 | |
|                 $parts[] = $p[0] . '=' . $p[1];
 | |
|             }
 | |
|         }
 | |
|         return implode($separator, $parts);
 | |
|     }
 | |
| 
 | |
|     public function __toString()
 | |
|     {
 | |
|         return $this->toString();
 | |
|     }
 | |
| 
 | |
|     public static function fromQueryString($queryString = null)
 | |
|     {
 | |
|         if ($queryString === null) {
 | |
|             $queryString = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
 | |
|         }
 | |
|         $params = new static();
 | |
|         $params->parseQueryString($queryString);
 | |
| 
 | |
|         return $params;
 | |
|     }
 | |
| }
 |