1<?php
2/**
3 * DokuWiki AJAX call handler
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author Pavel Vitis <pavel.vitis@seznam.cz>
7 */
8
9//fix for Opera XMLHttpRequests
10if(!count($_POST) && $HTTP_RAW_POST_DATA){
11  parse_str($HTTP_RAW_POST_DATA, $_POST);
12}
13
14if(!defined('DOKU_INC'))
15  define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/');
16require_once(DOKU_INC.'inc/init.php');
17require_once(DOKU_INC.'inc/common.php');
18require_once(DOKU_INC.'inc/auth.php');
19require_once(DOKU_INC.'inc/html.php');
20
21define(SHOW_GRAVATAR, false);
22define(BASE_URL, preg_replace('!(.+)(/.+){3}!', '\\1/', DOKU_BASE));
23
24session_write_close();
25
26header('Content-Type: text/html; charset=UTF-8');
27
28//call the requested function
29$call = 'ajax_'.$_REQUEST['call'];
30if ($call == '') {
31  $call = 'ajax_'.$_REQUEST['call'];
32}
33if(function_exists($call)){
34  $call();
35}else{
36  print "The called function '".htmlspecialchars($call)."' does not exist!";
37}
38
39function _getChatHtml($pageFN, $ltime = 0, $mtime = 0) {
40    if (!@file_exists($pageFN)) {
41	return;
42	print "1,";
43    }
44
45//    echo '<a style="text-decoration:none;" href="" title="'.$ltime.' / '.$mtime.'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a>';
46
47    $file = trim(io_readFile($pageFN));
48
49    if ($file == ' ') {
50	$file = '';
51    }
52
53    $html = "";
54
55//    $html .= "1,";
56
57    $lines = explode("\n----\n", $file."\n");
58
59    $patterns = array(
60	'!(\[\[((http|https|ftp)://[^\]\|]+)\]\])!',
61	'!(\[\[((http|https|ftp)://[^\]\|]+)\|([^\]]+)\]\])!',
62	'!(\[\[([^\]\|]+)\|([^\]]+)\]\])!',
63	'!(\[\[([^\]\|]+)\]\])!',
64	'!(\s)((http|https|ftp)://[^\s\n\r]+)!',
65	'!\*{2}([^\*]+)\*{2}!',
66	'!(\s)/{2}([^/]+)/{2}(\s)!',
67	'!(\s)_{2}([^_]+)_{2}(\s)!'
68    );
69    $replaces = array(
70        '<a href="\\2" class="urlextern" target="_blank">\\2</a>',
71        '<a href="\\2" class="urlextern" target="_blank">\\4</a>',
72        '<a href="\\2" class="urlintern">\\3</a>',
73        '<a href="\\2" class="urlintern">\\2</a>',
74        '\\1<a href="\\2" class="urlextern" target="_blank">\\2</a>',
75	'<strong>\\1</strong>',
76	'\\1<em>\\2</em>\\3',
77	'\\1<u>\\2</u>\\3'
78    );
79
80    $smileys = getSmileys();
81    foreach ($smileys as $key=>$value) {
82	$key_escaped = preg_replace(
83	    array("/\\\\/","/\*/",'/\&/','/\(/','/\)/','/\[/','/\]/','/\|/','/\=/','!/!','/\?/'),
84	    array('\\\\\\','\\*','\\&','\\(','\\)','\\[','\\]','\\|','\\=','\\/','\\?'),
85	    $key);
86//	echo $key_escaped.'<br />';
87//	echo $value;
88	$patterns[] = '@'.$key_escaped.'@';
89	$files = preg_split('/\|/', $value);
90	if (count($files) > 1) {
91	    $file = $files[mt_rand(0,count($files)-1)];
92	}
93	else {
94	    $file = $files[0];
95	}
96	$replaces[] = '<img src="'.BASE_URL.'lib/images/smileys/'.$file.'" '.
97	    'class="smiley" alt="'.str_replace('"',"'",$key).'" title="'.str_replace('"',"'",$key).'" />';
98    }
99//    print implode('|', array_keys($smileys));
100
101    if (true == SHOW_GRAVATAR) {
102		@require_once(DOKU_INC.'lib/plugins/gravatar/syntax.php');
103		if (true == SHOW_GRAVATAR && class_exists('syntax_plugin_gravatar')) {
104			$gravatar = true;
105		}
106    }
107
108	$color = count($lines) % 2 == 0 ? 0 : 1;
109
110    for ($i = 0; $i < count($lines); $i++) {
111	if (trim($lines[$i]) == '') {
112	    continue;
113	}
114	preg_match('/\(([^\)]+)\)[\s]+([^:]+):[\s]+(.+)/', $lines[$i], $parts);
115
116	if ($parts[1]*1 != 0 && $parts[1]*1 <= $ltime) {
117//	    print $ltime.'<br />';
118//	    print $parts[1].'<br />';
119	    break;
120	}
121
122	$uinfo = explode('|', $parts[2]);
123
124	$html .= '<div class="chat-line ';
125    	$html .= ' chat-line-'.(0 == ($color++) % 2 ? 'even' : 'odd');
126
127//		if ($i == 0 && $ltime < $mtime) {
128//			$html .= ' chat-line-last" id="chat-last-message"';
129//		}
130//		else {
131			$html .= '"';
132//		}
133		$html .= '>';
134
135		if ($gravatar) {
136			if (!empty($uinfo[1])) {
137			$html .= syntax_plugin_gravatar::_renderAvatar(
138		    	$uinfo[1],
139		    	'left',
140		    	40,
141		    	'',
142		    	DOKU_INC,
143		    	BASE_URL);
144	    	}
145		}
146
147		$lang = $_REQUEST['HTTP_ACCEPT_LANGUAGE'];
148		if (date('Yz',time()) == date('Yz',$parts[1])) {
149			$datetime = date('H:i:s',$parts[1]);
150		}
151		else {
152			if ($lang) {
153			}
154			$datetime = date('Y/m/d, H:i:s',$parts[1]);
155		}
156
157		$html .= '<strong>'.(!empty($uinfo[2]) ? $uinfo[2] : $uinfo[0]).'</strong> ('.$datetime.'): <br /><blockquote>';
158		$html .= preg_replace($patterns, $replaces, ' '.$parts[3].' ');
159		if ($i+1 < count($lines)) {
160	    	$html .= '<br />';//'<hr noshade="noshade" size="1" />';
161		}
162		else {
163		    $html .= '<br />';
164		}
165
166		$html .= '</blockquote></div>';
167    }
168
169    return $html;
170}
171
172/**
173 * Get number of new comments
174 *
175 * @author Pavel Vitis <pavel.vitis@seznam.cz>
176 */
177function ajax_check() {
178    global $conf;
179    global $lang;
180
181    $pageId = cleanID($_POST['pageId']);
182    if(empty($pageId)) {
183	return;
184    }
185
186    $ltime = (int)$_POST['time'];
187    $pageFN = wikiFN($pageId);
188    $mtime = @filemtime($pageFN);
189
190    if ($ltime == 0 || $mtime > $ltime) {
191	echo "1";
192    }
193}
194
195/**
196 * Get new comments
197 *
198 * @author Pavel Vitis <pavel.vitis@seznam.cz>
199 */
200function ajax_checkAndGet() {
201    global $conf;
202    global $lang;
203
204    $pageId = cleanID($_POST['pageId']);
205    if(empty($pageId)) {
206    	return;
207    }
208
209    if ($conf['useacl'] && auth_quickAclCheck($pageId) < AUTH_READ) {
210        print "<!--AJAXCHAT_MTIME:0-->\n";
211	print "<p><em>Not sufficient user rights. Please re-login to see the messages.<br />".
212	"If that does not work for you from some reason, clear your browser cookies and then login again:</em></p>".
213	"<p><strong>IE:</strong> Tools->Internet options...->Delete cookies...<br />".
214	"<strong>Mozilla/Firefox:</strong> Tools->Options...->Privacy->Cookies->Clear cookies now...</p>";
215	return;
216    }
217
218    $pageFN = wikiFN($pageId);
219    $mtime = @filemtime($pageFN);
220
221    $ltime = (int)$_POST['time'];
222//  echo $time ." - " . $pageId;
223//  echo "<BR>$mtime";
224
225    if ($ltime == 0 || $mtime > $ltime) {
226        print "<!--AJAXCHAT_MTIME:$mtime-->\n";
227    	print _getChatHtml($pageFN, $ltime, $mtime);
228	print ' ';
229    }
230}
231
232function ajax_send(){
233    global $conf;
234    global $auth;
235    global $lang;
236
237    // check pageid validity
238    $pageId = cleanID($_POST['pageId']);
239    if(empty($pageId)) {
240	return;
241    }
242
243    $ltime = (int)$_POST['time'];
244    if ($ltime > 0) {
245	while (time() - $ltime < 1) {
246	    sleep(5);
247	}
248    }
249
250    // modified now
251    $mtime = time();
252    // set modified header
253    $html = "<!--AJAXCHAT_MTIME:$mtime-->\n";
254
255    // check user rights
256    if ($conf['useacl'] && auth_quickAclCheck($pageId) < AUTH_EDIT) {
257	// and append warning if not possible to send messages
258	$html .= "<p><em>Insufficient user rights. Please re-login to be able to send the messages.</em></p>";
259    }
260    else {
261//        $ltime = (int)$_POST['time'];
262        $user = cleanUser($_POST['user']);
263
264        $message = cleanMessage($_POST['msg']);
265
266	while (checklock($pageId)) {
267	    sleep(50);
268        }
269	lock($pageId);
270
271        $pageFN = wikiFN($pageId);
272        $file = trim(@io_readFile($pageFN));
273
274	if ($file == ' ') {
275	    $file = '';
276        }
277
278	$udata = $auth->getUserData($user);
279
280        $line = "(".time().") ".$user;
281	if (!empty($udata['mail'])) {
282	    $line .= "|".$udata['mail'];
283        }
284	if (!empty($udata['name'])) {
285	    $line .= "|".$udata['name'];
286        }
287	$line .= ": ".htmlspecialchars($message);
288
289        $file = $line."\n----\n".$file."\n";
290
291	saveWikiText($pageId, $file, "Message added", true);
292
293        unlock($pageId);
294    }
295
296    print $html . _getChatHtml($pageFN, $ltime, $mtime);
297}
298
299function ajax_clear(){
300    global $conf;
301    global $lang;
302
303    $ltime = $_POST['time'];
304    $ltime = (int)$ltime;
305
306    $pageId = $_POST['pageId'];
307    $user = cleanUser($_POST['user']);
308    $message = $_POST['msg'];
309
310    $pageFN = wikiFN($pageId);
311    if (!@file_exists($pageFN)) {
312	return;
313    }
314
315    while (checklock($pageId)) {
316	usleep(50);
317    }
318    lock($pageId);
319
320    saveWikiText($pageId, ' ', "Messages cleared", true);
321
322//    @touch($pageFN);
323
324    unlock($pageId);
325
326    print ' ';
327}
328
329function cleanUser($user) {
330    global $conf;
331
332    $user = preg_replace('/[^ .,a-zA-Z0-9_\-]/i', '', $user);
333    $user = substr($user, 0, 40);
334    return $user;
335}
336
337function cleanMessage($msg) {
338    global $conf;
339
340    $maxmsgsize = (int) $conf['chat']['max-message-size'];
341    if ($maxmsgsize <= 0) {
342	$maxmsgsize = 1024;
343    }
344    if ($maxmsgsize > 4*1024) {
345	$maxmsgsize = 4*1024;
346    }
347
348    if (strlen($msg) > $maxmsgsize) {
349        $msg = substr($msg, 0, $maxmsgsize);
350    }
351
352    return $msg;
353}
354
355//Setup VIM: ex: et ts=2 enc=utf-8 :
356?>