7c07bc7673bd2981962987136657a81271f0ad01
[infodrom.org/www.zeitungsliste.de] / lib / functions.inc
1 <?php
2
3 /*
4  * ==================== Configuration of/for the platform ===============
5  */
6 $pages = array('logout.html' => array('lib' => 'login.inc',
7                                       'func' => 'logout'),
8                'login.html' => array('lib' => 'login.inc',
9                                      'func' => 'process_login'),
10                'activate.html' => array('lib' => 'login.inc',
11                                         'func' => 'process_activate'),
12                'passwd.html' => array('lib' => 'login.inc',
13                                       'func' => 'process_passwd'),
14                'options.html' => array('lib' => 'login.inc',
15                                        'func' => 'process_options'),
16                'search.html' => array('lib' => 'search.inc',
17                                       'func' => 'process_search'),
18                'topic.html' => array('lib' => 'board.inc',
19                                      'func' => 'process_topic'),
20                'reply.html' => array('lib' => 'board.inc',
21                                      'func' => 'process_reply'),
22                'tags.html' => array('lib' => 'tags.inc',
23                                      'func' => 'process_tags'),
24                'edit.html' => array('lib' => 'zeitung.inc',
25                                    'func' => 'process_edit'),
26                'new.html' => array('lib' => 'zeitung.inc',
27                                    'func' => 'process_new'),
28                'bookmark.html' => array('lib' => 'bookmarks.inc',
29                                         'func' => 'process_bookmark'),
30                'contact.html' => array('func' => 'process_contact'),
31                'sitemap.html' => array('lib' => 'layout.inc',
32                                        'func' => 'layout_sitemap'),
33                );
34
35 $dirs = array('zeitung' => array('func' => 'layout_showpaper'),
36               'archiv' => array('func' => 'layout_archive'),
37               'tag' => array('func' => 'layout_showtag'),
38               'topic' => array('func' => 'layout_topic'),
39               );
40
41
42 /*
43  * ==================== Commonly use code ===============================
44  */
45 include_once('layout.inc');
46
47 function carp($msg)
48 {
49   error_log($msg);
50   exit;
51 }
52
53 function userstatus()
54 {
55   global $_SESSION;
56
57   if (isset($_SESSION['uid']))
58     $info = array($_SESSION['online'], $_SESSION['users'], $_SESSION['zeitungen'],
59                   $_SESSION['ztags'], $_SESSION['tags']);
60   else
61     $info = userstatus_info();
62   
63   return sprintf('%d Nutzer von %d online | %d Zeitungen | Bewertungen: %d | Tags: %d',
64                  $info[0], $info[1], $info[2], $info[3], $info[4]);
65 }
66
67 function dispatch()
68 {
69   global $cfg;
70   global $_SERVER;
71   global $_SESSION;
72   global $_GET;
73   global $_POST;
74   global $zlist;
75   global $pages;
76   global $dirs;
77
78   $zlist['info'] = array('info_searchform', 'info_new', 'info_tags', 'info_tagcloud',
79                          'info_actions', 'info_bookmarks','info_hitlist');
80
81   if (strlen($cfg['path']) && array_key_exists($cfg['path'], $pages)) {
82       if (array_key_exists('lib', $pages[$cfg['path']]))
83         include_once($pages[$cfg['path']]['lib']);
84       if (array_key_exists('func', $pages[$cfg['path']])) {
85         if (function_exists($pages[$cfg['path']]['func']))
86           $body = $pages[$cfg['path']]['func']();
87         else
88           $body = notfound();
89       }
90   } elseif (strlen($cfg['dir']) && array_key_exists($cfg['dir'], $dirs)) {
91       if (array_key_exists('lib', $dirs[$cfg['dir']]))
92         include_once($dirs[$cfg['dir']]['lib']);
93       if (array_key_exists('func', $dirs[$cfg['dir']])) {
94         if (function_exists($dirs[$cfg['dir']]['func']))
95           $body = $dirs[$cfg['dir']]['func']();
96         else
97           $body = notfound();
98       }
99   } elseif (empty($_SERVER['QUERY_STRING']) &&
100            empty($cfg['path']) && empty($cfg['dir'])) {
101     $body .= load_template('main.html');
102     $zlist['page'] = 'index';
103   } else {
104     $body = notfound();
105   }
106
107   return layout_page($body);
108 }
109
110 function tagcloud_min()
111 {
112   $query = 'SELECT count(uid) AS count FROM zeitung_tags GROUP BY zeitung,tag ORDER BY count ASC LIMIT 1';
113
114   $sth = db_query($query);
115
116   if ($sth === false)
117     return 1;
118
119   if (pg_num_rows($sth) === 0)
120     return 1;
121
122   $row = pg_fetch_array($sth, 0);
123   return $row['count'];
124 }
125
126 function tagcloud_max()
127 {
128   $query = 'SELECT count(uid) AS count FROM zeitung_tags GROUP BY zeitung,tag ORDER BY count DESC LIMIT 1';
129
130   $sth = db_query($query);
131
132   if ($sth === false)
133     return 10;
134
135   if (pg_num_rows($sth) === 0)
136     return 10;
137
138   $row = pg_fetch_array($sth, 0);
139   return $row['count'];
140 }
141
142 function tag_class($count)
143 {
144   global $_SESSION;
145
146   if (isset($_SESSION['uid'])) {
147     if (!isset($_SESSION['tagcloud_lastupdate']) ||
148         $_SESSION["tagcloud_lastupdate"] < time() - 60*60*12) {
149       $min = $_SESSION["tagcloud_min"] = tagcloud_min();
150       $max = $_SESSION["tagcloud_max"] = tagcloud_max();
151       $_SESSION["tagcloud_lastupdate"] = time();
152     }
153   }
154
155   if (!isset($min)) {
156     $min = tagcloud_min();
157     $max = tagcloud_max();
158   }
159
160   if ($count > (int)($min + ($max - $min) * 0.8))
161     return 4;
162   elseif ($count > (int)($min + ($max - $min) * 0.6))
163     return 3;
164   elseif ($count > (int)($min + ($max - $min) * 0.4))
165     return 2;
166   elseif ($count > (int)($min + ($max - $min) * 0.2))
167     return 1;
168   else
169     return 0;
170 }
171
172 function load_template($template, $replace=false)
173 {
174   global $cfg;
175
176   $fname = $cfg['tmpldir'] . '/' . $template;
177   if (!file_exists($fname))
178     return false;
179
180   $f = fopen($fname, 'r');
181   $content = fread($f, filesize($fname));
182   fclose($f);
183
184   if (preg_match_all('/@([^@]+)@/', $content, $matches)) {
185     $fields = array();
186     $values = array();
187
188     $found = array_unique($matches[1]);
189
190     foreach ($found as $field) {
191       $fields[] = '/@'.$field.'@/';
192       if ($replace != false && array_key_exists($field, $replace))
193         $values[] = $replace[$field];
194       else
195         $values[] = '';
196     }
197
198     $content = preg_replace($fields, $values, $content);
199   }
200
201   return $content;
202 }
203
204 function load_javascript($file)
205 {
206   global $cfg;
207
208   if (!javascript_ok())
209     return;
210
211   $fname = $cfg['tmpldir'] . '/' . $file;
212   if (!file_exists($fname))
213     return;
214
215   $f = fopen($fname, 'r');
216   $content = fread($f, filesize($fname));
217   fclose($f);
218
219   $ret = "\n" . '<script type="text/javascript"><!--' . "\n";
220   $ret .= $content;
221   $ret .= "\n" . '//--></script>' . "\n";
222
223   return $ret;
224 }
225
226 function format_date($date)
227 {
228   setlocale(LC_TIME, "de_DE.UTF-8");
229
230   return strftime("%e. %B %Y, %H:%M", strtotime($date));
231 }
232
233 function format_newspaper($id)
234 {
235   global $cfg;
236   global $zlist;
237
238   $query = sprintf("SELECT * FROM zeitungen WHERE id = %d AND deleted IS false", $id);
239
240   $sth = db_query($query) or carp("format_newspaper");
241
242   if (pg_num_rows ($sth) == 0)
243     return false;
244
245   $row = pg_fetch_array ($sth, 0);
246
247   $ret = '<div class="newspaper">';
248   $ret .= sprintf('<h3>%s</h3>', $row['name']);
249   $zlist['newspaper'] = $row['name'];
250   $zlist['city'] = $row['city'];
251
252   $ret .= sprintf('<p>%s<br>Ort: %s<br>URL: <a href="%s"><code>%s</code></a></p>',
253                   $row['description'], $row['city'],
254                   $row['url'], $row['url']);
255   $ret .= '</div>';
256
257   return $ret;
258 }
259
260 function format_topten($uid)
261 {
262   global $cfg;
263
264   if ($uid > 0)
265     $query = sprintf("SELECT zeitung,name,counter FROM hits " .
266                      "INNER JOIN zeitungen ON id = zeitung " .
267                      "WHERE deleted IS false AND uid = %d " .
268                      "ORDER BY counter DESC LIMIT 10", $uid);
269   else
270     $query = "SELECT zeitung,name,sum(counter) as counter FROM hits " .
271              "INNER JOIN zeitungen ON id = zeitung " .
272              "WHERE deleted IS false " .
273              "GROUP BY zeitung,name ORDER BY counter DESC LIMIT 10";
274
275   $sth = db_query($query) or carp("format_topten");
276
277   if (pg_num_rows ($sth) == 0)
278     return;
279
280   $ret = '<h3>Top 10</h3>';
281   $ret .= '<p><ul>';
282   for ($n=0; $n < pg_num_rows ($sth); $n++) {
283     $row = pg_fetch_array ($sth, $n);
284     $ret .= sprintf('<li><a href="%szeitung/%d.html">%s</a></li>',
285                     $cfg['basepath'], $row['zeitung'], $row['name']);
286   }
287   $ret .= '</ul></p>';
288
289   return $ret;
290 }
291
292 function format_topic($topic)
293 {
294   global $cfg;
295   global $zlist;
296   global $_SERVER;
297
298   $query = sprintf("SELECT topic,archived,zeitung FROM topics WHERE id = %d",
299                    $topic);
300
301   if (($sth = db_query($query)) === false)
302     return warning('Es ist ein Datenbankfehler aufgetreten.');
303
304   if (pg_num_rows ($sth) == 0)
305     return warning('Keine passende Diskussion gefunden.');
306
307   if (($info = pg_fetch_array ($sth, 0)) == false)
308     return warning('Es ist ein Datenbankfehler aufgetreten.');
309
310   $query = sprintf("SELECT nickname,url,created,body FROM article " .
311                    "JOIN users ON users.id = uid " .
312                    "WHERE topic = %d AND article.status = 1 " .
313                    "ORDER BY created", $topic);
314
315   if (($sth2 = db_query($query)) === false) return false;
316
317   if (pg_num_rows ($sth2) > 0) {
318     $ret .= '<div class="topic">';
319     $ret .= sprintf ('<h3>%s</h3>', htmlspecialchars($info['topic']));
320     $col = 0;
321     $zlist['zid'] = $info['zeitung'];
322     $zlist['topic'] = $info['topic'];
323     $zlist['archived'] = $info['archived'] == 't';
324
325     for ($j=0; $j < pg_num_rows ($sth2); $j++) {
326       $row = pg_fetch_array ($sth2, $j);
327
328       $ret .= sprintf('<div class="art%d">', $col);
329
330       if (strlen($row['url']))
331         $author = sprintf('<a href="%s">%s</a>', $row['url'], $row['nickname']);
332       else
333         $author = $row['nickname'];
334
335       $ret .= sprintf('<p><b>%s</b>, %s</p>', $author, format_date($row['created']));
336       $ret .= sprintf('<p>%s</p>', $row['body']);
337       $ret .= '</div>';
338       $col = 1-$col;
339     }
340
341     if ($info['archived'] == 'f' &&
342         strpos($_SERVER['REQUEST_URI'], "/reply.html", 0) === false) {
343       $ret .= '<div class="buttons"><p>';
344       if (logged_in()) {
345         $link_rep = sprintf('%sreply.html?topic=%d', $cfg['basepath'], $topic);
346       } else {
347         $link_rep = sprintf('%slogin.html?from=article', $cfg['basepath']);
348       }
349
350       $ret .= sprintf('<img src="%santworten.gif" width="21" height="17">&nbsp;', $cfg['basepath']);
351       $ret .= sprintf('<a href="%s"><strong>antworten</strong></a>', $link_rep);
352       $ret .= '</p></div>';
353     }
354       
355     $ret .= '</div>';
356   }
357   return $ret;
358 }
359
360 function format_board($zid, $archived=false)
361 {
362   global $cfg;
363   global $zlist;
364
365   $query = sprintf("SELECT id FROM topics " .
366                    "WHERE zeitung = %d AND archived IS %s " .
367                    "ORDER BY created DESC", $zid,
368                    $archived?'true':'false');
369
370   if (($sth = db_query($query)) === false) return false;
371
372   if (pg_num_rows ($sth) == 0 && !$archived) {
373     $zlist['notopic'] = true;
374
375     return $ret;
376   }
377
378   if (pg_num_rows ($sth) > 0) {
379     if ($archived)
380       $ret = '<h3>Abgeschlossene Diskussionen</h3>';
381     else
382       $ret = '<h3>Diskussion</h3>';
383   }
384
385   for ($i=0; $i < pg_num_rows ($sth); $i++) {
386     $row = pg_fetch_array ($sth, $i);
387
388     $ret .= format_topic($row['id']);
389   }
390
391   return $ret;
392 }
393
394 function fix_url($url) {
395   if (!strlen($url))
396     return false;
397
398   if (strpos($url, "http://") === false)
399     $url = "http://" . $url;
400
401   $parts = parse_url($url);
402
403   if ($parts === false)
404     return false;
405
406   if (empty($parts['path']))
407     $url .= '/';
408
409   return $url;
410 }
411
412 function is_valid_url($url) {
413   if (strpos($url, '.') === false)
414     return false;
415
416   $parts = parse_url($url);
417
418   if (empty($parts['host']) || empty($parts['scheme']) || empty($parts['path']))
419     return false;
420
421   if ($parts['scheme'] != 'http' && $parts['scheme'] != 'https')
422     return false;
423
424   if (!preg_match ('/^[a-zA-Z][a-zA-Z0-9\.-]+$/', $parts['host'], $matches))
425     return false;
426
427   if (preg_match ('/[\\\\<>"\'\(\)\[\]]/', $parts['path'], $matches))
428     return false;
429
430   if (!empty($parts['query']) && preg_match ('/[\\\\<>"\'\(\)\[\]]/', $parts['query'], $matches))
431     return false;
432
433   return true;
434 }
435
436 function ajax_check_url()
437 {
438   global $POST;
439
440   if (!empty($_POST['url']) && is_valid_url($_POST['url']))
441     return true;
442
443   return false;
444 }
445
446 function sendmail($to, $name, $subject, $body, $header=array())
447 {
448   global $cfg;
449
450   if (empty($to))
451     return false;
452
453   $header[] = 'From: ' . $cfg['from'];
454   if (empty($name))
455     $header[] = 'To: ' . $to;
456   else
457     $header[] = sprintf('To: %s <%s>', $name, $to);
458   $header[] = 'MIME-Version: 1.0';
459   $header[] = 'Content-type: text/plain; charset=utf-8';
460   $header[] = 'Content-Disposition: inline';
461   $header[] = 'Content-Transfer-Encoding: 8bit';
462
463   $sig = load_template('signature');
464   if (!empty($sig))
465     $body .= $sig;
466
467   $subject = mb_encode_mimeheader($subject,"UTF-8", "Q", "\n");
468
469   if (mail ($to, $subject, $body, implode("\n", $header)) === false)
470     return false;
471
472   return true;
473 }
474
475 function logbook($table,$refid,$column,$old,$new)
476 {
477   global $_SESSION;
478
479   $query = sprintf("INSERT INTO logbook (uid,tab,refid,col,oldval,newval,modified) " .
480                    "VALUES (%d,'%s',%d,'%s','%s','%s',now())",
481                    $_SESSION['uid'], $table,$refid,$column,
482                    pg_escape_string($old),
483                    pg_escape_string($new));
484
485   db_query($query);
486 }
487
488 function hits_inc($zeitung)
489 {
490   global $cfg;
491   global $_SESSION;
492
493   if (is_spider())
494     return;
495
496   $uid = isset($_SESSION['uid'])?$_SESSION['uid']:0;
497
498   $query = sprintf("SELECT counter FROM hits WHERE uid = %d AND zeitung = %d", $uid, $zeitung);
499
500   $sth = db_query($query);
501
502   if (pg_num_rows ($sth) == 0)
503     $query = sprintf("INSERT INTO hits (zeitung,uid,counter) " .
504                      "VALUES (%d,%d,1)", $zeitung, $uid);
505   else
506     $query = sprintf("UPDATE hits SET counter = counter + 1 " .
507                      "WHERE zeitung = %d AND uid = %d", $zeitung, $uid);
508
509   db_query($query);
510 }
511
512 ?>