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->renderer->section_open(1);
56         $this->renderer->cdata($this->plugin->getLang('doesntexist').$wantedNS);
57         $this->renderer->section_close();
58    }
59
60    private function _printHeader(&$tab, $type, $text, $hideno) {
61        if(empty($tab) && $hideno) return;
62
63        $this->_sorter->sort($tab);
64        $this->_keepOnlyNMaxItems($tab);
65
66        if($text != '') {
67            if($this->actualTitleLevel){
68                $this->renderer->header($text, $this->actualTitleLevel, $this->pos);
69            } else if($this->mode == 'xhtml') {
70                $this->renderer->doc .= '<p class="catpageheadline">';
71                $this->renderer->cdata($text);
72                $this->renderer->doc .= '</p>';
73            } else {
74                $this->renderer->linebreak();
75                $this->renderer->p_open();
76                $this->renderer->cdata($text);
77                $this->renderer->p_close();
78            }
79        }
80
81        if(empty($tab)) {
82            $this->renderer->p_open();
83            $this->renderer->cdata($this->plugin->getLang(($type == 'page') ? 'nopages' : 'nosubns'));
84            $this->renderer->p_close();
85        }
86    }
87
88    private function _getSorter($reverse) {
89        if ( $this->natOrder ){
90            return new nspages_naturalOrder_sorter($reverse);
91        } else if ($this->dictOrder) {
92            return new nspages_dictOrder_sorter($reverse, $this->dictOrder);
93        } else {
94            return new nspages_default_sorter($reverse);
95        }
96    }
97
98    private function _keepOnlyNMaxItems(&$tab){
99        if ($this->nbItemsMax){
100            $tab = array_slice($tab, 0, $this->nbItemsMax);
101        }
102    }
103
104    /**
105     * @param Array        $item      Represents the file
106     */
107    protected function _printElement($item, $level=1, $node=false) {
108        $this->_printElementOpen($level, $node);
109        $this->_printElementContent($item, $level);
110        $this->_printElementClose();
111    }
112
113    protected function _printElementOpen($level=1, $node=false) {
114        if($item['type'] !== 'd') {
115            $this->renderer->listitem_open($level, $node);
116        } else { //Case of a subnamespace
117            if($this->mode == 'xhtml') {
118                $this->renderer->doc .= '<li class="closed">';
119            } else {
120                $this->renderer->listitem_open($level, $node);
121            }
122        }
123    }
124
125    protected function _printElementContent($item, $level=1) {
126        $this->renderer->listcontent_open();
127        $this->_printElementLink($item, $level);
128        $this->renderer->listcontent_close();
129    }
130
131    protected function _printElementLink($item, $level=1) {
132        $linkText = "";
133        if ($this->_displayModificationDate) {
134          $linkText = '[' . date('Y-m-d', $item["mtime"]) . '] - ';
135        }
136        $linkText .= $item['nameToDisplay'];
137        if ($this->includeItemsInTOC){
138          $anchorId = $this->buildAnchorId($item);
139          $this->renderer->doc .= '<span id="' . $anchorId . '">';
140          $this->renderer->toc_additem($anchorId, $linkText, $this->renderer->getLastLevel() + $level);
141        }
142        $this->renderer->internallink(':'.$item['id'], $linkText);
143        if ($this->includeItemsInTOC){
144          $this->renderer->doc .= "</span>";
145        }
146    }
147
148    protected function buildAnchorId($item){
149      // Prefix with "nspages_" to avoid collisions with headers
150      return "nspages_" . sectionID($item['id'], self::$builtSectionIds);
151    }
152
153    protected function _printElementClose() {
154        $this->renderer->listitem_close();
155    }
156
157    function printBeginning(){
158        if($this->mode == 'xhtml') {
159            $this->renderer->doc .= '<div class="plugin_nspages">';
160        }
161    }
162
163    function printEnd(){
164        //this is needed to make sure everything after the plugin is written below the output
165        if($this->mode == 'xhtml') {
166            $this->renderer->doc .= '<div class="catpageeofidx"></div>';
167            $this->renderer->doc .= '</div>';
168        } else {
169            $this->renderer->linebreak();
170        }
171    }
172
173    function printTransition(){ }
174}
175