1<?php
2/**
3 * DokuWiki Editions Plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Anika Henke <anika@selfthinker.org>
7 */
8// must be run within Dokuwiki
9if(!defined('DOKU_INC')) die();
10
11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
12if(!defined('DOKU_LF')) define('DOKU_LF', "\n");
13
14require_once(DOKU_PLUGIN.'action.php');
15
16/**
17 * All DokuWiki plugins to interfere with the event system
18 * need to inherit from this class
19 */
20class action_plugin_editions extends DokuWiki_Action_Plugin {
21
22    // register hooks
23    function register(Doku_Event_Handler $controller) {
24        $controller->register_hook('TPL_METAHEADER_OUTPUT','BEFORE', $this, 'addIcons');
25        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'openContent');
26        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, 'closeContent');
27        $controller->register_hook('PLUGIN_PURPLENUMBERS_P_OPENED', 'BEFORE', $this, 'openSection');
28        $controller->register_hook('PLUGIN_PURPLENUMBERS_P_CLOSED', 'AFTER', $this, 'closeSection');
29        $controller->register_hook('TPL_CONTENT_DISPLAY', 'AFTER', $this, 'cleanDocument');
30    }
31
32
33    /**
34     * Add lang and class around all content if in edition
35     */
36    function openContent(&$event, $param){
37        if ($this->_isEdition()) {
38            echo '<div '.$this->_getLang().' class="editions_edition">';
39        }
40    }
41
42    /**
43     * Close content div from openContent()
44     */
45    function closeContent(&$event, $param){
46        if ($this->_isEdition()) {
47            echo '</div>';
48        }
49    }
50
51    /**
52     * Add div around each paragraph
53     */
54    function openSection(&$event, $param) {
55        $pid = $event->data['pid'];
56        if ($this->_isEdition() && $pid) {
57            $event->data['doc'] .= '<div class="editions_section">';
58        }
59    }
60
61    /**
62     * Add edition links below each paragraph and close div from openSection()
63     */
64    function closeSection(&$event, $param){
65        $pid = $event->data['pid'];
66        if ($this->_isEdition() && $pid) {
67            $event->data['doc'] .= $this->_getEditionLinks($pid) . '</div>';
68        }
69    }
70
71    /**
72     * Remove open divs from empty paragraphs
73     */
74    function cleanDocument(&$event, $param){
75        if ($this->_isEdition()) {
76            $event->data = preg_replace('/(<div class="editions_section">\s*){2}/','<div class="editions_section">',$event->data);
77        }
78    }
79
80    /**
81     * Add icons to edition links
82     */
83    function addIcons(&$event, $param) {
84        $pluginDir = DOKU_BASE.'lib/plugins/editions/';
85
86        $CSS = '';
87        foreach ($this->_getEditions() as $edition => $lang) {
88            $CSS .= '.editions_editionlist a.'.$edition.' { background-image: url('.$pluginDir.'images/'.$edition.'.png); }'.DOKU_LF;
89        }
90
91        if (!empty($CSS)){
92            $event->data['style'][] = array(
93                'type'    => 'text/css',
94                'media'   => 'screen',
95                '_data'   => $CSS
96            );
97        }
98    }
99
100
101    /**
102     * Get links to same paragraph in all editions
103     */
104    function _getEditionLinks($pid) {
105        global $ID;
106
107        $editionLinks = '<div class="editions_editionlist">';
108
109        // links to other editions
110        $editionLinks .= '<ul>';
111        foreach ($this->_getEditions() as $edition => $lang) {
112            if (curNS($ID)!=$edition) {
113                $eLink = wl($this->getConf('editionNamespace').':'.$edition.':'.noNS($ID)).'#'.$pid;
114                $editionLinkTitle = sprintf($this->getLang('editionLinkTitle'), ucfirst($edition));
115                $editionLinks .= '<li>'.tpl_link($eLink,ucfirst($edition),'class="'.$edition.'" title="'.$editionLinkTitle.'"',1).'</li>';
116            }
117        }
118        $editionLinks .= '</ul>';
119
120        // where to load the snippet
121        $editionLinks .= '<div id="load__'.$pid.'" class="editions_snippet JSpopup"></div>';
122
123        $editionLinks .= '</div>';
124
125        return $editionLinks;
126    }
127
128    /**
129     * Get editions (and their language) from config file
130     */
131    function _getEditions() {
132        $editionFile = DOKU_CONF.'editions.conf';
133        if (@file_exists($editionFile)) {
134            return confToHash($editionFile);
135        }
136        return array();
137    }
138
139    /**
140     * Check if current page is part of an edition
141     */
142    function _isEdition() {
143        global $ID;
144        global $ACT;
145        global $conf;
146        $includeStartpage = $this->_getPurpleNumbersConf();
147
148        if (!$includeStartpage && (noNS($ID) == $conf['start'])) return false;
149        $curRootNS = substr($ID, 0, strpos($ID,':'));
150        if ( ($curRootNS == $this->getConf('editionNamespace')) && ($ACT=='show') ) return true;
151        return false;
152    }
153
154    /**
155     * Get language string for current edition
156     */
157    function _getLang() {
158        global $ID;
159
160        if ($this->_isEdition()) {
161            $editions = $this->_getEditions();
162            if (array_key_exists(curNS($ID), $editions)) {
163                $lang = $editions[curNS($ID)];
164                return ' lang="'.$lang.'" xml:lang="'.$lang.'"';
165            }
166        }
167        return '';
168    }
169
170    /**
171     * Get 'includeStartpage' config setting from purplenumbers plugin
172     */
173    function _getPurpleNumbersConf() {
174        if(!plugin_isdisabled('purplenumbers')) {
175            $purplenumbers =& plugin_load('renderer', 'purplenumbers');
176            return $purplenumbers->getConf('includeStartpage');
177        }
178        return false;
179    }
180
181}
182
183// vim:ts=4:sw=4:
184