1<?php 2/** 3 * Include Plugin: displays a wiki page within another 4 * Usage: 5 * {{page>page}} for "page" in same namespace 6 * {{page>:page}} for "page" in top namespace 7 * {{page>namespace:page}} for "page" in namespace "namespace" 8 * {{page>.namespace:page}} for "page" in subnamespace "namespace" 9 * {{page>page#section}} for a section of "page" 10 * 11 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 12 * @author Esther Brunner <wikidesign@gmail.com> 13 * @author Christopher Smith <chris@jalakai.co.uk> 14 * @author Gina Häußge, Michael Klier <dokuwiki@chimeric.de> 15 */ 16 17if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 18if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 19require_once(DOKU_PLUGIN.'syntax.php'); 20 21/** 22 * All DokuWiki plugins to extend the parser/rendering mechanism 23 * need to inherit from this class 24 */ 25class syntax_plugin_include_include extends DokuWiki_Syntax_Plugin { 26 27 function getInfo() { 28 return array( 29 'author' => 'Gina Häußge, Michael Klier, Esther Brunner', 30 'email' => 'dokuwiki@chimeric.de', 31 'date' => '2008-06-15', 32 'name' => 'Include Plugin', 33 'desc' => 'Displays a wiki page (or a section thereof) within another', 34 'url' => 'http://wiki.splitbrain.org/plugin:include', 35 ); 36 } 37 38 function getType() { return 'substition'; } 39 function getSort() { return 303; } 40 function getPType() { return 'block'; } 41 42 function connectTo($mode) { 43 $this->Lexer->addSpecialPattern("{{page>.+?}}", $mode, 'plugin_include_include'); 44 $this->Lexer->addSpecialPattern("{{section>.+?}}", $mode, 'plugin_include_include'); 45 } 46 47 function handle($match, $state, $pos, &$handler) { 48 49 $match = substr($match, 2, -2); // strip markup 50 list($match, $flags) = explode('&', $match, 2); 51 52 // break the pattern up into its constituent parts 53 list($include, $id, $section) = preg_split('/>|#/u', $match, 3); 54 return array($include, $id, cleanID($section), explode('&', $flags)); 55 } 56 57 function render($format, &$renderer, $data) { 58 global $ID; 59 60 list($type, $raw_id, $section, $flags) = $data; 61 62 $id = $this->_applyMacro($raw_id); 63 $nocache = ($id != $raw_id); 64 resolve_pageid(getNS($ID), $id, $exists); // resolve shortcuts 65 66 $include =& plugin_load('helper', 'include'); 67 $include->setMode($type); 68 $include->setFlags($flags); 69 70 if ($nocache) $renderer->info['cache'] = false; // prevent caching 71 if (AUTH_READ > auth_quickaclcheck($id)) return true; // check for permission 72 if (!$include->setPage(compact('type','id','section','exists'))) return false; 73 74 // initiate inclusion of external content for those renderer formats which require it 75 // - currently only 'xhtml' 76 if (in_array($format, array('xhtml'))) { 77 78 $ok = $this->_include($include, $format, $renderer, $type, $id, $section, $flags, $nocache); 79 80 } else if (in_array($format, array('odt'))) { 81 82 // current section level 83 $clevel = 0; 84 preg_match_all('|<text:h text:style-name="Heading_20_\d" text:outline-level="(\d)">|i', $renderer->doc, $matches, PREG_SET_ORDER); 85 $n = count($matches) - 1; 86 if ($n > -1) $clevel = $matches[$n][1]; 87 $include->setLevel($clevel); 88 89 // include the page now 90 $include->renderODT($renderer); 91 92 return true; 93 94 } else { 95 // carry out renderering for all other formats 96 $ok = $this->_no_include($include, $format, $renderer, $type, $id, $section, $flags, $nocache); 97 98 #global $debug; 99 #$debug[] = compact('id','raw_id','flg_macro','format'); 100 } 101 102 return false; 103 } 104 105 /* ---------- Util Functions ---------- */ 106 107 /** 108 * render process for renderer formats which do include external content 109 * 110 * @param $include obj include helper plugin 111 * @param $format string renderer format 112 * @param $renderer obj renderer 113 * @param $type string include type ('page' or 'section') 114 * @param $id string fully resolved wiki page id of included page 115 * @param $section string fragment identifier for page fragment to be included 116 * @param $flg_macro bool true if $id was modified by macro substitution 117 */ 118 function _include(&$include, $format, &$renderer, $type, $id, $section, $flags, $flg_macro) { 119 120 $file = wikiFN($id); 121 122 if ($format == 'xhtml') { 123 124 // current section level 125 $matches = array(); 126 preg_match_all('|<div class="level(\d)">|i', $renderer->doc, $matches, PREG_SET_ORDER); 127 $n = count($matches)-1; 128 $clevel = ($n > -1) ? $clevel = $matches[$n][1] : 0; 129 $include->setLevel($clevel); 130 131 // close current section 132 if ($clevel && ($type == 'section')) $renderer->doc .= '</div>'; 133 134 // include the page 135 $include->renderXHTML($renderer,$info); 136 137 // propagate any cache prevention from included pages into this page 138 if ($info['cache'] == false) $renderer->info['cache'] = false; 139 140 // resume current section 141 if ($clevel && ($type == 'section')) $renderer->doc .= '<div class="level'.$clevel.'">'; 142 143 return true; 144 145 } else { // other / unsupported format 146 } 147 148 return false; 149 } 150 151 /** 152 * render process for renderer formats which don't include external content 153 * 154 * @param $include obj include helper plugin 155 * @param $format string renderer format 156 * @param $renderer obj renderer 157 * @param $type string include type ('page' or 'section') 158 * @param $id string fully resolved wiki page id of included page 159 * @param $section string fragment identifier for page fragment to be included 160 * @param $flg_macro bool true if $id was modified by macro substitution 161 */ 162 function _no_include(&$include, $format, &$renderer, $type, $id, $section, $flags, $flg_macro) { 163 164 switch ($format) { 165 case 'metadata' : 166 if (!$flg_macro) { 167 $renderer->meta['relation']['haspart'][$id] = @file_exists(wikiFN($id)); 168 } 169 return true; 170 171 default : // unknown / unsupported renderer format 172 return false; 173 } 174 175 return false; 176 } 177 178 /** 179 * Makes user or date dependent includes possible 180 */ 181 function _applyMacro($id) { 182 global $INFO, $auth; 183 184 $user = $_SERVER['REMOTE_USER']; 185 $userdata = $auth->getUserData($user); 186 $group = $userdata['grps'][0]; 187 188 $replace = array( 189 '@USER@' => cleanID($user), 190 '@NAME@' => cleanID($INFO['userinfo']['name']), 191 '@GROUP@' => cleanID($group), 192 '@YEAR@' => date('Y'), 193 '@MONTH@' => date('m'), 194 '@DAY@' => date('d'), 195 ); 196 return str_replace(array_keys($replace), array_values($replace), $id); 197 } 198} 199// vim:ts=4:sw=4:et:enc=utf-8: 200