Major rework, lean more towards OO for clarity and extensibility.
authorjollytoad <jollytoad>
Wed, 9 Mar 2005 12:21:10 +0000 (12:21 +0000)
committerjollytoad <jollytoad>
Wed, 9 Mar 2005 12:21:10 +0000 (12:21 +0000)
libraries/decorator.inc.php

index 249763217bbe88773c19d6cdffb84a4cd9e04c38..c563e9a46e94c0addad5a004767d22c3a6207f48 100644 (file)
 <?php
-// $Id: decorator.inc.php,v 1.1.2.3 2005/03/08 12:35:04 jollytoad Exp $
-
-// Field decorator
-function &field($fieldname, $default = null) {
-       $dec = new Decorator();
-       $dec->f = $fieldname;
-       if ($default !== null) $dec->d = $default;
-       return $dec;
+// $Id: decorator.inc.php,v 1.1.2.4 2005/03/09 12:21:10 jollytoad Exp $
+
+// This group of functions and classes provides support for
+// resolving values in a lazy manner (ie, as and when required)
+// using the Decorator pattern.
+
+###TODO: Better documentation!!!
+
+// Construction functions:
+
+function field($fieldName, $default = null) {
+       return new FieldDecorator($fieldName, $default);
 }
 
-// Merge arrays decorator
-function &merge() {
-       $dec = new Decorator();
-       $dec->m = func_get_args();
-       return $dec;
+function merge() {
+       return new ArrayMergeDecorator(func_get_args());
 }
 
-function &noEscape($value) {
+function concat() {
+       return new ConcatDecorator(func_get_args());
+}
+
+function noEscape($value) {
        if (is_a($value, 'Decorator')) {
-               $value->noEscape = true;
+               $value->esc = false;
                return $value;
        }
-       $dec = new Decorator();
-       $dec->v = $value;
-       $dec->noEscape = true;
-       return $dec;
+       return new Decorator($value, false);
 }
 
-// Resolve a value
-function value(&$var, &$fields) {
+// Resolving functions:
+
+function value(&$var, &$fields, $esc = null) {
        if (is_a($var, 'Decorator')) {
-               if (isset($var->v)) return $var->v;
-               if (isset($var->f)) {
-                       return isset($fields[$var->f]) ? $fields[$var->f] : (isset($var->d) ? $var->d : null);
-               }
-               if (isset($var->m)) {
-                       foreach ($var->m as $dec) {
-                               $val = value($dec, $fields);
-                               if (!isset($accum))
-                                       $accum = $val;
-                               else
-                                       $accum = array_merge($accum, $val);
-                       }
-                       return $accum;
+               $val = $var->value($fields);
+               if (!$var->esc) $esc = null;
+       } else {
+               $val = $var;
+       }
+       if (is_string($val)) {
+               switch($esc) {
+                       case 'xml':
+                               ###TODO: proper escaping for XML
+                       case 'html':
+                               return htmlentities($val);
+                       case 'url':
+                               return urlencode($val);
                }
-       } else
-               return $var;
+       }
+       return $val;
 }
 
-// Resolve a value, and escape for an XML doc
 function value_xml(&$var, &$fields) {
-       if (is_a($var, 'Decorator') && isset($var->noEscape) && $var->noEscape === true)
-               return value($var, $fields);
-       else
-               ### TODO: Escape for XML's limited entities rather than for HTML
-               return htmlentities(value($var, $fields));
+       return value($var, $fields, 'xml');
 }
 
-// Resolve a value, and escape for a URL
-function value_url(&$var, &$fields) {
-       if (is_a($var, 'Decorator') && isset($var->noEscape) && $var->noEscape === true)
-               return value($var, $fields);
-       else
-               return urlencode(value($var, $fields));
-}
-
-// Resolve a value as an XML/HTML attribute
 function value_xml_attr($attr, &$var, &$fields) {
-       $value = value_xml($var, $fields);
-       if (!empty($value))
-               return " {$attr}=\"{$value}\"";
+       $val = value($var, $fields, 'xml');
+       if (!empty($val))
+               return " {$attr}=\"{$val}\"";
        else
                return '';
 }
 
+function value_url(&$var, &$fields) {
+       return value($var, $fields, 'url');
+}
+
+// Underlying classes:
+
 class Decorator
 {
-       function Decorator() {
+       var $esc = true;
+       
+       function Decorator($value, $esc = true) {
+               $this->v = $value;
+               $this->esc = $esc;
+       }
+       
+       function value() {
+               return $this->v;
+       }
+}
+
+class FieldDecorator extends Decorator
+{
+       function FieldDecorator($fieldName, $default = null) {
+               $this->f = $fieldName;
+               if ($default !== null) $this->d = $default;
+       }
+       
+       function value($fields) {
+               return isset($fields[$this->f]) ? $fields[$this->f] : (isset($this->d) ? $this->d : null);
+       }
+}
+
+class ArrayMergeDecorator extends Decorator
+{
+       function ArrayMergeDecorator($arrays) {
+               $this->m = $arrays;
+       }
+       
+       function value($fields) {
+               $accum = array();
+               foreach($this->m as $var) {
+                       $accum = array_merge($accum, value($var, $fields));
+               }
+               return $accum;
        }
 }
 
+class ConcatDecorator extends Decorator
+{
+       function ConcatDecorator($values) {
+               $this->c = $values;
+       }
+       
+       function value($fields) {
+               $accum = '';
+               foreach($this->c as $var) {
+                       $accum .= value($var, $fields);
+               }
+               return $accum;
+       }
+}
 ?>