<?php
namespace Rize;
use Rize\UriTemplate\Parser;
/**
* URI Template
*/
class UriTemplate
{
/**
* @var Parser
*/
protected $parser,
$parsed = array(),
$base_uri,
$params = array();
public function __construct($base_uri = '', $params = array(), Parser $parser = null)
{
$this->base_uri = $base_uri;
$this->params = $params;
$this->parser = $parser ?: $this->createNodeParser();
}
/**
* Expands URI Template
*
* @param string $uri URI Template
* @param array $params URI Template's parameters
* @return string
*/
public function expand($uri, $params = array())
{
$params += $this->params;
$uri = $this->base_uri.$uri;
$result = array();
// quick check
if (($start = strpos($uri, '{')) === false) {
return $uri;
}
$parser = $this->parser;
$nodes = $parser->parse($uri);
foreach($nodes as $node) {
$result[] = $node->expand($parser, $params);
}
return implode('', $result);
}
/**
* Extracts variables from URI
*
* @param string $template
* @param string $uri
* @param bool $strict This will perform a full match
* @return null|array params or null if not match and $strict is true
*/
public function extract($template, $uri, $strict = false)
{
$params = array();
$nodes = $this->parser->parse($template);
# PHP 8.1.0RC4-dev still throws deprecation warning for `strlen`.
# $uri = (string) $uri;
foreach($nodes as $node) {
// if strict is given, and there's no remaining uri just return null
if ($strict && !strlen((string) $uri)) {
return null;
}
// uri'll be truncated from the start when a match is found
$match = $node->match($this->parser, $uri, $params, $strict);
list($uri, $params) = $match;
}
// if there's remaining $uri, matching is failed
if ($strict && strlen((string) $uri)) {
return null;
}
return $params;
}
public function getParser()
{
return $this->parser;
}
protected function createNodeParser()
{
static $parser;
if ($parser) {
return $parser;
}
return $parser = new Parser;
}
}