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