xref: /plugin/include/syntax/include.php (revision 71ec110157357319e914a434bc535b5b0c2fb3bd)
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