1<?php
2/**
3 * @package tikiwiki
4 */
5// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
6//
7// All Rights Reserved. See copyright.txt for details and a complete list of authors.
8// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
9// $Id$
10
11require_once 'tiki-setup.php';
12$categlib = TikiLib::lib('categ');
13
14$access->check_feature('feature_print_indexed');
15
16$inputConfiguration = [
17	['staticKeyFilters' => [
18		'list' => 'alpha',
19		'comments' => 'alpha',
20	] ],
21	['staticKeyFiltersForArrays' => [
22		'languages' => 'alpha',
23		'categId' => 'digits',
24	] ],
25	[ 'catchAllUnset' => null ],
26];
27
28if (! isset($_GET['list']) || ! in_array($_GET['list'], ['categorylist', 'glossary'])) {
29	$access->display_error('tiki-print_indexed.php', tra('Missing object list type argument'));
30}
31
32
33// Classes to be extracted at some later point {{{
34/**
35 *
36 */
37class ObjectList // {{{
38{
39	private $lastIndex = 0;
40	private $customIndexes = [];
41	private $renderers = [];
42
43	/**
44	 * @param $indexKey
45	 */
46	function addCustomIndex($indexKey)
47	{
48		$this->customIndexes[ $indexKey ] = [];
49	}
50
51	/**
52	 * @param $type
53	 * @param $object
54	 * @param $options
55	 */
56	function add($type, $object, $options)
57	{
58		if (! isset($dataIndex[$type])) {
59			$this->dataIndex[$type] = [];
60		}
61
62		switch ($type) {
63			case 'wiki page':
64				if (array_key_exists('languages', $options)) {
65					$renderer = new ObjectRenderer_MultilingualWiki($type, $object, $options);
66				} else {
67					$renderer = new ObjectRenderer_Wiki($type, $object, $options);
68				}
69
70				break;
71
72			default:
73				$renderer = new ObjectRenderer_TrackerItem($type, $object, $options);
74				break;
75		}
76
77		if ($renderer && $renderer->isValid()) {
78			$index = ++$this->lastIndex;
79			$this->renderers[$index] = $renderer;
80
81			foreach ($this->customIndexes as $key => & $data) {
82				if ($prop = $renderer->getIndexValue($key)) {
83					$prop = strtolower($prop);
84
85					if (isset($data[$prop])) {
86						$data[$prop][] = $index;
87					} else {
88						$data[$prop] = [ $index ];
89					}
90				}
91			}
92		}
93	}
94
95	function finalize()
96	{
97		foreach ($this->customIndexes as & $data) {
98			ksort($data);
99		}
100	}
101
102	/**
103	 * @param $smarty
104	 * @param $key
105	 * @param $options
106	 */
107	function render($smarty, $key, $options)
108	{
109		if (is_null($key)) {
110			foreach ($this->renderers as $index => $renderer) {
111				$smarty->assign('index', $index);
112
113				$renderer->render($smarty, $options);
114			}
115		} else {
116			foreach ($this->customIndexes[$key] as $indexes) {
117				foreach ($indexes as $index) {
118					$renderer = $this->renderers[$index];
119					$smarty->assign('index', $index);
120
121					$renderer->render($smarty, $options);
122				}
123			}
124		}
125	}
126} // }}}
127
128/**
129 *
130 */
131abstract class ObjectRenderer // {{{
132{
133	protected $objectType;
134	protected $objectId;
135
136	/**
137	 * @param $objectType
138	 * @param $objectId
139	 */
140	function __construct($objectType, $objectId)
141	{
142		$this->objectType = $objectType;
143		$this->objectId = $objectId;
144	}
145
146	/**
147	 * @param $smarty
148	 * @param $options
149	 */
150	function render($smarty, $options)
151	{
152		$options['decorator_template'] = 'print/print-decorator_' . $options['decorator'] . '.tpl';
153		$smarty->assign('body', $this->_render($smarty, $options));
154		$smarty->display($options['decorator_template']);
155	}
156
157	/**
158	 * @return bool
159	 */
160	function isValid()
161	{
162		return true;
163	}
164
165	/**
166	 * @param $smarty
167	 * @param $template
168	 * @return mixed
169	 */
170	abstract function _render($smarty, $template);
171
172	/**
173	 * @param $key
174	 * @return mixed
175	 */
176	abstract function getIndexValue($key);
177} // }}}
178
179/**
180 *
181 */
182class ObjectRenderer_TrackerItem extends ObjectRenderer // {{{
183{
184	private static $trackers = [];
185	private $valid = false;
186	private $tracker;
187	private $info;
188
189	/**
190	 * @param $type
191	 * @param $object
192	 * @param array $options
193	 */
194	function __construct($type, $object, $options = [])
195	{
196		parent::__construct($type, $object, $options);
197
198		$trklib = TikiLib::lib('trk');
199
200		$info = $trklib->get_tracker_item($object);
201		$trackerId = $info['trackerId'];
202
203		if (! isset(self::$trackers[$trackerId])) {
204			if (self::$trackers[$trackerId] = $trklib->get_tracker($trackerId)) {
205				$fields = $trklib->list_tracker_fields($trackerId);
206
207				self::$trackers[$trackerId]['fields'] = $fields['data'];
208			} else {
209				$this->valid = false;
210				return;
211			}
212		}
213
214		$this->tracker = self::$trackers[ $info['trackerId'] ];
215		$this->info = $info;
216		$this->valid = ($type == $this->tracker['name']);
217
218		foreach ($this->tracker['fields'] as & $field) {
219			$field['value'] = $this->info[ $field['fieldId'] ];
220		}
221	}
222
223	/**
224	 * @return bool
225	 */
226	function isValid()
227	{
228		return $this->valid;
229	}
230
231	/**
232	 * @param $smarty
233	 * @param $options
234	 * @return mixed
235	 */
236	function _render($smarty, $options)
237	{
238		$smarty->assign('title', $this->getTitle());
239		$smarty->assign('tracker', $this->tracker);
240		$smarty->assign('item', $this->info);
241
242		$options['display_template'] = 'print/print-' . $options['display'] . '_trackeritem.tpl';
243		return $smarty->fetch($options['display_template']);
244	}
245
246	/**
247	 * @param $key
248	 * @return mixed
249	 */
250	function getIndexValue($key)
251	{
252		switch ($key) {
253			case 'title':
254				return $this->getTitle();
255		}
256	}
257
258	/**
259	 * @return mixed
260	 */
261	function getTitle()
262	{
263		foreach ($this->tracker['fields'] as $field) {
264			if ($field['isMain'] == 'y') {
265				return $field['value'];
266			}
267		}
268	}
269} // }}}
270
271/**
272 *
273 */
274class ObjectRenderer_Wiki extends ObjectRenderer // {{{
275{
276	private $info;
277
278	/**
279	 * @param $objectType
280	 * @param $objectId
281	 */
282	function __construct($objectType, $objectId)
283	{
284		parent::__construct($objectType, $objectId);
285		global $tikilib;
286
287		$info = $tikilib->get_page_info($objectId);
288
289		$info['parsed'] = TikiLib::lib('parser')->parse_data(
290			$info['data'],
291			[
292				'is_html' => $info['is_html'],
293				'print' => 'y',
294			]
295		);
296
297		$this->info = $info;
298	}
299
300	/**
301	 * @param $smarty
302	 * @param $options
303	 * @return mixed
304	 */
305	function _render($smarty, $options)
306	{
307		$options['display_template'] = 'print/print-' . $options['display'] . '_wiki.tpl';
308		$smarty->assign('info', $this->info);
309
310		return $smarty->fetch($options['display_template']);
311	}
312
313	/**
314	 * @param $key
315	 * @return mixed
316	 */
317	function getIndexValue($key)
318	{
319		switch ($key) {
320			case 'title':
321				return $this->info['pageName'];
322		}
323	}
324} // }}}
325
326/**
327 *
328 */
329class ObjectRenderer_MultilingualWiki extends ObjectRenderer // {{{
330{
331	private $renderers = [];
332
333	/**
334	 * @param $type
335	 * @param $object
336	 * @param array $options
337	 */
338	function __construct($type, $object, $options = [])
339	{
340		parent::__construct($type, $object, $options);
341		$multilinguallib = TikiLib::lib('multilingual');
342		$tikilib = TikiLib::lib('tiki');
343
344		$languages = $options['languages'];
345		$this->renderers = array_fill_keys($languages, null);
346
347		if ($trads = $multilinguallib->getTrads($type, $tikilib->get_page_id_from_name($object))) {
348			foreach ($trads as $trad) {
349				if (in_array($trad['lang'], $languages)) {
350					$this->renderers[ $trad['lang'] ] = new ObjectRenderer_Wiki($type, $tikilib->get_page_name_from_id($trad['objId']), $options);
351				}
352			}
353		} else {
354			$this->renderers[ reset($languages) ] = new ObjectRenderer_Wiki($type, $object, $options);
355		}
356	}
357
358	/**
359	 * @param $smarty
360	 * @param $options
361	 * @return string
362	 */
363	function _render($smarty, $options)
364	{
365		$out = '';
366
367		$languages = array_keys($this->renderers);
368		if (isset($options['languages'])) {
369			$languages = $options['languages'];
370		}
371
372		foreach ($languages as $lang) {
373			if ($this->renderers[$lang]) {
374				$out .= $this->renderers[$lang]->_render($smarty, $options);
375			}
376		}
377
378		return $out;
379	}
380
381	/**
382	 * @param $key
383	 * @return mixed
384	 */
385	function getIndexValue($key)
386	{
387		if (strpos($key, 'lang_') === 0) {
388			list( $key, $lang ) = explode('_', substr($key, 5), 2);
389
390			if (isset($this->renderers[$lang]) && $this->renderers[$lang]) {
391				return $this->renderers[$lang]->getIndexValue($key);
392			}
393
394			return;
395		}
396
397		return reset($this->renderers)->getIndexValue($key);
398	}
399} // }}}
400
401// End of classes }}}
402
403$objectList = new ObjectList;
404$objectList->addCustomIndex('title');
405$indexPages = [];
406
407switch ($_GET['list']) {
408	case 'categorylist':
409		$access->check_feature('feature_categories');
410
411		if (isset($_GET['categId'])) {
412			$categId = (int) $_GET['categId'];
413			$objects = $categlib->list_category_objects($categId, 0, -1, 'name_asc', '', '', true, false);
414
415			$indexPages[] = [
416					'key' => 'title',
417					'indextitle' => tra('Index'),
418					'options' => [
419							'decorator' => 'indexrow',
420							'display' => 'title',
421					],
422			];
423
424			foreach ($objects['data'] as $index => $values) {
425				$type = $values['type'];
426				$item = $values['itemId'];
427				$objectList->add($type, $item, []);
428			}
429		}
430		break;
431
432	case 'glossary':
433		if (isset($_REQUEST['languages'])) {
434			$languages = (array)$_REQUEST['languages'];
435		} else {
436			$languages = [$prefs['language']];
437		}
438
439		$filterLang = reset($languages);
440		foreach ($languages as $num => $code) {
441			$key = 'lang_title_' . $code;
442
443			if ($num > 0) {
444				$objectList->addCustomIndex($key);
445			} else {
446				$key = 'title';
447			}
448
449			$indexPages[] = [
450				'key' => $key,
451				'indextitle' => tr('Index (%0)', $code),
452				'options' => [
453					'decorator' => 'indexrow',
454					'display' => 'title',
455					'languages' => [$code],
456				],
457			];
458		}
459
460		$filter = [ 'lang' => $filterLang ];
461
462		if (isset($_GET['categId'])) {
463			$access->check_feature('feature_categories');
464			$filter['categId'] = $_GET['categId'];
465		}
466
467		$pages = $tikilib->list_pages(0, -1, 'pageName_asc', '', '', true, true, false, false, $filter);
468
469		foreach ($pages['data'] as $info) {
470			$objectList->add('wiki page', $info['pageName'], ['languages' => $languages]);
471		}
472
473		break;
474}
475
476$objectList->finalize();
477
478$smarty->display('header.tpl');
479$smarty->display('print/print-page_header.tpl');
480
481foreach ($indexPages as $page) {
482	$smarty->assign('indextitle', $page['indextitle']);
483	$smarty->display('print/print-index_header.tpl');
484	$objectList->render($smarty, $page['key'], $page['options']);
485	$smarty->display('print/print-index_footer.tpl');
486}
487
488// Display all data
489$objectList->render(
490	$smarty,
491	null,
492	[
493		'decorator' => 'indexed',
494		'display' => 'object',
495		'comments' => $_REQUEST['comments'] == 'y',
496	]
497);
498
499$smarty->display('print/print-page_footer.tpl');
500$smarty->display('footer.tpl');
501