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