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