1<?php
2/**
3 * Plugin nspages : Displays nicely a list of the pages of a namespace
4 *
5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 */
7
8if(!defined('DOKU_INC')) die();
9require_once 'sorters.php';
10
11abstract class nspages_printer {
12    protected $plugin;
13    protected $renderer;
14    protected $mode;
15    private $pos;
16    private $actualTitleLevel;
17    private $natOrder;
18    private $nbItemsMax;
19    private $dictOrder;
20    protected $_displayModificationDate;
21    protected $_sorter;
22    protected $includeItemsInTOC;
23
24    // Static to prevent conflicts if there are several <nspages> tag in a same page
25    static private $builtSectionIds = array();
26
27    function __construct($plugin, $mode, $renderer, $data){
28      $this->plugin = $plugin;
29      $this->renderer =& $renderer;
30      $this->mode = $mode;
31      $this->pos = $data['pos'];
32      $this->natOrder = $data['natOrder'];
33      $this->actualTitleLevel = $data['actualTitleLevel'];
34      $this->nbItemsMax = $data['nbItemsMax'];
35      $this->dictOrder = $data['dictOrder'];
36      $this->_displayModificationDate = $data['displayModificationDate']
37        || $data['modificationDateOnPictures']; // This is a deprecated option. We should kill it after checking no users are still using it
38      $this->_sorter = $this->_getSorter($data['reverse']);
39      $this->includeItemsInTOC = $data['includeItemsInTOC'] && $mode === 'xhtml';
40    }
41
42    function printTOC($tab, $type, $text, $hideno){
43        $this->_printHeader($tab, $type, $text, $hideno);
44
45        if(empty($tab)) {
46            return;
47        }
48
49        $this->_print($tab, $type);
50    }
51
52    abstract function _print($tab, $type);
53
54    function printUnusableNamespace($wantedNS){
55        $this->printError($this->plugin->getLang('doesntexist').$wantedNS);
56    }
57
58    function printErrorSidebarDoestAcceptNamespace($wantedNS){
59        $this->printError($this->plugin->getLang('sidebarOrNs').$wantedNS);
60    }
61
62    private function printError($errorMessage){
63        $this->renderer->section_open(1);
64        $this->renderer->cdata($errorMessage);
65        $this->renderer->section_close();
66    }
67
68    private function _printHeader(&$tab, $type, $text, $hideno) {
69        if(empty($tab) && $hideno) return;
70
71        $this->_sorter->sort($tab);
72        $this->_keepOnlyNMaxItems($tab);
73
74        if($text != '') {
75            if($this->actualTitleLevel){
76                $this->renderer->header($text, $this->actualTitleLevel, $this->pos);
77            } else if($this->mode == 'xhtml') {
78                $this->renderer->doc .= '<p class="catpageheadline">';
79                $this->renderer->cdata($text);
80                $this->renderer->doc .= '</p>';
81            } else {
82                $this->renderer->linebreak();
83                $this->renderer->p_open();
84                $this->renderer->cdata($text);
85                $this->renderer->p_close();
86            }
87        }
88
89        if(empty($tab)) {
90            $this->renderer->p_open();
91            $this->renderer->cdata($this->plugin->getLang(($type == 'page') ? 'nopages' : 'nosubns'));
92            $this->renderer->p_close();
93        }
94    }
95
96    private function _getSorter($reverse) {
97        if ( $this->natOrder ){
98            return new nspages_naturalOrder_sorter($reverse);
99        } else if ($this->dictOrder) {
100            return new nspages_dictOrder_sorter($reverse, $this->dictOrder);
101        } else {
102            return new nspages_default_sorter($reverse);
103        }
104    }
105
106    private function _keepOnlyNMaxItems(&$tab){
107        if ($this->nbItemsMax){
108            $tab = array_slice($tab, 0, $this->nbItemsMax);
109        }
110    }
111
112    /**
113     * @param Array        $item      Represents the file
114     * @param bool $node true when a node; false when a leaf
115     */
116    protected function _printElement($item, $level=1) {
117        $this->_printElementOpen($item, $level);
118        $this->_printElementContent($item, $level);
119        $this->_printElementClose();
120    }
121
122    protected function _printElementOpen($item, $level) {
123        if($item == null || $item['type'] !== 'd') {
124            $this->renderer->listitem_open($level, false);
125        } else { //Case of a subnamespace
126          $this->renderer->listitem_open($level, true);
127        }
128    }
129
130    protected function _printElementContent($item, $level=1) {
131        $this->renderer->listcontent_open();
132        $this->_printElementLink($item, $level);
133        $this->renderer->listcontent_close();
134    }
135
136    protected function _printElementLink($item, $level=1) {
137        $linkText = "";
138        if ($this->_displayModificationDate) {
139          $linkText = '[' . date('Y-m-d', $item["mtime"]) . '] - ';
140        }
141        $linkText .= $item['nameToDisplay'];
142        if ($this->includeItemsInTOC){
143          $anchorId = $this->buildAnchorId($item);
144          $this->renderer->doc .= '<span id="' . $anchorId . '">';
145          $this->renderer->toc_additem($anchorId, $linkText, $this->renderer->getLastLevel() + $level);
146        }
147        $this->renderer->internallink(':'.$item['id'], $linkText);
148        if ($this->includeItemsInTOC){
149          $this->renderer->doc .= "</span>";
150        }
151    }
152
153    protected function buildAnchorId($item){
154      // Prefix with "nspages_" to avoid collisions with headers
155      return "nspages_" . sectionID($item['id'], self::$builtSectionIds);
156    }
157
158    protected function _printElementClose() {
159        $this->renderer->listitem_close();
160    }
161
162    function printBeginning(){
163        if($this->mode == 'xhtml') {
164            $this->renderer->doc .= '<div class="plugin_nspages">';
165        }
166    }
167
168    function printEnd(){
169        //this is needed to make sure everything after the plugin is written below the output
170        if($this->mode == 'xhtml') {
171            $this->renderer->doc .= '<div class="catpageeofidx"></div>';
172            $this->renderer->doc .= '</div>';
173        } else {
174            $this->renderer->linebreak();
175        }
176    }
177
178    function printTransition(){ }
179}
180