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 10use dokuwiki\Extension\ActionPlugin; 11use dokuwiki\Extension\Event; 12use dokuwiki\Extension\EventHandler; 13use dokuwiki\plugin\struct\meta\Schema; 14 15/** 16 * Class action_plugin_struct_output 17 * 18 * This action component handles the automatic output of all schema data that has been assigned 19 * to the current page by appending the appropriate instruction to the handler calls. 20 * 21 * The real output creation is done within the syntax component 22 * @see syntax_plugin_struct_output 23 */ 24class action_plugin_struct_output extends ActionPlugin 25{ 26 protected const DW2PDF_PLACEHOLDER_PREFIX = 'PLUGIN_STRUCT'; 27 28 /** 29 * Registers a callback function for a given event 30 * 31 * @param EventHandler $controller DokuWiki's event controller object 32 * @return void 33 */ 34 public function register(EventHandler $controller) 35 { 36 $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handleOutput'); 37 $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'BEFORE', $this, 'replaceDw2pdf'); 38 $controller->register_hook('PLUGIN_DW2PDF_REPLACE', 'AFTER', $this, 'cleanupDw2pdf'); 39 } 40 41 /** 42 * Appends the instruction to render our syntax output component to each page 43 * after the first found headline or the very begining if no headline was found 44 * 45 * @param Event $event 46 * @param $param 47 */ 48 public function handleOutput(Event $event, $param) 49 { 50 global $ID; 51 if (!$ID) return; 52 if (!page_exists($ID)) return; 53 54 $pos = 0; 55 $ins = -1; 56 57 // display struct data at the bottom? 58 if ($this->getConf('bottomoutput')) { 59 $ins = count($event->data->calls); 60 } elseif (!$this->getConf('topoutput')) { 61 foreach ($event->data->calls as $num => $call) { 62 // try to find the first header 63 if ($call[0] == 'header') { 64 $pos = $call[2]; 65 $ins = $num; 66 break; 67 } 68 69 // abort when after we looked at the first 150 bytes 70 if (isset($call[3]) && $call[3] > 150) { 71 break; 72 } 73 } 74 } 75 76 // insert our own call after the found position 77 array_splice( 78 $event->data->calls, 79 $ins + 1, 80 0, 81 [ 82 [ 83 'plugin', 84 [ 85 'struct_output', ['pos' => $pos], DOKU_LEXER_SPECIAL, '' 86 ], 87 $pos 88 ] 89 ] 90 ); 91 } 92 93 /** 94 * If the page has a schema assigned, add its struct data 95 * to dw2pdf's template replacements 96 * 97 * @param Event $event 98 * @param $param 99 */ 100 public function replaceDw2pdf(Event $event, $param) 101 { 102 if (!$event->data['id'] || !page_exists($event->data['id'])) return; 103 104 global $REV; 105 $rev = $REV ?: time(); 106 107 /** @var helper_plugin_struct $helper */ 108 $helper = plugin_load('helper', 'struct'); 109 $data = $helper->getData($event->data['id'], null, $rev); 110 111 if (!$data) return; 112 113 foreach ($data as $schema => $fields) { 114 $schemaObject = new Schema($schema); 115 foreach ($fields as $field => $value) { 116 // format fields 117 $col = $schemaObject->findColumn($field); 118 if (is_a($col->getType(), '\dokuwiki\plugin\struct\types\Date')) { 119 $format = $col->getType()->getConfig()['format']; 120 $value = date($format, strtotime($value)); 121 } 122 123 $placeholder = sprintf('@%s_%s_%s@', self::DW2PDF_PLACEHOLDER_PREFIX, $schema, $field); 124 $event->data['replace'][$placeholder] = is_array($value) ? implode(', ', $value) : $value; 125 } 126 } 127 } 128 129 /** 130 * Remove struct placeholders still present after replacement. 131 * Requested data was not found. 132 * 133 * @param Event $event 134 * @param $param 135 */ 136 public function cleanupDw2pdf(Event $event, $param) 137 { 138 $pattern = '~@' . self::DW2PDF_PLACEHOLDER_PREFIX . '_[^@]+?@~'; 139 $event->data['content'] = preg_replace($pattern, '', $event->data['content']); 140 } 141} 142 143// vim:ts=4:sw=4:et: 144