1<?php 2 3/** 4 * DokuWiki Plugin struct (Action Component) 5 * 6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7 * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 8 */ 9 10// must be run within Dokuwiki 11if (!defined('DOKU_INC')) die(); 12 13/** 14 * Class action_plugin_struct_output 15 * 16 * This action component handles the automatic output of all schema data that has been assigned 17 * to the current page by appending the appropriate instruction to the handler calls. 18 * 19 * The real output creation is done within the syntax component 20 * @see syntax_plugin_struct_output 21 */ 22class action_plugin_struct_output extends DokuWiki_Action_Plugin 23{ 24 25 const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT'; 26 27 /** 28 * Registers a callback function for a given event 29 * 30 * @param Doku_Event_Handler $controller DokuWiki's event controller object 31 * @return void 32 */ 33 public function register(Doku_Event_Handler $controller) 34 { 35 $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handle_output'); 36 $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replace_dw2pdf'); 37 $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanup_dw2pdf'); 38 } 39 40 /** 41 * Appends the instruction to render our syntax output component to each page 42 * after the first found headline or the very begining if no headline was found 43 * 44 * @param Doku_Event $event 45 * @param $param 46 */ 47 public function handle_output(Doku_Event $event, $param) 48 { 49 global $ID; 50 if (!page_exists($ID)) return; 51 $ins = -1; 52 $pos = 0; 53 foreach ($event->data->calls as $num => $call) { 54 // try to find the first header 55 if ($call[0] == 'header') { 56 $pos = $call[2]; 57 $ins = $num; 58 break; 59 } 60 61 // abort when after we looked at the first 150 bytes 62 if (isset($call[3]) && $call[3] > 150) { 63 break; 64 } 65 } 66 67 // insert our own call after the found position 68 array_splice( 69 $event->data->calls, 70 $ins + 1, 71 0, 72 array( 73 array( 74 'plugin', 75 array( 76 'struct_output', array('pos' => $pos), DOKU_LEXER_SPECIAL, '' 77 ), 78 $pos 79 ) 80 ) 81 ); 82 } 83 84 /** 85 * If the page has a schema assigned, add its struct data 86 * to dw2pdf's template replacements 87 * 88 * @param Doku_Event $event 89 * @param $param 90 */ 91 public function replace_dw2pdf(Doku_Event $event, $param) 92 { 93 if (!$event->data['id'] || !page_exists($event->data['id'])) return; 94 95 global $REV; 96 $rev = $REV ?: time(); 97 98 /** @var helper_plugin_struct $helper */ 99 $helper = plugin_load('helper', 'struct'); 100 $data = $helper->getData($event->data['id'], null, $rev); 101 102 if (!$data) return; 103 104 foreach ($data as $schema => $fields) { 105 foreach ($fields as $field => $value) { 106 $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field); 107 $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value; 108 } 109 } 110 } 111 112 /** 113 * Remove struct placeholders still present after replacement. 114 * Requested data was not found. 115 * 116 * @param Doku_Event $event 117 * @param $param 118 */ 119 public function cleanup_dw2pdf(Doku_Event $event, $param) 120 { 121 $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~'; 122 $event->data['content'] = preg_replace($pattern, '', $event->data['content']); 123 } 124} 125 126// vim:ts=4:sw=4:et: 127