1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8//this script may only be included - so its better to die if called directly.
9if (strpos($_SERVER["SCRIPT_NAME"], basename(__FILE__)) !== false) {
10	header("location: index.php");
11	exit;
12}
13
14function smarty_function_object_link($params, $smarty)
15{
16	if (! isset($params['type'], $params['id']) &&  ! isset($params['type'], $params['objectId']) && ! isset($params['identifier'])) {
17		return tra('No object information provided.');
18	}
19
20	if (isset($params['type'], $params['id'])) {
21		$type = $params['type'];
22		$object = $params['id'];
23	} else {
24		list($type, $object) = explode(':', $params['identifier'], 2);
25	}
26
27	if (isset($params['objectId']) && ! isset($params['id'])) {
28		$type = $params['type'];
29		$object = $params['objectId'];
30	}
31
32	$title = isset($params['title']) ? $params['title'] : null;
33	$url = isset($params['url']) ? $params['url'] : null;
34
35	switch ($type) {
36		case 'wiki page':
37		case 'wikipage':
38		case 'wiki':
39			$type = 'wiki page';
40			$function = 'smarty_function_object_link_default';
41			if (! $title) {
42				$title = $object;
43			}
44			global $prefs;
45			if ($prefs['feature_wiki_structure'] === 'y') {
46				$structlib = TikiLib::lib('struct');
47				$page_id = $structlib->get_struct_ref_id($title);
48				if ($page_id) {
49					$alias = $structlib->get_page_alias($page_id);
50					if ($alias) {
51						$title = $alias;
52					}
53				}
54			}
55			break;
56		case 'user':
57			$function = 'smarty_function_object_link_user';
58			break;
59		case 'external':
60		case 'external_extended':
61			$function = 'smarty_function_object_link_external';
62			break;
63		case 'relation_source':
64			$function = 'smarty_function_object_link_relation_source';
65			break;
66		case 'relation_target':
67			$function = 'smarty_function_object_link_relation_target';
68			break;
69		case 'freetag':
70			$function = 'smarty_function_object_link_freetag';
71			break;
72		case 'trackeritemfield':
73			$type = 'trackeritem';
74			$object = (int)(explode(':', $object)[0]);
75		case 'trackeritem':
76			$function = 'smarty_function_object_link_trackeritem';
77			break;
78		case 'group':
79			// Nowhere to link, at least, yet.
80			return $object;
81		case 'forumpost':
82		case 'forum post':
83			$function = 'smarty_function_object_link_forumpost';
84			break;
85		case 'comment':
86			$function = 'smarty_function_object_link_comment';
87			break;
88		default:
89			$function = 'smarty_function_object_link_default';
90			break;
91	}
92
93	return $function($smarty, $object, $title, $type, $url, $params);
94}
95
96function smarty_function_object_link_default($smarty, $object, $title = null, $type = 'wiki page', $url = null, $params = [])
97{
98	global $base_url;
99
100	$smarty->loadPlugin('smarty_modifier_sefurl');
101	$smarty->loadPlugin('smarty_modifier_escape');
102
103	if (empty($title)) {
104		$title = TikiLib::lib('object')->get_title($type, $object, empty($params['format']) ? null : $params['format']);
105	}
106
107	if (empty($title) && ! empty($params['backuptitle'])) {
108		$title = $params['backuptitle'];
109	}
110
111	if (empty($title) && $type == 'freetag') {
112		// Blank freetag should not be returned with "No title specified"
113		return '';
114	}
115
116	$text = $title;
117	$titleAttribute = '';
118	if ($type == 'wiki page') {
119		$titleAttribute .= ' title="' . smarty_modifier_escape($title) . '"';
120		$text = TikiLib::lib('wiki')->get_without_namespace($title);
121	}
122
123	$escapedText = smarty_modifier_escape($text ? $text : tra('No title specified'), 'html', 'UTF-8', false);
124
125	if ($url) {
126		$escapedHref = smarty_modifier_escape(TikiLib::tikiUrlOpt($url));
127	} else {
128		$escapedHref = smarty_modifier_escape(smarty_modifier_sefurl($object, $type));
129	}
130
131	$classList = [];
132
133	if ($type == "blog post") {
134		$classList[] = "link";
135	} elseif ($type == "freetag") {
136		$classList[] = 'freetag';
137	}
138
139	$metadata = TikiLib::lib('object')->get_metadata($type, $object, $classList);
140
141	if (! empty($params['class'])) {
142		$classList[] = $params['class'];
143	}
144
145	$class = ' class="' . implode(' ', $classList) . '"';
146
147	if (strpos($escapedHref, '://') === false) {
148		//$html = '<a href="' . $base_url . $escapedHref . '"' . $class . $titleAttribute . $metadata . '>' . $escapedText . '</a>';
149		// When the link is created for a tiki page, then we do NOT want the baseurl included,
150		// because it might be we are using a reverse proxy or a an ssl offloader, or we access from a public fqdn that is not
151		// configured for teh ip adress we run our webserver.
152		// Eaxmple: Fqdn = tiki.mydomain.com -> port forwarding/nat to: 192.168.1.110.
153		// In this case links should NOT be generated as absolut urls pointing to  192.168.1.110 which would be the part of the baseUrl.
154		$html = '<a href="' . $escapedHref . '"' . $class . $titleAttribute . $metadata . '>' . $escapedText . '</a>';
155	} else {
156		$html = '<a rel="external" href="' . $escapedHref . '"' . $class . $titleAttribute . $metadata . '>' . $escapedText . '</a>';
157	}
158
159	$attributelib = TikiLib::lib('attribute');
160	$attributes = $attributelib->get_attributes($type, $object);
161
162	global $prefs;
163	if (isset($attributes['tiki.content.source']) && $prefs['fgal_source_show_refresh'] == 'y') {
164		$smarty->loadPlugin('smarty_function_icon');
165		$smarty->loadPlugin('smarty_function_service');
166		$html .= '<a class="file-refresh" href="' .
167			smarty_function_service(
168				[
169					'controller' => 'file',
170					'action' => 'refresh',
171					'fileId' => (int)$object,
172				],
173				$smarty
174			) . '">' .
175			smarty_function_icon(
176				['_id' => 'arrow_refresh',],
177				$smarty
178			) . '</a>';
179
180		TikiLib::lib('header')->add_js(
181			'
182			$(".file-refresh").removeClass("file-refresh").click(function () {
183			$.getJSON($(this).attr("href"));
184			$(this).remove();
185			return false;
186		});'
187		);
188	}
189
190	return $html;
191}
192
193function smarty_function_object_link_comment($smarty, $object, $title = null, $type = 'wiki page', $url = null, $params = [])
194{
195	$smarty->loadPlugin('smarty_modifier_sefurl');
196	$comments_lib = TikiLib::lib('comments');
197	$comment = $comments_lib->get_comment($object);
198	$url = smarty_modifier_sefurl($object, $comment['objectType'] . '_comment');
199
200	if (empty($title)) {
201		$title = TikiLib::lib('object')->get_title($type, $object, empty($params['format']) ? null : $params['format']);
202	}
203
204	return '<a href="' . $url . '">' . $title . '</a>';
205}
206
207function smarty_function_object_link_trackeritem($smarty, $object, $title = null, $type = 'wiki page', $url = null, $params = [])
208{
209	$item = Tracker_Item::fromId($object);
210
211	$smarty->loadPlugin('smarty_function_tracker_item_status_icon');
212	$pre = smarty_function_tracker_item_status_icon(['item' => $item], $smarty);
213	if (!empty($pre)) {
214		$pre .= " ";
215	}
216
217	if ($item && $item->canView()) {
218		return $pre . smarty_function_object_link_default($smarty, $object, $title, $type, $url, $params);
219	} else {
220		$smarty->loadPlugin('smarty_modifier_escape');
221
222		if (empty($title)) {
223			$title = TikiLib::lib('object')->get_title($type, $object, empty($params['format']) ? null : $params['format']);
224		}
225
226		return $pre . smarty_modifier_escape($title);
227	}
228}
229
230function smarty_function_object_link_user($smarty, $user, $title = null)
231{
232	$smarty->loadPlugin('smarty_modifier_userlink');
233
234	return smarty_modifier_userlink($user, 'link', 'not_set', $title ? $title : '');
235}
236
237function smarty_function_object_link_external($smarty, $link_orig, $title = null, $type = null)
238{
239	$cachelib = TikiLib::lib('cache');
240	$tikilib = TikiLib::lib('tiki');
241
242	if (substr($link_orig, 0, 4) === 'www.') {
243		$link = 'http://' . $link_orig;
244	} else {
245		$link = $link_orig;
246	}
247
248	if (! $title) {
249		if (! $title = $cachelib->getCached($link, 'object_link_ext_title')) {
250			$body = $tikilib->httprequest($link);
251			if (preg_match('|<title>(.+)</title>|', $body, $parts)) {
252				$title = TikiFilter::get('text')->filter($parts[1]);
253			} else {
254				$title = $link_orig;
255			}
256
257			$cachelib->cacheItem($link, $title, 'object_link_ext_title');
258		}
259	}
260
261	$smarty->loadPlugin('smarty_modifier_escape');
262	$escapedHref = smarty_modifier_escape($link);
263	$escapedLink = smarty_modifier_escape($link_orig);
264	$escapedTitle = smarty_modifier_escape($title);
265
266	if ($type == 'external_extended' && "$link_orig" != "$title") {
267		$data = '<a rel="external" href="' . $escapedHref . '">' . $escapedLink . '</a>'
268					. "<div class='link_extend_title'><em>" . $escapedTitle . "</em></div>";
269	} else {
270		$data = '<a rel="external" href="' . $escapedHref . '">' . $escapedTitle . '</a>';
271	}
272
273	return $data;
274}
275
276function smarty_function_object_link_relation_source($smarty, $relationId, $title = null)
277{
278	return smarty_function_object_link_relation_end($smarty, 'source', $relationId, $title);
279}
280
281function smarty_function_object_link_relation_target($smarty, $relationId, $title = null)
282{
283	return smarty_function_object_link_relation_end($smarty, 'target', $relationId, $title);
284}
285
286function smarty_function_object_link_relation_end($smarty, $end, $relationId, $title = null)
287{
288	$relationlib = TikiLib::lib('relation');
289	$attributelib = TikiLib::lib('attribute');
290	$cachelib = TikiLib::lib('cache');
291
292	$cacheKey = "$relationId:$end:$title";
293
294	if (! $out = $cachelib->getCached($cacheKey, 'relation_link')) {
295		$relation = $relationlib->get_relation($relationId);
296
297		if ($relation) {
298			if (! $title) {
299				$attributes = $attributelib->get_attributes('relation', $relationId);
300				$key = 'tiki.relation.' . $end;
301
302				if (isset($attributes[$key]) && ! empty($attributes[$key])) {
303					$title = $attributes[$key];
304				}
305			}
306
307			$type = $relation[$end . '_type'];
308			$object = $relation[$end . '_itemId'];
309
310			$out = smarty_function_object_link(
311				[
312					'type' => $type,
313					'id' => $object,
314					'title' => $title,
315				],
316				$smarty
317			);
318
319			$cachelib->cacheItem($cacheKey, $out, 'relation_link');
320		} else {
321			$out = tra('Relation not found.');
322		}
323	}
324
325	return $out;
326}
327
328function smarty_function_object_link_freetag($smarty, $tag, $title = null)
329{
330	global $prefs;
331	if ($prefs['feature_freetags'] != 'y') {
332		return tr('tags disabled');
333	}
334
335	if (is_numeric($tag)) {
336		$tag = TikiLib::lib('freetag')->get_tag_from_id($tag);
337	}
338
339	return smarty_function_object_link_default($smarty, $tag, $tag, 'freetag');
340}
341function smarty_function_object_link_forumpost($smarty, $object, $title = null, $type = 'forumpost', $url = null)
342{
343	$commentslib = TikiLib::lib('comments');
344	$comment = $commentslib->get_comment($object);
345
346	while (empty($comment['title'])) {
347		$parent = $commentslib->get_comment($comment['parentId']);
348		$comment['title'] = $parent['title'];
349		if ($parent['parentId'] == 0) {
350			break;
351		}
352	}
353
354	return "<a href='tiki-view_forum_thread.php?threadId=" . $comment['threadId'] . "'>" . $comment['title'] . "</a>";
355}
356