xref: /plugin/strata/helper/util.php (revision 5153720fcc1dd2b6e63035d45f7c2bc32e429371)
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