Browse Source

Implemented a common base class to provide a common header to all pages

- Page and Page_Memcache_Base are now abstract classes
- Page::build() is a new abstract method
- concrete classes are now names Page_Memcache_*
- concrete classes Page_Memcache_* extend Page_Memcache_Base
Frederic G. MARAND 12 years ago
parent
commit
ee713a2ffb
2 changed files with 114 additions and 33 deletions
  1. 45 19
      memcache_ui.css
  2. 69 14
      memcache_ui.php

+ 45 - 19
memcache_ui.css

@@ -13,25 +13,6 @@ a { color:black; font-weight:none; text-decoration:none; }
 a:hover { text-decoration:underline; }
 div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
 
-h1.memcache { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
-* html h1.memcache { margin-bottom:-7px; }
-h1.memcache a:hover { text-decoration:none; color:rgb(90,90,90); }
-h1.memcache span.logo {
-  background:rgb(119,123,180);
-  color:black;
-  border-right: solid black 1px;
-  border-bottom: solid black 1px;
-  font-style:italic;
-  font-size:1em;
-  padding-left:1.2em;
-  padding-right:1.2em;
-  text-align:right;
-  display:block;
-  width:130px;
-  }
-h1.memcache span.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
-h1.memcache span.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
-h1.memcache div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
 hr.memcache {
   background:white;
   border-bottom:solid rgb(102,102,153) 1px;
@@ -203,6 +184,51 @@ input {
 /**
  * New version styles
  */
+ 
+/**
+ * Header region
+ */
+h1.memcache { 
+  background: rgb(153, 153, 204); 
+  margin: 0 0 -7px 0; 
+  padding: 0.5em 1em 0.5em 1em; 
+}
+h1.memcache a: hover { 
+  color: rgb(90, 90, 90); 
+  text-decoration: none; 
+}
+h1.memcache span.logo {
+  background: rgb(119, 123, 180);
+  border-bottom: solid black 1px;
+  border-right: solid black 1px;
+  color: black;
+  display: block;
+  font-size: 1em;
+  font-style: italic;
+  padding-left: 1.2em;
+  padding-right: 1.2em;
+  text-align: right;
+  width: 130px;
+}
+h1.memcache span.logo span.name { 
+  color: white; 
+  font-size: 0.7em; 
+  padding: 0 0.8em 0 2em; 
+}
+h1.memcache span.nameinfo { 
+  color: white; 
+  display: block /* was inline */; 
+  font-size: 0.4em; 
+  margin-left: 3em; 
+}
+/* Unused style from PECL apc.php
+h1.memcache div.copy { 
+  color: black; 
+  font-size: 0.4em; 
+  position: absolute; 
+  right: 1em; 
+}
+*/
 
 /**
  * Generic "OK" style

+ 69 - 14
memcache_ui.php

@@ -12,7 +12,7 @@ function applyTidy (&$html) {
       'indent'          => TRUE,
       'output-xhtml'    => TRUE,
       'sort-attributes' => 'alpha',
-      'wrap'            => 80,
+      'wrap'            => 200,
   );
   $tidy = new tidy();
   $tidy->parseString($html, $config, 'utf8');
@@ -275,7 +275,7 @@ class Element {
         $ret .= (string) $this->value; // force __toString()
       }
       elseif (is_array($this->value)) {
-        $ret .= implode('', $this->value);
+        $ret .= implode("\n", $this->value);
       }
       else {
         $ret .= $this->value;
@@ -290,7 +290,7 @@ class GraphicsContext {
   protected $palette = array();
 }
 
-class Page extends Element {
+abstract class Page extends Element {
 
   /**
    * The HTML body element of the page.
@@ -299,17 +299,32 @@ class Page extends Element {
    */
   protected $body;
 
+  /**
+   * The MIME content type with charset
+   *
+   * @var string
+   */
+  protected $contentType = 'text/html; charset=utf8';
+
   /**
    * @var Context
    */
   protected $context;
 
   /**
-   * Ths HTML head element of the page.
+   * The HTML head element of the page.
    *
    * @var array
    */
   protected $head;
+
+  /**
+   * The array of HTTP headers
+   *
+   * @var array
+   */
+  protected $headers = array();
+
   /**
    * @var array
    */
@@ -335,16 +350,25 @@ class Page extends Element {
     $this->context = $context;
     $this->initializeHead();
     $this->initializeBody();
-    if (method_exists($this, 'build')) {
-      $this->build();
-    }
+    // Will fail if not reimplemented as a concrete method in a child class
+    $this->build();
   }
 
   public function __toString() {
+    $this->finalizeHeader();
     $html = new Element('html', NULL, $this->getHead() . $this->getBody());
     return (string) $html;
   }
 
+  public abstract function build();
+
+  public function emitHeaders() {
+    $this->finalizeHeader();
+    foreach ($this->headers as $name => $value) {
+      header("$name: $value");
+    }
+  }
+
   public function finalizeBody() {
     if (isset($this->finalized['body'])) {
       throw new Exception('Attempt to finalize already finalized body');
@@ -377,6 +401,13 @@ class Page extends Element {
     $this->finalized['head'] = TRUE;
   }
 
+  public function finalizeHeader() {
+    $contentType = $this->getHeader('content-type');
+    if (empty($contentType)) {
+      $this->setHeader('content-type', $this->contentType);
+    }
+  }
+
   public function getBody() {
     $this->finalizeBody();
     $body = new Element('body', NULL, $this->body);
@@ -434,25 +465,48 @@ class Page extends Element {
   }
 
   public function setHeader($name, $value) {
-
+    $this->headers[$name] = $value;
   }
 
 }
 
-class Page_Main extends Page {
+/**
+ * Provide common layout elements to child classes.
+ *
+ * - header
+ */
+abstract class Page_Memcache_Base extends Page {
+  function build() {
+    $this->setBody(
+      new Element('div', array('class' => array('head')),
+        new Element('h1', array('class' => array('memcache')), array(
+          new Element('span', array('class' => array('logo')),
+            new Element('a', array('href' => 'http://pecl.php.net/package/memcache'), 'memcache')
+          ),
+          new Element('span', array('class' => array('nameinfo')), 'memcache_ui.php from an idea by <a href="http://livebookmark.net">Harun Yayli</a>'),
+        ))),
+      'header'
+    );
+  }
+}
+
+class Page_Memcache_Main extends Page_Memcache_Base {
   function build() {
+    parent::build();
     $this->setBody(new Element('p', NULL, 'Hello world'));
   }
 }
 
-class Page_Server_Flush extends Page {
+class Page_Memcache_Server_Flush extends Page_Memcache_Base {
   function build() {
+    parent::build();
     $this->setBody(new Element('p', NULL, 'Flush server'));
   }
 }
 
-class Page_Slab_Overview extends Page {
+class Page_Memcache_Slab_Overview extends Page_Memcache_Base {
   function build() {
+    parent::build();
     $this->setBody(new Element('p', NULL, 'Slabs'));
   }
 }
@@ -471,7 +525,7 @@ class Router {
         'title arguments' => 'page arguments',
       ),
       '^server/(\w+)/flush$' => array(
-        'page class' => 'Page_server_Flush',
+        'page class' => 'Page_Memcache_Server_Flush',
         'page arguments' => array('$1'),
         'title callback' => 'title_server',
         'title arguments' => 'page arguments',
@@ -517,12 +571,12 @@ class Router {
       ),
 
       '^slabs$' => array(
-        'page class' => 'Page_Slab_Overview',
+        'page class' => 'Page_Memcache_Slab_Overview',
         'title' => 'Slabs per server',
       ),
 
       '' => array( // Catch-all regex
-        'page class' => 'Page_Main',
+        'page class' => 'Page_Memcache_Main',
         'title' => 'Overview',
       ),
     );
@@ -577,6 +631,7 @@ function main() {
     $router = new Router($context);
     $item = $router->getRoute();
     $page = new $item['page class']($context, $item);
+    $page->emitHeaders();
     echo $page;
 
     $html = ob_get_clean();