Web components
File detail
Source code
<?php
/**
* @file PageServer.class.php
* Definition of PageServer class.
* @author Kamil Dudka <xdudka00@gmail.com>
*/
/**
* Nested page requested by user not found.
* @param msg Message text to carry inside exception.
*/
class ExceptionRedirect extends Exception {
/**
* @param msg Message text to carry inside exception.
*/
public function __construct($msg=null) {
parent::__construct($msg);
}
};
/**
* Stands for page xml templates transformation and cache.
*/
class PageServer {
private $src_;
private $dest_;
private $xslTemplate_;
/**
* Check if XML template for page with given name exists.
* @return Return true if XML template exists, false if not.
*/
public static function isPageValid($page) {
$page = ereg_replace('\/$', '', $page);
if (false === ereg('^[A-Za-z_][A-Za-z0-9_\.\-]*$', $page))
return false;
$config = Config::instance();
return file_exists(
$config->documentRoot().
$config->pageDir().'/'.
$page.'.xml'
);
}
/**
* @param page Name of requested page.
* @throw ExceptionNotFound Exception is thrown if page name is invalid.
*/
public function __construct($page, $nestedPage) {
if (!self::isPageValid($page))
throw new ExceptionNotFound;
// Load configuration
$config = Config::instance();
$docRoot = $config->documentRoot();
$pageDir_ = $docRoot.$config->pageDir();
$cacheDir_ = $docRoot.$config->cacheDir();
$xslBase = $pageDir_.'/'.__CLASS__;
$this->page_ = $page;
$this->src_ = $pageDir_.'/'.$page.'.xml';
$this->pageContentTemplate_ = $xslBase.'.xsl';
$this->titleInitTemplate_ = $xslBase.'_init.xsl';
$this->pageContentScript_ = $cacheDir_.'/'.$page.'.php';
$this->titleInitScript_ = $cacheDir_.'/'.$page.'_init.php';
if (!file_exists($this->src_))
// Invalid page name
throw new ExceptionNotFound;
if (!empty($nestedPage)) {
$xml = new DOMDocument;
$xml->load($this->src_);
$xpath = new DOMXpath($xml);
$list = $xpath->query('//page/nestedPage[@id=\''.$nestedPage.'\']');
if (1!=$list->length)
throw new ExceptionRedirect;
}
// Update cache when needed
if ($this->needUpdate())
$this->updateScript();
}
/**
* Name of page maintained by this object.
* @return Name of page.
*/
public function page() {
return $this->page_;
}
/**
* Name of script, which initialize pageTitle variable.
* @return Full path to script.
*/
public function titleInitScript() {
return $this->titleInitScript_;
}
/**
* Name of script, which displays requested page.
* @return Full path to script.
*/
public function pageContentScript() {
return $this->pageContentScript_;
}
/**
* @return Return true if one of scripts needs update.
*/
private function needUpdate() {
if (
!file_exists($this->pageContentScript_) ||
!file_exists($this->titleInitScript_))
return true;
else
return
min(filemtime($this->pageContentScript_),filemtime($this->titleInitScript_)) <
max(filemtime($this->src_),filemtime($this->pageContentTemplate_),filemtime($this->titleInitTemplate_));
}
/**
* Update scripts using XSLT processor.
*/
private function updateScript() {
// Load the XML source
$xml = new DOMDocument;
$xml->load($this->src_);
$xsl = new DOMDocument;
$xsl->load($this->pageContentTemplate_);
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules
// Process XSLT and write to $menuCache
$fd = fopen($this->pageContentScript_, 'w');
fwrite($fd, $proc->transformToXML($xml));
fclose($fd);
$xsl = new DOMDocument;
$xsl->load($this->titleInitTemplate_);
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules
// Process XSLT and write to $menuCache
$fd = fopen($this->titleInitScript_, 'w');
fwrite($fd, $proc->transformToXML($xml));
fclose($fd);
}
};
?>