|  | @@ -1,49 +1,28 @@
 | 
	
		
			
				|  |  |  <?php
 | 
	
		
			
				|  |  | -class GraphicsContext {
 | 
	
		
			
				|  |  | -  protected $palette = array();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  | - * A wrapper for XML elements.
 | 
	
		
			
				|  |  | + * Wrapper around php tidy class.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * @param string $html
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * @return void
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  | -class Element {
 | 
	
		
			
				|  |  | -  public $name = NULL;
 | 
	
		
			
				|  |  | -  public $attributes = array();
 | 
	
		
			
				|  |  | -  public $value = NULL;
 | 
	
		
			
				|  |  | -  public $new_line; // Add a new line after element
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  public function __construct($name, $attr = NULL, $value = NULL) {
 | 
	
		
			
				|  |  | -    $this->name = $name;
 | 
	
		
			
				|  |  | -    $this->attributes = $attr;
 | 
	
		
			
				|  |  | -    $this->value = $value;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  public function __toString() {
 | 
	
		
			
				|  |  | -    $ret = '<'. $this->name;
 | 
	
		
			
				|  |  | -    if (!empty($this->attributes)) {
 | 
	
		
			
				|  |  | -      $ret .= ' ' . implode(' ', $this->attributes);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    if (empty($this->value)) {
 | 
	
		
			
				|  |  | -      $ret .= ' />';
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else {
 | 
	
		
			
				|  |  | -      $ret .= '>';
 | 
	
		
			
				|  |  | -      if ($this->value instanceof Element) {
 | 
	
		
			
				|  |  | -        $ret .= (string) $this->value; // force __toString()
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      elseif (is_array($this->value)) {
 | 
	
		
			
				|  |  | -        $ret .= implode('', $this->value);
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      else {
 | 
	
		
			
				|  |  | -        $ret .= $this->value;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      $ret .= "</$this->name>";
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    return $ret;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +function applyTidy (&$html) {
 | 
	
		
			
				|  |  | +  $config = array(
 | 
	
		
			
				|  |  | +      'indent'          => TRUE,
 | 
	
		
			
				|  |  | +      'output-xhtml'    => TRUE,
 | 
	
		
			
				|  |  | +      'sort-attributes' => 'alpha',
 | 
	
		
			
				|  |  | +      'wrap'            => 80,
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +  $tidy = new tidy();
 | 
	
		
			
				|  |  | +  $tidy->parseString($html, $config, 'utf8');
 | 
	
		
			
				|  |  | +  $tidy->cleanRepair();
 | 
	
		
			
				|  |  | +  $html = (string) $tidy;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class Context {
 | 
	
		
			
				|  |  | +  protected $logLevelClasses = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  |     * Directory in which the current script is located.
 | 
	
		
			
				|  |  |     *
 | 
	
	
		
			
				|  | @@ -55,6 +34,29 @@ class Context {
 | 
	
		
			
				|  |  |     */
 | 
	
		
			
				|  |  |    protected $dirname;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * Graphics context
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @var GraphicsContext
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  protected $gc = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * Logging level, as per RFC5424
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @link http://php.net/network.constants.php
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @var integer
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  protected $logLevel = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * Messages for display.
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @var array
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  protected $messages = array();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  |     * Requested path: <$PHP_SELF>?q=a/b/c
 | 
	
		
			
				|  |  |     *
 | 
	
	
		
			
				|  | @@ -63,11 +65,31 @@ class Context {
 | 
	
		
			
				|  |  |    protected $path = NULL;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  | -   * Graphics context
 | 
	
		
			
				|  |  | +   * Tidy the output ?
 | 
	
		
			
				|  |  |     *
 | 
	
		
			
				|  |  | -   * @var GraphicsContext
 | 
	
		
			
				|  |  | +   * @var boolean
 | 
	
		
			
				|  |  |     */
 | 
	
		
			
				|  |  | -  protected $gc = NULL;
 | 
	
		
			
				|  |  | +  protected $tidy = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * User information: logged or not ?
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @var boolean
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  protected $user = FALSE;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function __destruct() {
 | 
	
		
			
				|  |  | +    if (!empty($this->messages)) {
 | 
	
		
			
				|  |  | +      $ret = (string) new Element('pre', array('class' => array('messages')),
 | 
	
		
			
				|  |  | +        implode("\n", $this->getMessage(TRUE)));
 | 
	
		
			
				|  |  | +      echo $ret;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function __toString() {
 | 
	
		
			
				|  |  | +    $ret = '<pre>' . print_r($this, TRUE) . '</pre>';
 | 
	
		
			
				|  |  | +    return $ret;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    public function getDirname() {
 | 
	
		
			
				|  |  |      if (!isset($this->dirname)) {
 | 
	
	
		
			
				|  | @@ -77,6 +99,64 @@ class Context {
 | 
	
		
			
				|  |  |      return $this->dirname;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  public function getLogLevel() {
 | 
	
		
			
				|  |  | +    if (!isset($this->logLevel)) {
 | 
	
		
			
				|  |  | +      $usLogLevel = NULL;
 | 
	
		
			
				|  |  | +      foreach ($_GET as $key => $value) {
 | 
	
		
			
				|  |  | +        if (strtolower($key) === 'loglevel') {
 | 
	
		
			
				|  |  | +          $usLogLevel = (int) $value;
 | 
	
		
			
				|  |  | +          break;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      if (!isset($usLogLevel)) {
 | 
	
		
			
				|  |  | +        $usLogLevel = LOG_NOTICE;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if ($usLogLevel < LOG_EMERG) {
 | 
	
		
			
				|  |  | +        $this->logLevel = LOG_EMERG;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      elseif ($usLogLevel > LOG_DEBUG) {
 | 
	
		
			
				|  |  | +        $this->logLevel = LOG_DEBUG;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      else {
 | 
	
		
			
				|  |  | +        $this->logLevel = $usLogLevel; // We now know it to be safe
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return $this->logLevel;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  public function getLogLevelClass($logLevel) {
 | 
	
		
			
				|  |  | +    if (!isset($this->logLevelClasses)) {
 | 
	
		
			
				|  |  | +      $this->logLevelClasses = array(
 | 
	
		
			
				|  |  | +        LOG_EMERG   => 'error',
 | 
	
		
			
				|  |  | +        LOG_ALERT   => 'error',
 | 
	
		
			
				|  |  | +        LOG_CRIT    => 'error',
 | 
	
		
			
				|  |  | +        LOG_ERR     => 'error',
 | 
	
		
			
				|  |  | +        LOG_WARNING => 'warning',
 | 
	
		
			
				|  |  | +        LOG_NOTICE  => 'warning',
 | 
	
		
			
				|  |  | +        LOG_INFO    => 'status',
 | 
	
		
			
				|  |  | +        LOG_DEBUG   => 'status',
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ($logLevel < LOG_EMERG) {
 | 
	
		
			
				|  |  | +      $logLevel = LOG_EMERG;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    elseif ($logLevel > LOG_DEBUG) {
 | 
	
		
			
				|  |  | +      $logLevel = LOG_DEBUG;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return $this->logLevelClasses[$logLevel];
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  public function getMessage($clear = FALSE) {
 | 
	
		
			
				|  |  | +    $ret = $this->messages;
 | 
	
		
			
				|  |  | +    if ($clear) {
 | 
	
		
			
				|  |  | +      $this->messages = array();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return $ret;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  |     * Return the requested path.
 | 
	
		
			
				|  |  |     *
 | 
	
	
		
			
				|  | @@ -90,67 +170,161 @@ class Context {
 | 
	
		
			
				|  |  |      return $this->path;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  public function getTidy() {
 | 
	
		
			
				|  |  | +    if (!isset($this->tidy)) {
 | 
	
		
			
				|  |  | +      $this->tidy = TRUE;
 | 
	
		
			
				|  |  | +      foreach ($_GET as $key => $value) {
 | 
	
		
			
				|  |  | +        if (strtolower($key) === 'tidy') {
 | 
	
		
			
				|  |  | +          $this->tidy = !!$value;
 | 
	
		
			
				|  |  | +          break;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return $this->tidy;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  | -   * User information: logged or not ?
 | 
	
		
			
				|  |  | +   * Add a message to the messages list if it is above the current logging level.
 | 
	
		
			
				|  |  |     *
 | 
	
		
			
				|  |  | -   * @var boolean
 | 
	
		
			
				|  |  | +   * @param string $text
 | 
	
		
			
				|  |  | +   * @param integer $logLevel
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @return void
 | 
	
		
			
				|  |  |     */
 | 
	
		
			
				|  |  | -  protected $user = FALSE;
 | 
	
		
			
				|  |  | +  public function setMessage($text, $logLevel = LOG_NOTICE) {
 | 
	
		
			
				|  |  | +    if ($logLevel <= $this->getlogLevel()) {
 | 
	
		
			
				|  |  | +      if (is_array($text) || (is_object($text) && !method_exists($text, '__toString'))) {
 | 
	
		
			
				|  |  | +        $this->messages[] = array(print_r($text, TRUE), $logLevel);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      else {
 | 
	
		
			
				|  |  | +        $this->messages[] = array((string) $text, $logLevel);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * A wrapper for XML elements.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +class Element {
 | 
	
		
			
				|  |  | +  public $attributes = array();
 | 
	
		
			
				|  |  | +  public $name = NULL;
 | 
	
		
			
				|  |  | +  public $new_line; // Add a new line after element
 | 
	
		
			
				|  |  | +  public $value = NULL;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  function __construct() {
 | 
	
		
			
				|  |  | -    $this->getPath();
 | 
	
		
			
				|  |  | +  public function __construct($name, $attr = NULL, $value = NULL) {
 | 
	
		
			
				|  |  | +    $this->name = $name;
 | 
	
		
			
				|  |  | +    $this->attributes = $attr;
 | 
	
		
			
				|  |  | +    $this->value = $value;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  function __toString() {
 | 
	
		
			
				|  |  | -    $ret = '<pre>' . print_r($this, TRUE) . '</pre>';
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * @link drupal7/includes/common.inc#check_plain()
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  public static function check_plain($text) {
 | 
	
		
			
				|  |  | +    return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * @link drupal7/includes/common.inc#drupal_attributes()
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  public static function getSerializedAttributes(array $attributes = array()) {
 | 
	
		
			
				|  |  | +    foreach ($attributes as $attribute => &$data) {
 | 
	
		
			
				|  |  | +      $data = implode(' ', (array) $data);
 | 
	
		
			
				|  |  | +      $data = $attribute . '="' . self::check_plain($data) . '"';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return $attributes ? ' ' . implode(' ', $attributes) : '';
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  public function __toString() {
 | 
	
		
			
				|  |  | +    $ret = '<'. $this->name;
 | 
	
		
			
				|  |  | +    if (!empty($this->attributes) && is_array($this->attributes)) {
 | 
	
		
			
				|  |  | +      $ret .= self::getSerializedAttributes($this->attributes);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (empty($this->value)) {
 | 
	
		
			
				|  |  | +      $ret .= ' />';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +      $ret .= '>';
 | 
	
		
			
				|  |  | +      if ($this->value instanceof Element) {
 | 
	
		
			
				|  |  | +        $ret .= (string) $this->value; // force __toString()
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      elseif (is_array($this->value)) {
 | 
	
		
			
				|  |  | +        $ret .= implode('', $this->value);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      else {
 | 
	
		
			
				|  |  | +        $ret .= $this->value;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      $ret .= "</$this->name>";
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      return $ret;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +class GraphicsContext {
 | 
	
		
			
				|  |  | +  protected $palette = array();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class Page extends Element {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * The HTML body element of the page.
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @var array
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  protected $body;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  |     * @var Context
 | 
	
		
			
				|  |  |     */
 | 
	
		
			
				|  |  |    protected $context;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  | +   * Ths HTML head element of the page.
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  |     * @var array
 | 
	
		
			
				|  |  |     */
 | 
	
		
			
				|  |  | -  protected $styles;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +  protected $head;
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  |     * @var array
 | 
	
		
			
				|  |  |     */
 | 
	
		
			
				|  |  |    protected $finalized = array();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  public function getHeader($name) {
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  public function setHeader($name, $value) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  public function getHead() {
 | 
	
		
			
				|  |  | -    $this->finalizeHead();
 | 
	
		
			
				|  |  | -    $head = new Element('head', NULL, $this->head);
 | 
	
		
			
				|  |  | -    $ret = (string) $head;
 | 
	
		
			
				|  |  | -    return $ret;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  public function setHead($item) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * @var array
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  protected $styles;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  public function getBody() {
 | 
	
		
			
				|  |  | -    $this->finalizeBody();
 | 
	
		
			
				|  |  | -    $body = new Element('body', NULL, $this->body);
 | 
	
		
			
				|  |  | -    $ret = (string) $body;
 | 
	
		
			
				|  |  | -    return $ret;
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * Page constructor.
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @param Context $context
 | 
	
		
			
				|  |  | +   * @param array $item
 | 
	
		
			
				|  |  | +   *   A router info array.
 | 
	
		
			
				|  |  | +   *
 | 
	
		
			
				|  |  | +   * @see Router::getInfo()
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  public function __construct(Context $context, array $item) {
 | 
	
		
			
				|  |  | +    parent::__construct('html');
 | 
	
		
			
				|  |  | +    $this->context = $context;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  public function setBody($fragment) {
 | 
	
		
			
				|  |  | -    $this->body[] = $fragment;
 | 
	
		
			
				|  |  | +  public function finalizeBody() {
 | 
	
		
			
				|  |  | +    if (isset($this->finalized['body'])) {
 | 
	
		
			
				|  |  | +      throw new Exception('Attempt to finalize already finalized body');
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ($message = $this->context->getMessage(TRUE)) {
 | 
	
		
			
				|  |  | +      $items = array();
 | 
	
		
			
				|  |  | +      foreach ($message as $row) {
 | 
	
		
			
				|  |  | +        $items[] = new Element('li', array(
 | 
	
		
			
				|  |  | +          'class' => array($this->context->getLogLevelClass($row[1])),
 | 
	
		
			
				|  |  | +        ), $row[0]);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      $this->setBody(new Element('div', array('class' => array('messages')), $items));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    $this->finalized['body'] = TRUE;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    public function finalizeHead() {
 | 
	
	
		
			
				|  | @@ -167,11 +341,21 @@ class Page extends Element {
 | 
	
		
			
				|  |  |      $this->finalized['head'] = TRUE;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  public function finalizeBody() {
 | 
	
		
			
				|  |  | -    if (isset($this->finalized['body'])) {
 | 
	
		
			
				|  |  | -      throw new Exception('Attempt to finalize already finalized body');
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    $this->finalized['body'] = TRUE;
 | 
	
		
			
				|  |  | +  public function getBody() {
 | 
	
		
			
				|  |  | +    $this->finalizeBody();
 | 
	
		
			
				|  |  | +    $body = new Element('body', NULL, $this->body);
 | 
	
		
			
				|  |  | +    $ret = (string) $body;
 | 
	
		
			
				|  |  | +    return $ret;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  public function getHead() {
 | 
	
		
			
				|  |  | +    $this->finalizeHead();
 | 
	
		
			
				|  |  | +    $head = new Element('head', NULL, $this->head);
 | 
	
		
			
				|  |  | +    $ret = (string) $head;
 | 
	
		
			
				|  |  | +    return $ret;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  public function getHeader($name) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    public function render() {
 | 
	
	
		
			
				|  | @@ -179,22 +363,34 @@ class Page extends Element {
 | 
	
		
			
				|  |  |      return (string) $html;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  /**
 | 
	
		
			
				|  |  | -   * Page constructor.
 | 
	
		
			
				|  |  | -   *
 | 
	
		
			
				|  |  | -   * @param Context $context
 | 
	
		
			
				|  |  | -   * @param array $item
 | 
	
		
			
				|  |  | -   *   A router info array.
 | 
	
		
			
				|  |  | -   *
 | 
	
		
			
				|  |  | -   * @see Router::getInfo()
 | 
	
		
			
				|  |  | -   */
 | 
	
		
			
				|  |  | -  public function __construct(Context $context, array $item) {
 | 
	
		
			
				|  |  | -    parent::__construct('html');
 | 
	
		
			
				|  |  | -    $this->context = $context;
 | 
	
		
			
				|  |  | +  public function setBody($fragment) {
 | 
	
		
			
				|  |  | +    $this->body[] = $fragment;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  public function setHead($item) {
 | 
	
		
			
				|  |  | +    $this->head[] = $item;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  public function setHeader($name, $value) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class Page_Main extends Page {
 | 
	
		
			
				|  |  | +  function finalizeBody() {
 | 
	
		
			
				|  |  | +    $hello = new Element('p', NULL, 'Hello world');
 | 
	
		
			
				|  |  | +    $this->setBody($hello);
 | 
	
		
			
				|  |  | +    parent::finalizeBody();
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class Router {
 | 
	
		
			
				|  |  | +  function __construct(Context $context) {
 | 
	
		
			
				|  |  | +    $this->context = $context;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    function getInfo() {
 | 
	
		
			
				|  |  |      $ret = array(
 | 
	
		
			
				|  |  |        '^server/(\w+)/flush/(\w+)$' => array(
 | 
	
	
		
			
				|  | @@ -266,25 +462,27 @@ class Router {
 | 
	
		
			
				|  |  |    function getRoute() {
 | 
	
		
			
				|  |  |      $found = FALSE;
 | 
	
		
			
				|  |  |      $path = $this->context->getPath();
 | 
	
		
			
				|  |  | -    // echo "<pre>Path: [". $path . "]</p>";
 | 
	
		
			
				|  |  |      $matches = array();
 | 
	
		
			
				|  |  | +    $infoDefaults = array(
 | 
	
		
			
				|  |  | +      'page arguments' => array(),
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  |      foreach ($this->getInfo() as $regex => $info) {
 | 
	
		
			
				|  |  |        $regex = "@$regex@";
 | 
	
		
			
				|  |  |        $count = preg_match($regex, $path, $matches);
 | 
	
		
			
				|  |  | -      // echo "<pre>$regex: $count";
 | 
	
		
			
				|  |  | -      // if ($count) print_r($matches);
 | 
	
		
			
				|  |  | -      // echo "</pre>";
 | 
	
		
			
				|  |  |        if ($count) {
 | 
	
		
			
				|  |  |          $found = TRUE;
 | 
	
		
			
				|  |  |          break;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if ($found) {
 | 
	
		
			
				|  |  | -      // echo "Found at $regex<pre>";
 | 
	
		
			
				|  |  | -      // print_r($info);
 | 
	
		
			
				|  |  | -      $regexes = array_fill(0, count($info['page arguments']), $regex);
 | 
	
		
			
				|  |  | -      $paths = array_fill(0, count($info['page arguments']), $path);
 | 
	
		
			
				|  |  | -      $info['page arguments'] = preg_replace($regexes, $info['page arguments'], $paths);
 | 
	
		
			
				|  |  | +      $this->context->setMessage("Found at $regex", LOG_DEBUG);
 | 
	
		
			
				|  |  | +      $this->context->setMessage("Info: ". print_r($info, TRUE), LOG_DEBUG);
 | 
	
		
			
				|  |  | +      $info = array_merge($infoDefaults, $info);
 | 
	
		
			
				|  |  | +      if (!empty($info['page arguments'])) {
 | 
	
		
			
				|  |  | +        $regexes = array_fill(0, count($info['page arguments']), $regex);
 | 
	
		
			
				|  |  | +        $paths = array_fill(0, count($info['page arguments']), $path);
 | 
	
		
			
				|  |  | +        $info['page arguments'] = preg_replace($regexes, $info['page arguments'], $paths);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      else {
 | 
	
		
			
				|  |  |        $info = NULL;
 | 
	
	
		
			
				|  | @@ -292,39 +490,33 @@ class Router {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      return $info;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  function __construct(Context $context) {
 | 
	
		
			
				|  |  | -    $this->context = $context;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -class Page_Main extends Page {
 | 
	
		
			
				|  |  | -  function finalizeBody() {
 | 
	
		
			
				|  |  | -    $hello = new Element('p', NULL, 'Hello world');
 | 
	
		
			
				|  |  | -    $this->setBody($hello);
 | 
	
		
			
				|  |  | -    parent::finalizeBody();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  function main() {
 | 
	
		
			
				|  |  | -  $context = new Context();
 | 
	
		
			
				|  |  | -  // echo "<p>Dirname: [". $context->getDirname() . "]</p>";
 | 
	
		
			
				|  |  | -  // echo "<p>Path: [". $context->getPath() . "]</p><pre>";
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  $router = new Router($context);
 | 
	
		
			
				|  |  | -  $item = $router->getRoute();
 | 
	
		
			
				|  |  | -  $page = new $item['page class']($context, $item);
 | 
	
		
			
				|  |  | -  // echo '<pre>'; var_dump($page);
 | 
	
		
			
				|  |  | -  echo $page->render();
 | 
	
		
			
				|  |  | +  try {
 | 
	
		
			
				|  |  | +    ob_start();
 | 
	
		
			
				|  |  | +    $context = new Context();
 | 
	
		
			
				|  |  | +    $context->setMessage("Dirname: [". $context->getDirname() . "]", LOG_DEBUG);
 | 
	
		
			
				|  |  | +    $context->setMessage("Path: [". $context->getPath() . "]", LOG_DEBUG);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    $router = new Router($context);
 | 
	
		
			
				|  |  | +    $item = $router->getRoute();
 | 
	
		
			
				|  |  | +    $page = new $item['page class']($context, $item);
 | 
	
		
			
				|  |  | +    // echo '<pre>'; var_dump($page);
 | 
	
		
			
				|  |  | +    echo $page->render();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    $html = ob_get_clean();
 | 
	
		
			
				|  |  | +    if ($context->getTidy()) {
 | 
	
		
			
				|  |  | +      applyTidy($html);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    echo $html;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  catch (Exception $e) {
 | 
	
		
			
				|  |  | +    echo '<pre>';
 | 
	
		
			
				|  |  | +    echo $e->getMessage() . PHP_EOL;
 | 
	
		
			
				|  |  | +    echo $e->getTraceAsString();
 | 
	
		
			
				|  |  | +    echo "</pre>";
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -try {
 | 
	
		
			
				|  |  | -  main();
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -catch (Exception $e) {
 | 
	
		
			
				|  |  | -  echo '<pre>';
 | 
	
		
			
				|  |  | -  echo $e->getMessage() . PHP_EOL;
 | 
	
		
			
				|  |  | -  echo $e->getTraceAsString();
 | 
	
		
			
				|  |  | -  echo "</pre>";
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +main();
 |