xref: /plugin/include/syntax/include.php (revision efa360b92268d1c1bd6252190231a65193d015d1)
171ec1101SGina Haeussge<?php
271ec1101SGina Haeussge/**
371ec1101SGina Haeussge * Include Plugin: displays a wiki page within another
471ec1101SGina Haeussge * Usage:
571ec1101SGina Haeussge * {{page>page}} for "page" in same namespace
671ec1101SGina Haeussge * {{page>:page}} for "page" in top namespace
771ec1101SGina Haeussge * {{page>namespace:page}} for "page" in namespace "namespace"
871ec1101SGina Haeussge * {{page>.namespace:page}} for "page" in subnamespace "namespace"
971ec1101SGina Haeussge * {{page>page#section}} for a section of "page"
1071ec1101SGina Haeussge *
1171ec1101SGina Haeussge * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
1271ec1101SGina Haeussge * @author     Esther Brunner <wikidesign@gmail.com>
1371ec1101SGina Haeussge * @author     Christopher Smith <chris@jalakai.co.uk>
1471ec1101SGina Haeussge * @author     Gina Häußge, Michael Klier <dokuwiki@chimeric.de>
1571ec1101SGina Haeussge */
1671ec1101SGina Haeussge
1771ec1101SGina Haeussgeif(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
1871ec1101SGina Haeussgeif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
1971ec1101SGina Haeussgerequire_once(DOKU_PLUGIN.'syntax.php');
2071ec1101SGina Haeussge
2171ec1101SGina Haeussge/**
2271ec1101SGina Haeussge * All DokuWiki plugins to extend the parser/rendering mechanism
2371ec1101SGina Haeussge * need to inherit from this class
2471ec1101SGina Haeussge */
2571ec1101SGina Haeussgeclass syntax_plugin_include_include extends DokuWiki_Syntax_Plugin {
2671ec1101SGina Haeussge
2771ec1101SGina Haeussge    function getInfo() {
2871ec1101SGina Haeussge        return array(
2971ec1101SGina Haeussge                'author' => 'Gina Häußge, Michael Klier, Esther Brunner',
3071ec1101SGina Haeussge                'email'  => 'dokuwiki@chimeric.de',
314052f233SGina Haeussge                'date'   => @file_get_contents(DOKU_PLUGIN . 'blog/VERSION'),
3271ec1101SGina Haeussge                'name'   => 'Include Plugin',
3371ec1101SGina Haeussge                'desc'   => 'Displays a wiki page (or a section thereof) within another',
3471ec1101SGina Haeussge                'url'    => 'http://wiki.splitbrain.org/plugin:include',
3571ec1101SGina Haeussge                );
3671ec1101SGina Haeussge    }
3771ec1101SGina Haeussge
3871ec1101SGina Haeussge    function getType() { return 'substition'; }
3971ec1101SGina Haeussge    function getSort() { return 303; }
4071ec1101SGina Haeussge    function getPType() { return 'block'; }
4171ec1101SGina Haeussge
4271ec1101SGina Haeussge    function connectTo($mode) {
4371ec1101SGina Haeussge        $this->Lexer->addSpecialPattern("{{page>.+?}}", $mode, 'plugin_include_include');
4471ec1101SGina Haeussge        $this->Lexer->addSpecialPattern("{{section>.+?}}", $mode, 'plugin_include_include');
4571ec1101SGina Haeussge    }
4671ec1101SGina Haeussge
4771ec1101SGina Haeussge    function handle($match, $state, $pos, &$handler) {
4871ec1101SGina Haeussge
4971ec1101SGina Haeussge        $match = substr($match, 2, -2); // strip markup
5071ec1101SGina Haeussge        list($match, $flags) = explode('&', $match, 2);
5171ec1101SGina Haeussge
5271ec1101SGina Haeussge        // break the pattern up into its constituent parts
5371ec1101SGina Haeussge        list($include, $id, $section) = preg_split('/>|#/u', $match, 3);
5471ec1101SGina Haeussge        return array($include, $id, cleanID($section), explode('&', $flags));
5571ec1101SGina Haeussge    }
5671ec1101SGina Haeussge
5771ec1101SGina Haeussge    function render($format, &$renderer, $data) {
5871ec1101SGina Haeussge        global $ID;
5971ec1101SGina Haeussge
6071ec1101SGina Haeussge        list($type, $raw_id, $section, $flags) = $data;
6171ec1101SGina Haeussge
6271ec1101SGina Haeussge        $id = $this->_applyMacro($raw_id);
6371ec1101SGina Haeussge        $nocache = ($id != $raw_id);
6471ec1101SGina Haeussge        resolve_pageid(getNS($ID), $id, $exists); // resolve shortcuts
6571ec1101SGina Haeussge
6671ec1101SGina Haeussge        $include =& plugin_load('helper', 'include');
6771ec1101SGina Haeussge        $include->setMode($type);
6871ec1101SGina Haeussge        $include->setFlags($flags);
6971ec1101SGina Haeussge
7071ec1101SGina Haeussge        if ($nocache) $renderer->info['cache'] = false;                 // prevent caching
7171ec1101SGina Haeussge        if (AUTH_READ > auth_quickaclcheck($id)) return true;           // check for permission
7271ec1101SGina Haeussge        if (!$include->setPage(compact('type','id','section','exists'))) return false;
7371ec1101SGina Haeussge
7471ec1101SGina Haeussge        //  initiate inclusion of external content for those renderer formats which require it
7571ec1101SGina Haeussge        //  - currently only 'xhtml'
7671ec1101SGina Haeussge        if (in_array($format, array('xhtml'))) {
7771ec1101SGina Haeussge
7871ec1101SGina Haeussge            $ok = $this->_include($include, $format, $renderer, $type, $id, $section, $flags, $nocache);
7971ec1101SGina Haeussge
8071ec1101SGina Haeussge        } else if (in_array($format, array('odt'))) {
8171ec1101SGina Haeussge
8271ec1101SGina Haeussge            // current section level
8371ec1101SGina Haeussge            $clevel = 0;
8471ec1101SGina Haeussge            preg_match_all('|<text:h text:style-name="Heading_20_\d" text:outline-level="(\d)">|i', $renderer->doc, $matches, PREG_SET_ORDER);
8571ec1101SGina Haeussge            $n = count($matches) - 1;
8671ec1101SGina Haeussge            if ($n > -1) $clevel = $matches[$n][1];
8771ec1101SGina Haeussge            $include->setLevel($clevel);
8871ec1101SGina Haeussge
8971ec1101SGina Haeussge            // include the page now
9071ec1101SGina Haeussge            $include->renderODT($renderer);
9171ec1101SGina Haeussge
9271ec1101SGina Haeussge            return true;
9371ec1101SGina Haeussge
9471ec1101SGina Haeussge        } else {
9571ec1101SGina Haeussge            // carry out renderering for all other formats
9671ec1101SGina Haeussge            $ok = $this->_no_include($include, $format, $renderer, $type, $id, $section, $flags, $nocache);
9771ec1101SGina Haeussge
9871ec1101SGina Haeussge        #global $debug;
9971ec1101SGina Haeussge        #$debug[] = compact('id','raw_id','flg_macro','format');
10071ec1101SGina Haeussge        }
10171ec1101SGina Haeussge
10271ec1101SGina Haeussge        return false;
10371ec1101SGina Haeussge    }
10471ec1101SGina Haeussge
10571ec1101SGina Haeussge    /* ---------- Util Functions ---------- */
10671ec1101SGina Haeussge
10771ec1101SGina Haeussge    /**
10871ec1101SGina Haeussge     * render process for renderer formats which do include external content
10971ec1101SGina Haeussge     *
11071ec1101SGina Haeussge     * @param  $include   obj     include helper plugin
11171ec1101SGina Haeussge     * @param  $format    string  renderer format
11271ec1101SGina Haeussge     * @param  $renderer  obj     renderer
11371ec1101SGina Haeussge     * @param  $type      string  include type ('page' or 'section')
11471ec1101SGina Haeussge     * @param  $id        string  fully resolved wiki page id of included page
11571ec1101SGina Haeussge     * @param  $section   string  fragment identifier for page fragment to be included
11671ec1101SGina Haeussge     * @param  $flg_macro bool    true if $id was modified by macro substitution
11771ec1101SGina Haeussge     */
11871ec1101SGina Haeussge    function _include(&$include, $format, &$renderer, $type, $id, $section, $flags, $flg_macro) {
11971ec1101SGina Haeussge
12071ec1101SGina Haeussge        $file    = wikiFN($id);
12171ec1101SGina Haeussge
12271ec1101SGina Haeussge        if ($format == 'xhtml') {
12371ec1101SGina Haeussge
12471ec1101SGina Haeussge            // current section level
12571ec1101SGina Haeussge            $matches = array();
12671ec1101SGina Haeussge            preg_match_all('|<div class="level(\d)">|i', $renderer->doc, $matches, PREG_SET_ORDER);
12771ec1101SGina Haeussge            $n = count($matches)-1;
12871ec1101SGina Haeussge            $clevel = ($n > -1)  ? $clevel = $matches[$n][1] : 0;
12971ec1101SGina Haeussge            $include->setLevel($clevel);
13071ec1101SGina Haeussge
13171ec1101SGina Haeussge            // close current section
13271ec1101SGina Haeussge            if ($clevel && ($type == 'section')) $renderer->doc .= '</div>';
13371ec1101SGina Haeussge
13471ec1101SGina Haeussge            // include the page
13571ec1101SGina Haeussge            $include->renderXHTML($renderer,$info);
13671ec1101SGina Haeussge
13771ec1101SGina Haeussge            // propagate any cache prevention from included pages into this page
13871ec1101SGina Haeussge            if ($info['cache'] == false) $renderer->info['cache'] = false;
13971ec1101SGina Haeussge
14071ec1101SGina Haeussge            // resume current section
14171ec1101SGina Haeussge            if ($clevel && ($type == 'section')) $renderer->doc .= '<div class="level'.$clevel.'">';
14271ec1101SGina Haeussge
14371ec1101SGina Haeussge            return true;
14471ec1101SGina Haeussge
14571ec1101SGina Haeussge        } else {  // other / unsupported format
14671ec1101SGina Haeussge        }
14771ec1101SGina Haeussge
14871ec1101SGina Haeussge        return false;
14971ec1101SGina Haeussge    }
15071ec1101SGina Haeussge
15171ec1101SGina Haeussge    /**
15271ec1101SGina Haeussge     * render process for renderer formats which don't include external content
15371ec1101SGina Haeussge     *
15471ec1101SGina Haeussge     * @param  $include   obj     include helper plugin
15571ec1101SGina Haeussge     * @param  $format    string  renderer format
15671ec1101SGina Haeussge     * @param  $renderer  obj     renderer
15771ec1101SGina Haeussge     * @param  $type      string  include type ('page' or 'section')
15871ec1101SGina Haeussge     * @param  $id        string  fully resolved wiki page id of included page
15971ec1101SGina Haeussge     * @param  $section   string  fragment identifier for page fragment to be included
16071ec1101SGina Haeussge     * @param  $flg_macro bool    true if $id was modified by macro substitution
16171ec1101SGina Haeussge     */
16271ec1101SGina Haeussge    function _no_include(&$include, $format, &$renderer, $type, $id, $section, $flags, $flg_macro) {
16371ec1101SGina Haeussge
16471ec1101SGina Haeussge        switch ($format) {
16571ec1101SGina Haeussge            case 'metadata' :
16671ec1101SGina Haeussge                if (!$flg_macro) {
16771ec1101SGina Haeussge                    $renderer->meta['relation']['haspart'][$id] = @file_exists(wikiFN($id));
16871ec1101SGina Haeussge                }
16971ec1101SGina Haeussge                return true;
17071ec1101SGina Haeussge
17171ec1101SGina Haeussge            default :  // unknown / unsupported renderer format
17271ec1101SGina Haeussge                return false;
17371ec1101SGina Haeussge        }
17471ec1101SGina Haeussge
17571ec1101SGina Haeussge        return false;
17671ec1101SGina Haeussge    }
17771ec1101SGina Haeussge
17871ec1101SGina Haeussge    /**
17971ec1101SGina Haeussge     * Makes user or date dependent includes possible
18071ec1101SGina Haeussge     */
18171ec1101SGina Haeussge    function _applyMacro($id) {
18271ec1101SGina Haeussge        global $INFO, $auth;
183*efa360b9SGina Haeussge
184*efa360b9SGina Haeussge        // if we don't have an auth object, do nothing
185*efa360b9SGina Haeussge        if (!$auth)
186*efa360b9SGina Haeussge        	return $id;
18771ec1101SGina Haeussge
18871ec1101SGina Haeussge        $user     = $_SERVER['REMOTE_USER'];
18971ec1101SGina Haeussge        $userdata = $auth->getUserData($user);
19071ec1101SGina Haeussge        $group    = $userdata['grps'][0];
19171ec1101SGina Haeussge
19271ec1101SGina Haeussge        $replace = array(
19371ec1101SGina Haeussge                '@USER@'  => cleanID($user),
19471ec1101SGina Haeussge                '@NAME@'  => cleanID($INFO['userinfo']['name']),
19571ec1101SGina Haeussge                '@GROUP@' => cleanID($group),
19671ec1101SGina Haeussge                '@YEAR@'  => date('Y'),
19771ec1101SGina Haeussge                '@MONTH@' => date('m'),
19871ec1101SGina Haeussge                '@DAY@'   => date('d'),
19971ec1101SGina Haeussge                );
20071ec1101SGina Haeussge        return str_replace(array_keys($replace), array_values($replace), $id);
20171ec1101SGina Haeussge    }
20271ec1101SGina Haeussge}
20371ec1101SGina Haeussge// vim:ts=4:sw=4:et:enc=utf-8:
204