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