<commit_before><?php
/* This class is part of the XP framework
 *
 * $Id$
 */

  uses(
    'util.Hashmap',
    'webservices.rest.server.routing.RestRouter',
    'webservices.rest.server.routing.RestMethodRoute'
  );
  
  /**
   * Represent REST resource path
   *
   * @test xp://net.xp_framework.webservices.rest.server.routing.RestPathTest
   * @purpose Path
   */
  class RestPath extends Object {
    protected
      $path= '',
      $query= array(),
      $names= array(),
      $pattern= '';
    
    /**
     * Constructor
     * 
     * @param string path The path
     */
    public function __construct($path) {
      static $search= '/\{([\w]*)\}/';
      static $replace= '([%\w]*)';
      
      list ($this->path, $this->query)= $this->splitParams($path);
      
      foreach ($this->query as $name => $param) {
        if (preg_match($search, $param, $matches)) {
          $this->query[$name]= $matches[1];
        } else {
          unset($this->query[$name]);
        }
      }
      
      // Check if placeholders are in path
      if (preg_match_all($search, $this->path, $names)) {
        $this->names= $names[1];
        $this->pattern= preg_replace($search, $replace, $this->path);
      } else {
        $this->pattern= $this->path;
      }
    }
    
    /**
     * Split path and query parameters
     * 
     * @param string path The path and query string
     * @return var[]
     */
    protected function splitParams($path) {
      $query= array();
      
      if (FALSE !== ($p= strpos($path, '?'))) {
        parse_str(substr($path, $p+1), $query);
        $path= substr($path, 0, $p-1);
      }
      
      return array($path, $query);
    }
    
    /**
     * Match the given URL and return values matched
     * 
     * @param string path The URL path
     * @return var[]
     */
    public function match($path) {
      list ($path, $query)= $this->splitParams($path);
      
      if (preg_match('#^'.$this->pattern.'$#', $path, $matches)) {
        array_shift($matches);
        
        $params= array();
        foreach ($this->names as $i => $name) {
          $params[$name]= rawurldecode($matches[$i]);
        }
        
        foreach ($this->query as $name => $param) {
          if (isset($query[$name])) $params[$param]= $query[$name];
        }
        
        return $params;
      }
      
      return FALSE;
    }
    
    /**
     * Return path
     * 
     * @return string
     */
    public function getPath() {
      return $this->path;
    }
    
    /**
     * Return parameter names
     * 
     */
    public function getParamNames() {
      return array_merge($this->names, array_values($this->query));
    }
    
    /**
     * Test if parameter exist
     * 
     * @param string name The name of parameter
     * @return bool
     */
    public function hasParam($name) {
      return in_array($name, $this->getParamNames());
    }
  }
?>
<commit_msg>- fixed match bug<commit_after><?php
/* This class is part of the XP framework
 *
 * $Id$
 */

  uses(
    'util.Hashmap',
    'webservices.rest.server.routing.RestRouter',
    'webservices.rest.server.routing.RestMethodRoute'
  );
  
  /**
   * Represent REST resource path
   *
   * @test xp://net.xp_framework.webservices.rest.server.routing.RestPathTest
   * @purpose Path
   */
  class RestPath extends Object {
    protected
      $path= '',
      $query= array(),
      $names= array(),
      $pattern= '';
    
    /**
     * Constructor
     * 
     * @param string path The path
     */
    public function __construct($path) {
      static $search= '/\{([\w]*)\}/';
      static $replace= '([%\w]*)';
      
      list ($this->path, $this->query)= $this->splitParams($path);
      
      foreach ($this->query as $name => $param) {
        if (preg_match($search, $param, $matches)) {
          $this->query[$name]= $matches[1];
        } else {
          unset($this->query[$name]);
        }
      }
      
      // Check if placeholders are in path
      if (preg_match_all($search, $this->path, $names)) {
        $this->names= $names[1];
        $this->pattern= preg_replace($search, $replace, $this->path);
      } else {
        $this->pattern= $this->path;
      }
    }
    
    /**
     * Split path and query parameters
     * 
     * @param string path The path and query string
     * @return var[]
     */
    protected function splitParams($path) {
      $query= array();
      
      if (FALSE !== ($p= strpos($path, '?'))) {
        parse_str(substr($path, $p+1), $query);
        $path= substr($path, 0, $p-1);
      }
      
      return array($path, $query);
    }
    
    /**
     * Match the given URL and return values matched
     * 
     * @param string path The URL path
     * @return var[]
     */
    public function match($path) {
      if ($path === $this->path) return TRUE;
      
      list ($path, $query)= $this->splitParams($path);
      
      if (preg_match('#^'.$this->pattern.'$#', $path, $matches)) {
        array_shift($matches);
        
        $params= array();
        foreach ($this->names as $i => $name) {
          $params[$name]= rawurldecode($matches[$i]);
        }
        
        foreach ($this->query as $name => $param) {
          if (isset($query[$name])) $params[$param]= $query[$name];
        }
        
        return $params;
      }
      
      return FALSE;
    }
    
    /**
     * Return path
     * 
     * @return string
     */
    public function getPath() {
      return $this->path;
    }
    
    /**
     * Return parameter names
     * 
     */
    public function getParamNames() {
      return array_merge($this->names, array_values($this->query));
    }
    
    /**
     * Test if parameter exist
     * 
     * @param string name The name of parameter
     * @return bool
     */
    public function hasParam($name) {
      return in_array($name, $this->getParamNames());
    }
  }
?>

{'fraction_non_alphanumeric': 0.16427000507528336, 'fraction_numerical': 0.001691761123329386, 'mean_word_length': 1.8657295201163355, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 52, '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': '16812', 'n_tokens_mistral': 1844, 'n_tokens_neox': 1826, 'n_words': 418}