<?php
/**
 * Implementation of an easy URL accessor.
 *
 * @package Library
 * @author Miroslav Kubelik (koubel@volny.cz)
 * @copyright Copyright (c) 2007-2009 Miroslav Kubelik
 * @license http://opensource.org/licenses/gpl-license.php GNU GPL
 */
/**
 * Class for simple access for application defined Url.
 *
 * Return URL as overloaded member. E.g. for calling $urlenum->index returnd URL
 * for index URL. Can be used also for syntax path. E.g. for calling $urlenum->getURLfromPath(index/something)
 * return URL for syntax path index/something.
 *
 * @package Library
 * @author Miroslav Kubelik (koubel@volny.cz)
 * @copyright Copyright (c) 2007-2009 Miroslav Kubelik
 * @license http://opensource.org/licenses/gpl-license.php GNU GPL
 */
class UrlEasyGet 
{
    /**
     * Search by URL name
     */
    const SEARCHBYNAME = 1;
    /**
     * Search by syntax path
     */
    const SEARCHBYSYNTAXPATH = 2;
    /**
     * Url XML map Iterator based on SPL RecursiveIteratorIterator
     */
    private $urlIterator;
    /**
     * searched URL name, is set from __get as overloaded member
     */
    private $searchedNodeName;
    /**
     * searched syntax path
     */
    private $searchedSyntaxPath;
    /**
     * type of search
     */
    private $searchType;

    /**
     * Build iterator from XML file.
     *
     * @param string $xmlfile full directory path to the XML file with a URL map.
     */
    function __construct($xmlfile) 
    {
        $this->urlIterator = new UrlMapIterator($xmlfile);
        //default search by URL name identifier
        $this->searchType = self::SEARCHBYNAME;
    }

    /**
     * Set search type. Must be one of the class constant.
     *
     * @param int $type id full directory path to XML file with URL map.
     */
    public function setSearchType($typeId) 
    {
        switch ($typeId) {
        case self::SEARCHBYNAME:
            $this->searchType = self::SEARCHBYNAME;
            break;
        case self::SEARCHBYSYNTAXPATH:
            $this->searchType = self::SEARCHBYSYNTAXPATH;
            break;
        default:
            throw new Exception(__METHOD__ . ": unknow search type");
        }
    }

    /**
     * Set searched syntax path
     * @param string $str
     */
    public function setSearchedPath($str) 
    {
        $this->searchedSyntaxPath = $str;
        $this->searchedNodeName = "";
        $this->setSearchType(self::SEARCHBYSYNTAXPATH);
    }

    /**
     * Main function, return URL which is defined by urlName in XML file
     *
     * @param string $urlName
     * @return string
     */
    public function __get($urlName) 
    {
        $this->searchedNodeName = $urlName;
        $this->searchedSyntaxPath = "";
        $this->setSearchType(self::SEARCHBYNAME);
        //return URL
        return $this->getURLpath();
    }

    /**
     * Return URL path for our searched node.
     * return string
     */
    public function getURLpath() 
    {
        $this->urlIterator->rewind();
        //iteration
        while ($this->urlIterator->valid()) {
            //current syntax path and name
            $currentInfo = array("synPath" => $this->urlIterator->getCurrentSyntaxPath(), "name" => $this->urlIterator->getCurrentName());
            //node find
            if ($this->isNode($currentInfo)) {
                return $this->urlIterator->getCurrentUrlPath();
            }
            $this->urlIterator->next();
        }
        throw new LogicException(__METHOD__ . ": node not found - searchedNodeName " . $this->searchedNodeName . " searchedSyntaxPath $this->searchedSyntaxPath");
    }

    /**
     * Test if current node is our searched node.
     *
     *  @param array $currentNodeInfo array with information about current node
     * Indexes : "synPath" = current syntax path, "name" => current URL name identifier
     *
     * return bool
     */
    private function isNode($currentNodeInfo) 
    {
        //print "tested node.";
        //print_r($currentNodeInfo);
        switch ($this->searchType) {
        case self::SEARCHBYNAME:
            if ($this->searchedNodeName == $currentNodeInfo["name"]) return true;
            break;
        case self::SEARCHBYSYNTAXPATH:
            if ($this->searchedSyntaxPath == $currentNodeInfo["synPath"]) return true;
            break;
        default:
            break;
        }
        return false;
    }
}
