gnu-social/extlib/Net/URL/Mapper/Path.plex

334 lines
9.5 KiB
Plaintext
Raw Normal View History

2010-11-28 06:52:32 +09:00
<?php
/**
* URL parser and mapper
*
* PHP version 5
*
* LICENSE:
*
* Copyright (c) 2006, Bertrand Mansion <golgote@mamasam.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The names of the authors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category Net
* @package Net_URL_Mapper
* @author Bertrand Mansion <golgote@mamasam.com>
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: Path.plex 283937 2009-07-12 11:37:21Z mansion $
* @link http://pear.php.net/package/Net_URL_Mapper
*/
require_once 'Net/URL/Mapper/Part/Dynamic.php';
require_once 'Net/URL/Mapper/Part/Wildcard.php';
require_once 'Net/URL/Mapper/Part/Fixed.php';
class Net_URL_Mapper_Path
{
private $path = '';
private $N = 0;
public $token;
public $value;
private $line = 1;
private $state = 1;
protected $alias;
protected $rules = array();
protected $defaults = array();
protected $parts = array();
protected $rule;
protected $format;
protected $minKeys;
protected $maxKeys;
protected $fixed = true;
protected $required;
public function __construct($path = '', $defaults = array(), $rules = array())
{
$this->path = '/'.trim(Net_URL::resolvePath($path), '/');
$this->setDefaults($defaults);
$this->setRules($rules);
try {
$this->parsePath();
} catch (Exception $e) {
// The path could not be parsed correctly, treat it as fixed
$this->fixed = true;
$part = self::createPart(Net_URL_Mapper_Part::FIXED, $this->path, $this->path);
$this->parts = array($part);
}
$this->getRequired();
}
/**
* Called when the object is serialized
* Make sure we do not store too much info when the object is serialized
* and call the regular expressions generator functions so that they will
* not need to be generated again on wakeup.
*
* @return array Name of properties to store when serialized
*/
public function __sleep()
{
$this->getFormat();
$this->getRule();
return array('alias', 'path', 'defaults', 'rule', 'format',
'parts', 'minKeys', 'maxKeys', 'fixed', 'required');
}
public function getPath()
{
return $this->path;
}
protected function parsePath()
{
while ($this->yylex()) { }
}
/**
* Get the path alias
* Path aliases can be used instead of full path
* @return null|string
*/
public function getAlias()
{
return $this->alias;
}
/**
* Set the path name
* @param string Set the path name
* @see getAlias()
*/
public function setAlias($alias)
{
$this->alias = $alias;
return $this;
}
/**
* Get the path parts default values
* @return null|array
*/
public function getDefaults()
{
return $this->defaults;
}
/**
* Set the path parts default values
* @param array Associative array with format partname => value
*/
public function setDefaults($defaults)
{
if (is_array($defaults)) {
$this->defaults = $defaults;
} else {
$this->defaults = array();
}
}
/**
* Set the path parts default values
* @param array Associative array with format partname => value
*/
public function setRules($rules)
{
if (is_array($rules)) {
$this->rules = $rules;
} else {
$this->rules = array();
}
}
/**
* Returns the regular expression used to match this path
* @return string PERL Regular expression
*/
public function getRule()
{
if (is_null($this->rule)) {
$this->rule = '/^';
foreach ($this->parts as $path => $part) {
$this->rule .= $part->getRule();
}
$this->rule .= '$/';
}
return $this->rule;
}
public function getFormat()
{
if (is_null($this->format)) {
$this->format = '/^';
foreach ($this->parts as $path => $part) {
$this->format .= $part->getFormat();
}
$this->format .= '$/';
}
return $this->format;
}
protected function addPart($part)
{
if (array_key_exists($part->content, $this->defaults)) {
$part->setRequired(false);
$part->setDefaults($this->defaults[$part->content]);
}
if (isset($this->rules[$part->content])) {
$part->setRule($this->rules[$part->content]);
}
$this->rule = null;
if ($part->getType() != Net_URL_Mapper_Part::FIXED) {
$this->fixed = false;
$this->parts[$part->content] = $part;
} else {
$this->parts[] = $part;
}
return $part;
}
public static function createPart($type, $content, $path)
{
switch ($type) {
case Net_URL_Mapper_Part::DYNAMIC:
return new Net_URL_Mapper_Part_Dynamic($content, $path);
break;
case Net_URL_Mapper_Part::WILDCARD:
return new Net_URL_Mapper_Part_Wildcard($content, $path);
break;
default:
return new Net_URL_Mapper_Part_Fixed($content, $path);
}
}
/**
* Checks whether the path contains the given part by name
* If value parameter is given, the part also checks if the
* given value conforms to the part rule.
* @param string Part name
* @param mixed The value to check against
*/
public function hasKey($partName, $value = null)
{
if (array_key_exists($partName, $this->parts)) {
if (!is_null($value) && $value !== false) {
return $this->parts[$partName]->match($value);
} else {
return true;
}
} elseif (array_key_exists($partName, $this->defaults) &&
$value == $this->defaults[$partName]) {
return true;
}
return false;
}
public function generate($values = array(), $qstring = array(), $anchor = '')
{
$path = '';
foreach ($this->parts as $part) {
$path .= $part->generate($values);
}
$path = '/'.trim(Net_URL::resolvePath($path), '/');
if (!empty($qstring)) {
$path .= '?'.http_build_query($qstring);
}
if (!empty($anchor)) {
$path .= '#'.ltrim($anchor, '#');
}
return $path;
}
public function getRequired()
{
if (!isset($this->required)) {
$req = array();
foreach ($this->parts as $part) {
if ($part->isRequired()) {
$req[] = $part->content;
}
}
$this->required = $req;
}
return $this->required;
}
public function getMaxKeys()
{
if (is_null($this->maxKeys)) {
$this->maxKeys = count($this->required);
$this->maxKeys += count($this->defaults);
}
return $this->maxKeys;
}
/*!lex2php
%input $this->path
%counter $this->N
%token $this->token
%value $this->value
%line $this->line
static = /\/?([^\/:\*]+)/
variable = /([a-zA-Z0-9_]+)/
dynamic = /\/?:/
wildcard = @/?\*@
grouping = /\/?\(([a-zA-Z0-9_]+)\)/
*/
/*!lex2php
%statename START
dynamic grouping {
$c = $yy_subpatterns[0];
$part = self::createPart(Net_URL_Mapper_Part::DYNAMIC, $c, $this->value);
$this->addPart($part);
}
wildcard grouping {
$c = $yy_subpatterns[0];
$part = self::createPart(Net_URL_Mapper_Part::WILDCARD, $c, $this->value);
$this->addPart($part);
}
dynamic variable {
$c = $yy_subpatterns[0];
$part = self::createPart(Net_URL_Mapper_Part::DYNAMIC, $c, $this->value);
$this->addPart($part);
}
wildcard variable {
$c = $yy_subpatterns[0];
$part = self::createPart(Net_URL_Mapper_Part::WILDCARD, $c, $this->value);
$this->addPart($part);
}
static {
$c = $yy_subpatterns[0];
$part = self::createPart(Net_URL_Mapper_Part::FIXED, $c, $this->value);
$this->addPart($part);
}
*/
}
?>