cyrilleinvalides/choupas/www/admin/app/cache/debug/libs/sense/Path.php

152 lines
2.9 KiB
PHP

<?php
// Immutable
class Path implements IteratorAggregate {
public static function get ( $path ) {
return new self($path);
}
public static function conv ( $path ) {
if ( is_string($path) ) {
if ( !$path )
return array();
$abs = $path[0] === DIRECTORY_SEPARATOR ? array(null) : array();
$elements = array_filter(explode(DIRECTORY_SEPARATOR, $path));
return array_merge($abs, $elements);
} elseif ( is_array($path) )
return $path;
elseif ( $path instanceof self )
return $path->elements;
else throw new InvalidArgumentException();
}
private static function compute ( $elements, $target ) {
foreach ( $target as $elem )
if ( $elem === '.' );
elseif ( $elem === '..' ) {
if ( count($elements) && end($elements) && end($elements) !== '..' )
array_pop($elements);
elseif (!count($elements) || end($elements) === '..' ) $elements[] = $elem;
} elseif ( $elem || !$elements )
$elements[] = $elem;
return $elements;
}
private $elements;
public function __construct ( $path ) {
$this->elements = self::compute(array(), self::conv($path));
}
public function getIterator () {
return new ArrayIterator($this->elements);
}
public function isAbsolute () {
return count($this->elements) && !$this->elements;
}
public function append ( $path ) {
$source = $this->elements;
foreach ( func_get_args() as $path )
$source = self::compute($source, self::conv($path));
return new self($source);
}
public function pop ( $path ) {
$source = $this->elements;
$target = self::compute(array(), self::conv($path));
foreach ( func_get_args() as $path ) {
while ( count($source) && count($target) && last($source) === last($target) ) {
array_pop($source);
array_pop($target);
}
if ( count($target) )
return false;
}
return new self($source);
}
public function prepend ( $path ) {
$source = $this->elements;
foreach ( func_get_args() as $path )
$source = self::compute(self::conv($path), $source);
return new self($source);
}
public function shift ( $path ) {
$source = $this->elements;
$target = self::compute(array(), self::conv($path));
foreach ( func_get_args() as $path ) {
while ( count($source) && count($target) && reset($source) === reset($target) ) {
array_shift($source);
array_shift($target);
}
if ( count($target) )
return false;
}
return new self($source);
}
public function absolute () {
return array_key_exists(0, $this->elements) && !$this->elements[0];
}
public function __toString () {
$abs = count($this->elements) === 1 && array_key_exists(0, $this->elements) && !$this->elements[0] ? DIRECTORY_SEPARATOR : '';
return $abs . implode(DIRECTORY_SEPARATOR, $this->elements);
}
}
?>