Česky
Kamil Dudka

Web components

File detail

Name:DownloadPageServer.class.php [Download]
Location: src > lib
Size:4.1 KB
Last modification:2022-09-09 13:06

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);
  }
};
?>