1<?php 2/** 3 * DokuWiki Plugin strata (Helper Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Brend Wanders <b.wanders@utwente.nl> 7 */ 8 9// must be run within Dokuwiki 10if (!defined('DOKU_INC')) die('Meh.'); 11 12/** 13 * This utility helper offers methods for configuration handling 14 * type and aggregator loading, and rendering. 15 */ 16class helper_plugin_strata_util extends DokuWiki_Plugin { 17 /** 18 * Constructor. 19 */ 20 function __construct() { 21 // we can't depend on the syntax helper due to recursive dependencies. 22 // Since we really only need the pattern helper anyway, we grab it 23 // directly. (This isn't the nicest solution -- but depending on 24 // a helper that depends on us isn't either) 25 $this->patterns = helper_plugin_strata_syntax::$patterns; 26 } 27 28 function getMethods() { 29 $result = array(); 30 return $result; 31 } 32 33 /** 34 * The loaded types and aggregates cache. 35 */ 36 var $loaded = array(); 37 38 /** 39 * Loads something. 40 */ 41 private function _load($kind, $name, $default) { 42 // handle null value 43 if($name == null) { 44 $name = $default; 45 } 46 47 // use cache if possible 48 if(empty($this->loaded[$kind][$name])) { 49 $class = "plugin_strata_${kind}_${name}"; 50 $this->loaded[$kind][$name] = new $class(); 51 } 52 53 return $this->loaded[$kind][$name]; 54 55 } 56 57 /** 58 * Loads a type. 59 */ 60 function loadType($type) { 61 list($default,) = $this->getDefaultType(); 62 return $this->_load('type', $type, $default); 63 } 64 65 /** 66 * Loads an aggregate. 67 */ 68 function loadAggregate($aggregate) { 69 return $this->_load('aggregate', $aggregate, 'all'); 70 } 71 72 /** 73 * Parses a 'name(hint)' pattern. 74 * 75 * @param string string the text to parse 76 * @return an array with a name and hint, or false 77 */ 78 function parseType($string) { 79 $p = $this->patterns; 80 if(preg_match("/^({$p->type})?$/", $string, $match)) { 81 list($type, $hint) = $p->type($match[1]); 82 return array($type, $hint); 83 } else { 84 return false; 85 } 86 } 87 88 /** 89 * The parsed configuration types. 90 */ 91 var $configTypes = array(); 92 93 /** 94 * Parses a type from configuration. 95 */ 96 function _parseConfigType($key) { 97 // lazy parse 98 if(empty($this->configTypes[$key])) { 99 // parse 100 $this->configTypes[$key] = $this->parseType($this->getConf($key)); 101 102 // handle failed parse 103 if($this->configTypes[$key] === false) { 104 msg(sprintf($this->getLang('error_types_config'), $key), -1); 105 $this->configTypes[$key] = array( 106 'text', 107 null 108 ); 109 } 110 } 111 112 return $this->configTypes[$key]; 113 } 114 115 /** 116 * Returns the default type. 117 */ 118 function getDefaultType() { 119 return $this->_parseConfigType('default_type'); 120 } 121 122 /** 123 * Returns the type used for predicates. 124 */ 125 function getPredicateType() { 126 return $this->_parseConfigType('predicate_type'); 127 } 128 129 /** 130 * Returns the normalized value for the 'is a' predicate. 131 */ 132 function getIsaKey($normalized=true) { 133 $result = $this->getConf('isa_key'); 134 if($normalized) $result = $this->normalizePredicate($result); 135 return $result; 136 } 137 138 /** 139 * Returns the normalized valued for the 'title' predicate. 140 */ 141 function getTitleKey($normalized=true) { 142 $result = $this->getConf('title_key'); 143 if($normalized) $result = $this->normalizePredicate($result); 144 return $result; 145 } 146 147 /** 148 * Normalizes a predicate. 149 * 150 * @param p the string to normalize 151 */ 152 function normalizePredicate($p) { 153 list($type, $hint) = $this->getPredicateType(); 154 return $this->loadType($type)->normalize($p, $hint); 155 } 156 157 /** 158 * Renders a predicate as a full field. 159 * 160 * @param mode the rendering mode 161 * @param R the renderer 162 * @param T the triples helper 163 * @param p the predicate 164 */ 165 function renderPredicate($mode, &$R, &$T, $p) { 166 list($typename, $hint) = $this->getPredicateType(); 167 $this->renderField($mode, $R, $T, $p, $typename, $hint); 168 } 169 170 /** 171 * Renders a single value. If the mode is xhtml, this also surrounds the value with 172 * the necessary <span> tag to allow styling of types and to ease extraction of values 173 * with javascript. 174 * 175 * @param mode the rendering mode 176 * @param R the renderer 177 * @param T the triples helper 178 * @param value the value to render 179 * @param typename name of the type 180 * @param hint optional type hint 181 * @param type optional type object, if omitted the typename will be used to get the type 182 */ 183 function renderValue($mode, &$R, &$T, $value, $typename, $hint=null, &$type=null) { 184 // load type if needed 185 if($type == null) $type = $this->loadType($typename); 186 187 // render value 188 $this->openValue($mode, $R, $typename); 189 $type->render($mode, $R, $T, $value, $hint); 190 $this->closeValue($mode, $R); 191 } 192 193 /** 194 * Renders multiple values. If the mode is xhtml, this also surrounds the field with 195 * the necessary <span> tag to allow styling of fields and to ease extraction of values 196 * with javascript. 197 * 198 * @param mode the rendering mode 199 * @param R the renderer 200 * @param T the triples helper 201 * @param values a list of values to render, or optionally a single value 202 * @param typename the name of the type 203 * @param hint optional type hint 204 * @param type optional type object, if omitted typename will be used 205 * @param field the field name of this field 206 * @param separator the seperation string to use in-between values 207 */ 208 function renderField($mode, &$R, &$T, $values, $typename, $hint=null, &$type=null, $field=null, $separator=', ') { 209 // arrayfication of values (if a single value is given) 210 if(!is_array($values)) $values = array($values); 211 212 // load type if needed 213 if($type == null) $type = $this->loadType($typename); 214 215 // render values 216 $firstValue = true; 217 $this->openField($mode, $R, $field); 218 foreach($values as $value) { 219 if(!$firstValue) $R->cdata($separator); 220 $this->renderValue($mode, $R, $T, $value, $typename, $hint, $type); 221 $firstValue = false; 222 } 223 $this->closeField($mode, $R); 224 } 225 226 function openField($mode, &$R, $field=null) { 227 if($mode == 'xhtml') $R->doc .= '<span class="strata-field" '.(!empty($field)?'data-field="'.hsc($field).'"':'').'>'; 228 } 229 230 function closeField($mode, &$R) { 231 if($mode == 'xhtml') $R->doc .= '</span>'; 232 } 233 234 function openValue($mode, &$R, $typename) { 235 if($mode == 'xhtml') $R->doc .= '<span class="strata-value strata-type-'.$typename.'">'; 236 } 237 238 function closeValue($mode, &$R) { 239 if($mode == 'xhtml') $R->doc .= '</span>'; 240 } 241 242 function renderCaptions($mode, &$R, $fields) { 243 if($mode == 'xhtml') { 244 foreach($fields as $f) { 245 $R->doc .= '<div class="strata-caption hidden" data-field="'.hsc($f['variable']).'">'; 246 $R->cdata($f['caption']); 247 $R->doc .= '</div>'.DOKU_LF; 248 } 249 } 250 } 251} 252