xref: /plugin/strata/action.php (revision 0847ebd29a490ea4bc8c536bb9f6dda8b6bbaa1a)
15153720fSfkaag71<?php
25153720fSfkaag71/**
35153720fSfkaag71 * DokuWiki Plugin strata (Action Component)
45153720fSfkaag71 *
55153720fSfkaag71 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
65153720fSfkaag71 * @author  Brend Wanders <b.wanders@utwente.nl>
75153720fSfkaag71 */
85153720fSfkaag71
95153720fSfkaag71// must be run within Dokuwiki
105153720fSfkaag71if (!defined('DOKU_INC')) die('Meh.');
115153720fSfkaag71
125153720fSfkaag71/**
135153720fSfkaag71 * This action component exists to allow the definition of
145153720fSfkaag71 * the type autoloader.
155153720fSfkaag71 */
165153720fSfkaag71class action_plugin_strata extends DokuWiki_Action_Plugin {
175153720fSfkaag71
185153720fSfkaag71    /**
195153720fSfkaag71     * Register function called by DokuWiki to allow us
205153720fSfkaag71     * to register events we're interested in.
215153720fSfkaag71     *
225153720fSfkaag71     * @param controller object the controller to register with
235153720fSfkaag71     */
245153720fSfkaag71    public function register(Doku_Event_Handler $controller) {
255153720fSfkaag71        $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, '_io_page_write');
265153720fSfkaag71        $controller->register_hook('PARSER_METADATA_RENDER', 'BEFORE', $this, '_parser_metadata_render_before');
275153720fSfkaag71        $controller->register_hook('STRATA_PREVIEW_METADATA_RENDER', 'BEFORE', $this, '_parser_metadata_render_before');
285153720fSfkaag71        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, '_preview_before');
295153720fSfkaag71        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, '_preview_after');
305153720fSfkaag71
315153720fSfkaag71        $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, '_parser_metadata_render_after');
325153720fSfkaag71        $controller->register_hook('STRATA_PREVIEW_METADATA_RENDER', 'AFTER', $this, '_parser_metadata_render_after');
335153720fSfkaag71    }
345153720fSfkaag71
355153720fSfkaag71
365153720fSfkaag71    /**
375153720fSfkaag71     * Triggers before preview xhtml render,
385153720fSfkaag71     * allows plugins to metadata render on the preview.
395153720fSfkaag71     */
405153720fSfkaag71    public function _preview_before(&$event, $param) {
415153720fSfkaag71        global $ACT;
425153720fSfkaag71        global $TEXT;
435153720fSfkaag71        global $SUF;
445153720fSfkaag71        global $PRE;
455153720fSfkaag71        global $ID;
465153720fSfkaag71        global $METADATA_RENDERERS;
475153720fSfkaag71
485153720fSfkaag71        if($ACT == 'preview') {
495153720fSfkaag71            $triples =& plugin_load('helper', 'strata_triples');
505153720fSfkaag71            $triples->beginPreview();
515153720fSfkaag71
525153720fSfkaag71            $text = $PRE.$TEXT.$SUF;
535153720fSfkaag71            $orig = p_read_metadata($ID);
545153720fSfkaag71
555153720fSfkaag71            // store the original metadata in the global $METADATA_RENDERERS so p_set_metadata can use it
565153720fSfkaag71            $METADATA_RENDERERS[$ID] =& $orig;
575153720fSfkaag71
585153720fSfkaag71            // add an extra key for the event - to tell event handlers the page whose metadata this is
595153720fSfkaag71            $orig['page'] = $ID;
605153720fSfkaag71            $evt = new Doku_Event('STRATA_PREVIEW_METADATA_RENDER', $orig);
615153720fSfkaag71            if ($evt->advise_before()) {
625153720fSfkaag71                // get instructions
635153720fSfkaag71                $instructions = p_get_instructions($text);
645153720fSfkaag71                if(is_null($instructions)){
655153720fSfkaag71                    unset($METADATA_RENDERERS[$ID]);
665153720fSfkaag71                    return null; // something went wrong with the instructions
675153720fSfkaag71                }
685153720fSfkaag71
695153720fSfkaag71                // set up the renderer
705153720fSfkaag71                $renderer = new renderer_plugin_strata();
715153720fSfkaag71                $renderer->meta =& $orig['current'];
725153720fSfkaag71                $renderer->persistent =& $orig['persistent'];
735153720fSfkaag71
745153720fSfkaag71                // loop through the instructions
755153720fSfkaag71                foreach ($instructions as $instruction){
765153720fSfkaag71                    // execute the callback against the renderer
775153720fSfkaag71                    call_user_func_array(array(&$renderer, $instruction[0]), (array) $instruction[1]);
785153720fSfkaag71                }
795153720fSfkaag71
805153720fSfkaag71                $evt->result = array('current'=>&$renderer->meta,'persistent'=>&$renderer->persistent);
815153720fSfkaag71            }
825153720fSfkaag71            $evt->advise_after();
835153720fSfkaag71
845153720fSfkaag71            // clean up
85*0847ebd2SFKaag            unset($METADATA_RENDERERS[$ID]);
865153720fSfkaag71        }
875153720fSfkaag71    }
885153720fSfkaag71
895153720fSfkaag71
905153720fSfkaag71    public function _preview_after(&$event, $param) {
915153720fSfkaag71        global $ACT;
925153720fSfkaag71
935153720fSfkaag71        if($ACT == 'preview') {
945153720fSfkaag71            $triples =& plugin_load('helper', 'strata_triples');
955153720fSfkaag71            $triples->endPreview();
965153720fSfkaag71        }
975153720fSfkaag71    }
985153720fSfkaag71
995153720fSfkaag71    /**
1005153720fSfkaag71     * Triggered whenever a page is written. We need to handle
1015153720fSfkaag71     * this event because metadata is not rendered if a page is removed.
1025153720fSfkaag71     */
1035153720fSfkaag71    public function _io_page_write(&$event, $param) {
1045153720fSfkaag71        // only remove triples if page is a new revision, or if it is removed
1055153720fSfkaag71        if($event->data[3] == false || $event->data[0][1] == '') {
1065153720fSfkaag71            $id = ltrim($event->data[1].':'.$event->data[2],':');
1075153720fSfkaag71            $this->_purge_data($id);
1085153720fSfkaag71        }
1095153720fSfkaag71    }
1105153720fSfkaag71
1115153720fSfkaag71    /**
1125153720fSfkaag71     * Triggered before metadata is going to be rendered. We
1135153720fSfkaag71     * remove triples previously generated by the page that is going to
1145153720fSfkaag71     * be rendered so we don't get duplicate entries.
1155153720fSfkaag71     */
1165153720fSfkaag71    public function _parser_metadata_render_before(&$event, $param) {
1175153720fSfkaag71        $this->_purge_data($event->data['page']);
1185153720fSfkaag71    }
1195153720fSfkaag71
1205153720fSfkaag71    /**
1215153720fSfkaag71     * Triggered after metadata has been rendered.
1225153720fSfkaag71     * We check the fixTitle flag, and if it is present, we
1235153720fSfkaag71     * add the entry title.
1245153720fSfkaag71     */
1255153720fSfkaag71    public function _parser_metadata_render_after(&$event, $param) {
1265153720fSfkaag71        $id = $event->data['page'];
1275153720fSfkaag71
1285153720fSfkaag71        $current =& $event->data['current'];
1295153720fSfkaag71
1305153720fSfkaag71        if(isset($current['strata']['fixTitle']) && $current['strata']['fixTitle']) {
1315153720fSfkaag71            // get helpers
1325153720fSfkaag71            $triples =& plugin_load('helper', 'strata_triples');
1335153720fSfkaag71            $util =& plugin_load('helper', 'strata_util');
1345153720fSfkaag71
135*0847ebd2SFKaag            $title = $current['title'] ?? null;
1365153720fSfkaag71            if(!$title) {
1375153720fSfkaag71                $title = noNS($id);
1385153720fSfkaag71            }
1395153720fSfkaag71
1405153720fSfkaag71            $title = $util->loadType('text')->normalize($title,'');
1415153720fSfkaag71
1425153720fSfkaag71            $triples->addTriple($id, $util->getTitleKey(), $title, $id);
1435153720fSfkaag71        }
1445153720fSfkaag71    }
1455153720fSfkaag71
1465153720fSfkaag71    /**
1475153720fSfkaag71     * Purges the data for a single page id.
1485153720fSfkaag71     *
1495153720fSfkaag71     * @param id string the page that needs to be purged
1505153720fSfkaag71     */
1515153720fSfkaag71    private function _purge_data($id) {
1525153720fSfkaag71        // get triples helper
1535153720fSfkaag71        $triples =& plugin_load('helper', 'strata_triples');
1545153720fSfkaag71
1555153720fSfkaag71        // remove all triples defined in this graph
1565153720fSfkaag71        $triples->removeTriples(null,null,null,$id);
1575153720fSfkaag71    }
1585153720fSfkaag71}
1595153720fSfkaag71
1605153720fSfkaag71/**
1615153720fSfkaag71 * Strata 'pluggable' autoloader. This function is responsible
1625153720fSfkaag71 * for autoloading classes that should be pluggable by external
1635153720fSfkaag71 * plugins.
1645153720fSfkaag71 *
1655153720fSfkaag71 * @param fullname string the name of the class to load
1665153720fSfkaag71 */
1675153720fSfkaag71function plugin_strata_autoload($fullname) {
1685153720fSfkaag71    static $classes = null;
1695153720fSfkaag71    if(is_null($classes)) $classes = array(
1705153720fSfkaag71        'strata_exception'         => DOKU_PLUGIN.'strata/lib/strata_exception.php',
1715153720fSfkaag71        'strata_querytree_visitor' => DOKU_PLUGIN.'strata/lib/strata_querytree_visitor.php',
1725153720fSfkaag71        'plugin_strata_type'       => DOKU_PLUGIN.'strata/lib/strata_type.php',
1735153720fSfkaag71        'plugin_strata_aggregate'  => DOKU_PLUGIN.'strata/lib/strata_aggregate.php',
1745153720fSfkaag71   );
1755153720fSfkaag71
1765153720fSfkaag71    if(isset($classes[$fullname])) {
1775153720fSfkaag71        require_once($classes[$fullname]);
1785153720fSfkaag71        return;
1795153720fSfkaag71    }
1805153720fSfkaag71
1815153720fSfkaag71    // only load matching components
1825153720fSfkaag71    if(preg_match('/^plugin_strata_(type|aggregate)_(.*)$/',$fullname, $matches)) {
1835153720fSfkaag71        // use descriptive names
1845153720fSfkaag71        list(,$kind,$name) = $matches;
1855153720fSfkaag71
1865153720fSfkaag71        // glob to find the required file
1875153720fSfkaag71        $filenames = glob(DOKU_PLUGIN."*/{$kind}s/{$name}.php");
1885153720fSfkaag71        if($filenames === false || count($filenames) == 0) {
1895153720fSfkaag71            // if we have no file, fake an implementation
1905153720fSfkaag71            eval("class $fullname extends plugin_strata_{$kind} { };");
1915153720fSfkaag71        } else {
1925153720fSfkaag71            // include the file
1935153720fSfkaag71            require_once $filenames[0];
1945153720fSfkaag71            // If the class still does not exist, the required file does not define the class, so we fall back
1955153720fSfkaag71            // to the default
1965153720fSfkaag71            if(!class_exists($fullname)) {
1975153720fSfkaag71                eval("class $fullname extends plugin_strata_{$kind} { };");
1985153720fSfkaag71            }
1995153720fSfkaag71        }
2005153720fSfkaag71
2015153720fSfkaag71        return;
2025153720fSfkaag71    }
2035153720fSfkaag71}
2045153720fSfkaag71
2055153720fSfkaag71// register autoloader with SPL loader stack
2065153720fSfkaag71spl_autoload_register('plugin_strata_autoload');
207