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