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