<?php
/*
* igitigit - Web frontend for Git repositories
* Copyright (C) 2011 Klaus Reimer <hide@address.com>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace igitigit;
/**
* A system directory.
*
* @author Klaus Reimer <hide@address.com>
*/
class SystemDirectory implements Directory, SystemObject
{
/** The path (relative to REPOS, empty if root directory). */
private $path;
/** The directory name. */
private $name;
/** The parent file. NULL when this is the root directory. */
private $parent;
/**
* Constructs a new directory.
*
* @param string $name
* Directory name.
* @param Directory $parent
* Optional parent file. If not specified then this
* directory is the root directory.
*/
public function __construct($name, Directory $parent = NULL)
{
$this->name = $name;
$this->parent = $parent;
if ($parent)
{
$parentPath = $this->parent->getPath();
$this->path = $parentPath;
if ($parentPath && $name) $this->path .= "/";
$this->path .= $name;
}
else
$this->path = "";
}
/**
* @see Object#getName()
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @see Object#getPath()
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* @see Object#getMode()
*
* @return int
*/
public function getMode()
{
$stats = stat($this->getAbsPath());
return $stats["mode"];
}
/**
* @see Object#getUrl()
*
* @return string
*/
public function getUrl()
{
$path = $this->getPath();
return CONTROLLER . ($path ? "/$path" : "");
}
/**
* @see Object#getType()
*
* @return string
*/
public function getType()
{
return Object::TYPE_SYSTEM_DIR;
}
/**
* @see Object#getLastModified()
*
* @return int
*/
public function getLastModified()
{
return filemtime($this->getAbsPath());
}
/**
* @see SystemObject#getAbsPath()
*
* @return string
*/
public function getAbsPath()
{
$path = $this->getPath();
return REPOS . ($path ? ("/" . $this->getPath()) : "");
}
/**
* @see File#getBreadcrumbs()
*
* @return Breadcrumb[]
*/
public function getBreadcrumbs()
{
$breadcrumbs = array();
$current = $this;
while ($current)
{
array_unshift($breadcrumbs, new Breadcrumb($current->getName(),
$current->getUrl(), $current == $this));
$current = $current->getParent();
}
return $breadcrumbs;
}
/**
* @see Directory#getParent()
*
* @return Directory
*/
public function getParent()
{
return $this->parent;
}
/**
* @see Directory#isRoot()
*
* @return boolean
*/
public function isRoot()
{
return $this->parent == NULL;
}
/**
* @see Directory#getObject()
*
* @param string $name
* @return Object
*/
public function getObject($name)
{
// When no name of "." was specified as name then return this
// directory
if (!$name || $name == ".") return $this;
// If ".." was specified as name then return the parent directory
// (Or NULL if no parent is present)
if ($name == "..") return $this->parent;
// Determine absolute path of the file.
$absPath = $this->getAbsPath() . "/" . $name;
// Determine type of file (and check if it exists at all).
if (!file_exists($absPath))
$object = NULL;
else if (GitRepository::isGitRepository($absPath))
$object = new GitRepository($name, $this);
else if (is_dir($absPath))
$object = new SystemDirectory($name, $this);
else
$object = new SystemFile($name, $this);
return $object;
}
/**
* @see Directory#getObjects()
*
* @return Object[]
*/
public function getObjects()
{
$objects = array();
$dir = opendir($this->getAbsPath());
while ($name = readdir($dir))
{
// Ignore current and parent directory
if ($name == "." || $name == "..") continue;
$objects[] = $this->getObject($name);
}
usort($objects, array($this, "compareObjects"));
return $objects;
}
/**
* Compare method to sort an object array by type and name.
*
* TODO This is the same as in GitDirectory. Should move to a common
* place.
*
* @param Object $a
* First object to compare.
* @param Object $b
* Second object to compare.
* @return int
* The comparison result.
*/
private function compareObjects($a, $b)
{
$r = strcmp($a->getType(), $b->getType());
if (!$r) $r = strcmp($a->getName(), $b->getName());
return $r;
}
}