|
@@ -0,0 +1,330 @@
|
|
|
+<?php
|
|
|
+class GraphicsContext {
|
|
|
+ protected $palette = array();
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * A wrapper for XML elements.
|
|
|
+ */
|
|
|
+class Element {
|
|
|
+ public $name = NULL;
|
|
|
+ public $attributes = array();
|
|
|
+ public $value = NULL;
|
|
|
+ public $new_line;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ elseif (is_array($this->value)) {
|
|
|
+ $ret .= implode('', $this->value);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ $ret .= $this->value;
|
|
|
+ }
|
|
|
+ $ret .= "</$this->name>";
|
|
|
+ }
|
|
|
+ return $ret;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Context {
|
|
|
+
|
|
|
+ * Directory in which the current script is located.
|
|
|
+ *
|
|
|
+ * Follow symlinks if applicable, to obtain the actual implementation
|
|
|
+ * directory, instead of just the main file symlink, in order to find the
|
|
|
+ * other files.
|
|
|
+ *
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ protected $dirname;
|
|
|
+
|
|
|
+
|
|
|
+ * Requested path: <$PHP_SELF>?q=a/b/c
|
|
|
+ *
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ protected $path = NULL;
|
|
|
+
|
|
|
+
|
|
|
+ * Graphics context
|
|
|
+ *
|
|
|
+ * @var GraphicsContext
|
|
|
+ */
|
|
|
+ protected $gc = NULL;
|
|
|
+
|
|
|
+ public function getDirname() {
|
|
|
+ if (!isset($this->dirname)) {
|
|
|
+ $this->dirname = dirname(__FILE__);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->dirname;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Return the requested path.
|
|
|
+ *
|
|
|
+ * @param string $path
|
|
|
+ */
|
|
|
+ public function getPath() {
|
|
|
+ if (!isset($this->path)) {
|
|
|
+ $this->path = empty($_GET['q']) ? '' : $_GET['q'];
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this->path;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * User information: logged or not ?
|
|
|
+ *
|
|
|
+ * @var boolean
|
|
|
+ */
|
|
|
+ protected $user = FALSE;
|
|
|
+
|
|
|
+
|
|
|
+ function __construct() {
|
|
|
+ $this->getPath();
|
|
|
+ }
|
|
|
+
|
|
|
+ function __toString() {
|
|
|
+ $ret = '<pre>' . print_r($this, TRUE) . '</pre>';
|
|
|
+ return $ret;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Page extends Element {
|
|
|
+
|
|
|
+ * @var Context
|
|
|
+ */
|
|
|
+ protected $context;
|
|
|
+
|
|
|
+
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ protected $styles;
|
|
|
+
|
|
|
+
|
|
|
+ * @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) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getBody() {
|
|
|
+ $this->finalizeBody();
|
|
|
+ $body = new Element('body', NULL, $this->body);
|
|
|
+ $ret = (string) $body;
|
|
|
+ return $ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function setBody($fragment) {
|
|
|
+ $this->body[] = $fragment;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function finalizeHead() {
|
|
|
+ if (isset($this->finalized['head'])) {
|
|
|
+ throw new Exception('Attempt to finalize already finalized head');
|
|
|
+ }
|
|
|
+ $cssLink = new Element('link', array(
|
|
|
+ 'rel' => 'stylesheet',
|
|
|
+ 'type' => 'text/css',
|
|
|
+ 'href' => $this->context->getPath() .'/memcache_ui.css',
|
|
|
+ ));
|
|
|
+ $this->setHead($cssLink);
|
|
|
+
|
|
|
+ $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 render() {
|
|
|
+ $html = new Element('html', NULL, $this->getHead() . $this->getBody());
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Router {
|
|
|
+ function getInfo() {
|
|
|
+ $ret = array(
|
|
|
+ '^server/(\w+)/flush/(\w+)$' => array(
|
|
|
+ 'page class' => 'page_server_flush',
|
|
|
+ 'page arguments' => array('$1', '$2'),
|
|
|
+ 'title callback' => 'title_server',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+ '^server/(\w+)/flush$' => array(
|
|
|
+ 'page class' => 'page_server_flush',
|
|
|
+ 'page arguments' => array('$1'),
|
|
|
+ 'title callback' => 'title_server',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+
|
|
|
+ '^server/(\w+)/slab/(\d+)$' => array(
|
|
|
+ 'page class' => 'page_slab_view',
|
|
|
+ 'page arguments' => array('$1', '$2'),
|
|
|
+ 'title callback' => 'title_slab',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+
|
|
|
+ '^server/(\w+)/key/(.+)/delete/(\w+)$' => array(
|
|
|
+ 'page class' => 'page_variable_delete_confirm',
|
|
|
+ 'page arguments' => array('$1', '$2', '$3'),
|
|
|
+ 'title callback' => 'title_variable',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+ '^server/(\w+)/key/(.+)/delete$' => array(
|
|
|
+ 'page class' => 'page_variable_delete_form',
|
|
|
+ 'page arguments' => array('$1', '$2'),
|
|
|
+ 'title callback' => 'title_variable',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+
|
|
|
+ '^server/(\w+)/key/(.+)/dump$' => array(
|
|
|
+ 'page class' => 'page_variable_view_php',
|
|
|
+ 'page arguments' => array('$1', '$2'),
|
|
|
+ 'title callback' => 'title_variable',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+ '^server/(\w+)/key/(.+)/php$' => array(
|
|
|
+ 'page class' => 'page_variable_view_php',
|
|
|
+ 'page arguments' => array('$1', '$2'),
|
|
|
+ 'title callback' => 'title_variable',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+ '^server/(\w+)/key/(.+)$' => array(
|
|
|
+ 'page class' => 'page_variable_view_text',
|
|
|
+ 'page arguments' => array('$1', '$2'),
|
|
|
+ 'title callback' => 'title_variable',
|
|
|
+ 'title arguments' => 'page arguments',
|
|
|
+ ),
|
|
|
+
|
|
|
+ '^slabs$' => array(
|
|
|
+ 'page class' => 'page_slab_overview',
|
|
|
+ 'title' => 'Slabs per server',
|
|
|
+ ),
|
|
|
+
|
|
|
+ '^$' => array(
|
|
|
+ 'page class' => 'Page_Main',
|
|
|
+ 'title' => 'Overview',
|
|
|
+ ),
|
|
|
+ );
|
|
|
+
|
|
|
+ return $ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ function getRoute() {
|
|
|
+ $found = FALSE;
|
|
|
+ $path = $this->context->getPath();
|
|
|
+
|
|
|
+ $matches = array();
|
|
|
+ foreach ($this->getInfo() as $regex => $info) {
|
|
|
+ $regex = "@$regex@";
|
|
|
+ $count = preg_match($regex, $path, $matches);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if ($count) {
|
|
|
+ $found = TRUE;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($found) {
|
|
|
+
|
|
|
+
|
|
|
+ $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;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ $router = new Router($context);
|
|
|
+ $item = $router->getRoute();
|
|
|
+ $page = new $item['page class']($context, $item);
|
|
|
+
|
|
|
+ echo $page->render();
|
|
|
+}
|
|
|
+
|
|
|
+try {
|
|
|
+ main();
|
|
|
+}
|
|
|
+catch (Exception $e) {
|
|
|
+ echo '<pre>';
|
|
|
+ echo $e->getMessage() . PHP_EOL;
|
|
|
+ echo $e->getTraceAsString();
|
|
|
+ echo "</pre>";
|
|
|
+}
|