1*5153720fSfkaag71<?php 2*5153720fSfkaag71/** 3*5153720fSfkaag71 * DokuWiki Plugin strata (Action 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 action component exists to allow the definition of 14*5153720fSfkaag71 * the type autoloader. 15*5153720fSfkaag71 */ 16*5153720fSfkaag71class action_plugin_strata extends DokuWiki_Action_Plugin { 17*5153720fSfkaag71 18*5153720fSfkaag71 /** 19*5153720fSfkaag71 * Register function called by DokuWiki to allow us 20*5153720fSfkaag71 * to register events we're interested in. 21*5153720fSfkaag71 * 22*5153720fSfkaag71 * @param controller object the controller to register with 23*5153720fSfkaag71 */ 24*5153720fSfkaag71 public function register(Doku_Event_Handler $controller) { 25*5153720fSfkaag71 $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, '_io_page_write'); 26*5153720fSfkaag71 $controller->register_hook('PARSER_METADATA_RENDER', 'BEFORE', $this, '_parser_metadata_render_before'); 27*5153720fSfkaag71 $controller->register_hook('STRATA_PREVIEW_METADATA_RENDER', 'BEFORE', $this, '_parser_metadata_render_before'); 28*5153720fSfkaag71 $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, '_preview_before'); 29*5153720fSfkaag71 $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, '_preview_after'); 30*5153720fSfkaag71 31*5153720fSfkaag71 $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, '_parser_metadata_render_after'); 32*5153720fSfkaag71 $controller->register_hook('STRATA_PREVIEW_METADATA_RENDER', 'AFTER', $this, '_parser_metadata_render_after'); 33*5153720fSfkaag71 } 34*5153720fSfkaag71 35*5153720fSfkaag71 36*5153720fSfkaag71 /** 37*5153720fSfkaag71 * Triggers before preview xhtml render, 38*5153720fSfkaag71 * allows plugins to metadata render on the preview. 39*5153720fSfkaag71 */ 40*5153720fSfkaag71 public function _preview_before(&$event, $param) { 41*5153720fSfkaag71 global $ACT; 42*5153720fSfkaag71 global $TEXT; 43*5153720fSfkaag71 global $SUF; 44*5153720fSfkaag71 global $PRE; 45*5153720fSfkaag71 global $ID; 46*5153720fSfkaag71 global $METADATA_RENDERERS; 47*5153720fSfkaag71 48*5153720fSfkaag71 if($ACT == 'preview') { 49*5153720fSfkaag71 $triples =& plugin_load('helper', 'strata_triples'); 50*5153720fSfkaag71 $triples->beginPreview(); 51*5153720fSfkaag71 52*5153720fSfkaag71 $text = $PRE.$TEXT.$SUF; 53*5153720fSfkaag71 $orig = p_read_metadata($ID); 54*5153720fSfkaag71 55*5153720fSfkaag71 // store the original metadata in the global $METADATA_RENDERERS so p_set_metadata can use it 56*5153720fSfkaag71 $METADATA_RENDERERS[$ID] =& $orig; 57*5153720fSfkaag71 58*5153720fSfkaag71 // add an extra key for the event - to tell event handlers the page whose metadata this is 59*5153720fSfkaag71 $orig['page'] = $ID; 60*5153720fSfkaag71 $evt = new Doku_Event('STRATA_PREVIEW_METADATA_RENDER', $orig); 61*5153720fSfkaag71 if ($evt->advise_before()) { 62*5153720fSfkaag71 // get instructions 63*5153720fSfkaag71 $instructions = p_get_instructions($text); 64*5153720fSfkaag71 if(is_null($instructions)){ 65*5153720fSfkaag71 unset($METADATA_RENDERERS[$ID]); 66*5153720fSfkaag71 return null; // something went wrong with the instructions 67*5153720fSfkaag71 } 68*5153720fSfkaag71 69*5153720fSfkaag71 // set up the renderer 70*5153720fSfkaag71 $renderer = new renderer_plugin_strata(); 71*5153720fSfkaag71 $renderer->meta =& $orig['current']; 72*5153720fSfkaag71 $renderer->persistent =& $orig['persistent']; 73*5153720fSfkaag71 74*5153720fSfkaag71 // loop through the instructions 75*5153720fSfkaag71 foreach ($instructions as $instruction){ 76*5153720fSfkaag71 // execute the callback against the renderer 77*5153720fSfkaag71 call_user_func_array(array(&$renderer, $instruction[0]), (array) $instruction[1]); 78*5153720fSfkaag71 } 79*5153720fSfkaag71 80*5153720fSfkaag71 $evt->result = array('current'=>&$renderer->meta,'persistent'=>&$renderer->persistent); 81*5153720fSfkaag71 } 82*5153720fSfkaag71 $evt->advise_after(); 83*5153720fSfkaag71 84*5153720fSfkaag71 // clean up 85*5153720fSfkaag71 unset($METADATA_RENDERERS[$id]); 86*5153720fSfkaag71 } 87*5153720fSfkaag71 } 88*5153720fSfkaag71 89*5153720fSfkaag71 90*5153720fSfkaag71 public function _preview_after(&$event, $param) { 91*5153720fSfkaag71 global $ACT; 92*5153720fSfkaag71 93*5153720fSfkaag71 if($ACT == 'preview') { 94*5153720fSfkaag71 $triples =& plugin_load('helper', 'strata_triples'); 95*5153720fSfkaag71 $triples->endPreview(); 96*5153720fSfkaag71 } 97*5153720fSfkaag71 } 98*5153720fSfkaag71 99*5153720fSfkaag71 /** 100*5153720fSfkaag71 * Triggered whenever a page is written. We need to handle 101*5153720fSfkaag71 * this event because metadata is not rendered if a page is removed. 102*5153720fSfkaag71 */ 103*5153720fSfkaag71 public function _io_page_write(&$event, $param) { 104*5153720fSfkaag71 // only remove triples if page is a new revision, or if it is removed 105*5153720fSfkaag71 if($event->data[3] == false || $event->data[0][1] == '') { 106*5153720fSfkaag71 $id = ltrim($event->data[1].':'.$event->data[2],':'); 107*5153720fSfkaag71 $this->_purge_data($id); 108*5153720fSfkaag71 } 109*5153720fSfkaag71 } 110*5153720fSfkaag71 111*5153720fSfkaag71 /** 112*5153720fSfkaag71 * Triggered before metadata is going to be rendered. We 113*5153720fSfkaag71 * remove triples previously generated by the page that is going to 114*5153720fSfkaag71 * be rendered so we don't get duplicate entries. 115*5153720fSfkaag71 */ 116*5153720fSfkaag71 public function _parser_metadata_render_before(&$event, $param) { 117*5153720fSfkaag71 $this->_purge_data($event->data['page']); 118*5153720fSfkaag71 } 119*5153720fSfkaag71 120*5153720fSfkaag71 /** 121*5153720fSfkaag71 * Triggered after metadata has been rendered. 122*5153720fSfkaag71 * We check the fixTitle flag, and if it is present, we 123*5153720fSfkaag71 * add the entry title. 124*5153720fSfkaag71 */ 125*5153720fSfkaag71 public function _parser_metadata_render_after(&$event, $param) { 126*5153720fSfkaag71 $id = $event->data['page']; 127*5153720fSfkaag71 128*5153720fSfkaag71 $current =& $event->data['current']; 129*5153720fSfkaag71 130*5153720fSfkaag71 if(isset($current['strata']['fixTitle']) && $current['strata']['fixTitle']) { 131*5153720fSfkaag71 // get helpers 132*5153720fSfkaag71 $triples =& plugin_load('helper', 'strata_triples'); 133*5153720fSfkaag71 $util =& plugin_load('helper', 'strata_util'); 134*5153720fSfkaag71 135*5153720fSfkaag71 $title = $current['title']; 136*5153720fSfkaag71 if(!$title) { 137*5153720fSfkaag71 $title = noNS($id); 138*5153720fSfkaag71 } 139*5153720fSfkaag71 140*5153720fSfkaag71 $title = $util->loadType('text')->normalize($title,''); 141*5153720fSfkaag71 142*5153720fSfkaag71 $triples->addTriple($id, $util->getTitleKey(), $title, $id); 143*5153720fSfkaag71 } 144*5153720fSfkaag71 } 145*5153720fSfkaag71 146*5153720fSfkaag71 /** 147*5153720fSfkaag71 * Purges the data for a single page id. 148*5153720fSfkaag71 * 149*5153720fSfkaag71 * @param id string the page that needs to be purged 150*5153720fSfkaag71 */ 151*5153720fSfkaag71 private function _purge_data($id) { 152*5153720fSfkaag71 // get triples helper 153*5153720fSfkaag71 $triples =& plugin_load('helper', 'strata_triples'); 154*5153720fSfkaag71 155*5153720fSfkaag71 // remove all triples defined in this graph 156*5153720fSfkaag71 $triples->removeTriples(null,null,null,$id); 157*5153720fSfkaag71 } 158*5153720fSfkaag71} 159*5153720fSfkaag71 160*5153720fSfkaag71/** 161*5153720fSfkaag71 * Strata 'pluggable' autoloader. This function is responsible 162*5153720fSfkaag71 * for autoloading classes that should be pluggable by external 163*5153720fSfkaag71 * plugins. 164*5153720fSfkaag71 * 165*5153720fSfkaag71 * @param fullname string the name of the class to load 166*5153720fSfkaag71 */ 167*5153720fSfkaag71function plugin_strata_autoload($fullname) { 168*5153720fSfkaag71 static $classes = null; 169*5153720fSfkaag71 if(is_null($classes)) $classes = array( 170*5153720fSfkaag71 'strata_exception' => DOKU_PLUGIN.'strata/lib/strata_exception.php', 171*5153720fSfkaag71 'strata_querytree_visitor' => DOKU_PLUGIN.'strata/lib/strata_querytree_visitor.php', 172*5153720fSfkaag71 'plugin_strata_type' => DOKU_PLUGIN.'strata/lib/strata_type.php', 173*5153720fSfkaag71 'plugin_strata_aggregate' => DOKU_PLUGIN.'strata/lib/strata_aggregate.php', 174*5153720fSfkaag71 ); 175*5153720fSfkaag71 176*5153720fSfkaag71 if(isset($classes[$fullname])) { 177*5153720fSfkaag71 require_once($classes[$fullname]); 178*5153720fSfkaag71 return; 179*5153720fSfkaag71 } 180*5153720fSfkaag71 181*5153720fSfkaag71 // only load matching components 182*5153720fSfkaag71 if(preg_match('/^plugin_strata_(type|aggregate)_(.*)$/',$fullname, $matches)) { 183*5153720fSfkaag71 // use descriptive names 184*5153720fSfkaag71 list(,$kind,$name) = $matches; 185*5153720fSfkaag71 186*5153720fSfkaag71 // glob to find the required file 187*5153720fSfkaag71 $filenames = glob(DOKU_PLUGIN."*/{$kind}s/{$name}.php"); 188*5153720fSfkaag71 if($filenames === false || count($filenames) == 0) { 189*5153720fSfkaag71 // if we have no file, fake an implementation 190*5153720fSfkaag71 eval("class $fullname extends plugin_strata_{$kind} { };"); 191*5153720fSfkaag71 } else { 192*5153720fSfkaag71 // include the file 193*5153720fSfkaag71 require_once $filenames[0]; 194*5153720fSfkaag71 // If the class still does not exist, the required file does not define the class, so we fall back 195*5153720fSfkaag71 // to the default 196*5153720fSfkaag71 if(!class_exists($fullname)) { 197*5153720fSfkaag71 eval("class $fullname extends plugin_strata_{$kind} { };"); 198*5153720fSfkaag71 } 199*5153720fSfkaag71 } 200*5153720fSfkaag71 201*5153720fSfkaag71 return; 202*5153720fSfkaag71 } 203*5153720fSfkaag71} 204*5153720fSfkaag71 205*5153720fSfkaag71// register autoloader with SPL loader stack 206*5153720fSfkaag71spl_autoload_register('plugin_strata_autoload'); 207