<commit_before><?php


class HTTPRoute extends ControllerRoute {
	
	protected $method;
	protected $defaults;
	protected $pathRegex;
	protected $pathVariables;
	
	const METHOD_GET	= 'GET';
	const METHOD_POST	= 'POST';
	const METHOD_PUT	= 'PUT';
	const METHOD_DELETE	= 'DELETE';
	
	protected static $typesRegex	= array();
	protected static $routes		= array();
	protected static $knownMethods	= array('GET', 'POST', 'PUT', 'DELETE');
	
	protected function __construct($name, $path, $controller, $method) {
		parent::__construct($name, $path, $controller);
		$this->method	= $method;
		$this->generatePathRegex();
	}
	
	/**
	 * Format the current route to get an URL from path
	 * @param string[] $values
	 * @return string
	 * @throws Exception
	 */
	public function formatURL($values=array()) {
		return preg_replace_callback(
			'#\{[^\}]+\}#sm',
			function($matches) use($values) {
				$var = $regex = null;
				static::extractVariable($matches[0], $var, $regex);
				if( !isset($values[$var]) ) {
					throw new Exception('The variable `'.$var.'` is missing to generate URL for route '.$this->name);
				}
				$value	= $values[$var].'';
				if( !preg_match('#^'.$regex.'$#', $value) ) {
					throw new Exception('The given value "'.$value.'" of variable `'.$var.'` is not matching the regex requirements to generate URL for route '.$this->name);
				}
				return $value;
			},
			$this->path
		);
	}
	
	public function __toString() {
		return $this->method.'("'.$this->path.'")';
	}
	
	protected static function extractVariable($str, &$var=null, &$regex=null) {
		list($p1, $p2) 	= explodeList(':', $str, 2);
		// Optionnal only if there is a default value
		if( $p2 ) {
			// {regex|type:variable}
			$var	= $p2;
			$regex	= $p1;
			if( ctype_alpha($regex) && isset(static::$typesRegex[$regex]) ) {
				$regex	= static::$typesRegex[$regex];
			}
		} else {
			// {variable}, regex=[^\/]+
			$var	= $p1;
			$regex	= '[^\/]+';
		}
	}
	
	protected function generatePathRegex() {
		if( $this->pathRegex ) { return; }
// 		$variables	= &$this->pathVariables;
		$variables	= array();
		$this->pathRegex	= preg_replace_callback(
			'#\{([^\}]+)\}#sm',
			function($matches) use(&$variables) {
				debug('$matches', $matches);
				static::extractVariable(str_replace('\.', '.', $matches[1]), $var, $regex);
				$variables[]	= $var;
				return '('.$regex.')';
			},
			str_replace('.', '\.', $this->path)
		);
		$this->pathVariables	= $variables;
	}
	
	/**
	 * @param HTTPRequest $request
	 * @param array $values
	 * @see ControllerRoute::isMatchingRequest()
	 */<commit_msg>Fix issue generating URL with variables<commit_after><?php


class HTTPRoute extends ControllerRoute {
	
	protected $method;
	protected $defaults;
	protected $pathRegex;
	protected $pathVariables;
	
	const METHOD_GET	= 'GET';
	const METHOD_POST	= 'POST';
	const METHOD_PUT	= 'PUT';
	const METHOD_DELETE	= 'DELETE';
	
	protected static $typesRegex	= array();
	protected static $routes		= array();
	protected static $knownMethods	= array('GET', 'POST', 'PUT', 'DELETE');
	
	protected function __construct($name, $path, $controller, $method) {
		parent::__construct($name, $path, $controller);
		$this->method	= $method;
		$this->generatePathRegex();
	}
	
	/**
	 * Format the current route to get an URL from path
	 * @param string[] $values
	 * @return string
	 * @throws Exception
	 */
	public function formatURL($values=array()) {
		return preg_replace_callback(
			'#\{([^\}]+)\}#sm',
			function($matches) use($values) {
				$var = $regex = null;
				static::extractVariable($matches[1], $var, $regex);
				if( !isset($values[$var]) ) {
					throw new Exception('The variable `'.$var.'` is missing to generate URL for route '.$this->name);
				}
				$value	= $values[$var].'';
				if( !preg_match('#^'.$regex.'$#', $value) ) {
					throw new Exception('The given value "'.$value.'" of variable `'.$var.'` is not matching the regex requirements to generate URL for route '.$this->name);
				}
				return $value;
			},
			$this->path
		);
	}
	
	public function __toString() {
		return $this->method.'("'.$this->path.'")';
	}
	
	protected static function extractVariable($str, &$var=null, &$regex=null) {
		list($p1, $p2) 	= explodeList(':', $str, 2);
		// Optionnal only if there is a default value
		if( $p2 ) {
			// {regex|type:variable}
			$var	= $p2;
			$regex	= $p1;
			if( ctype_alpha($regex) && isset(static::$typesRegex[$regex]) ) {
				$regex	= static::$typesRegex[$regex];
			}
		} else {
			// {variable}, regex=[^\/]+
			$var	= $p1;
			$regex	= '[^\/]+';
		}
	}
	
	protected function generatePathRegex() {
		if( $this->pathRegex ) { return; }
// 		$variables	= &$this->pathVariables;
		$variables	= array();
		$this->pathRegex	= preg_replace_callback(
			'#\{([^\}]+)\}#sm',
			function($matches) use(&$variables) {
// 				debug('$matches', $matches);
				static::extractVariable(str_replace('\.', '.', $matches[1]), $var, $regex);
				$variables[]	= $var;
				return '('.$regex.')';
			},
			str_replace('.', '\.', $this->path)
		);
		$this->pathVariables	= $variables;
	}
	
	/**
	 * @param HTTPRequest $request
	 * @param array $values
	 * @see ControllerRoute::isMatchingRequest()
	 */
{'fraction_non_alphanumeric': 0.19841423322374782, 'fraction_numerical': 0.0034809514600657515, 'mean_word_length': 3.723287671232877, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2277', 'n_tokens_mistral': 1979, 'n_tokens_neox': 1731, 'n_words': 417}