OSDN Git Service

Merge branch 'master' of git.sourceforge.jp:/gitroot/nucleus-jp/nucleus-next
[nucleus-jp/nucleus-next.git] / nucleus / libs / ADMIN.php
1 <?php
2 /*
3  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4  * Copyright (C) 2002-2009 The Nucleus Group
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * (see nucleus/documentation/index.html#license for more info)
11  */
12 /**
13  * The code for the Nucleus admin area
14  *
15  * @license http://nucleuscms.org/license.txt GNU General Public License
16  * @copyright Copyright (C) 2002-2009 The Nucleus Group
17  * @version $Id: ADMIN.php 1661 2012-02-12 11:55:39Z sakamocchi $
18
19  */
20
21 if ( !function_exists('requestVar') ) exit;
22 require_once dirname(__FILE__) . '/showlist.php';
23
24 /**
25  * Builds the admin area and executes admin actions
26  */
27 class Admin
28 {
29         private $xml_version_info = '1.0';
30         private $formal_public_identifier = '-//W3C//DTD XHTML 1.0 Strict//EN';
31         private $system_identifier = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd';
32         private $xhtml_namespace = 'http://www.w3.org/1999/xhtml';
33         
34     /**
35      * @var string $action action currently being executed ($action=xxxx -> action_xxxx method)
36      */
37     var $action;
38
39     /**
40      * Class constructor
41      */
42     function ADMIN() {
43
44     }
45
46     /**
47      * Executes an action
48      *
49      * @param string $action action to be performed
50      */
51     function action($action) {
52         global $CONF, $manager;
53
54         // list of action aliases
55         $alias = array(
56             'login' => 'overview',
57             '' => 'overview'
58         );
59
60         if (isset($alias[$action]))
61             $action = $alias[$action];
62
63         $methodName = 'action_' . $action;
64
65         $this->action = strtolower($action);
66
67         // check ticket. All actions need a ticket, unless they are considered to be safe (a safe action
68         // is an action that requires user interaction before something is actually done)
69         // all safe actions are in this array:
70         $aActionsNotToCheck = array(
71             'showlogin',
72             'login',
73             'overview',
74             'itemlist',
75             'blogcommentlist',
76             'bookmarklet',
77             'blogsettings',
78             'banlist',
79             'deleteblog',
80             'editmembersettings',
81             'browseownitems',
82             'browseowncomments',
83             'createitem',
84             'itemedit',
85             'itemmove',
86             'categoryedit',
87             'categorydelete',
88             'manage',
89             'actionlog',
90             'settingsedit',
91             'backupoverview',
92             'pluginlist',
93             'createnewlog',
94             'usermanagement',
95             'skinoverview',
96             'templateoverview',
97             'skinieoverview',
98             'itemcommentlist',
99             'commentedit',
100             'commentdelete',
101             'banlistnewfromitem',
102             'banlistdelete',
103             'itemdelete',
104             'manageteam',
105             'teamdelete',
106             'banlistnew',
107             'memberedit',
108             'memberdelete',
109             'pluginhelp',
110             'pluginoptions',
111             'plugindelete',
112             'skinedittype',
113             'skinremovetype',
114             'skindelete',
115             'skinedit',
116             'templateedit',
117             'templatedelete',
118             'activate',
119             'systemoverview'
120         );
121 /*
122         // the rest of the actions needs to be checked
123         $aActionsToCheck = array('additem', 'itemupdate', 'itemmoveto', 'categoryupdate', 'categorydeleteconfirm', 'itemdeleteconfirm', 'commentdeleteconfirm', 'teamdeleteconfirm', 'memberdeleteconfirm', 'templatedeleteconfirm', 'skindeleteconfirm', 'banlistdeleteconfirm', 'plugindeleteconfirm', 'batchitem', 'batchcomment', 'batchmember', 'batchcategory', 'batchteam', 'regfile', 'commentupdate', 'banlistadd', 'changemembersettings', 'clearactionlog', 'settingsupdate', 'blogsettingsupdate', 'categorynew', 'teamchangeadmin', 'teamaddmember', 'memberadd', 'addnewlog', 'addnewlog2', 'backupcreate', 'backuprestore', 'pluginup', 'plugindown', 'pluginupdate', 'pluginadd', 'pluginoptionsupdate', 'skinupdate', 'skinclone', 'skineditgeneral', 'templateclone', 'templatenew', 'templateupdate', 'skinieimport', 'skinieexport', 'skiniedoimport', 'skinnew', 'deleteblogconfirm', 'activatesetpwd');
124 */
125         if (!in_array($this->action, $aActionsNotToCheck))
126         {
127             if (!$manager->checkTicket())
128                 $this->error(_ERROR_BADTICKET);
129         }
130
131         if (method_exists($this, $methodName))
132             call_user_func(array(&$this, $methodName));
133         else
134             $this->error(_BADACTION . Entity::hsc(" ($action)"));
135
136     }
137
138     /**
139      * @todo document this
140      */
141     function action_showlogin() {
142         global $error;
143         $this->action_login($error);
144     }
145
146     /**
147      * @todo document this
148      */
149     function action_login($msg = '', $passvars = 1) {
150         global $member;
151
152         // skip to overview when allowed
153         if ($member->isLoggedIn() && $member->canLogin()) {
154             $this->action_overview();
155             exit;
156         }
157
158         $this->pagehead();
159
160         echo '<h2>', _LOGIN ,'</h2>';
161         if ($msg) echo _MESSAGE , ': ', Entity::hsc($msg);
162         ?>
163
164         <form action="index.php" method="post"><p>
165         <?php echo _LOGIN_NAME; ?> <br /><input name="login"  tabindex="10" />
166         <br />
167         <?php echo _LOGIN_PASSWORD; ?> <br /><input name="password"  tabindex="20" type="password" />
168         <br />
169         <input name="action" value="login" type="hidden" />
170         <br />
171         <input type="submit" value="<?php echo _LOGIN?>" tabindex="30" />
172         <br />
173         <small>
174             <input type="checkbox" value="1" name="shared" tabindex="40" id="shared" /><label for="shared"><?php echo _LOGIN_SHARED?></label>
175             <br /><a href="forgotpassword.html"><?php echo _LOGIN_FORGOT?></a>
176         </small>
177         <?php           // pass through vars
178
179             $oldaction = postVar('oldaction');
180             if (  ($oldaction != 'logout')  && ($oldaction != 'login')  && $passvars ) {
181                 passRequestVars();
182             }
183
184
185         ?>
186         </p></form>
187         <?php       $this->pagefoot();
188     }
189
190
191     /**
192      * provides a screen with the overview of the actions available
193      * @todo document parameter
194      */
195     function action_overview($msg = '') {
196         global $member;
197
198         $this->pagehead();
199
200         if ($msg)
201             echo _MESSAGE , ': ', $msg;
202
203         /* ---- add items ---- */
204         echo '<h2>' . _OVERVIEW_YRBLOGS . '</h2>';
205
206         $showAll = requestVar('showall');
207
208         if (($member->isAdmin()) && ($showAll == 'yes')) {
209             // Super-Admins have access to all blogs! (no add item support though)
210             $query =  'SELECT bnumber, bname, 1 as tadmin, burl, bshortname'
211                    . ' FROM ' . sql_table('blog')
212                    . ' ORDER BY bname';
213         } else {
214             $query =  'SELECT bnumber, bname, tadmin, burl, bshortname'
215                    . ' FROM ' . sql_table('blog') . ', ' . sql_table('team')
216                    . ' WHERE tblog=bnumber and tmember=' . $member->getID()
217                    . ' ORDER BY bname';
218         }
219         $template['content'] = 'bloglist';
220         $template['superadmin'] = $member->isAdmin();
221         $amount = showlist($query,'table',$template);
222
223         if (($showAll != 'yes') && ($member->isAdmin())) {
224             $total = quickQuery('SELECT COUNT(*) as result FROM ' . sql_table('blog'));
225             if ($total > $amount)
226                 echo '<p><a href="index.php?action=overview&amp;showall=yes">' . _OVERVIEW_SHOWALL . '</a></p>';
227         }
228
229         if ($amount == 0)
230             echo _OVERVIEW_NOBLOGS;
231
232         if ($amount != 0) {
233             echo '<h2>' . _OVERVIEW_YRDRAFTS . '</h2>';
234             $query =  'SELECT ititle, inumber, bshortname'
235                    . ' FROM ' . sql_table('item'). ', ' . sql_table('blog')
236                    . ' WHERE iauthor='.$member->getID().' and iblog=bnumber and idraft=1';
237             $template['content'] = 'draftlist';
238             $amountdrafts = showlist($query, 'table', $template);
239             if ($amountdrafts == 0)
240                 echo _OVERVIEW_NODRAFTS;
241         }
242                                 
243                 if ($amount != 0) {
244                         $yrBlogs = $member->getAdminBlogs();
245                         if ($showAll != 'yes') {
246                                 $admBlogs = array();
247                                 foreach ($yrBlogs as $value) {
248                                         if ($member->isBlogAdmin(intval($value))) {
249                                                 $admBlogs[] = intval($value);
250                                         }
251                                 }
252                                 $yrBlogs = $admBlogs;
253                         }
254                         
255                         if (count($yrBlogs) > 0) {
256                                 echo '<h2>' . _OVERVIEW_OTHER_DRAFTS . '</h2>';
257                                 $query =  'SELECT ititle, inumber, bshortname, mname'
258                                            . ' FROM ' . sql_table('item'). ', ' . sql_table('blog'). ', ' . sql_table('member')
259                                            . ' WHERE iauthor<>'.$member->getID().' and iblog IN ('.implode(",",$yrBlogs).') and iblog=bnumber and iauthor=mnumber and idraft=1'
260                                            . ' ORDER BY iblog ASC';
261                                 $template['content'] = 'otherdraftlist';
262                                 $amountdrafts = showlist($query, 'table', $template);
263                                 if ($amountdrafts == 0)
264                                         echo _OVERVIEW_NODRAFTS;
265                         }
266         }
267
268         /* ---- user settings ---- */
269         echo '<h2>' . _OVERVIEW_YRSETTINGS . '</h2>';
270         echo '<ul>';
271         echo '<li><a href="index.php?action=editmembersettings">' . _OVERVIEW_EDITSETTINGS. '</a></li>';
272         echo '<li><a href="index.php?action=browseownitems">' . _OVERVIEW_BROWSEITEMS.'</a></li>';
273         echo '<li><a href="index.php?action=browseowncomments">'._OVERVIEW_BROWSECOMM.'</a></li>';
274         echo '</ul>';
275
276         /* ---- general settings ---- */
277         if ($member->isAdmin()) {
278             echo '<h2>' . _OVERVIEW_MANAGEMENT. '</h2>';
279             echo '<ul>';
280             echo '<li><a href="index.php?action=manage">',_OVERVIEW_MANAGE,'</a></li>';
281             echo '</ul>';
282         }
283
284
285         $this->pagefoot();
286     }
287
288     /**
289      * Returns a link to a weblog
290      * @param object BLOG
291      */
292     function bloglink(&$blog) {
293         return '<a href="'.Entity::hsc($blog->getURL()).'" title="'._BLOGLIST_TT_VISIT.'">'. Entity::hsc( $blog->getName() ) .'</a>';
294     }
295
296     /**
297      * @todo document this
298      */
299     function action_manage($msg = '') {
300         global $member;
301
302         $member->isAdmin() or $this->disallow();
303
304         $this->pagehead();
305
306         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
307
308         if ($msg)
309             echo '<p>' , _MESSAGE , ': ', $msg , '</p>';
310
311
312         echo '<h2>' . _MANAGE_GENERAL. '</h2>';
313
314         echo '<ul>';
315         echo '<li><a href="index.php?action=createnewlog">'._OVERVIEW_NEWLOG.'</a></li>';
316         echo '<li><a href="index.php?action=settingsedit">'._OVERVIEW_SETTINGS.'</a></li>';
317         echo '<li><a href="index.php?action=usermanagement">'._OVERVIEW_MEMBERS.'</a></li>';
318         echo '<li><a href="index.php?action=actionlog">'._OVERVIEW_VIEWLOG.'</a></li>';
319         echo '</ul>';
320
321         echo '<h2>' . _MANAGE_SKINS . '</h2>';
322         echo '<ul>';
323         echo '<li><a href="index.php?action=skinoverview">'._OVERVIEW_SKINS.'</a></li>';
324         echo '<li><a href="index.php?action=templateoverview">'._OVERVIEW_TEMPLATES.'</a></li>';
325         echo '<li><a href="index.php?action=skinieoverview">'._OVERVIEW_SKINIMPORT.'</a></li>';
326         echo '</ul>';
327
328         echo '<h2>' . _MANAGE_EXTRA . '</h2>';
329         echo '<ul>';
330         echo '<li><a href="index.php?action=backupoverview">'._OVERVIEW_BACKUP.'</a></li>';
331         echo '<li><a href="index.php?action=pluginlist">'._OVERVIEW_PLUGINS.'</a></li>';
332         echo '</ul>';
333
334         $this->pagefoot();
335     }
336
337     /**
338      * @todo document this
339      */
340     function action_itemlist($blogid = '') {
341         global $member, $manager, $CONF;
342
343         if ($blogid == '')
344             $blogid = intRequestVar('blogid');
345
346         $member->teamRights($blogid) or $member->isAdmin() or $this->disallow();
347
348         $this->pagehead();
349         $blog =& $manager->getBlog($blogid);
350
351         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
352         echo '<h2>' . _ITEMLIST_BLOG . ' ' . $this->bloglink($blog) . '</h2>';
353
354         // start index
355         if (postVar('start'))
356             $start = intPostVar('start');
357         else
358             $start = 0;
359
360         if ($start == 0)
361             echo '<p><a href="index.php?action=createitem&amp;blogid='.$blogid.'">',_ITEMLIST_ADDNEW,'</a></p>';
362
363         // amount of items to show
364         if (postVar('amount'))
365             $amount = intPostVar('amount');
366         else {
367             $amount = intval($CONF['DefaultListSize']);
368             if ($amount < 1)
369                 $amount = 10;
370         }
371
372         $search = postVar('search');    // search through items
373
374         $query =  'SELECT bshortname, cname, mname, ititle, ibody, inumber, idraft, itime'
375                . ' FROM ' . sql_table('item') . ', ' . sql_table('blog') . ', ' . sql_table('member') . ', ' . sql_table('category')
376                . ' WHERE iblog=bnumber and iauthor=mnumber and icat=catid and iblog=' . $blogid;
377
378         if ($search)
379             $query .= ' and ((ititle LIKE "%' . sql_real_escape_string($search) . '%") or (ibody LIKE "%' . sql_real_escape_string($search) . '%") or (imore LIKE "%' . sql_real_escape_string($search) . '%"))';
380
381         // non-blog-admins can only edit/delete their own items
382         if (!$member->blogAdminRights($blogid))
383             $query .= ' and iauthor=' . $member->getID();
384
385
386         $query .= ' ORDER BY itime DESC'
387                 . " LIMIT $start,$amount";
388
389         $template['content'] = 'itemlist';
390         $template['now'] = $blog->getCorrectTime(time());
391
392         $manager->loadClass("ENCAPSULATE");
393         $navList = new NavList('itemlist', $start, $amount, 0, 1000, $blogid, $search, 0);
394         $navList->showBatchList('item',$query,'table',$template);
395
396
397         $this->pagefoot();
398     }
399
400     /**
401      * @todo document this
402      */
403     function action_batchitem() {
404         global $member, $manager;
405
406         // check if logged in
407         $member->isLoggedIn() or $this->disallow();
408
409         // more precise check will be done for each performed operation
410
411         // get array of itemids from request
412         $selected = requestIntArray('batch');
413         $action = requestVar('batchaction');
414
415         // Show error when no items were selected
416         if (!is_array($selected) || sizeof($selected) == 0)
417             $this->error(_BATCH_NOSELECTION);
418
419         // On move: when no destination blog/category chosen, show choice now
420         $destCatid = intRequestVar('destcatid');
421         if (($action == 'move') && (!$manager->existsCategory($destCatid)))
422             $this->batchMoveSelectDestination('item',$selected);
423
424         // On delete: check if confirmation has been given
425         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
426             $this->batchAskDeleteConfirmation('item',$selected);
427
428         $this->pagehead();
429
430         echo '<a href="index.php?action=overview">(',_BACKHOME,')</a>';
431         echo '<h2>',_BATCH_ITEMS,'</h2>';
432         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
433         echo '<ul>';
434
435
436         // walk over all itemids and perform action
437         foreach ($selected as $itemid) {
438             $itemid = intval($itemid);
439             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONITEM,' <b>', $itemid, '</b>...';
440
441             // perform action, display errors if needed
442             switch($action) {
443                 case 'delete':
444                     $error = $this->deleteOneItem($itemid);
445                     break;
446                 case 'move':
447                     $error = $this->moveOneItem($itemid, $destCatid);
448                     break;
449                 default:
450                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
451             }
452
453             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
454             echo '</li>';
455         }
456
457         echo '</ul>';
458         echo '<b>',_BATCH_DONE,'</b>';
459
460         $this->pagefoot();
461
462
463     }
464
465     /**
466      * @todo document this
467      */
468     function action_batchcomment() {
469         global $member;
470
471         // check if logged in
472         $member->isLoggedIn() or $this->disallow();
473
474         // more precise check will be done for each performed operation
475
476         // get array of itemids from request
477         $selected = requestIntArray('batch');
478         $action = requestVar('batchaction');
479
480         // Show error when no items were selected
481         if (!is_array($selected) || sizeof($selected) == 0)
482             $this->error(_BATCH_NOSELECTION);
483
484         // On delete: check if confirmation has been given
485         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
486             $this->batchAskDeleteConfirmation('comment',$selected);
487
488         $this->pagehead();
489
490         echo '<a href="index.php?action=overview">(',_BACKHOME,')</a>';
491         echo '<h2>',_BATCH_COMMENTS,'</h2>';
492         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
493         echo '<ul>';
494
495         // walk over all itemids and perform action
496         foreach ($selected as $commentid) {
497             $commentid = intval($commentid);
498             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONCOMMENT,' <b>', $commentid, '</b>...';
499
500             // perform action, display errors if needed
501             switch($action) {
502                 case 'delete':
503                     $error = $this->deleteOneComment($commentid);
504                     break;
505                 default:
506                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
507             }
508
509             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
510             echo '</li>';
511         }
512
513         echo '</ul>';
514         echo '<b>',_BATCH_DONE,'</b>';
515
516         $this->pagefoot();
517
518
519     }
520
521     /**
522      * @todo document this
523      */
524     function action_batchmember() {
525         global $member;
526
527         // check if logged in and admin
528         ($member->isLoggedIn() && $member->isAdmin()) or $this->disallow();
529
530         // get array of itemids from request
531         $selected = requestIntArray('batch');
532         $action = requestVar('batchaction');
533
534         // Show error when no members selected
535         if (!is_array($selected) || sizeof($selected) == 0)
536             $this->error(_BATCH_NOSELECTION);
537
538         // On delete: check if confirmation has been given
539         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
540             $this->batchAskDeleteConfirmation('member',$selected);
541
542         $this->pagehead();
543
544         echo '<a href="index.php?action=usermanagement">(',_MEMBERS_BACKTOOVERVIEW,')</a>';
545         echo '<h2>',_BATCH_MEMBERS,'</h2>';
546         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
547         echo '<ul>';
548
549         // walk over all itemids and perform action
550         foreach ($selected as $memberid) {
551             $memberid = intval($memberid);
552             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONMEMBER,' <b>', $memberid, '</b>...';
553
554             // perform action, display errors if needed
555             switch($action) {
556                 case 'delete':
557                     $error = $this->deleteOneMember($memberid);
558                     break;
559                 case 'setadmin':
560                     // always succeeds
561                     sql_query('UPDATE ' . sql_table('member') . ' SET madmin=1 WHERE mnumber='.$memberid);
562                     $error = '';
563                     break;
564                 case 'unsetadmin':
565                     // there should always remain at least one super-admin
566                     $r = sql_query('SELECT * FROM '.sql_table('member'). ' WHERE madmin=1 and mcanlogin=1');
567                     if (sql_num_rows($r) < 2)
568                         $error = _ERROR_ATLEASTONEADMIN;
569                     else
570                         sql_query('UPDATE ' . sql_table('member') .' SET madmin=0 WHERE mnumber='.$memberid);
571                     break;
572                 default:
573                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
574             }
575
576             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
577             echo '</li>';
578         }
579
580         echo '</ul>';
581         echo '<b>',_BATCH_DONE,'</b>';
582
583         $this->pagefoot();
584
585
586     }
587
588     /**
589      * @todo document this
590      */
591     function action_batchteam() {
592         global $member;
593
594         $blogid = intRequestVar('blogid');
595
596         // check if logged in and admin
597         ($member->isLoggedIn() && $member->blogAdminRights($blogid)) or $this->disallow();
598
599         // get array of itemids from request
600         $selected = requestIntArray('batch');
601         $action = requestVar('batchaction');
602
603         // Show error when no members selected
604         if (!is_array($selected) || sizeof($selected) == 0)
605             $this->error(_BATCH_NOSELECTION);
606
607         // On delete: check if confirmation has been given
608         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
609             $this->batchAskDeleteConfirmation('team',$selected);
610
611         $this->pagehead();
612
613         echo '<p><a href="index.php?action=manageteam&amp;blogid=',$blogid,'">(',_BACK,')</a></p>';
614
615         echo '<h2>',_BATCH_TEAM,'</h2>';
616         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
617         echo '<ul>';
618
619         // walk over all itemids and perform action
620         foreach ($selected as $memberid) {
621             $memberid = intval($memberid);
622             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONTEAM,' <b>', $memberid, '</b>...';
623
624             // perform action, display errors if needed
625             switch($action) {
626                 case 'delete':
627                     $error = $this->deleteOneTeamMember($blogid, $memberid);
628                     break;
629                 case 'setadmin':
630                     // always succeeds
631                     sql_query('UPDATE '.sql_table('team').' SET tadmin=1 WHERE tblog='.$blogid.' and tmember='.$memberid);
632                     $error = '';
633                     break;
634                 case 'unsetadmin':
635                     // there should always remain at least one admin
636                     $r = sql_query('SELECT * FROM '.sql_table('team').' WHERE tadmin=1 and tblog='.$blogid);
637                     if (sql_num_rows($r) < 2)
638                         $error = _ERROR_ATLEASTONEBLOGADMIN;
639                     else
640                         sql_query('UPDATE '.sql_table('team').' SET tadmin=0 WHERE tblog='.$blogid.' and tmember='.$memberid);
641                     break;
642                 default:
643                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
644             }
645
646             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
647             echo '</li>';
648         }
649
650         echo '</ul>';
651         echo '<b>',_BATCH_DONE,'</b>';
652
653         $this->pagefoot();
654
655
656     }
657
658     /**
659      * @todo document this
660      */
661     function action_batchcategory() {
662         global $member, $manager;
663
664         // check if logged in
665         $member->isLoggedIn() or $this->disallow();
666
667         // more precise check will be done for each performed operation
668
669         // get array of itemids from request
670         $selected = requestIntArray('batch');
671         $action = requestVar('batchaction');
672
673         // Show error when no items were selected
674         if (!is_array($selected) || sizeof($selected) == 0)
675             $this->error(_BATCH_NOSELECTION);
676
677         // On move: when no destination blog chosen, show choice now
678         $destBlogId = intRequestVar('destblogid');
679         if (($action == 'move') && (!$manager->existsBlogID($destBlogId)))
680             $this->batchMoveCategorySelectDestination('category',$selected);
681
682         // On delete: check if confirmation has been given
683         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
684             $this->batchAskDeleteConfirmation('category',$selected);
685
686         $this->pagehead();
687
688         echo '<a href="index.php?action=overview">(',_BACKHOME,')</a>';
689         echo '<h2>',BATCH_CATEGORIES,'</h2>';
690         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
691         echo '<ul>';
692
693         // walk over all itemids and perform action
694         foreach ($selected as $catid) {
695             $catid = intval($catid);
696             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONCATEGORY,' <b>', $catid, '</b>...';
697
698             // perform action, display errors if needed
699             switch($action) {
700                 case 'delete':
701                     $error = $this->deleteOneCategory($catid);
702                     break;
703                 case 'move':
704                     $error = $this->moveOneCategory($catid, $destBlogId);
705                     break;
706                 default:
707                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
708             }
709
710             echo '<b>',($error ? _ERROR . ': '.$error : _BATCH_SUCCESS),'</b>';
711             echo '</li>';
712         }
713
714         echo '</ul>';
715         echo '<b>',_BATCH_DONE,'</b>';
716
717         $this->pagefoot();
718
719     }
720
721     /**
722      * @todo document this
723      */
724     function batchMoveSelectDestination($type, $ids) {
725         global $manager;
726         $this->pagehead();
727         ?>
728         <h2><?php echo _MOVE_TITLE?></h2>
729         <form method="post" action="index.php"><div>
730
731             <input type="hidden" name="action" value="batch<?php echo $type?>" />
732             <input type="hidden" name="batchaction" value="move" />
733             <?php
734                 $manager->addTicketHidden();
735
736                 // insert selected item numbers
737                 $idx = 0;
738                 foreach ($ids as $id)
739                     echo '<input type="hidden" name="batch[',($idx++),']" value="',intval($id),'" />';
740
741                 // show blog/category selection list
742                 $this->selectBlogCategory('destcatid');
743
744             ?>
745
746
747             <input type="submit" value="<?php echo _MOVE_BTN?>" onclick="return checkSubmit();" />
748
749         </div></form>
750         <?php       $this->pagefoot();
751         exit;
752     }
753
754     /**
755      * @todo document this
756      */
757     function batchMoveCategorySelectDestination($type, $ids) {
758         global $manager;
759         $this->pagehead();
760         ?>
761         <h2><?php echo _MOVECAT_TITLE?></h2>
762         <form method="post" action="index.php"><div>
763
764             <input type="hidden" name="action" value="batch<?php echo $type?>" />
765             <input type="hidden" name="batchaction" value="move" />
766             <?php
767                 $manager->addTicketHidden();
768
769                 // insert selected item numbers
770                 $idx = 0;
771                 foreach ($ids as $id)
772                     echo '<input type="hidden" name="batch[',($idx++),']" value="',intval($id),'" />';
773
774                 // show blog/category selection list
775                 $this->selectBlog('destblogid');
776
777             ?>
778
779
780             <input type="submit" value="<?php echo _MOVECAT_BTN?>" onclick="return checkSubmit();" />
781
782         </div></form>
783         <?php       $this->pagefoot();
784         exit;
785     }
786
787     /**
788      * @todo document this
789      */
790     function batchAskDeleteConfirmation($type, $ids) {
791         global $manager;
792
793         $this->pagehead();
794         ?>
795         <h2><?php echo _BATCH_DELETE_CONFIRM?></h2>
796         <form method="post" action="index.php"><div>
797
798             <input type="hidden" name="action" value="batch<?php echo $type?>" />
799             <?php $manager->addTicketHidden() ?>
800             <input type="hidden" name="batchaction" value="delete" />
801             <input type="hidden" name="confirmation" value="yes" />
802             <?php               // insert selected item numbers
803                 $idx = 0;
804                 foreach ($ids as $id)
805                     echo '<input type="hidden" name="batch[',($idx++),']" value="',intval($id),'" />';
806
807                 // add hidden vars for team & comment
808                 if ($type == 'team')
809                 {
810                     echo '<input type="hidden" name="blogid" value="',intRequestVar('blogid'),'" />';
811                 }
812                 if ($type == 'comment')
813                 {
814                     echo '<input type="hidden" name="itemid" value="',intRequestVar('itemid'),'" />';
815                 }
816
817             ?>
818
819             <input type="submit" value="<?php echo _BATCH_DELETE_CONFIRM_BTN?>" onclick="return checkSubmit();" />
820
821         </div></form>
822         <?php       $this->pagefoot();
823         exit;
824     }
825
826
827     /**
828      * Inserts a HTML select element with choices for all categories to which the current
829      * member has access
830      * @see function selectBlog
831      */
832     function selectBlogCategory($name, $selected = 0, $tabindex = 0, $showNewCat = 0, $iForcedBlogInclude = -1) {
833         Admin::selectBlog($name, 'category', $selected, $tabindex, $showNewCat, $iForcedBlogInclude);
834     }
835
836         /**
837          * Admin::selectBlog()
838          * Inserts a HTML select element with choices for all blogs to which the user has access
839          *  mode = 'blog' => shows blognames and values are blogids
840          *  mode = 'category' => show category names and values are catids
841          * 
842          * @param       string  $name                           name of 
843          * @param       string  $mode                           blog/category
844          * @param       integer $selected                       category ID to be selected
845          * @param       integer $tabindex                       tab index value
846          * @param       integer $showNewCat                     show category to newly be created
847          * @param       integer $iForcedBlogInclude     ID of a blog that always needs to be included,
848          *                                              without checking if the member is on the blog team (-1 = none)
849          * @return      void
850          */
851         public function selectBlog($name, $mode='blog', $selected = 0, $tabindex = 0, $showNewCat = 0, $iForcedBlogInclude = -1)
852         {
853                 global $member, $CONF;
854                 
855                 // 0. get IDs of blogs to which member can post items (+ forced blog)
856                 $aBlogIds = array();
857                 if ( $iForcedBlogInclude != -1 )
858                 {
859                         $aBlogIds[] = intval($iForcedBlogInclude);
860                 }
861                 
862                 if ( !$member->isAdmin() || !array_key_exists('ShowAllBlogs', $CONF) || !$CONF['ShowAllBlogs'] )
863                 {
864                         $query = "SELECT bnumber FROM %s,%s WHERE tblog=bnumber and tmember=%d;";
865                         $query = sprintf($query, sql_table('blog'), sql_table('team'), (integer) $member->getID());
866                 }
867                 else
868                 {
869                         $query = "SELECT bnumber FROM %s ORDER BY bname;";
870                         $query = sprintf($query, sql_table('blog'));
871                 }
872                 
873                 $rblogids = sql_query($query);
874                 while ( $o = sql_fetch_object($rblogids) )
875                 {
876                         if ( $o->bnumber != $iForcedBlogInclude )
877                         {
878                                 $aBlogIds[] = (integer) $o->bnumber;
879                         }
880                 }
881                 if ( count($aBlogIds) == 0 )
882                 {
883                         return;
884                 }
885                 
886                 echo "<select name=\"{$name}\" tabindex=\"{$tabindex}\">\n";
887                 
888                 // 1. select blogs (we'll create optiongroups)
889                 // (only select those blogs that have the user on the team)
890                 $query = "SELECT bnumber, bname FROM %s WHERE bnumber in ('%s') ORDER BY bname;";
891                 $query = sprintf($query, sql_table('blog'), implode(',',$aBlogIds));
892                 $blogs = sql_query($query);
893                 
894                 if ( $mode == 'category' )
895                 {
896                         if ( sql_num_rows($blogs) > 1 )
897                         {
898                                 $multipleBlogs = 1;
899                         }
900                         
901                         while ( $oBlog = sql_fetch_object($blogs) )
902                         {
903                                 if ( $multipleBlogs )
904                                 {
905                                         echo '<optgroup label="' . Entity::hsc($oBlog->bname) . '">' . "\n";
906                                 }
907                                 
908                                 // show selection to create new category when allowed/wanted
909                                 if ( $showNewCat )
910                                 {
911                                         // check if allowed to do so
912                                         if ( $member->blogAdminRights($oBlog->bnumber) )
913                                         {
914                                                 echo "<option value=\"newcat-{$oBlog->bnumber}\">" . _ADD_NEWCAT . "</option>\n";
915                                         }
916                                 }
917                                 
918                                 // 2. for each category in that blog
919                                 $query = "SELECT cname, catid FROM %s WHERE cblog=%d ORDER BY cname ASC;";
920                                 $query = sprintf($query, sql_table('category'), (integer) $oBlog->bnumber);
921                                 $categories = sql_query($query);
922                                 while ( $oCat = sql_fetch_object($categories) )
923                                 {
924                                         if ( $oCat->catid != $selected )
925                                         {
926                                         echo "<option value=\"{$oCat->catid}\" {$selectText} >" . Entity::hsc($oCat->cname) . "</option>\n";
927                                         }
928                                         else
929                                         {
930                                         echo "<option value=\"{$oCat->catid}\" selected=\"selected\" >" . Entity::hsc($oCat->cname) . "</option>\n";
931                                         }
932                                 }
933                                 
934                                 if ( $multipleBlogs )
935                                 {
936                                         echo "</optgroup>\n";
937                                 }
938                         }
939                 }
940                 else
941                 {
942                         // blog mode
943                         while ( $oBlog = sql_fetch_object($blogs) )
944                         {
945                                 if ( $oBlog->bnumber != $selected )
946                                 {
947                                         echo "<option value=\"{$oBlog->bnumber}\">" . Entity::hsc($oBlog->bname) . "</option>\n";
948                                 }
949                                 else
950                                 {
951                                         echo "<option value=\"{$oBlog->bnumber}\" selected=\"selected\">" . Entity::hsc($oBlog->bname) . "</option>\n";
952                                 }
953                         }
954                 }
955                 echo "</select>\n";
956                 return;
957         }
958         
959     /**
960      * @todo document this
961      */
962     function action_browseownitems() {
963         global $member, $manager, $CONF;
964
965         $this->pagehead();
966
967         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
968         echo '<h2>' . _ITEMLIST_YOUR. '</h2>';
969
970         // start index
971         if (postVar('start'))
972             $start = intPostVar('start');
973         else
974             $start = 0;
975
976         // amount of items to show
977         if (postVar('amount'))
978             $amount = intPostVar('amount');
979         else {
980             $amount = intval($CONF['DefaultListSize']);
981             if ($amount < 1)
982                 $amount = 10;
983         }
984
985         $search = postVar('search');    // search through items
986
987         $query =  'SELECT bshortname, cname, mname, ititle, ibody, idraft, inumber, itime'
988                . ' FROM '.sql_table('item').', '.sql_table('blog') . ', '.sql_table('member') . ', '.sql_table('category')
989                . ' WHERE iauthor='. $member->getID() .' and iauthor=mnumber and iblog=bnumber and icat=catid';
990
991         if ($search)
992             $query .= ' and ((ititle LIKE "%' . sql_real_escape_string($search) . '%") or (ibody LIKE "%' . sql_real_escape_string($search) . '%") or (imore LIKE "%' . sql_real_escape_string($search) . '%"))';
993
994         $query .= ' ORDER BY itime DESC'
995                 . " LIMIT $start,$amount";
996
997         $template['content'] = 'itemlist';
998         $template['now'] = time();
999
1000         $manager->loadClass("ENCAPSULATE");
1001         $navList = new NavList('browseownitems', $start, $amount, 0, 1000, /*$blogid*/ 0, $search, 0);
1002         $navList->showBatchList('item',$query,'table',$template);
1003
1004         $this->pagefoot();
1005
1006     }
1007
1008     /**
1009      * Show all the comments for a given item
1010      * @param int $itemid
1011      */
1012     function action_itemcommentlist($itemid = '') {
1013         global $member, $manager, $CONF;
1014
1015         if ($itemid == '')
1016             $itemid = intRequestVar('itemid');
1017
1018         // only allow if user is allowed to alter item
1019         $member->canAlterItem($itemid) or $this->disallow();
1020
1021         $blogid = getBlogIdFromItemId($itemid);
1022
1023         $this->pagehead();
1024
1025         // start index
1026         if (postVar('start'))
1027             $start = intPostVar('start');
1028         else
1029             $start = 0;
1030
1031         // amount of items to show
1032         if (postVar('amount'))
1033             $amount = intPostVar('amount');
1034         else {
1035             $amount = intval($CONF['DefaultListSize']);
1036             if ($amount < 1)
1037                 $amount = 10;
1038         }
1039
1040         $search = postVar('search');
1041
1042         echo '<p>(<a href="index.php?action=itemlist&amp;blogid=',$blogid,'">',_BACKTOOVERVIEW,'</a>)</p>';
1043         echo '<h2>',_COMMENTS,'</h2>';
1044
1045         $query = 'SELECT cbody, cuser, cmail, cemail, mname, ctime, chost, cnumber, cip, citem FROM ' . sql_table('comment') . ' LEFT OUTER JOIN ' . sql_table('member') . ' ON mnumber = cmember WHERE citem = ' . $itemid;
1046
1047         if ($search)
1048             $query .= ' and cbody LIKE "%' . sql_real_escape_string($search) . '%"';
1049
1050         $query .= ' ORDER BY ctime ASC'
1051                 . " LIMIT $start,$amount";
1052
1053         $template['content'] = 'commentlist';
1054         $template['canAddBan'] = $member->blogAdminRights(getBlogIDFromItemID($itemid));
1055
1056         $manager->loadClass("ENCAPSULATE");
1057         $navList = new NavList('itemcommentlist', $start, $amount, 0, 1000, 0, $search, $itemid);
1058         $navList->showBatchList('comment',$query,'table',$template,_NOCOMMENTS);
1059
1060         $this->pagefoot();
1061     }
1062
1063     /**
1064      * Browse own comments
1065      */
1066     function action_browseowncomments() {
1067         global $member, $manager, $CONF;
1068
1069         // start index
1070         if (postVar('start'))
1071             $start = intPostVar('start');
1072         else
1073             $start = 0;
1074
1075         // amount of items to show
1076         if (postVar('amount'))
1077             $amount = intPostVar('amount');
1078         else {
1079             $amount = intval($CONF['DefaultListSize']);
1080             if ($amount < 1)
1081                 $amount = 10;
1082         }
1083
1084         $search = postVar('search');
1085
1086
1087         $query =  'SELECT cbody, cuser, cmail, mname, ctime, chost, cnumber, cip, citem FROM '.sql_table('comment').' LEFT OUTER JOIN '.sql_table('member').' ON mnumber=cmember WHERE cmember=' . $member->getID();
1088
1089         if ($search)
1090             $query .= ' and cbody LIKE "%' . sql_real_escape_string($search) . '%"';
1091
1092         $query .= ' ORDER BY ctime DESC'
1093                 . " LIMIT $start,$amount";
1094
1095         $this->pagehead();
1096
1097         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
1098         echo '<h2>', _COMMENTS_YOUR ,'</h2>';
1099
1100         $template['content'] = 'commentlist';
1101         $template['canAddBan'] = 0; // doesn't make sense to allow banning yourself
1102
1103         $manager->loadClass("ENCAPSULATE");
1104         $navList = new NavList('browseowncomments', $start, $amount, 0, 1000, 0, $search, 0);
1105         $navList->showBatchList('comment',$query,'table',$template,_NOCOMMENTS_YOUR);
1106
1107         $this->pagefoot();
1108     }
1109
1110     /**
1111      * Browse all comments for a weblog
1112      * @param int $blogid
1113      */
1114     function action_blogcommentlist($blogid = '')
1115     {
1116         global $member, $manager, $CONF;
1117
1118         if ($blogid == '')
1119             $blogid = intRequestVar('blogid');
1120         else
1121             $blogid = intval($blogid);
1122
1123         $member->teamRights($blogid) or $member->isAdmin() or $this->disallow();
1124
1125         // start index
1126         if (postVar('start'))
1127             $start = intPostVar('start');
1128         else
1129             $start = 0;
1130
1131         // amount of items to show
1132         if (postVar('amount'))
1133             $amount = intPostVar('amount');
1134         else {
1135             $amount = intval($CONF['DefaultListSize']);
1136             if ($amount < 1)
1137                 $amount = 10;
1138         }
1139
1140         $search = postVar('search');        // search through comments
1141
1142
1143         $query =  'SELECT cbody, cuser, cemail, cmail, mname, ctime, chost, cnumber, cip, citem FROM '.sql_table('comment').' LEFT OUTER JOIN '.sql_table('member').' ON mnumber=cmember WHERE cblog=' . intval($blogid);
1144
1145         if ($search != '')
1146             $query .= ' and cbody LIKE "%' . sql_real_escape_string($search) . '%"';
1147
1148
1149         $query .= ' ORDER BY ctime DESC'
1150                 . " LIMIT $start,$amount";
1151
1152
1153         $blog =& $manager->getBlog($blogid);
1154
1155         $this->pagehead();
1156
1157         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
1158         echo '<h2>', _COMMENTS_BLOG , ' ' , $this->bloglink($blog), '</h2>';
1159
1160         $template['content'] = 'commentlist';
1161         $template['canAddBan'] = $member->blogAdminRights($blogid);
1162
1163         $manager->loadClass("ENCAPSULATE");
1164         $navList = new NavList('blogcommentlist', $start, $amount, 0, 1000, $blogid, $search, 0);
1165         $navList->showBatchList('comment',$query,'table',$template, _NOCOMMENTS_BLOG);
1166
1167         $this->pagefoot();
1168     }
1169         
1170         /**
1171          * Admin::action_createitem()
1172          * Provide a page to item a new item to the given blog
1173          * 
1174          * @param       void
1175          * @return      void
1176          */
1177         public function action_createitem()
1178         {
1179                 global $member, $manager;
1180                 
1181                 $blogid = intRequestVar('blogid');
1182                 
1183                 // check if allowed
1184                 $member->teamRights($blogid) or $this->disallow();
1185                 
1186                 $memberid = $member->getID();
1187                 
1188                 $blog =& $manager->getBlog($blogid);
1189                 
1190                 $this->pagehead();
1191                 
1192                 // generate the add-item form
1193                 $formfactory = new PageFactory($blogid);
1194                 $formfactory->createAddForm('admin');
1195                 
1196                 $this->pagefoot();
1197                 return;
1198         }
1199         
1200         /**
1201          * Admin::action_itemedit()
1202          * 
1203          * @param       void
1204          * @return      void
1205          */
1206         public function action_itemedit()
1207         {
1208                 global $member, $manager;
1209                 
1210                 $itemid = intRequestVar('itemid');
1211                 
1212                 // only allow if user is allowed to alter item
1213                 $member->canAlterItem($itemid) or $this->disallow();
1214                 
1215                 $item =& $manager->getItem($itemid, 1, 1);
1216                 $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
1217                 
1218                 $manager->notify('PrepareItemForEdit', array('item' => &$item));
1219                 
1220                 if ( $blog->convertBreaks() )
1221                 {
1222                         $item['body'] = removeBreaks($item['body']);
1223                         $item['more'] = removeBreaks($item['more']);
1224                 }
1225                 
1226                 // form to edit blog items
1227                 $this->pagehead();
1228                 $formfactory = new PageFactory($blog->getID());
1229                 $formfactory->createEditForm('admin', $item);
1230                 $this->pagefoot();
1231                 return;
1232         }
1233         
1234     /**
1235      * @todo document this
1236      */
1237     function action_itemupdate() {
1238         global $member, $manager, $CONF;
1239
1240         $itemid = intRequestVar('itemid');
1241         $catid = postVar('catid');
1242
1243         // only allow if user is allowed to alter item
1244         $member->canUpdateItem($itemid, $catid) or $this->disallow();
1245
1246         $actiontype = postVar('actiontype');
1247
1248         // delete actions are handled by itemdelete (which has confirmation)
1249         if ($actiontype == 'delete') {
1250             $this->action_itemdelete();
1251             return;
1252         }
1253
1254         $body   = postVar('body');
1255         $title  = postVar('title');
1256         $more   = postVar('more');
1257         $closed = intPostVar('closed');
1258         $draftid = intPostVar('draftid');
1259
1260         // default action = add now
1261         if (!$actiontype)
1262             $actiontype='addnow';
1263
1264         // create new category if needed
1265         if (strstr($catid,'newcat')) {
1266             // get blogid
1267             list($blogid) = sscanf($catid,"newcat-%d");
1268
1269             // create
1270             $blog =& $manager->getBlog($blogid);
1271             $catid = $blog->createNewCategory();
1272
1273             // show error when sth goes wrong
1274             if (!$catid)
1275                 $this->doError(_ERROR_CATCREATEFAIL);
1276         }
1277
1278         /*
1279             set some variables based on actiontype
1280
1281             actiontypes:
1282                 draft items -> addnow, addfuture, adddraft, delete
1283                 non-draft items -> edit, changedate, delete
1284
1285             variables set:
1286                 $timestamp: set to a nonzero value for future dates or date changes
1287                 $wasdraft: set to 1 when the item used to be a draft item
1288                 $publish: set to 1 when the edited item is not a draft
1289         */
1290         $blogid =  getBlogIDFromItemID($itemid);
1291         $blog   =& $manager->getBlog($blogid);
1292
1293         $wasdrafts = array('adddraft', 'addfuture', 'addnow');
1294         $wasdraft  = in_array($actiontype, $wasdrafts) ? 1 : 0;
1295         $publish   = ($actiontype != 'adddraft' && $actiontype != 'backtodrafts') ? 1 : 0;
1296         if ($actiontype == 'addfuture' || $actiontype == 'changedate') {
1297             $timestamp = mktime(intPostVar('hour'), intPostVar('minutes'), 0, intPostVar('month'), intPostVar('day'), intPostVar('year'));
1298         } else {
1299             $timestamp =0;
1300         }
1301
1302         // edit the item for real
1303         Item::update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp);
1304
1305         $this->updateFuturePosted($blogid);
1306
1307         if ($draftid > 0) {
1308             // delete permission is checked inside Item::delete()
1309             Item::delete($draftid);
1310         }
1311
1312         // show category edit window when we created a new category
1313         // ($catid will then be a new category ID, while postVar('catid') will be 'newcat-x')
1314         if ($catid != intPostVar('catid')) {
1315             $this->action_categoryedit(
1316                 $catid,
1317                 $blog->getID(),
1318                 $CONF['AdminURL'] . 'index.php?action=itemlist&blogid=' . getBlogIDFromItemID($itemid)
1319             );
1320         } else {
1321             // TODO: set start item correctly for itemlist
1322             $this->action_itemlist(getBlogIDFromItemID($itemid));
1323         }
1324     }
1325         
1326         /**
1327          * Admin::action_itemdelete()
1328          * Delete item
1329          * 
1330          * @param       Void
1331          * @return      Void
1332          */
1333         function action_itemdelete()
1334         {
1335                 global $member, $manager;
1336                 
1337                 $itemid = intRequestVar('itemid');
1338                 
1339                 // only allow if user is allowed to alter item
1340                 $member->canAlterItem($itemid) or $this->disallow();
1341                 
1342                 if ( !$manager->existsItem($itemid,1,1) )
1343                 {
1344                         $this->error(_ERROR_NOSUCHITEM);
1345                 }
1346                 
1347                 $item =& $manager->getItem($itemid,1,1);
1348                 $title = Entity::hsc(strip_tags($item['title']));
1349                 $body = strip_tags($item['body']);
1350                 $body = Entity::hsc(Entity::shorten($body,300,'...'));
1351                 
1352                 $this->pagehead();
1353                 echo '<h2>' . _DELETE_CONFIRM . "</h2>\n";
1354                 echo '<p>' . _CONFIRMTXT_ITEM . "</p>\n";
1355                 echo "<div class=\"note\">\n";
1356                 echo "<b>{$title}</b>\n";
1357                 echo "<br />\n";
1358                 echo "{$body}\n";
1359                 echo "</div>\n";
1360                 echo "<form method=\"post\" action=\"index.php\">\n";
1361                 echo "<div>\n";
1362                 echo "<input type=\"hidden\" name=\"action\" value=\"itemdeleteconfirm\" />\n";
1363                 echo $manager->addTicketHidden() . "\n";
1364                 echo "<input type=\"hidden\" name=\"itemid\" value=\"{$itemid}\" />\n";
1365                 echo '<input type="submit" value="' . _DELETE_CONFIRM_BTN . "\"  tabindex=\"10\" />\n";
1366                 echo "</div>\n";
1367                 echo "</form>\n";
1368                 $this->pagefoot();
1369                 return;
1370         }
1371         
1372     /**
1373      * @todo document this
1374      */
1375     function action_itemdeleteconfirm() {
1376         global $member;
1377
1378         $itemid = intRequestVar('itemid');
1379
1380         // only allow if user is allowed to alter item
1381         $member->canAlterItem($itemid) or $this->disallow();
1382
1383         // get blogid first
1384         $blogid = getBlogIdFromItemId($itemid);
1385
1386         // delete item (note: some checks will be performed twice)
1387         $this->deleteOneItem($itemid);
1388
1389         $this->action_itemlist($blogid);
1390     }
1391
1392     /**
1393      * Deletes one item and returns error if something goes wrong
1394      * @param int $itemid
1395      */
1396     function deleteOneItem($itemid) {
1397         global $member, $manager;
1398
1399         // only allow if user is allowed to alter item (also checks if itemid exists)
1400         if (!$member->canAlterItem($itemid))
1401             return _ERROR_DISALLOWED;
1402
1403         // need to get blogid before the item is deleted
1404         $blogid = getBlogIDFromItemId($itemid);
1405
1406         $manager->loadClass('ITEM');
1407         Item::delete($itemid);
1408
1409         // update blog's futureposted
1410         $this->updateFuturePosted($blogid);
1411     }
1412
1413         /**
1414          * Admin::updateFuturePosted()
1415          * Update a blog's future posted flag
1416          * 
1417          * @param integer $blogid
1418          * @return      void
1419          * 
1420          */
1421         function updateFuturePosted($blogid)
1422         {
1423                 global $manager;
1424                 
1425                 $blog =& $manager->getBlog($blogid);
1426                 $currenttime = $blog->getCorrectTime(time());
1427                 
1428                 $query = "SELECT * FROM %s WHERE iblog=%d AND iposted=0 AND itime>'%s'";
1429                 $query = sprintf($query, sql_table('item'), (integer) $blogid, i18n::formatted_datetime('mysql', $currenttime));
1430                 $result = sql_query($query);
1431                 
1432                 if ( sql_num_rows($result) > 0 )
1433                 {
1434                                 $blog->setFuturePost();
1435                 }
1436                 else
1437                 {
1438                                 $blog->clearFuturePost();
1439                 }
1440                 return;
1441         }
1442
1443     /**
1444      * @todo document this
1445      */
1446     function action_itemmove() {
1447         global $member, $manager;
1448
1449         $itemid = intRequestVar('itemid');
1450
1451         // only allow if user is allowed to alter item
1452         $member->canAlterItem($itemid) or $this->disallow();
1453
1454         $item =& $manager->getItem($itemid,1,1);
1455
1456         $this->pagehead();
1457         ?>
1458             <h2><?php echo _MOVE_TITLE?></h2>
1459             <form method="post" action="index.php"><div>
1460                 <input type="hidden" name="action" value="itemmoveto" />
1461                 <input type="hidden" name="itemid" value="<?php echo  $itemid; ?>" />
1462
1463                 <?php
1464
1465                     $manager->addTicketHidden();
1466                     $this->selectBlogCategory('catid',$item['catid'],10,1);
1467                 ?>
1468
1469                 <input type="submit" value="<?php echo _MOVE_BTN?>" tabindex="10000" onclick="return checkSubmit();" />
1470             </div></form>
1471         <?php
1472         $this->pagefoot();
1473     }
1474
1475     /**
1476      * @todo document this
1477      */
1478     function action_itemmoveto() {
1479         global $member, $manager;
1480
1481         $itemid = intRequestVar('itemid');
1482         $catid = requestVar('catid');
1483
1484         // create new category if needed
1485         if (strstr($catid,'newcat')) {
1486             // get blogid
1487             list($blogid) = sscanf($catid,'newcat-%d');
1488
1489             // create
1490             $blog =& $manager->getBlog($blogid);
1491             $catid = $blog->createNewCategory();
1492
1493             // show error when sth goes wrong
1494             if (!$catid)
1495                 $this->doError(_ERROR_CATCREATEFAIL);
1496         }
1497
1498         // only allow if user is allowed to alter item
1499         $member->canUpdateItem($itemid, $catid) or $this->disallow();
1500
1501         $old_blogid = getBlogIDFromItemId($itemid);
1502
1503         Item::move($itemid, $catid);
1504
1505         // set the futurePosted flag on the blog
1506         $this->updateFuturePosted(getBlogIDFromItemId($itemid));
1507
1508         // reset the futurePosted in case the item is moved from one blog to another
1509         $this->updateFuturePosted($old_blogid);
1510
1511         if ($catid != intRequestVar('catid'))
1512             $this->action_categoryedit($catid, $blog->getID());
1513         else
1514             $this->action_itemlist(getBlogIDFromCatID($catid));
1515     }
1516
1517     /**
1518      * Moves one item to a given category (category existance should be checked by caller)
1519      * errors are returned
1520      * @param int $itemid
1521      * @param int $destCatid category ID to which the item will be moved
1522      */
1523     function moveOneItem($itemid, $destCatid) {
1524         global $member;
1525
1526         // only allow if user is allowed to move item
1527         if (!$member->canUpdateItem($itemid, $destCatid))
1528             return _ERROR_DISALLOWED;
1529
1530         Item::move($itemid, $destCatid);
1531     }
1532
1533     /**
1534      * Adds a item to the chosen blog
1535      */
1536     function action_additem() {
1537         global $manager, $CONF;
1538
1539         $manager->loadClass('ITEM');
1540
1541         $result = Item::createFromRequest();
1542
1543         if ($result['status'] == 'error')
1544             $this->error($result['message']);
1545
1546         $blogid = getBlogIDFromItemID($result['itemid']);
1547         $blog =& $manager->getBlog($blogid);
1548         $btimestamp = $blog->getCorrectTime();
1549         $item       = $manager->getItem(intval($result['itemid']), 1, 1);
1550
1551         if ($result['status'] == 'newcategory') {
1552             $distURI = $manager->addTicketToUrl($CONF['AdminURL'] . 'index.php?action=itemList&blogid=' . intval($blogid));
1553             $this->action_categoryedit($result['catid'], $blogid, $distURI);
1554         } else {
1555             $methodName = 'action_itemList';
1556             call_user_func(array(&$this, $methodName), $blogid);
1557         }
1558     }
1559
1560         /**
1561          * Allows to edit previously made comments
1562          **/
1563         function action_commentedit() {
1564
1565                 global $member, $manager;
1566
1567                 $commentid = intRequestVar('commentid');
1568
1569                 $member->canAlterComment($commentid) or $this->disallow();
1570
1571                 $comment = Comment::getComment($commentid);
1572
1573                 $manager->notify('PrepareCommentForEdit', array('comment' => &$comment) );
1574
1575                 // change <br /> to \n
1576                 $comment['body'] = str_replace('<br />', '', $comment['body']);
1577
1578                 // replaced eregi_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
1579                 /* original eregi_replace: eregi_replace("<a href=['\"]([^'\"]+)['\"]( rel=\"nofollow\")?>[^<]*</a>", "\\1", $comment['body']) */
1580
1581         $comment['body'] = preg_replace("#<a href=['\"]([^'\"]+)['\"]( rel=\"nofollow\")?>[^<]*</a>#i", "\\1", $comment['body']);
1582
1583         $this->pagehead();
1584
1585         ?>
1586         <h2><?php echo _EDITC_TITLE?></h2>
1587
1588         <form action="index.php" method="post"><div>
1589
1590         <input type="hidden" name="action" value="commentupdate" />
1591         <?php $manager->addTicketHidden(); ?>
1592         <input type="hidden" name="commentid" value="<?php echo  $commentid; ?>" />
1593         <table><tr>
1594             <th colspan="2"><?php echo _EDITC_TITLE?></th>
1595         </tr><tr>
1596             <td><?php echo _EDITC_WHO?></td>
1597             <td>
1598             <?php               if ($comment['member'])
1599                     echo $comment['member'] . " (" . _EDITC_MEMBER . ")";
1600                 else
1601                     echo $comment['user'] . " (" . _EDITC_NONMEMBER . ")";
1602             ?>
1603             </td>
1604         </tr><tr>
1605             <td><?php echo _EDITC_WHEN?></td>
1606             <td><?php echo  date("Y-m-d @ H:i",$comment['timestamp']); ?></td>
1607         </tr><tr>
1608             <td><?php echo _EDITC_HOST?></td>
1609             <td><?php echo  $comment['host']; ?></td>
1610         </tr>
1611         <tr>
1612             <td><?php echo _EDITC_URL; ?></td>
1613             <td><input type="text" name="url" size="30" tabindex="6" value="<?php echo $comment['userid']; ?>" /></td>
1614         </tr>
1615         <tr>
1616             <td><?php echo _EDITC_EMAIL; ?></td>
1617             <td><input type="text" name="email" size="30" tabindex="8" value="<?php echo $comment['email']; ?>" /></td>
1618         </tr>
1619         <tr>
1620             <td><?php echo _EDITC_TEXT?></td>
1621             <td>
1622                 <textarea name="body" tabindex="10" rows="10" cols="50"><?php                   // htmlspecialchars not needed (things should be escaped already)
1623                     echo $comment['body'];
1624                 ?></textarea>
1625             </td>
1626         </tr><tr>
1627             <td><?php echo _EDITC_EDIT?></td>
1628             <td><input type="submit"  tabindex="20" value="<?php echo _EDITC_EDIT?>" onclick="return checkSubmit();" /></td>
1629         </tr></table>
1630
1631         </div></form>
1632         <?php
1633         $this->pagefoot();
1634     }
1635
1636     /**
1637      * @todo document this
1638      */
1639     function action_commentupdate() {
1640         global $member, $manager;
1641
1642         $commentid = intRequestVar('commentid');
1643
1644         $member->canAlterComment($commentid) or $this->disallow();
1645
1646         $url = postVar('url');
1647         $email = postVar('email');
1648         $body = postVar('body');
1649
1650                 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
1651                 # original eregi: eregi("[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}", $body) != FALSE
1652                 # important note that '\' must be matched with '\\\\' in preg* expressions
1653
1654                 // intercept words that are too long
1655                 if (preg_match('#[a-zA-Z0-9|\.,;:!\?=\/\\\\]{90,90}#', $body) != FALSE)
1656                 {
1657                         $this->error(_ERROR_COMMENT_LONGWORD);
1658                 }
1659
1660                 // check length
1661                 if (i18n::strlen($body) < 3)
1662                 {
1663                         $this->error(_ERROR_COMMENT_NOCOMMENT);
1664                 }
1665
1666                 if (i18n::strlen($body) > 5000)
1667                 {
1668                         $this->error(_ERROR_COMMENT_TOOLONG);
1669                 }
1670
1671         // prepare body
1672         $body = Comment::prepareBody($body);
1673
1674         // call plugins
1675         $manager->notify('PreUpdateComment',array('body' => &$body));
1676
1677         $query = 'UPDATE ' . sql_table('comment')
1678                . " SET cmail = '" . sql_real_escape_string($url) . "', cemail = '" . sql_real_escape_string($email) . "', cbody = '" . sql_real_escape_string($body) . "'"
1679                . " WHERE cnumber = " . $commentid;
1680         sql_query($query);
1681
1682         // get itemid
1683         $res = sql_query('SELECT citem FROM '.sql_table('comment').' WHERE cnumber=' . $commentid);
1684         $o = sql_fetch_object($res);
1685         $itemid = $o->citem;
1686
1687         if ($member->canAlterItem($itemid))
1688             $this->action_itemcommentlist($itemid);
1689         else
1690             $this->action_browseowncomments();
1691
1692     }
1693         
1694         /**
1695          * Admin::action_commentdelete()
1696          * Update comment
1697          * 
1698          * @param       Void
1699          * @return      Void
1700          */
1701         function action_commentdelete()
1702         {
1703                 global $member, $manager;
1704                 
1705                 $commentid = intRequestVar('commentid');
1706                 $member->canAlterComment($commentid) or $this->disallow();
1707                 $comment = Comment::getComment($commentid);
1708                 
1709                 $body = strip_tags($comment['body']);
1710                 $body = Entity::hsc(Entity::shorten($body, 300, '...'));
1711                 
1712                 if ( $comment['member'] )
1713                 {
1714                         $author = $comment['member'];
1715                 }
1716                 else
1717                 {
1718                         $author = $comment['user'];
1719                 }
1720                 
1721                 $this->pagehead();
1722                 
1723                 echo '<h2>' . _DELETE_CONFIRM . "</h2>\n";
1724                 echo '<p>' . _CONFIRMTXT_COMMENT . "</p>\n";
1725                 echo "<div class=\"note\">\n";
1726                 echo '<b>' . _EDITC_WHO . ":</b>{$author}<br />\n";
1727                 echo '<b>' . _EDITC_TEXT . ":</b>{$body}\n";
1728                 echo "</div>\n";
1729                 echo "<form method=\"post\" action=\"index.php\">\n";
1730                 echo "<div>\n";
1731                 echo "<input type=\"hidden\" name=\"action\" value=\"commentdeleteconfirm\" />\n";
1732                 echo $manager->addTicketHidden() . "\n";
1733                 echo "<input type=\"hidden\" name=\"commentid\" value=\"{$commentid}\" />\n";
1734                 echo '<input type="submit" tabindex="10" value="'. _DELETE_CONFIRM_BTN . "\" />\n";
1735                 echo "</div>\n";
1736                 echo "</form>\n";
1737                 $this->pagefoot();
1738                 return;
1739         }
1740         
1741     /**
1742      * @todo document this
1743      */
1744     function action_commentdeleteconfirm() {
1745         global $member;
1746
1747         $commentid = intRequestVar('commentid');
1748
1749         // get item id first
1750         $res = sql_query('SELECT citem FROM '.sql_table('comment') .' WHERE cnumber=' . $commentid);
1751         $o = sql_fetch_object($res);
1752         $itemid = $o->citem;
1753
1754         $error = $this->deleteOneComment($commentid);
1755         if ($error)
1756             $this->doError($error);
1757
1758         if ($member->canAlterItem($itemid))
1759             $this->action_itemcommentlist($itemid);
1760         else
1761             $this->action_browseowncomments();
1762     }
1763
1764     /**
1765      * @todo document this
1766      */
1767     function deleteOneComment($commentid) {
1768         global $member, $manager;
1769
1770         $commentid = intval($commentid);
1771
1772         if (!$member->canAlterComment($commentid))
1773             return _ERROR_DISALLOWED;
1774
1775         $manager->notify('PreDeleteComment', array('commentid' => $commentid));
1776
1777         // delete the comments associated with the item
1778         $query = 'DELETE FROM '.sql_table('comment').' WHERE cnumber=' . $commentid;
1779         sql_query($query);
1780
1781         $manager->notify('PostDeleteComment', array('commentid' => $commentid));
1782
1783         return '';
1784     }
1785
1786     /**
1787      * Usermanagement main
1788      */
1789     function action_usermanagement() {
1790         global $member, $manager;
1791
1792         // check if allowed
1793         $member->isAdmin() or $this->disallow();
1794
1795         $this->pagehead();
1796
1797         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
1798
1799         echo '<h2>' . _MEMBERS_TITLE .'</h2>';
1800
1801         echo '<h3>' . _MEMBERS_CURRENT .'</h3>';
1802
1803         // show list of members with actions
1804         $query =  'SELECT *'
1805                . ' FROM '.sql_table('member');
1806         $template['content'] = 'memberlist';
1807         $template['tabindex'] = 10;
1808
1809         $manager->loadClass("ENCAPSULATE");
1810         $batch = new Batch('member');
1811         $batch->showlist($query,'table',$template);
1812
1813         echo '<h3>' . _MEMBERS_NEW .'</h3>';
1814         ?>
1815             <form method="post" action="index.php" name="memberedit"><div>
1816
1817             <input type="hidden" name="action" value="memberadd" />
1818             <?php $manager->addTicketHidden() ?>
1819
1820             <table>
1821             <tr>
1822                 <th colspan="2"><?php echo _MEMBERS_NEW?></th>
1823             </tr><tr>
1824                 <td><?php echo _MEMBERS_DISPLAY?> <?php help('shortnames');?>
1825                 <br /><small><?php echo _MEMBERS_DISPLAY_INFO?></small>
1826                 </td>
1827                 <td><input tabindex="10010" name="name" size="32" maxlength="32" /></td>
1828             </tr><tr>
1829                 <td><?php echo _MEMBERS_REALNAME?></td>
1830                 <td><input name="realname" tabindex="10020" size="40" maxlength="60" /></td>
1831             </tr><tr>
1832                 <td><?php echo _MEMBERS_PWD?></td>
1833                 <td><input name="password" tabindex="10030" size="16" maxlength="40" type="password" /></td>
1834             </tr><tr>
1835                 <td><?php echo _MEMBERS_REPPWD?></td>
1836                 <td><input name="repeatpassword" tabindex="10035" size="16" maxlength="40" type="password" /></td>
1837             </tr><tr>
1838                 <td><?php echo _MEMBERS_EMAIL?></td>
1839                 <td><input name="email" tabindex="10040" size="40" maxlength="60" /></td>
1840             </tr><tr>
1841                 <td><?php echo _MEMBERS_URL?></td>
1842                 <td><input name="url" tabindex="10050" size="40" maxlength="100" /></td>
1843             </tr><tr>
1844                 <td><?php echo _MEMBERS_SUPERADMIN?> <?php help('superadmin'); ?></td>
1845                 <td><?php $this->input_yesno('admin',0,10060); ?> </td>
1846             </tr><tr>
1847                 <td><?php echo _MEMBERS_CANLOGIN?> <?php help('canlogin'); ?></td>
1848                 <td><?php $this->input_yesno('canlogin',1,10070); ?></td>
1849             </tr><tr>
1850                 <td><?php echo _MEMBERS_NOTES?></td>
1851                 <td><input name="notes" maxlength="100" size="40" tabindex="10080" /></td>
1852             </tr><tr>
1853                 <td><?php echo _MEMBERS_NEW?></td>
1854                 <td><input type="submit" value="<?php echo _MEMBERS_NEW_BTN?>" tabindex="10090" onclick="return checkSubmit();" /></td>
1855             </tr></table>
1856
1857             </div></form>
1858         <?php
1859         $this->pagefoot();
1860     }
1861
1862     /**
1863      * Edit member settings
1864      */
1865     function action_memberedit() {
1866         $this->action_editmembersettings(intRequestVar('memberid'));
1867     }
1868
1869         /**
1870          * @todo document this
1871          */
1872         function action_editmembersettings($memberid = '') {
1873                 global $member, $manager, $CONF;
1874                 
1875                 if ($memberid == '')
1876                 {
1877                         $memberid = $member->getID();
1878                 }
1879                 
1880                 // check if allowed
1881                 ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
1882                 
1883                 $extrahead = '<script type="text/javascript" src="javascript/numbercheck.js"></script>';
1884                 $this->pagehead($extrahead);
1885                 
1886                 // show message to go back to member overview (only for admins)
1887                 if ($member->isAdmin())
1888                 {
1889                         echo '<a href="index.php?action=usermanagement">(' ._MEMBERS_BACKTOOVERVIEW. ')</a>';
1890                 }
1891                 else
1892                 {
1893                         echo '<a href="index.php?action=overview">(' ._BACKHOME. ')</a>';
1894                 }
1895                 echo '<h2>' . _MEMBERS_EDIT . '</h2>';
1896                 
1897                 $mem = Member::createFromID($memberid);
1898                 ?>
1899                 <form method="post" action="index.php" name="memberedit"><div>
1900                 
1901                 <input type="hidden" name="action" value="changemembersettings" />
1902                 <input type="hidden" name="memberid" value="<?php echo  $memberid; ?>" />
1903                 <?php $manager->addTicketHidden() ?>
1904                 
1905                 <table><tr>
1906                         <th colspan="2"><?php echo _MEMBERS_EDIT?></th>
1907                 </tr><tr>
1908                         <td><?php echo _MEMBERS_DISPLAY?> <?php help('shortnames');?>
1909                                 <br /><small><?php echo _MEMBERS_DISPLAY_INFO?></small>
1910                         </td>
1911                         <td>
1912                         <?php if ($CONF['AllowLoginEdit'] || $member->isAdmin()) { ?>
1913                                 <input name="name" tabindex="10" maxlength="32" size="32" value="<?php echo  Entity::hsc($mem->getDisplayName()); ?>" />
1914                         <?php } else {
1915                                 echo Entity::hsc($member->getDisplayName());
1916                            }
1917                         ?>
1918                         </td>
1919                 </tr><tr>
1920                         <td><?php echo _MEMBERS_REALNAME?></td>
1921                         <td><input name="realname" tabindex="20" maxlength="60" size="40" value="<?php echo  Entity::hsc($mem->getRealName()); ?>" /></td>
1922                 </tr><tr>
1923                 <?php if ($CONF['AllowLoginEdit'] || $member->isAdmin()) { ?>
1924                         <td><?php echo _MEMBERS_PWD?></td>
1925                         <td><input type="password" tabindex="30" maxlength="40" size="16" name="password" /></td>
1926                 </tr><tr>
1927                         <td><?php echo _MEMBERS_REPPWD?></td>
1928                         <td><input type="password" tabindex="35" maxlength="40" size="16" name="repeatpassword" /></td>
1929                 <?php } ?>
1930                 </tr><tr>
1931                         <td><?php echo _MEMBERS_EMAIL?>
1932                                 <br /><small><?php echo _MEMBERS_EMAIL_EDIT?></small>
1933                         </td>
1934                         <td><input name="email" tabindex="40" size="40" maxlength="60" value="<?php echo  Entity::hsc($mem->getEmail()); ?>" /></td>
1935                 </tr><tr>
1936                         <td><?php echo _MEMBERS_URL?></td>
1937                         <td><input name="url" tabindex="50" size="40" maxlength="100" value="<?php echo  Entity::hsc($mem->getURL()); ?>" /></td>
1938                 <?php // only allow to change this by super-admins
1939                    // we don't want normal users to 'upgrade' themselves to super-admins, do we? ;-)
1940                    if ($member->isAdmin()) {
1941                 ?>
1942                         </tr><tr>
1943                                 <td><?php echo _MEMBERS_SUPERADMIN?> <?php help('superadmin'); ?></td>
1944                                 <td><?php $this->input_yesno('admin',$mem->isAdmin(),60); ?></td>
1945                         </tr><tr>
1946                                 <td><?php echo _MEMBERS_CANLOGIN?> <?php help('canlogin'); ?></td>
1947                                 <td><?php $this->input_yesno('canlogin',$mem->canLogin(),70,1,0,_YES,_NO,$mem->isAdmin()); ?></td>
1948                 <?php } ?>
1949                 </tr><tr>
1950                         <td><?php echo _MEMBERS_NOTES?></td>
1951                         <td><input name="notes" tabindex="80" size="40" maxlength="100" value="<?php echo  Entity::hsc($mem->getNotes()); ?>" /></td>
1952                 </tr><tr>
1953                         <td><?php echo _MEMBERS_LOCALE?> <?php help('locale'); ?>
1954                         </td>
1955                         <td>
1956                         
1957                                 <select name="locale" tabindex="85">
1958                                 <?php
1959                                 $locales = i18n::get_available_locale_list();
1960                                 if ( !$mem->getLocale() || !in_array($mem->getLocale(), $locales) )
1961                                 {
1962                                         echo "<option value=\"\" selected=\"selected\">" . Entity::hsc(_MEMBERS_USESITELANG) . "</option>\n";
1963                                 }
1964                                 else
1965                                 {
1966                                         echo "<option value=\"\">" . Entity::hsc(_MEMBERS_USESITELANG) . "</option>\n";
1967                                 }
1968                                 
1969                                 foreach( $locales as $locale )
1970                                 {
1971                                         if( $locale == $mem->getLocale() )
1972                                         {
1973                                                 echo "<option value=\"{$locale}\" selected=\"selected\">{$locale}</option>\n";
1974                                         }
1975                                         else
1976                                         {
1977                                                 echo "<option value=\"{$locale}\">{$locale}</option>\n";
1978                                         }
1979                                 }
1980                                 ?>
1981                                 </select>
1982                                 
1983                         </td>
1984                 </tr>
1985                 <tr>
1986                         <td><?php echo _MEMBERS_USEAUTOSAVE?> <?php help('autosave'); ?></td>
1987                         <td><?php $this->input_yesno('autosave', $mem->getAutosave(), 87); ?></td>
1988                 </tr>
1989                 <?php
1990                         // plugin options
1991                         $this->_insertPluginOptions('member',$memberid);
1992                 ?>
1993                 <tr>
1994                         <th colspan="2"><?php echo _MEMBERS_EDIT ?></th>
1995                 </tr><tr>
1996                         <td><?php echo _MEMBERS_EDIT?></td>
1997                         <td><input type="submit" tabindex="90" value="<?php echo _MEMBERS_EDIT_BTN?>" onclick="return checkSubmit();" /></td>
1998                 </tr></table>
1999                 
2000                 </div></form>
2001                 
2002                 <?php
2003                         echo '<h3>',_PLUGINS_EXTRA,'</h3>';
2004                         
2005                         $manager->notify(
2006                                 'MemberSettingsFormExtras',
2007                                 array(
2008                                         'member' => &$mem
2009                                 )
2010                         );
2011                 $this->pagefoot();
2012         }
2013         
2014     /**
2015      * @todo document this
2016      */
2017     function action_changemembersettings() {
2018         global $member, $CONF, $manager;
2019
2020         $memberid = intRequestVar('memberid');
2021
2022         // check if allowed
2023         ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
2024
2025         $name           = trim(strip_tags(postVar('name')));
2026         $realname       = trim(strip_tags(postVar('realname')));
2027         $password       = postVar('password');
2028         $repeatpassword = postVar('repeatpassword');
2029         $email          = strip_tags(postVar('email'));
2030         $url            = strip_tags(postVar('url'));
2031
2032                 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
2033                 # original eregi: !eregi("^https?://", $url)
2034
2035                 // begin if: sometimes user didn't prefix the URL with http:// or https://, this cause a malformed URL. Let's fix it.
2036                 if (!preg_match('#^https?://#', $url) )
2037                 {
2038                         $url = 'http://' . $url;
2039                 }
2040
2041         $admin          = postVar('admin');
2042         $canlogin       = postVar('canlogin');
2043         $notes          = strip_tags(postVar('notes'));
2044         $locale        = postVar('locale');
2045
2046         $mem = Member::createFromID($memberid);
2047
2048         if ($CONF['AllowLoginEdit'] || $member->isAdmin()) {
2049
2050             if (!isValidDisplayName($name))
2051                 $this->error(_ERROR_BADNAME);
2052
2053             if (($name != $mem->getDisplayName()) && Member::exists($name))
2054                 $this->error(_ERROR_NICKNAMEINUSE);
2055
2056             if ($password != $repeatpassword)
2057                 $this->error(_ERROR_PASSWORDMISMATCH);
2058
2059             if ($password && (i18n::strlen($password) < 6))
2060                 $this->error(_ERROR_PASSWORDTOOSHORT);
2061                 
2062             if ($password) {
2063                                 $pwdvalid = true;
2064                                 $pwderror = '';
2065                                 $manager->notify('PrePasswordSet',array('password' => $password, 'errormessage' => &$pwderror, 'valid' => &$pwdvalid));
2066                                 if (!$pwdvalid) {
2067                                         $this->error($pwderror);
2068                                 }
2069                         }
2070                 }
2071                 
2072                 if ( !NOTIFICATION::address_validation($email) )
2073                 {
2074                         $this->error(_ERROR_BADMAILADDRESS);
2075                 }
2076                 if ( !$realname )
2077                 {
2078                         $this->error(_ERROR_REALNAMEMISSING);
2079                 }
2080         if ( ($locale != '') && (!in_array($locale, i18n::get_available_locale_list())) )
2081             $this->error(_ERROR_NOSUCHTRANSLATION);
2082
2083         // check if there will remain at least one site member with both the logon and admin rights
2084         // (check occurs when taking away one of these rights from such a member)
2085         if (    (!$admin && $mem->isAdmin() && $mem->canLogin())
2086              || (!$canlogin && $mem->isAdmin() && $mem->canLogin())
2087            )
2088         {
2089             $r = sql_query('SELECT * FROM '.sql_table('member').' WHERE madmin=1 and mcanlogin=1');
2090             if (sql_num_rows($r) < 2)
2091                 $this->error(_ERROR_ATLEASTONEADMIN);
2092         }
2093
2094         if ($CONF['AllowLoginEdit'] || $member->isAdmin()) {
2095             $mem->setDisplayName($name);
2096             if ($password)
2097                 $mem->setPassword($password);
2098         }
2099
2100         $oldEmail = $mem->getEmail();
2101
2102         $mem->setRealName($realname);
2103         $mem->setEmail($email);
2104         $mem->setURL($url);
2105         $mem->setNotes($notes);
2106         $mem->setLocale($locale);
2107
2108
2109         // only allow super-admins to make changes to the admin status
2110         if ($member->isAdmin()) {
2111             $mem->setAdmin($admin);
2112             $mem->setCanLogin($canlogin);
2113         }
2114
2115         $autosave = postVar ('autosave');
2116         $mem->setAutosave($autosave);
2117
2118         $mem->write();
2119
2120         // store plugin options
2121         $aOptions = requestArray('plugoption');
2122         NucleusPlugin::apply_plugin_options($aOptions);
2123         $manager->notify('PostPluginOptionsUpdate',array('context' => 'member', 'memberid' => $memberid, 'member' => &$mem));
2124
2125         // if email changed, generate new password
2126         if ($oldEmail != $mem->getEmail())
2127         {
2128             $mem->sendActivationLink('addresschange', $oldEmail);
2129             // logout member
2130             $mem->newCookieKey();
2131
2132             // only log out if the member being edited is the current member.
2133             if ($member->getID() == $memberid)
2134                 $member->logout();
2135             $this->action_login(_MSG_ACTIVATION_SENT, 0);
2136             return;
2137         }
2138
2139
2140         if (  ( $mem->getID() == $member->getID() )
2141            && ( $mem->getDisplayName() != $member->getDisplayName() )
2142            ) {
2143             $mem->newCookieKey();
2144             $member->logout();
2145             $this->action_login(_MSG_LOGINAGAIN, 0);
2146         } else {
2147             $this->action_overview(_MSG_SETTINGSCHANGED);
2148         }
2149     }
2150
2151         /**
2152          * Admin::action_memberadd()
2153          * 
2154          * @param       void
2155          * @return      void
2156          * 
2157         */
2158         function action_memberadd()
2159         {
2160                 global $member, $manager;
2161                 
2162                 // check if allowed
2163                 $member->isAdmin() or $this->disallow();
2164                 
2165                 if ( postVar('password') != postVar('repeatpassword') )
2166                 {
2167                         $this->error(_ERROR_PASSWORDMISMATCH);
2168                 }
2169                 
2170                 if ( i18n::strlen(postVar('password')) < 6 )
2171                 {
2172                         $this->error(_ERROR_PASSWORDTOOSHORT);
2173                 }
2174                 
2175                 $res = Member::create(postVar('name'), postVar('realname'), postVar('password'), postVar('email'), postVar('url'), postVar('admin'), postVar('canlogin'), postVar('notes'));
2176                 if ( $res != 1 )
2177                 {
2178                         $this->error($res);
2179                 }
2180                 
2181                 // fire PostRegister event
2182                 $newmem = new Member();
2183                 $newmem->readFromName(postVar('name'));
2184                 $manager->notify('PostRegister',array('member' => &$newmem));
2185                 
2186                 $this->action_usermanagement();
2187                 return;
2188         }
2189
2190     /**
2191      * Account activation
2192      *
2193      * @author dekarma
2194      */
2195     function action_activate() {
2196
2197         $key = getVar('key');
2198         $this->_showActivationPage($key);
2199     }
2200
2201     /**
2202      * @todo document this
2203      */
2204     function _showActivationPage($key, $message = '')
2205     {
2206         global $manager;
2207
2208         // clean up old activation keys
2209         Member::cleanupActivationTable();
2210
2211         // get activation info
2212         $info = Member::getActivationInfo($key);
2213
2214         if (!$info)
2215             $this->error(_ERROR_ACTIVATE);
2216
2217         $mem = Member::createFromId($info->vmember);
2218
2219         if (!$mem)
2220             $this->error(_ERROR_ACTIVATE);
2221
2222         $text = '';
2223         $title = '';
2224         $bNeedsPasswordChange = true;
2225
2226         switch ($info->vtype)
2227         {
2228             case 'forgot':
2229                 $title = _ACTIVATE_FORGOT_TITLE;
2230                 $text = _ACTIVATE_FORGOT_TEXT;
2231                 break;
2232             case 'register':
2233                 $title = _ACTIVATE_REGISTER_TITLE;
2234                 $text = _ACTIVATE_REGISTER_TEXT;
2235                 break;
2236             case 'addresschange':
2237                 $title = _ACTIVATE_CHANGE_TITLE;
2238                 $text = _ACTIVATE_CHANGE_TEXT;
2239                 $bNeedsPasswordChange = false;
2240                 Member::activate($key);
2241                 break;
2242         }
2243
2244         $aVars = array(
2245             'memberName' => Entity::hsc($mem->getDisplayName())
2246         );
2247         $title = Template::fill($title, $aVars);
2248         $text = Template::fill($text, $aVars);
2249
2250         $this->pagehead();
2251
2252             echo '<h2>' , $title, '</h2>';
2253             echo '<p>' , $text, '</p>';
2254
2255             if ($message != '')
2256             {
2257                 echo '<p class="error">',$message,'</p>';
2258             }
2259
2260             if ($bNeedsPasswordChange)
2261             {
2262                 ?>
2263                     <div><form action="index.php" method="post">
2264
2265                         <input type="hidden" name="action" value="activatesetpwd" />
2266                         <?php $manager->addTicketHidden() ?>
2267                         <input type="hidden" name="key" value="<?php echo Entity::hsc($key) ?>" />
2268
2269                         <table><tr>
2270                             <td><?php echo _MEMBERS_PWD?></td>
2271                             <td><input type="password" maxlength="40" size="16" name="password" /></td>
2272                         </tr><tr>
2273                             <td><?php echo _MEMBERS_REPPWD?></td>
2274                             <td><input type="password" maxlength="40" size="16" name="repeatpassword" /></td>
2275                         <?php
2276
2277                             global $manager;
2278                             $manager->notify('FormExtra', array('type' => 'activation', 'member' => $mem));
2279
2280                         ?>
2281                         </tr><tr>
2282                             <td><?php echo _MEMBERS_SETPWD ?></td>
2283                             <td><input type='submit' value='<?php echo _MEMBERS_SETPWD_BTN ?>' /></td>
2284                         </tr></table>
2285
2286
2287                     </form></div>
2288
2289                 <?php
2290
2291             }
2292
2293         $this->pagefoot();
2294
2295     }
2296
2297     /**
2298      * Account activation - set password part
2299      *
2300      * @author dekarma
2301      */
2302     function action_activatesetpwd() {
2303
2304         $key = postVar('key');
2305
2306         // clean up old activation keys
2307         Member::cleanupActivationTable();
2308
2309         // get activation info
2310         $info = Member::getActivationInfo($key);
2311
2312         if (!$info || ($info->type == 'addresschange'))
2313             return $this->_showActivationPage($key, _ERROR_ACTIVATE);
2314
2315         $mem = Member::createFromId($info->vmember);
2316
2317         if (!$mem)
2318             return $this->_showActivationPage($key, _ERROR_ACTIVATE);
2319
2320         $password       = postVar('password');
2321         $repeatpassword = postVar('repeatpassword');
2322
2323         if ($password != $repeatpassword)
2324             return $this->_showActivationPage($key, _ERROR_PASSWORDMISMATCH);
2325
2326         if ($password && (i18n::strlen($password) < 6))
2327             return $this->_showActivationPage($key, _ERROR_PASSWORDTOOSHORT);
2328             
2329         if ($password) {
2330                         $pwdvalid = true;
2331                         $pwderror = '';
2332                         global $manager;
2333                         $manager->notify('PrePasswordSet',array('password' => $password, 'errormessage' => &$pwderror, 'valid' => &$pwdvalid));
2334                         if (!$pwdvalid) {
2335                                 return $this->_showActivationPage($key,$pwderror);
2336                         }
2337                 }
2338
2339         $error = '';
2340         
2341         $manager->notify('ValidateForm', array('type' => 'activation', 'member' => $mem, 'error' => &$error));
2342         if ($error != '')
2343             return $this->_showActivationPage($key, $error);
2344
2345
2346         // set password
2347         $mem->setPassword($password);
2348         $mem->write();
2349
2350         // do the activation
2351         Member::activate($key);
2352
2353         $this->pagehead();
2354             echo '<h2>',_ACTIVATE_SUCCESS_TITLE,'</h2>';
2355             echo '<p>',_ACTIVATE_SUCCESS_TEXT,'</p>';
2356         $this->pagefoot();
2357     }
2358
2359     /**
2360      * Manage team
2361      */
2362     function action_manageteam() {
2363         global $member, $manager;
2364
2365         $blogid = intRequestVar('blogid');
2366
2367         // check if allowed
2368         $member->blogAdminRights($blogid) or $this->disallow();
2369
2370         $this->pagehead();
2371
2372         echo "<p><a href='index.php?action=blogsettings&amp;blogid=$blogid'>(",_BACK_TO_BLOGSETTINGS,")</a></p>";
2373
2374         echo '<h2>' . _TEAM_TITLE . getBlogNameFromID($blogid) . '</h2>';
2375
2376         echo '<h3>' . _TEAM_CURRENT . '</h3>';
2377
2378
2379
2380         $query =  'SELECT tblog, tmember, mname, mrealname, memail, tadmin'
2381                . ' FROM '.sql_table('member').', '.sql_table('team')
2382                . ' WHERE tmember=mnumber and tblog=' . $blogid;
2383
2384         $template['content'] = 'teamlist';
2385         $template['tabindex'] = 10;
2386
2387         $manager->loadClass("ENCAPSULATE");
2388         $batch = new Batch('team');
2389         $batch->showlist($query, 'table', $template);
2390
2391         ?>
2392             <h3><?php echo _TEAM_ADDNEW?></h3>
2393
2394             <form method='post' action='index.php'><div>
2395
2396             <input type='hidden' name='action' value='teamaddmember' />
2397             <input type='hidden' name='blogid' value='<?php echo  $blogid; ?>' />
2398             <?php $manager->addTicketHidden() ?>
2399
2400             <table><tr>
2401                 <td><?php echo _TEAM_CHOOSEMEMBER?></td>
2402                 <td><?php                   // TODO: try to make it so only non-team-members are listed
2403                     $query =  'SELECT mname as text, mnumber as value'
2404                            . ' FROM '.sql_table('member');
2405
2406                     $template['name'] = 'memberid';
2407                     $template['tabindex'] = 10000;
2408                     showlist($query,'select',$template);
2409                 ?></td>
2410             </tr><tr>
2411                 <td><?php echo _TEAM_ADMIN?><?php help('teamadmin'); ?></td>
2412                 <td><?php $this->input_yesno('admin',0,10020); ?></td>
2413             </tr><tr>
2414                 <td><?php echo _TEAM_ADD?></td>
2415                 <td><input type='submit' value='<?php echo _TEAM_ADD_BTN?>' tabindex="10030" /></td>
2416             </tr></table>
2417
2418             </div></form>
2419         <?php
2420         $this->pagefoot();
2421     }
2422
2423     /**
2424      * Add member to team
2425      */
2426     function action_teamaddmember() {
2427         global $member, $manager;
2428
2429         $memberid = intPostVar('memberid');
2430         $blogid = intPostVar('blogid');
2431         $admin = intPostVar('admin');
2432
2433         // check if allowed
2434         $member->blogAdminRights($blogid) or $this->disallow();
2435
2436         $blog =& $manager->getBlog($blogid);
2437         if (!$blog->addTeamMember($memberid, $admin))
2438             $this->error(_ERROR_ALREADYONTEAM);
2439
2440         $this->action_manageteam();
2441
2442     }
2443
2444     /**
2445      * @todo document this
2446      */
2447     function action_teamdelete() {
2448         global $member, $manager;
2449
2450         $memberid = intRequestVar('memberid');
2451         $blogid = intRequestVar('blogid');
2452
2453         // check if allowed
2454         $member->blogAdminRights($blogid) or $this->disallow();
2455
2456         $teammem = Member::createFromID($memberid);
2457         $blog =& $manager->getBlog($blogid);
2458
2459         $this->pagehead();
2460         ?>
2461             <h2><?php echo _DELETE_CONFIRM?></h2>
2462
2463             <p><?php echo _CONFIRMTXT_TEAM1?><b><?php echo  Entity::hsc($teammem->getDisplayName()) ?></b><?php echo _CONFIRMTXT_TEAM2?><b><?php echo  Entity::hsc(strip_tags($blog->getName())) ?></b>
2464             </p>
2465
2466
2467             <form method="post" action="index.php"><div>
2468             <input type="hidden" name="action" value="teamdeleteconfirm" />
2469             <?php $manager->addTicketHidden() ?>
2470             <input type="hidden" name="memberid" value="<?php echo  $memberid; ?>" />
2471             <input type="hidden" name="blogid" value="<?php echo  $blogid; ?>" />
2472             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
2473             </div></form>
2474         <?php
2475         $this->pagefoot();
2476     }
2477
2478     /**
2479      * @todo document this
2480      */
2481     function action_teamdeleteconfirm() {
2482         global $member;
2483
2484         $memberid = intRequestVar('memberid');
2485         $blogid = intRequestVar('blogid');
2486
2487         $error = $this->deleteOneTeamMember($blogid, $memberid);
2488         if ($error)
2489             $this->error($error);
2490
2491
2492         $this->action_manageteam();
2493     }
2494
2495     /**
2496      * @todo document this
2497      */
2498     function deleteOneTeamMember($blogid, $memberid) {
2499         global $member, $manager;
2500
2501         $blogid = intval($blogid);
2502         $memberid = intval($memberid);
2503
2504         // check if allowed
2505         if (!$member->blogAdminRights($blogid))
2506             return _ERROR_DISALLOWED;
2507
2508         // check if: - there remains at least one blog admin
2509         //           - (there remains at least one team member)
2510         $tmem = Member::createFromID($memberid);
2511
2512         $manager->notify('PreDeleteTeamMember', array('member' => &$tmem, 'blogid' => $blogid));
2513
2514         if ($tmem->isBlogAdmin($blogid)) {
2515             // check if there are more blog members left and at least one admin
2516             // (check for at least two admins before deletion)
2517             $query = 'SELECT * FROM '.sql_table('team') . ' WHERE tblog='.$blogid.' and tadmin=1';
2518             $r = sql_query($query);
2519             if (sql_num_rows($r) < 2)
2520                 return _ERROR_ATLEASTONEBLOGADMIN;
2521         }
2522
2523         $query = 'DELETE FROM '.sql_table('team')." WHERE tblog=$blogid and tmember=$memberid";
2524         sql_query($query);
2525
2526         $manager->notify('PostDeleteTeamMember', array('member' => &$tmem, 'blogid' => $blogid));
2527
2528         return '';
2529     }
2530
2531     /**
2532      * @todo document this
2533      */
2534     function action_teamchangeadmin() {
2535         global $member;
2536
2537         $blogid = intRequestVar('blogid');
2538         $memberid = intRequestVar('memberid');
2539
2540         // check if allowed
2541         $member->blogAdminRights($blogid) or $this->disallow();
2542
2543         $mem = Member::createFromID($memberid);
2544
2545         // don't allow when there is only one admin at this moment
2546         if ($mem->isBlogAdmin($blogid)) {
2547             $r = sql_query('SELECT * FROM '.sql_table('team') . " WHERE tblog=$blogid and tadmin=1");
2548             if (sql_num_rows($r) == 1)
2549                 $this->error(_ERROR_ATLEASTONEBLOGADMIN);
2550         }
2551
2552         if ($mem->isBlogAdmin($blogid))
2553             $newval = 0;
2554         else
2555             $newval = 1;
2556
2557         $query = 'UPDATE '.sql_table('team') ." SET tadmin=$newval WHERE tblog=$blogid and tmember=$memberid";
2558         sql_query($query);
2559
2560         // only show manageteam if member did not change its own admin privileges
2561         if ($member->isBlogAdmin($blogid))
2562             $this->action_manageteam();
2563         else
2564             $this->action_overview(_MSG_ADMINCHANGED);
2565     }
2566
2567     /**
2568      * @todo document this
2569      */
2570     function action_blogsettings() {
2571         global $member, $manager;
2572
2573         $blogid = intRequestVar('blogid');
2574
2575         // check if allowed
2576         $member->blogAdminRights($blogid) or $this->disallow();
2577
2578         $blog =& $manager->getBlog($blogid);
2579
2580         $extrahead = '<script type="text/javascript" src="javascript/numbercheck.js"></script>';
2581         $this->pagehead($extrahead);
2582
2583         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
2584         ?>
2585         <h2><?php echo _EBLOG_TITLE?>: '<?php echo $this->bloglink($blog)?>'</h2>
2586
2587         <h3><?php echo _EBLOG_TEAM_TITLE?></h3>
2588
2589         <p><?php echo _EBLOG_CURRENT_TEAM_MEMBER; ?>
2590         <?php
2591             $res = sql_query('SELECT mname, mrealname FROM ' . sql_table('member') . ',' . sql_table('team') . ' WHERE mnumber=tmember AND tblog=' . intval($blogid));
2592             $aMemberNames = array();
2593             while ($o = sql_fetch_object($res))
2594                 array_push($aMemberNames, Entity::hsc($o->mname) . ' (' . Entity::hsc($o->mrealname). ')');
2595             echo implode(',', $aMemberNames);
2596         ?>
2597         </p>
2598
2599
2600
2601         <p>
2602         <a href="index.php?action=manageteam&amp;blogid=<?php echo $blogid?>"><?php echo _EBLOG_TEAM_TEXT?></a>
2603         </p>
2604
2605         <h3><?php echo _EBLOG_SETTINGS_TITLE?></h3>
2606
2607         <form method="post" action="index.php"><div>
2608
2609         <input type="hidden" name="action" value="blogsettingsupdate" />
2610         <?php $manager->addTicketHidden() ?>
2611         <input type="hidden" name="blogid" value="<?php echo  $blogid; ?>" />
2612         <table><tr>
2613             <td><?php echo _EBLOG_NAME?></td>
2614             <td><input name="name" tabindex="10" size="40" maxlength="60" value="<?php echo  Entity::hsc($blog->getName()) ?>" /></td>
2615         </tr><tr>
2616             <td><?php echo _EBLOG_SHORTNAME?> <?php help('shortblogname'); ?>
2617                 <?php echo _EBLOG_SHORTNAME_EXTRA?>
2618             </td>
2619             <td><input name="shortname" tabindex="20" maxlength="15" size="15" value="<?php echo  Entity::hsc($blog->getShortName()) ?>" /></td>
2620         </tr><tr>
2621             <td><?php echo _EBLOG_DESC?></td>
2622             <td><input name="desc" tabindex="30" maxlength="200" size="40" value="<?php echo  Entity::hsc($blog->getDescription()) ?>" /></td>
2623         </tr><tr>
2624             <td><?php echo _EBLOG_URL?></td>
2625             <td><input name="url" tabindex="40" size="40" maxlength="100" value="<?php echo  Entity::hsc($blog->getURL()) ?>" /></td>
2626         </tr><tr>
2627             <td><?php echo _EBLOG_DEFSKIN?>
2628                 <?php help('blogdefaultskin'); ?>
2629             </td>
2630             <td>
2631                 <?php
2632                     $query =  'SELECT sdname as text, sdnumber as value'
2633                            . ' FROM '.sql_table('skin_desc');
2634                     $template['name'] = 'defskin';
2635                     $template['selected'] = $blog->getDefaultSkin();
2636                     $template['tabindex'] = 50;
2637                     showlist($query,'select',$template);
2638                 ?>
2639
2640             </td>
2641         </tr><tr>
2642             <td><?php echo _EBLOG_LINEBREAKS?> <?php help('convertbreaks'); ?>
2643             </td>
2644             <td><?php $this->input_yesno('convertbreaks',$blog->convertBreaks(),55); ?></td>
2645         </tr><tr>
2646             <td><?php echo _EBLOG_ALLOWPASTPOSTING?> <?php help('allowpastposting'); ?>
2647             </td>
2648             <td><?php $this->input_yesno('allowpastposting',$blog->allowPastPosting(),57); ?></td>
2649         </tr><tr>
2650             <td><?php echo _EBLOG_DISABLECOMMENTS?>
2651             </td>
2652             <td><?php $this->input_yesno('comments',$blog->commentsEnabled(),60); ?></td>
2653         </tr><tr>
2654             <td><?php echo _EBLOG_ANONYMOUS?>
2655             </td>
2656             <td><?php $this->input_yesno('public',$blog->isPublic(),70); ?></td>
2657         </tr><tr>
2658     <td><?php echo _EBLOG_REQUIREDEMAIL?>
2659          </td>
2660          <td><?php $this->input_yesno('reqemail',$blog->emailRequired(),72); ?></td>
2661       </tr><tr>
2662             <td><?php echo _EBLOG_NOTIFY?> <?php help('blognotify'); ?></td>
2663             <td><input name="notify" tabindex="80" maxlength="128" size="40" value="<?php echo  Entity::hsc($blog->getNotifyAddress()); ?>" /></td>
2664         </tr><tr>
2665             <td><?php echo _EBLOG_NOTIFY_ON?></td>
2666             <td>
2667                 <input name="notifyComment" value="3" type="checkbox" tabindex="81" id="notifyComment"
2668                     <?php if  ($blog->notifyOnComment()) echo "checked='checked'" ?>
2669                 /><label for="notifyComment"><?php echo _EBLOG_NOTIFY_COMMENT?></label>
2670                 <br />
2671                 <input name="notifyVote" value="5" type="checkbox" tabindex="82" id="notifyVote"
2672                     <?php if  ($blog->notifyOnVote()) echo "checked='checked'" ?>
2673                 /><label for="notifyVote"><?php echo _EBLOG_NOTIFY_KARMA?></label>
2674                 <br />
2675                 <input name="notifyNewItem" value="7" type="checkbox" tabindex="83" id="notifyNewItem"
2676                     <?php if  ($blog->notifyOnNewItem()) echo "checked='checked'" ?>
2677                 /><label for="notifyNewItem"><?php echo _EBLOG_NOTIFY_ITEM?></label>
2678             </td>
2679         </tr><tr>
2680             <td><?php echo _EBLOG_MAXCOMMENTS?> <?php help('blogmaxcomments'); ?></td>
2681             <td><input name="maxcomments" tabindex="90" size="3" value="<?php echo  Entity::hsc($blog->getMaxComments()); ?>" /></td>
2682         </tr><tr>
2683             <td><?php echo _EBLOG_UPDATE?> <?php help('blogupdatefile'); ?></td>
2684             <td><input name="update" tabindex="100" size="40" maxlength="60" value="<?php echo  Entity::hsc($blog->getUpdateFile()) ?>" /></td>
2685         </tr><tr>
2686             <td><?php echo _EBLOG_DEFCAT?></td>
2687             <td>
2688                 <?php
2689                     $query =  'SELECT cname as text, catid as value'
2690                            . ' FROM '.sql_table('category')
2691                            . ' WHERE cblog=' . $blog->getID();
2692                     $template['name'] = 'defcat';
2693                     $template['selected'] = $blog->getDefaultCategory();
2694                     $template['tabindex'] = 110;
2695                     showlist($query,'select',$template);
2696                 ?>
2697             </td>
2698         </tr><tr>
2699             <td><?php echo _EBLOG_OFFSET?> <?php help('blogtimeoffset'); ?>
2700                 <br /><?php echo _EBLOG_STIME?> <b><?php echo  i18n::formatted_datetime('%H:%M', time()); ?></b>
2701                 <br /><?php echo _EBLOG_BTIME?> <b><?php echo  i18n::formatted_datetime('%H:%M', $blog->getCorrectTime()); ?></b>
2702                 </td>
2703             <td><input name="timeoffset" tabindex="120" size="3" value="<?php echo  Entity::hsc($blog->getTimeOffset()); ?>" /></td>
2704         </tr><tr>
2705             <td><?php echo _EBLOG_SEARCH?> <?php help('blogsearchable'); ?></td>
2706             <td><?php $this->input_yesno('searchable',$blog->getSearchable(),122); ?></td>
2707         </tr>
2708         <?php
2709             // plugin options
2710             $this->_insertPluginOptions('blog',$blogid);
2711         ?>
2712         <tr>
2713             <th colspan="2"><?php echo _EBLOG_CHANGE?></th>
2714         </tr><tr>
2715             <td><?php echo _EBLOG_CHANGE?></td>
2716             <td><input type="submit" tabindex="130" value="<?php echo _EBLOG_CHANGE_BTN?>" onclick="return checkSubmit();" /></td>
2717         </tr></table>
2718
2719         </div></form>
2720
2721         <h3><?php echo _EBLOG_CAT_TITLE?></h3>
2722
2723
2724         <?php
2725         $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog='.$blog->getID().' ORDER BY cname';
2726         $template['content'] = 'categorylist';
2727         $template['tabindex'] = 200;
2728
2729         $manager->loadClass("ENCAPSULATE");
2730         $batch = new Batch('category');
2731         $batch->showlist($query,'table',$template);
2732
2733         ?>
2734
2735
2736         <form action="index.php" method="post"><div>
2737         <input name="action" value="categorynew" type="hidden" />
2738         <?php $manager->addTicketHidden() ?>
2739         <input name="blogid" value="<?php echo $blog->getID()?>" type="hidden" />
2740
2741         <table><tr>
2742             <th colspan="2"><?php echo _EBLOG_CAT_CREATE?></th>
2743         </tr><tr>
2744             <td><?php echo _EBLOG_CAT_NAME?></td>
2745             <td><input name="cname" size="40" maxlength="40" tabindex="300" /></td>
2746         </tr><tr>
2747             <td><?php echo _EBLOG_CAT_DESC?></td>
2748             <td><input name="cdesc" size="40" maxlength="200" tabindex="310" /></td>
2749         </tr><tr>
2750             <td><?php echo _EBLOG_CAT_CREATE?></td>
2751             <td><input type="submit" value="<?php echo _EBLOG_CAT_CREATE?>" tabindex="320" /></td>
2752         </tr></table>
2753
2754         </div></form>
2755
2756         <?php
2757
2758             echo '<h3>',_PLUGINS_EXTRA,'</h3>';
2759
2760             $manager->notify(
2761                 'BlogSettingsFormExtras',
2762                 array(
2763                     'blog' => &$blog
2764                 )
2765             );
2766
2767         $this->pagefoot();
2768     }
2769
2770     /**
2771      * @todo document this
2772      */
2773     function action_categorynew() {
2774         global $member, $manager;
2775
2776         $blogid = intRequestVar('blogid');
2777
2778         $member->blogAdminRights($blogid) or $this->disallow();
2779
2780         $cname = postVar('cname');
2781         $cdesc = postVar('cdesc');
2782
2783         if (!isValidCategoryName($cname))
2784             $this->error(_ERROR_BADCATEGORYNAME);
2785
2786         $query = 'SELECT * FROM '.sql_table('category') . ' WHERE cname=\'' . sql_real_escape_string($cname).'\' and cblog=' . intval($blogid);
2787         $res = sql_query($query);
2788         if (sql_num_rows($res) > 0)
2789             $this->error(_ERROR_DUPCATEGORYNAME);
2790
2791         $blog       =& $manager->getBlog($blogid);
2792         $newCatID   =  $blog->createNewCategory($cname, $cdesc);
2793
2794         $this->action_blogsettings();
2795     }
2796
2797     /**
2798      * @todo document this
2799      */
2800     function action_categoryedit($catid = '', $blogid = '', $desturl = '') {
2801         global $member, $manager;
2802
2803         if ($blogid == '')
2804             $blogid = intGetVar('blogid');
2805         else
2806             $blogid = intval($blogid);
2807         if ($catid == '')
2808             $catid = intGetVar('catid');
2809         else
2810             $catid = intval($catid);
2811
2812         $member->blogAdminRights($blogid) or $this->disallow();
2813
2814         $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cblog=$blogid AND catid=$catid");
2815         $obj = sql_fetch_object($res);
2816
2817         $cname = $obj->cname;
2818         $cdesc = $obj->cdesc;
2819
2820         $extrahead = '<script type="text/javascript" src="javascript/numbercheck.js"></script>';
2821         $this->pagehead($extrahead);
2822
2823         echo "<p><a href='index.php?action=blogsettings&amp;blogid=$blogid'>(",_BACK_TO_BLOGSETTINGS,")</a></p>";
2824
2825         ?>
2826         <h2><?php echo _EBLOG_CAT_UPDATE?> '<?php echo Entity::hsc($cname)?>'</h2>
2827         <form method='post' action='index.php'><div>
2828         <input name="blogid" type="hidden" value="<?php echo $blogid?>" />
2829         <input name="catid" type="hidden" value="<?php echo $catid?>" />
2830         <input name="desturl" type="hidden" value="<?php echo Entity::hsc($desturl) ?>" />
2831         <input name="action" type="hidden" value="categoryupdate" />
2832         <?php $manager->addTicketHidden(); ?>
2833
2834         <table><tr>
2835             <th colspan="2"><?php echo _EBLOG_CAT_UPDATE ?></th>
2836         </tr><tr>
2837             <td><?php echo _EBLOG_CAT_NAME?></td>
2838             <td><input type="text" name="cname" value="<?php echo Entity::hsc($cname)?>" size="40" maxlength="40" /></td>
2839         </tr><tr>
2840             <td><?php echo _EBLOG_CAT_DESC?></td>
2841             <td><input type="text" name="cdesc" value="<?php echo Entity::hsc($cdesc)?>" size="40" maxlength="200" /></td>
2842         </tr>
2843         <?php
2844             // insert plugin options
2845             $this->_insertPluginOptions('category',$catid);
2846         ?>
2847         <tr>
2848             <th colspan="2"><?php echo _EBLOG_CAT_UPDATE ?></th>
2849         </tr><tr>
2850             <td><?php echo _EBLOG_CAT_UPDATE?></td>
2851             <td><input type="submit" value="<?php echo _EBLOG_CAT_UPDATE_BTN?>" /></td>
2852         </tr></table>
2853
2854         </div></form>
2855         <?php
2856         $this->pagefoot();
2857     }
2858
2859     /**
2860      * @todo document this
2861      */
2862     function action_categoryupdate() {
2863         global $member, $manager;
2864
2865         $blogid = intPostVar('blogid');
2866         $catid = intPostVar('catid');
2867         $cname = postVar('cname');
2868         $cdesc = postVar('cdesc');
2869         $desturl = postVar('desturl');
2870
2871         $member->blogAdminRights($blogid) or $this->disallow();
2872
2873         if (!isValidCategoryName($cname))
2874             $this->error(_ERROR_BADCATEGORYNAME);
2875
2876         $query = 'SELECT * FROM '.sql_table('category').' WHERE cname=\'' . sql_real_escape_string($cname).'\' and cblog=' . intval($blogid) . " and not(catid=$catid)";
2877         $res = sql_query($query);
2878         if (sql_num_rows($res) > 0)
2879             $this->error(_ERROR_DUPCATEGORYNAME);
2880
2881         $query =  'UPDATE '.sql_table('category').' SET'
2882                . " cname='" . sql_real_escape_string($cname) . "',"
2883                . " cdesc='" . sql_real_escape_string($cdesc) . "'"
2884                . " WHERE catid=" . $catid;
2885
2886         sql_query($query);
2887
2888         // store plugin options
2889         $aOptions = requestArray('plugoption');
2890         NucleusPlugin::apply_plugin_options($aOptions);
2891         $manager->notify('PostPluginOptionsUpdate',array('context' => 'category', 'catid' => $catid));
2892
2893
2894         if ($desturl) {
2895             redirect($desturl);
2896             exit;
2897         } else {
2898             $this->action_blogsettings();
2899         }
2900     }
2901
2902     /**
2903      * @todo document this
2904      */
2905     function action_categorydelete() {
2906         global $member, $manager;
2907
2908         $blogid = intRequestVar('blogid');
2909         $catid = intRequestVar('catid');
2910
2911         $member->blogAdminRights($blogid) or $this->disallow();
2912
2913         $blog =& $manager->getBlog($blogid);
2914
2915         // check if the category is valid
2916         if (!$blog->isValidCategory($catid))
2917             $this->error(_ERROR_NOSUCHCATEGORY);
2918
2919         // don't allow deletion of default category
2920         if ($blog->getDefaultCategory() == $catid)
2921             $this->error(_ERROR_DELETEDEFCATEGORY);
2922
2923         // check if catid is the only category left for blogid
2924         $query = 'SELECT catid FROM '.sql_table('category').' WHERE cblog=' . $blogid;
2925         $res = sql_query($query);
2926         if (sql_num_rows($res) == 1)
2927             $this->error(_ERROR_DELETELASTCATEGORY);
2928
2929
2930         $this->pagehead();
2931         ?>
2932             <h2><?php echo _DELETE_CONFIRM?></h2>
2933
2934             <div>
2935             <?php echo _CONFIRMTXT_CATEGORY?><b><?php echo  Entity::hsc($blog->getCategoryName($catid))?></b>
2936             </div>
2937
2938             <form method="post" action="index.php"><div>
2939             <input type="hidden" name="action" value="categorydeleteconfirm" />
2940             <?php $manager->addTicketHidden() ?>
2941             <input type="hidden" name="blogid" value="<?php echo $blogid?>" />
2942             <input type="hidden" name="catid" value="<?php echo $catid?>" />
2943             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
2944             </div></form>
2945         <?php
2946         $this->pagefoot();
2947     }
2948
2949     /**
2950      * @todo document this
2951      */
2952     function action_categorydeleteconfirm() {
2953         global $member, $manager;
2954
2955         $blogid = intRequestVar('blogid');
2956         $catid = intRequestVar('catid');
2957
2958         $member->blogAdminRights($blogid) or $this->disallow();
2959
2960         $error = $this->deleteOneCategory($catid);
2961         if ($error)
2962             $this->error($error);
2963
2964         $this->action_blogsettings();
2965     }
2966         
2967         /**
2968          * Admin::deleteOneCategory()
2969          * Delete a category by its id
2970          * 
2971          * @param       String  $catid  category id for deleting
2972          * @return      Void
2973          */
2974         function deleteOneCategory($catid)
2975         {
2976                 global $manager, $member;
2977                 
2978                 $catid = intval($catid);
2979                 $blogid = getBlogIDFromCatID($catid);
2980                 
2981                 if ( !$member->blogAdminRights($blogid) )
2982                 {
2983                         return ERROR_DISALLOWED;
2984                 }
2985                 
2986                 // get blog
2987                 $blog =& $manager->getBlog($blogid);
2988                 
2989                 // check if the category is valid
2990                 if ( !$blog || !$blog->isValidCategory($catid) )
2991                 {
2992                         return _ERROR_NOSUCHCATEGORY;
2993                 }
2994                 
2995                 $destcatid = $blog->getDefaultCategory();
2996                 
2997                 // don't allow deletion of default category
2998                 if ( $blog->getDefaultCategory() == $catid )
2999                 {
3000                         return _ERROR_DELETEDEFCATEGORY;
3001                 }
3002                 
3003                 // check if catid is the only category left for blogid
3004                 $query = 'SELECT catid FROM '.sql_table('category').' WHERE cblog=' . $blogid;
3005                 $res = sql_query($query);
3006                 if ( sql_num_rows($res) == 1 )
3007                 {
3008                         return _ERROR_DELETELASTCATEGORY;
3009                 }
3010                 
3011                 $manager->notify('PreDeleteCategory', array('catid' => $catid));
3012                 
3013                 // change category for all items to the default category
3014                 $query = 'UPDATE '.sql_table('item')." SET icat=$destcatid WHERE icat=$catid";
3015                 sql_query($query);
3016                 
3017                 // delete all associated plugin options
3018                 NucleusPlugin::delete_option_values('category', $catid);
3019                 
3020                 // delete category
3021                 $query = 'DELETE FROM '.sql_table('category').' WHERE catid=' .$catid;
3022                 sql_query($query);
3023                 
3024                 $manager->notify('PostDeleteCategory', array('catid' => $catid));
3025                 return;
3026         }
3027         
3028         /**
3029          * Admin::action_blogsettingsupdate
3030          * Updating blog settings
3031          * 
3032          * @param       Void
3033          * @return      Void
3034          */
3035         function action_blogsettingsupdate()
3036         {
3037                 global $member, $manager;
3038                 
3039                 $blogid = intRequestVar('blogid');
3040                 
3041                 $member->blogAdminRights($blogid) or $this->disallow();
3042                 
3043                 $blog =& $manager->getBlog($blogid);
3044                 
3045                 $notify_address = trim(postVar('notify'));
3046                 $shortname              = trim(postVar('shortname'));
3047                 $updatefile     = trim(postVar('update'));
3048                 
3049                 $notifyComment  = intPostVar('notifyComment');
3050                 $notifyVote             = intPostVar('notifyVote');
3051                 $notifyNewItem  = intPostVar('notifyNewItem');
3052                 
3053                 if ( $notifyComment == 0 )
3054                 {
3055                         $notifyComment = 1;
3056                 }
3057                 if ( $notifyVote == 0 )
3058                 {
3059                         $notifyVote = 1;
3060                 }
3061                 if ( $notifyNewItem == 0 )
3062                 {
3063                         $notifyNewItem = 1;
3064                 }
3065                 $notifyType = $notifyComment * $notifyVote * $notifyNewItem;
3066                 
3067                 if ( $notify_address && !NOTIFICATION::address_validation($notify_address) )
3068                 {
3069                         $this->error(_ERROR_BADNOTIFY);
3070                 }
3071                 
3072                 if ( !isValidShortName($shortname) )
3073                 {
3074                         $this->error(_ERROR_BADSHORTBLOGNAME);
3075                 }
3076                 
3077                 if ( ($blog->getShortName() != $shortname) && $manager->existsBlog($shortname) )
3078                 {
3079                         $this->error(_ERROR_DUPSHORTBLOGNAME);
3080                 }
3081                 // check if update file is writable
3082                 if ( $updatefile && !is_writeable($updatefile) )
3083                 {
3084                         $this->error(_ERROR_UPDATEFILE);
3085                 }
3086                 
3087                 $blog->setName(trim(postVar('name')));
3088                 $blog->setShortName($shortname);
3089                 $blog->setNotifyAddress($notify_address);
3090                 $blog->setNotifyType($notifyType);
3091                 $blog->setMaxComments(postVar('maxcomments'));
3092                 $blog->setCommentsEnabled(postVar('comments'));
3093                 $blog->setTimeOffset(postVar('timeoffset'));
3094                 $blog->setUpdateFile($updatefile);
3095                 $blog->setURL(trim(postVar('url')));
3096                 $blog->setDefaultSkin(intPostVar('defskin'));
3097                 $blog->setDescription(trim(postVar('desc')));
3098                 $blog->setPublic(postVar('public'));
3099                 $blog->setConvertBreaks(intPostVar('convertbreaks'));
3100                 $blog->setAllowPastPosting(intPostVar('allowpastposting'));
3101                 $blog->setDefaultCategory(intPostVar('defcat'));
3102                 $blog->setSearchable(intPostVar('searchable'));
3103                 $blog->setEmailRequired(intPostVar('reqemail'));
3104                 $blog->writeSettings();
3105                 
3106                 // store plugin options
3107                 $aOptions = requestArray('plugoption');
3108                 NucleusPlugin::apply_plugin_options($aOptions);
3109                 $manager->notify('PostPluginOptionsUpdate',array('context' => 'blog', 'blogid' => $blogid, 'blog' => &$blog));
3110                 
3111                 $this->action_overview(_MSG_SETTINGSCHANGED);
3112                 return;
3113         }
3114
3115     /**
3116      * @todo document this
3117      */
3118     function action_deleteblog() {
3119         global $member, $CONF, $manager;
3120
3121         $blogid = intRequestVar('blogid');
3122
3123         $member->blogAdminRights($blogid) or $this->disallow();
3124
3125         // check if blog is default blog
3126         if ($CONF['DefaultBlog'] == $blogid)
3127             $this->error(_ERROR_DELDEFBLOG);
3128
3129         $blog =& $manager->getBlog($blogid);
3130
3131         $this->pagehead();
3132         ?>
3133             <h2><?php echo _DELETE_CONFIRM?></h2>
3134
3135             <p><?php echo _WARNINGTXT_BLOGDEL?>
3136             </p>
3137
3138             <div>
3139             <?php echo _CONFIRMTXT_BLOG?><b><?php echo  Entity::hsc($blog->getName())?></b>
3140             </div>
3141
3142             <form method="post" action="index.php"><div>
3143             <input type="hidden" name="action" value="deleteblogconfirm" />
3144             <?php $manager->addTicketHidden() ?>
3145             <input type="hidden" name="blogid" value="<?php echo  $blogid; ?>" />
3146             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
3147             </div></form>
3148         <?php
3149         $this->pagefoot();
3150     }
3151         
3152         /**
3153          * Admin::action_deleteblogconfirm()
3154          * Delete Blog
3155          * 
3156          * @param       Void
3157          * @return      Void
3158          */
3159         function action_deleteblogconfirm()
3160         {
3161                 global $member, $CONF, $manager;
3162                 
3163                 $blogid = intRequestVar('blogid');
3164                 $manager->notify('PreDeleteBlog', array('blogid' => $blogid));
3165                 $member->blogAdminRights($blogid) or $this->disallow();
3166                 
3167                 // check if blog is default blog
3168                 if ( $CONF['DefaultBlog'] == $blogid )
3169                 {
3170                         $this->error(_ERROR_DELDEFBLOG);
3171                 }
3172                 
3173                 // delete all comments
3174                 $query = 'DELETE FROM '.sql_table('comment').' WHERE cblog='.$blogid;
3175                 sql_query($query);
3176                 
3177                 // delete all items
3178                 $query = 'DELETE FROM '.sql_table('item').' WHERE iblog='.$blogid;
3179                 sql_query($query);
3180                 
3181                 // delete all team members
3182                 $query = 'DELETE FROM '.sql_table('team').' WHERE tblog='.$blogid;
3183                 sql_query($query);
3184                 
3185                 // delete all bans
3186                 $query = 'DELETE FROM '.sql_table('ban').' WHERE blogid='.$blogid;
3187                 sql_query($query);
3188                 
3189                 // delete all categories
3190                 $query = 'DELETE FROM '.sql_table('category').' WHERE cblog='.$blogid;
3191                 sql_query($query);
3192                 
3193                 // delete all associated plugin options
3194                 NucleusPlugin::delete_option_values('blog', $blogid);
3195                 
3196                 // delete the blog itself
3197                 $query = 'DELETE FROM '.sql_table('blog').' WHERE bnumber='.$blogid;
3198                 sql_query($query);
3199                 
3200                 $manager->notify('PostDeleteBlog', array('blogid' => $blogid));
3201                 
3202                 $this->action_overview(_DELETED_BLOG);
3203                 return;
3204         }
3205         
3206     /**
3207      * @todo document this
3208      */
3209     function action_memberdelete() {
3210         global $member, $manager;
3211
3212         $memberid = intRequestVar('memberid');
3213
3214         ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
3215
3216         $mem = Member::createFromID($memberid);
3217
3218         $this->pagehead();
3219         ?>
3220             <h2><?php echo _DELETE_CONFIRM?></h2>
3221
3222             <p><?php echo _CONFIRMTXT_MEMBER?><b><?php echo Entity::hsc($mem->getDisplayName()) ?></b>
3223             </p>
3224
3225             <p>
3226             <?php echo _WARNINGTXT_NOTDELMEDIAFILES ?>
3227             </p>
3228
3229             <form method="post" action="index.php"><div>
3230             <input type="hidden" name="action" value="memberdeleteconfirm" />
3231             <?php $manager->addTicketHidden() ?>
3232             <input type="hidden" name="memberid" value="<?php echo  $memberid; ?>" />
3233             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
3234             </div></form>
3235         <?php
3236         $this->pagefoot();
3237     }
3238
3239     /**
3240      * @todo document this
3241      */
3242     function action_memberdeleteconfirm() {
3243         global $member;
3244
3245         $memberid = intRequestVar('memberid');
3246
3247         ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
3248
3249         $error = $this->deleteOneMember($memberid);
3250         if ($error)
3251             $this->error($error);
3252
3253         if ($member->isAdmin())
3254             $this->action_usermanagement();
3255         else
3256             $this->action_overview(_DELETED_MEMBER);
3257     }
3258         
3259         /**
3260          * Admin::deleteOneMember()
3261          * Delete a member by id
3262          * 
3263          * @static
3264          * @params      Integer $memberid       member id
3265          * @return      String  null string or error messages
3266          */
3267         function deleteOneMember($memberid)
3268         {
3269                 global $manager;
3270                 
3271                 $memberid = intval($memberid);
3272                 $mem = Member::createFromID($memberid);
3273                 
3274                 if ( !$mem->canBeDeleted() )
3275                 {
3276                         return _ERROR_DELETEMEMBER;
3277                 }
3278                 
3279                 $manager->notify('PreDeleteMember', array('member' => &$mem));
3280                 
3281                 /* unlink comments from memberid */
3282                 if ( $memberid )
3283                 {
3284                         $query = "UPDATE %s SET cmember=0, cuser='%s' WHERE cmember=%d";
3285                         $query = sprintf($query, sql_table('comment'), sql_real_escape_string($mem->getDisplayName()), $memberid);
3286                         sql_query($query);
3287                 }
3288                 
3289                 $query = 'DELETE FROM '.sql_table('member').' WHERE mnumber='.$memberid;
3290                 sql_query($query);
3291                 
3292                 $query = 'DELETE FROM '.sql_table('team').' WHERE tmember='.$memberid;
3293                 sql_query($query);
3294                 
3295                 $query = 'DELETE FROM '.sql_table('activation').' WHERE vmember='.$memberid;
3296                 sql_query($query);
3297                 
3298                 // delete all associated plugin options
3299                 NucleusPlugin::delete_option_values('member', $memberid);
3300                 
3301                 $manager->notify('PostDeleteMember', array('member' => &$mem));
3302                 
3303                 return '';
3304         }
3305         
3306     /**
3307      * @todo document this
3308      */
3309     function action_createnewlog() {
3310         global $member, $CONF, $manager;
3311
3312         // Only Super-Admins can do this
3313         $member->isAdmin() or $this->disallow();
3314
3315         $this->pagehead();
3316
3317         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
3318         ?>
3319         <h2><?php echo _EBLOG_CREATE_TITLE?></h2>
3320
3321         <h3><?php echo _ADMIN_NOTABILIA ?></h3>
3322
3323         <p><?php echo _ADMIN_PLEASE_READ ?></p>
3324
3325         <p><?php echo _ADMIN_HOW_TO_ACCESS ?></p>
3326
3327         <ol>
3328             <li><?php echo _ADMIN_SIMPLE_WAY ?></li>
3329             <li><?php echo _ADMIN_ADVANCED_WAY ?></li>
3330         </ol>
3331
3332         <h3><?php echo _ADMIN_HOW_TO_CREATE ?></h3>
3333
3334         <p>
3335         <?php echo _EBLOG_CREATE_TEXT?>
3336         </p>
3337
3338         <form method="post" action="index.php"><div>
3339
3340         <input type="hidden" name="action" value="addnewlog" />
3341         <?php $manager->addTicketHidden() ?>
3342
3343
3344         <table><tr>
3345             <td><?php echo _EBLOG_NAME?></td>
3346             <td><input name="name" tabindex="10" size="40" maxlength="60" /></td>
3347         </tr><tr>
3348             <td><?php echo _EBLOG_SHORTNAME?>
3349                 <?php help('shortblogname'); ?>
3350             </td>
3351             <td><input name="shortname" tabindex="20" maxlength="15" size="15" /></td>
3352         </tr><tr>
3353             <td><?php echo _EBLOG_DESC?></td>
3354             <td><input name="desc" tabindex="30" maxlength="200" size="40" /></td>
3355         </tr><tr>
3356             <td><?php echo _EBLOG_DEFSKIN?>
3357                 <?php help('blogdefaultskin'); ?>
3358             </td>
3359             <td>
3360                 <?php
3361                     $query =  'SELECT sdname as text, sdnumber as value'
3362                            . ' FROM '.sql_table('skin_desc');
3363                     $template['name'] = 'defskin';
3364                     $template['tabindex'] = 50;
3365                     $template['selected'] = $CONF['BaseSkin'];  // set default selected skin to be globally defined base skin
3366                     showlist($query,'select',$template);
3367                 ?>
3368             </td>
3369         </tr><tr>
3370             <td><?php echo _EBLOG_OFFSET?>
3371                 <?php help('blogtimeoffset'); ?>
3372                 <br /><?php echo _EBLOG_STIME?> <b><?php echo i18n::formatted_datetime('%H:%M',time()); ?></b>
3373             </td>
3374             <td><input name="timeoffset" tabindex="110" size="3" value="0" /></td>
3375         </tr><tr>
3376             <td><?php echo _EBLOG_ADMIN?>
3377                 <?php help('teamadmin'); ?>
3378             </td>
3379             <td><?php echo _EBLOG_ADMIN_MSG?></td>
3380         </tr><tr>
3381             <td><?php echo _EBLOG_CREATE?></td>
3382             <td><input type="submit" tabindex="120" value="<?php echo _EBLOG_CREATE_BTN?>" onclick="return checkSubmit();" /></td>
3383         </tr></table>
3384
3385         </div></form>
3386         <?php
3387         $this->pagefoot();
3388     }
3389
3390     /**
3391      * @todo document this
3392      */
3393     function action_addnewlog() {
3394         global $member, $manager, $CONF;
3395
3396         // Only Super-Admins can do this
3397         $member->isAdmin() or $this->disallow();
3398
3399         $bname          = trim(postVar('name'));
3400         $bshortname     = trim(postVar('shortname'));
3401         $btimeoffset    = postVar('timeoffset');
3402         $bdesc          = trim(postVar('desc'));
3403         $bdefskin       = postVar('defskin');
3404
3405         if (!isValidShortName($bshortname))
3406             $this->error(_ERROR_BADSHORTBLOGNAME);
3407
3408         if ($manager->existsBlog($bshortname))
3409             $this->error(_ERROR_DUPSHORTBLOGNAME);
3410
3411         $manager->notify(
3412             'PreAddBlog',
3413             array(
3414                 'name' => &$bname,
3415                 'shortname' => &$bshortname,
3416                 'timeoffset' => &$btimeoffset,
3417                 'description' => &$bdesc,
3418                 'defaultskin' => &$bdefskin
3419             )
3420         );
3421
3422
3423         // add slashes for sql queries
3424         $bname =        sql_real_escape_string($bname);
3425         $bshortname =   sql_real_escape_string($bshortname);
3426         $btimeoffset =  sql_real_escape_string($btimeoffset);
3427         $bdesc =        sql_real_escape_string($bdesc);
3428         $bdefskin =     sql_real_escape_string($bdefskin);
3429
3430         // create blog
3431         $query = 'INSERT INTO '.sql_table('blog')." (bname, bshortname, bdesc, btimeoffset, bdefskin) VALUES ('$bname', '$bshortname', '$bdesc', '$btimeoffset', '$bdefskin')";
3432         sql_query($query);
3433         $blogid = sql_insert_id();
3434         $blog   =& $manager->getBlog($blogid);
3435
3436         // create new category
3437         $catdefname = (defined('_EBLOGDEFAULTCATEGORY_NAME') ? _EBLOGDEFAULTCATEGORY_NAME : 'General');
3438         $catdefdesc = (defined('_EBLOGDEFAULTCATEGORY_DESC') ? _EBLOGDEFAULTCATEGORY_DESC : 'Items that do not fit in other categories');
3439         $sql = 'INSERT INTO %s (cblog, cname, cdesc) VALUES (%d, "%s", "%s")';
3440         sql_query(sprintf($sql, sql_table('category'), $blogid, $catdefname, $catdefdesc));
3441 //              sql_query(sprintf($sql, sql_table('category'), $blogid, _EBLOGDEFAULTCATEGORY_NAME, _EBLOGDEFAULTCATEGORY_DESC));
3442 //              sql_query('INSERT INTO '.sql_table('category')." (cblog, cname, cdesc) VALUES ($blogid, _EBLOGDEFAULTCATEGORY_NAME, _EBLOGDEFAULTCATEGORY_DESC)");
3443         $catid = sql_insert_id();
3444
3445         // set as default category
3446         $blog->setDefaultCategory($catid);
3447         $blog->writeSettings();
3448
3449         // create team member
3450         $memberid = $member->getID();
3451         $query = 'INSERT INTO '.sql_table('team')." (tmember, tblog, tadmin) VALUES ($memberid, $blogid, 1)";
3452         sql_query($query);
3453
3454         $itemdeftitle = (defined('_EBLOG_FIRSTITEM_TITLE') ? _EBLOG_FIRSTITEM_TITLE : 'First Item');
3455         $itemdefbody = (defined('_EBLOG_FIRSTITEM_BODY') ? _EBLOG_FIRSTITEM_BODY : 'This is the first item in your weblog. Feel free to delete it.');
3456
3457         $blog->additem($blog->getDefaultCategory(),$itemdeftitle,$itemdefbody,'',$blogid, $memberid,$blog->getCorrectTime(),0,0,0);
3458         //$blog->additem($blog->getDefaultCategory(),_EBLOG_FIRSTITEM_TITLE,_EBLOG_FIRSTITEM_BODY,'',$blogid, $memberid,$blog->getCorrectTime(),0,0,0);
3459
3460
3461
3462         $manager->notify(
3463             'PostAddBlog',
3464             array(
3465                 'blog' => &$blog
3466             )
3467         );
3468
3469         $manager->notify(
3470             'PostAddCategory',
3471             array(
3472                 'blog' => &$blog,
3473                 'name' => _EBLOGDEFAULTCATEGORY_NAME,
3474                 'description' => _EBLOGDEFAULTCATEGORY_DESC,
3475                 'catid' => $catid
3476             )
3477         );
3478
3479         $this->pagehead();
3480         ?>
3481         <h2><?php echo _BLOGCREATED_TITLE ?></h2>
3482
3483         <p><?php echo sprintf(_BLOGCREATED_ADDEDTXT, Entity::hsc($bname)) ?></p>
3484
3485         <ol>
3486             <li><a href="#index_php"><?php echo sprintf(_BLOGCREATED_SIMPLEWAY, Entity::hsc($bshortname)) ?></a></li>
3487             <li><a href="#skins"><?php echo _BLOGCREATED_ADVANCEDWAY ?></a></li>
3488         </ol>
3489
3490         <h3><a id="index_php"><?php echo sprintf(_BLOGCREATED_SIMPLEDESC1, Entity::hsc($bshortname)) ?></a></h3>
3491
3492         <p><?php echo sprintf(_BLOGCREATED_SIMPLEDESC2, Entity::hsc($bshortname)) ?></p>
3493 <pre><code>&lt;?php
3494
3495 $CONF['Self'] = '<b><?php echo Entity::hsc($bshortname)?>.php</b>';
3496
3497 include('<i>./config.php</i>');
3498
3499 selectBlog('<b><?php echo Entity::hsc($bshortname)?></b>');
3500 selector();
3501
3502 ?&gt;</code></pre>
3503
3504         <p><?php echo _BLOGCREATED_SIMPLEDESC3 ?></p>
3505
3506         <p><?php echo _BLOGCREATED_SIMPLEDESC4 ?></p>
3507
3508         <form action="index.php" method="post"><div>
3509             <input type="hidden" name="action" value="addnewlog2" />
3510             <?php $manager->addTicketHidden() ?>
3511             <input type="hidden" name="blogid" value="<?php echo intval($blogid)?>" />
3512             <table><tr>
3513                 <td><?php echo _EBLOG_URL?></td>
3514                 <td><input name="url" maxlength="100" size="40" value="<?php echo Entity::hsc($CONF['IndexURL'].$bshortname.'.php')?>" /></td>
3515             </tr><tr>
3516                 <td><?php echo _EBLOG_CREATE?></td>
3517                 <td><input type="submit" value="<?php echo _EBLOG_CREATE_BTN?>" onclick="return checkSubmit();" /></td>
3518             </tr></table>
3519         </div></form>
3520
3521         <h3><a id="skins"><?php echo _BLOGCREATED_ADVANCEDWAY2 ?></a></h3>
3522
3523         <p><?php echo _BLOGCREATED_ADVANCEDWAY3 ?></p>
3524
3525         <form action="index.php" method="post"><div>
3526             <input type="hidden" name="action" value="addnewlog2" />
3527             <?php $manager->addTicketHidden() ?>
3528             <input type="hidden" name="blogid" value="<?php echo intval($blogid)?>" />
3529             <table><tr>
3530                 <td><?php echo _EBLOG_URL?></td>
3531                 <td><input name="url" maxlength="100" size="40" /></td>
3532             </tr><tr>
3533                 <td><?php echo _EBLOG_CREATE?></td>
3534                 <td><input type="submit" value="<?php echo _EBLOG_CREATE_BTN?>" onclick="return checkSubmit();" /></td>
3535             </tr></table>
3536         </div></form>
3537
3538         <?php       $this->pagefoot();
3539
3540     }
3541
3542     /**
3543      * @todo document this
3544      */
3545     function action_addnewlog2() {
3546         global $member, $manager;
3547
3548         $member->blogAdminRights($blogid) or $this->disallow();
3549
3550         $burl   = requestVar('url');
3551         $blogid = intRequestVar('blogid');
3552
3553         $blog =& $manager->getBlog($blogid);
3554         $blog->setURL(trim($burl));
3555         $blog->writeSettings();
3556
3557         $this->action_overview(_MSG_NEWBLOG);
3558     }
3559
3560     /**
3561      * @todo document this
3562      */
3563     function action_skinieoverview() {
3564         global $member, $DIR_LIBS, $manager;
3565
3566         $member->isAdmin() or $this->disallow();
3567
3568         // load skinie class
3569         include_once($DIR_LIBS . 'skinie.php');
3570
3571         $this->pagehead();
3572
3573         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
3574
3575     ?>
3576         <h2><?php echo _SKINIE_TITLE_IMPORT?></h2>
3577
3578                 <p><label for="skinie_import_local"><?php echo _SKINIE_LOCAL?></label>
3579                 <?php                   global $DIR_SKINS;
3580
3581                     $candidates = SkinImport::searchForCandidates($DIR_SKINS);
3582
3583                     if (sizeof($candidates) > 0) {
3584                         ?>
3585                             <form method="post" action="index.php"><div>
3586                                 <input type="hidden" name="action" value="skinieimport" />
3587                                 <?php $manager->addTicketHidden() ?>
3588                                 <input type="hidden" name="mode" value="file" />
3589                                 <select name="skinfile" id="skinie_import_local">
3590                                 <?php                                   foreach ($candidates as $skinname => $skinfile) {
3591                                         $html = Entity::hsc($skinfile);
3592                                         echo '<option value="',$html,'">',$skinname,'</option>';
3593                                     }
3594                                 ?>
3595                                 </select>
3596                                 <input type="submit" value="<?php echo _SKINIE_BTN_IMPORT?>" />
3597                             </div></form>
3598                         <?php                   } else {
3599                         echo _SKINIE_NOCANDIDATES;
3600                     }
3601                 ?>
3602                 </p>
3603
3604                 <p><em><?php echo _OR?></em></p>
3605
3606                 <form method="post" action="index.php"><p>
3607                     <?php $manager->addTicketHidden() ?>
3608                     <input type="hidden" name="action" value="skinieimport" />
3609                     <input type="hidden" name="mode" value="url" />
3610                     <label for="skinie_import_url"><?php echo _SKINIE_FROMURL?></label>
3611                     <input type="text" name="skinfile" id="skinie_import_url" size="60" value="http://" />
3612                     <input type="submit" value="<?php echo _SKINIE_BTN_IMPORT?>" />
3613                 </p></form>
3614
3615
3616         <h2><?php echo _SKINIE_TITLE_EXPORT?></h2>
3617         <form method="post" action="index.php"><div>
3618             <input type="hidden" name="action" value="skinieexport" />
3619             <?php $manager->addTicketHidden() ?>
3620
3621             <p><?php echo _SKINIE_EXPORT_INTRO?></p>
3622
3623             <table><tr>
3624                 <th colspan="2"><?php echo _SKINIE_EXPORT_SKINS?></th>
3625             </tr><tr>
3626     <?php       // show list of skins
3627         $res = sql_query('SELECT * FROM '.sql_table('skin_desc'));
3628         while ($skinObj = sql_fetch_object($res)) {
3629             $id = 'skinexp' . $skinObj->sdnumber;
3630             echo '<td><input type="checkbox" name="skin[',$skinObj->sdnumber,']"  id="',$id,'" />';
3631             echo '<label for="',$id,'">',Entity::hsc($skinObj->sdname),'</label></td>';
3632             echo '<td>',Entity::hsc($skinObj->sddesc),'</td>';
3633             echo '</tr><tr>';
3634         }
3635
3636         echo '<th colspan="2">',_SKINIE_EXPORT_TEMPLATES,'</th></tr><tr>';
3637
3638         // show list of templates
3639         $res = sql_query('SELECT * FROM '.sql_table('template_desc'));
3640         while ($templateObj = sql_fetch_object($res)) {
3641             $id = 'templateexp' . $templateObj->tdnumber;
3642             echo '<td><input type="checkbox" name="template[',$templateObj->tdnumber,']" id="',$id,'" />';
3643             echo '<label for="',$id,'">',Entity::hsc($templateObj->tdname),'</label></td>';
3644             echo '<td>',Entity::hsc($templateObj->tddesc),'</td>';
3645             echo '</tr><tr>';
3646         }
3647
3648     ?>
3649                 <th colspan="2"><?php echo _SKINIE_EXPORT_EXTRA?></th>
3650             </tr><tr>
3651                 <td colspan="2"><textarea cols="40" rows="5" name="info"></textarea></td>
3652             </tr><tr>
3653                 <th colspan="2"><?php echo _SKINIE_TITLE_EXPORT?></th>
3654             </tr><tr>
3655                 <td colspan="2"><input type="submit" value="<?php echo _SKINIE_BTN_EXPORT?>" /></td>
3656             </tr></table>
3657         </div></form>
3658
3659     <?php
3660         $this->pagefoot();
3661
3662     }
3663
3664     /**
3665      * @todo document this
3666      */
3667     function action_skinieimport() {
3668         global $member, $DIR_LIBS, $DIR_SKINS, $manager;
3669
3670         $member->isAdmin() or $this->disallow();
3671
3672         // load skinie class
3673         include_once($DIR_LIBS . 'skinie.php');
3674
3675         $skinFileRaw= postVar('skinfile');
3676         $mode       = postVar('mode');
3677
3678         $importer = new SkinImport();
3679
3680         // get full filename
3681         if ($mode == 'file')
3682         {
3683             $skinFile = $DIR_SKINS . $skinFileRaw . '/skinbackup.xml';
3684
3685             // backwards compatibilty (in v2.0, exports were saved as skindata.xml)
3686             if (!file_exists($skinFile))
3687                 $skinFile = $DIR_SKINS . $skinFileRaw . '/skindata.xml';
3688         } else {
3689             $skinFile = $skinFileRaw;
3690         }
3691
3692         // read only metadata
3693         $error = $importer->readFile($skinFile, 1);
3694
3695         // clashes
3696         $skinNameClashes = $importer->checkSkinNameClashes();
3697         $templateNameClashes = $importer->checkTemplateNameClashes();
3698         $hasNameClashes = (count($skinNameClashes) > 0) || (count($templateNameClashes) > 0);
3699
3700         if ($error) $this->error($error);
3701
3702         $this->pagehead();
3703
3704         echo '<p><a href="index.php?action=skinieoverview">(',_BACK,')</a></p>';
3705         ?>
3706         <h2><?php echo _SKINIE_CONFIRM_TITLE?></h2>
3707
3708         <ul>
3709             <li><p><strong><?php echo _SKINIE_INFO_GENERAL?></strong> <?php echo Entity::hsc($importer->getInfo())?></p></li>
3710             <li><p><strong><?php echo _SKINIE_INFO_SKINS?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getSkinNames())?></p></li>
3711             <li><p><strong><?php echo _SKINIE_INFO_TEMPLATES?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getTemplateNames())?></p></li>
3712             <?php
3713                 if ($hasNameClashes)
3714                 {
3715             ?>
3716             <li><p><strong style="color: red;"><?php echo _SKINIE_INFO_SKINCLASH?></strong> <?php echo implode(' <em>'._AND.'</em> ',$skinNameClashes)?></p></li>
3717             <li><p><strong style="color: red;"><?php echo _SKINIE_INFO_TEMPLCLASH?></strong> <?php echo implode(' <em>'._AND.'</em> ',$templateNameClashes)?></p></li>
3718             <?php
3719                 } // if (hasNameClashes)
3720             ?>
3721         </ul>
3722
3723         <form method="post" action="index.php"><div>
3724             <input type="hidden" name="action" value="skiniedoimport" />
3725             <?php $manager->addTicketHidden() ?>
3726             <input type="hidden" name="skinfile" value="<?php echo Entity::hsc(postVar('skinfile'))?>" />
3727             <input type="hidden" name="mode" value="<?php echo Entity::hsc($mode)?>" />
3728             <input type="submit" value="<?php echo _SKINIE_CONFIRM_IMPORT?>" />
3729             <?php
3730                 if ($hasNameClashes)
3731                 {
3732             ?>
3733             <br />
3734             <input type="checkbox" name="overwrite" value="1" id="cb_overwrite" /><label for="cb_overwrite"><?php echo _SKINIE_CONFIRM_OVERWRITE?></label>
3735             <?php
3736                 } // if (hasNameClashes)
3737             ?>
3738         </div></form>
3739
3740
3741         <?php
3742         $this->pagefoot();
3743     }
3744
3745     /**
3746      * @todo document this
3747      */
3748     function action_skiniedoimport() {
3749         global $member, $DIR_LIBS, $DIR_SKINS;
3750
3751         $member->isAdmin() or $this->disallow();
3752
3753         // load skinie class
3754         include_once($DIR_LIBS . 'skinie.php');
3755
3756         $skinFileRaw= postVar('skinfile');
3757         $mode       = postVar('mode');
3758
3759         $allowOverwrite = intPostVar('overwrite');
3760
3761         // get full filename
3762         if ($mode == 'file')
3763         {
3764             $skinFile = $DIR_SKINS . $skinFileRaw . '/skinbackup.xml';
3765
3766             // backwards compatibilty (in v2.0, exports were saved as skindata.xml)
3767             if (!file_exists($skinFile))
3768                 $skinFile = $DIR_SKINS . $skinFileRaw . '/skindata.xml';
3769
3770         } else {
3771             $skinFile = $skinFileRaw;
3772         }
3773
3774         $importer = new SkinImport();
3775
3776         $error = $importer->readFile($skinFile);
3777
3778         if ($error)
3779             $this->error($error);
3780
3781         $error = $importer->writeToDatabase($allowOverwrite);
3782
3783         if ($error)
3784             $this->error($error);
3785
3786         $this->pagehead();
3787
3788         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
3789     ?>
3790         <h2><?php echo _SKINIE_DONE?></h2>
3791
3792         <ul>
3793             <li><p><strong><?php echo _SKINIE_INFO_GENERAL?></strong> <?php echo Entity::hsc($importer->getInfo())?></p></li>
3794             <li><p><strong><?php echo _SKINIE_INFO_IMPORTEDSKINS?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getSkinNames())?></p></li>
3795             <li><p><strong><?php echo _SKINIE_INFO_IMPORTEDTEMPLS?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getTemplateNames())?></p></li>
3796         </ul>
3797
3798     <?php       $this->pagefoot();
3799
3800     }
3801
3802     /**
3803      * @todo document this
3804      */
3805     function action_skinieexport() {
3806         global $member, $DIR_LIBS;
3807
3808         $member->isAdmin() or $this->disallow();
3809
3810         // load skinie class
3811         include_once($DIR_LIBS . 'skinie.php');
3812
3813         $aSkins = requestIntArray('skin');
3814         $aTemplates = requestIntArray('template');
3815
3816         if (!is_array($aTemplates)) $aTemplates = array();
3817         if (!is_array($aSkins)) $aSkins = array();
3818
3819         $skinList = array_keys($aSkins);
3820         $templateList = array_keys($aTemplates);
3821
3822         $info = postVar('info');
3823
3824         $exporter = new SkinExport();
3825         foreach ($skinList as $skinId) {
3826             $exporter->addSkin($skinId);
3827         }
3828         foreach ($templateList as $templateId) {
3829             $exporter->addTemplate($templateId);
3830         }
3831         $exporter->setInfo($info);
3832
3833         $exporter->export();
3834     }
3835
3836     /**
3837      * @todo document this
3838      */
3839     function action_templateoverview() {
3840         global $member, $manager;
3841
3842         $member->isAdmin() or $this->disallow();
3843
3844         $this->pagehead();
3845
3846         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
3847
3848         echo '<h2>' . _TEMPLATE_TITLE . '</h2>';
3849         echo '<h3>' . _TEMPLATE_AVAILABLE_TITLE . '</h3>';
3850
3851         $query = 'SELECT * FROM '.sql_table('template_desc').' ORDER BY tdname';
3852         $template['content'] = 'templatelist';
3853         $template['tabindex'] = 10;
3854         showlist($query,'table',$template);
3855
3856         echo '<h3>' . _TEMPLATE_NEW_TITLE . '</h3>';
3857
3858         ?>
3859         <form method="post" action="index.php"><div>
3860
3861         <input name="action" value="templatenew" type="hidden" />
3862         <?php $manager->addTicketHidden() ?>
3863         <table><tr>
3864             <td><?php echo _TEMPLATE_NAME?> <?php help('shortnames');?></td>
3865             <td><input name="name" tabindex="10010" maxlength="20" size="20" /></td>
3866         </tr><tr>
3867             <td><?php echo _TEMPLATE_DESC?></td>
3868             <td><input name="desc" tabindex="10020" maxlength="200" size="50" /></td>
3869         </tr><tr>
3870             <td><?php echo _TEMPLATE_CREATE?></td>
3871             <td><input type="submit" tabindex="10030" value="<?php echo _TEMPLATE_CREATE_BTN?>" onclick="return checkSubmit();" /></td>
3872         </tr></table>
3873
3874         </div></form>
3875
3876         <?php
3877         $this->pagefoot();
3878     }
3879
3880     /**
3881      * @todo document this
3882      */
3883     function action_templateedit($msg = '') {
3884         global $member, $manager;
3885
3886         $templateid = intRequestVar('templateid');
3887
3888         $member->isAdmin() or $this->disallow();
3889
3890         $extrahead = '<script type="text/javascript" src="javascript/templateEdit.js"></script>';
3891         $extrahead .= '<script type="text/javascript">setTemplateEditText("'.sql_real_escape_string(_EDITTEMPLATE_EMPTY).'");</script>';
3892
3893         $this->pagehead($extrahead);
3894
3895         $templatename = Template::getNameFromId($templateid);
3896         $templatedescription = Template::getDesc($templateid);
3897         $template =& $manager->getTemplate($templatename);
3898
3899         ?>
3900         <p>
3901         <a href="index.php?action=templateoverview">(<?php echo _TEMPLATE_BACK?>)</a>
3902         </p>
3903
3904         <h2><?php echo _TEMPLATE_EDIT_TITLE?> '<?php echo  Entity::hsc($templatename); ?>'</h2>
3905
3906         <?php                   if ($msg) echo "<p>"._MESSAGE.": $msg</p>";
3907         ?>
3908
3909         <p><?php echo _TEMPLATE_EDIT_MSG?></p>
3910
3911         <form method="post" action="index.php">
3912         <div>
3913
3914         <input type="hidden" name="action" value="templateupdate" />
3915         <?php $manager->addTicketHidden() ?>
3916         <input type="hidden" name="templateid" value="<?php echo  $templateid; ?>" />
3917
3918         <table><tr>
3919             <th colspan="2"><?php echo _TEMPLATE_SETTINGS?></th>
3920         </tr><tr>
3921             <td><?php echo _TEMPLATE_NAME?> <?php help('shortnames');?></td>
3922             <td><input name="tname" tabindex="4" size="20" maxlength="20" value="<?php echo  Entity::hsc($templatename) ?>" /></td>
3923         </tr><tr>
3924             <td><?php echo _TEMPLATE_DESC?></td>
3925             <td><input name="tdesc" tabindex="5" size="50" maxlength="200" value="<?php echo  Entity::hsc($templatedescription) ?>" /></td>
3926         </tr><tr>
3927             <th colspan="2"><?php echo _TEMPLATE_UPDATE?></th>
3928         </tr><tr>
3929             <td><?php echo _TEMPLATE_UPDATE?></td>
3930             <td>
3931                 <input type="submit" tabindex="6" value="<?php echo _TEMPLATE_UPDATE_BTN?>" onclick="return checkSubmit();" />
3932                 <input type="reset" tabindex="7" value="<?php echo _TEMPLATE_RESET_BTN?>" />
3933             </td>
3934         </tr><tr>
3935             <th colspan="2"><?php echo _TEMPLATE_ITEMS?> <?php help('templateitems'); ?></th>
3936 <?php   $this->_templateEditRow($template, _TEMPLATE_ITEMHEADER, 'ITEM_HEADER', '', 8);
3937     $this->_templateEditRow($template, _TEMPLATE_ITEMBODY, 'ITEM', '', 9, 1);
3938     $this->_templateEditRow($template, _TEMPLATE_ITEMFOOTER, 'ITEM_FOOTER', '', 10);
3939     $this->_templateEditRow($template, _TEMPLATE_MORELINK, 'MORELINK', 'morelink', 20);
3940     $this->_templateEditRow($template, _TEMPLATE_EDITLINK, 'EDITLINK', 'editlink', 25);
3941     $this->_templateEditRow($template, _TEMPLATE_NEW, 'NEW', 'new', 30);
3942 ?>
3943         </tr><tr>
3944             <th colspan="2"><?php echo _TEMPLATE_COMMENTS_ANY?> <?php help('templatecomments'); ?></th>
3945 <?php   $this->_templateEditRow($template, _TEMPLATE_CHEADER, 'COMMENTS_HEADER', 'commentheaders', 40);
3946     $this->_templateEditRow($template, _TEMPLATE_CBODY, 'COMMENTS_BODY', 'commentbody', 50, 1);
3947     $this->_templateEditRow($template, _TEMPLATE_CFOOTER, 'COMMENTS_FOOTER', 'commentheaders', 60);
3948     $this->_templateEditRow($template, _TEMPLATE_CONE, 'COMMENTS_ONE', 'commentwords', 70);
3949     $this->_templateEditRow($template, _TEMPLATE_CMANY, 'COMMENTS_MANY', 'commentwords', 80);
3950     $this->_templateEditRow($template, _TEMPLATE_CMORE, 'COMMENTS_CONTINUED', 'commentcontinued', 90);
3951     $this->_templateEditRow($template, _TEMPLATE_CMEXTRA, 'COMMENTS_AUTH', 'memberextra', 100);
3952 ?>
3953         </tr><tr>
3954             <th colspan="2"><?php echo _TEMPLATE_COMMENTS_NONE?> <?php help('templatecomments'); ?></th>
3955 <?php
3956     $this->_templateEditRow($template, _TEMPLATE_CNONE, 'COMMENTS_NONE', '', 110);
3957 ?>
3958         </tr><tr>
3959             <th colspan="2"><?php echo _TEMPLATE_COMMENTS_TOOMUCH?> <?php help('templatecomments'); ?></th>
3960 <?php   $this->_templateEditRow($template, _TEMPLATE_CTOOMUCH, 'COMMENTS_TOOMUCH', '', 120);
3961 ?>
3962         </tr><tr>
3963             <th colspan="2"><?php echo _TEMPLATE_ARCHIVELIST?> <?php help('templatearchivelists'); ?></th>
3964 <?php   $this->_templateEditRow($template, _TEMPLATE_AHEADER, 'ARCHIVELIST_HEADER', '', 130);
3965     $this->_templateEditRow($template, _TEMPLATE_AITEM, 'ARCHIVELIST_LISTITEM', '', 140);
3966     $this->_templateEditRow($template, _TEMPLATE_AFOOTER, 'ARCHIVELIST_FOOTER', '', 150);
3967 ?>
3968         </tr><tr>
3969             <th colspan="2"><?php echo _TEMPLATE_BLOGLIST?> <?php help('templatebloglists'); ?></th>
3970 <?php   $this->_templateEditRow($template, _TEMPLATE_BLOGHEADER, 'BLOGLIST_HEADER', '', 160);
3971     $this->_templateEditRow($template, _TEMPLATE_BLOGITEM, 'BLOGLIST_LISTITEM', '', 170);
3972     $this->_templateEditRow($template, _TEMPLATE_BLOGFOOTER, 'BLOGLIST_FOOTER', '', 180);
3973 ?>
3974         </tr><tr>
3975             <th colspan="2"><?php echo _TEMPLATE_CATEGORYLIST?> <?php help('templatecategorylists'); ?></th>
3976 <?php   $this->_templateEditRow($template, _TEMPLATE_CATHEADER, 'CATLIST_HEADER', '', 190);
3977     $this->_templateEditRow($template, _TEMPLATE_CATITEM, 'CATLIST_LISTITEM', '', 200);
3978     $this->_templateEditRow($template, _TEMPLATE_CATFOOTER, 'CATLIST_FOOTER', '', 210);
3979 ?>
3980         </tr><tr>
3981             <th colspan="2"><?php echo _TEMPLATE_DATETIME?></th>
3982 <?php   $this->_templateEditRow($template, _TEMPLATE_DHEADER, 'DATE_HEADER', 'dateheads', 220);
3983     $this->_templateEditRow($template, _TEMPLATE_DFOOTER, 'DATE_FOOTER', 'dateheads', 230);
3984     $this->_templateEditRow($template, _TEMPLATE_DFORMAT, 'FORMAT_DATE', 'datetime', 240);
3985     $this->_templateEditRow($template, _TEMPLATE_TFORMAT, 'FORMAT_TIME', 'datetime', 250);
3986     $this->_templateEditRow($template, _TEMPLATE_LOCALE, 'LOCALE', 'locale', 260);
3987 ?>
3988         </tr><tr>
3989             <th colspan="2"><?php echo _TEMPLATE_IMAGE?> <?php help('templatepopups'); ?></th>
3990 <?php   $this->_templateEditRow($template, _TEMPLATE_PCODE, 'POPUP_CODE', '', 270);
3991     $this->_templateEditRow($template, _TEMPLATE_ICODE, 'IMAGE_CODE', '', 280);
3992     $this->_templateEditRow($template, _TEMPLATE_MCODE, 'MEDIA_CODE', '', 290);
3993 ?>
3994         </tr><tr>
3995             <th colspan="2"><?php echo _TEMPLATE_SEARCH?></th>
3996 <?php   $this->_templateEditRow($template, _TEMPLATE_SHIGHLIGHT, 'SEARCH_HIGHLIGHT', 'highlight',300);
3997     $this->_templateEditRow($template, _TEMPLATE_SNOTFOUND, 'SEARCH_NOTHINGFOUND', 'nothingfound',310);
3998 ?>
3999         </tr><tr>
4000             <th colspan="2"><?php echo _TEMPLATE_PLUGIN_FIELDS?></th>
4001 <?php
4002         $tab = 600;
4003         $pluginfields = array();
4004         $manager->notify('TemplateExtraFields',array('fields'=>&$pluginfields));
4005
4006         foreach ($pluginfields as $pfkey=>$pfvalue) {
4007             echo "</tr><tr>\n";
4008             echo '<th colspan="2">' . Entity::hen($pfkey) . "</th>\n";
4009             foreach ($pfvalue as $pffield=>$pfdesc) {
4010                 $this->_templateEditRow($template, $pfdesc, $pffield, '',++$tab,0);
4011             }
4012         }
4013 ?>
4014         </tr><tr>
4015             <th colspan="2"><?php echo _TEMPLATE_UPDATE?></th>
4016         </tr><tr>
4017             <td><?php echo _TEMPLATE_UPDATE?></td>
4018             <td>
4019                 <input type="submit" tabindex="800" value="<?php echo _TEMPLATE_UPDATE_BTN?>" onclick="return checkSubmit();" />
4020                 <input type="reset" tabindex="810" value="<?php echo _TEMPLATE_RESET_BTN?>" />
4021             </td>
4022         </tr></table>
4023
4024         </div>
4025         </form>
4026         <?php
4027         $this->pagefoot();
4028     }
4029
4030     /**
4031      * @todo document this
4032      */
4033     function _templateEditRow(&$template, $description, $name, $help = '', $tabindex = 0, $big = 0) {
4034         static $count = 1;
4035         if (!isset($template[$name])) $template[$name] = '';
4036     ?>
4037         </tr><tr>
4038             <td><?php echo $description?> <?php if ($help) help('template'.$help); ?></td>
4039             <td id="td<?php echo $count?>"><textarea class="templateedit" name="<?php echo $name?>" tabindex="<?php echo $tabindex?>" cols="50" rows="<?php echo $big?10:5?>" id="textarea<?php echo $count?>"><?php echo  Entity::hsc($template[$name]); ?></textarea></td>
4040     <?php       $count++;
4041     }
4042
4043     /**
4044      * @todo document this
4045      */
4046     function action_templateupdate() {
4047         global $member,$manager;
4048
4049         $templateid = intRequestVar('templateid');
4050
4051         $member->isAdmin() or $this->disallow();
4052
4053         $name = postVar('tname');
4054         $desc = postVar('tdesc');
4055
4056         if (!isValidTemplateName($name))
4057             $this->error(_ERROR_BADTEMPLATENAME);
4058
4059         if ((Template::getNameFromId($templateid) != $name) && Template::exists($name))
4060             $this->error(_ERROR_DUPTEMPLATENAME);
4061
4062
4063         $name = sql_real_escape_string($name);
4064         $desc = sql_real_escape_string($desc);
4065
4066         // 1. Remove all template parts
4067         $query = 'DELETE FROM '.sql_table('template').' WHERE tdesc=' . $templateid;
4068         sql_query($query);
4069
4070         // 2. Update description
4071         $query =  'UPDATE '.sql_table('template_desc').' SET'
4072                . " tdname='" . $name . "',"
4073                . " tddesc='" . $desc . "'"
4074                . " WHERE tdnumber=" . $templateid;
4075         sql_query($query);
4076
4077         // 3. Add non-empty template parts
4078         $this->addToTemplate($templateid, 'ITEM_HEADER', postVar('ITEM_HEADER'));
4079         $this->addToTemplate($templateid, 'ITEM', postVar('ITEM'));
4080         $this->addToTemplate($templateid, 'ITEM_FOOTER', postVar('ITEM_FOOTER'));
4081         $this->addToTemplate($templateid, 'MORELINK', postVar('MORELINK'));
4082         $this->addToTemplate($templateid, 'EDITLINK', postVar('EDITLINK'));
4083         $this->addToTemplate($templateid, 'NEW', postVar('NEW'));
4084         $this->addToTemplate($templateid, 'COMMENTS_HEADER', postVar('COMMENTS_HEADER'));
4085         $this->addToTemplate($templateid, 'COMMENTS_BODY', postVar('COMMENTS_BODY'));
4086         $this->addToTemplate($templateid, 'COMMENTS_FOOTER', postVar('COMMENTS_FOOTER'));
4087         $this->addToTemplate($templateid, 'COMMENTS_CONTINUED', postVar('COMMENTS_CONTINUED'));
4088         $this->addToTemplate($templateid, 'COMMENTS_TOOMUCH', postVar('COMMENTS_TOOMUCH'));
4089         $this->addToTemplate($templateid, 'COMMENTS_AUTH', postVar('COMMENTS_AUTH'));
4090         $this->addToTemplate($templateid, 'COMMENTS_ONE', postVar('COMMENTS_ONE'));
4091         $this->addToTemplate($templateid, 'COMMENTS_MANY', postVar('COMMENTS_MANY'));
4092         $this->addToTemplate($templateid, 'COMMENTS_NONE', postVar('COMMENTS_NONE'));
4093         $this->addToTemplate($templateid, 'ARCHIVELIST_HEADER', postVar('ARCHIVELIST_HEADER'));
4094         $this->addToTemplate($templateid, 'ARCHIVELIST_LISTITEM', postVar('ARCHIVELIST_LISTITEM'));
4095         $this->addToTemplate($templateid, 'ARCHIVELIST_FOOTER', postVar('ARCHIVELIST_FOOTER'));
4096         $this->addToTemplate($templateid, 'BLOGLIST_HEADER', postVar('BLOGLIST_HEADER'));
4097         $this->addToTemplate($templateid, 'BLOGLIST_LISTITEM', postVar('BLOGLIST_LISTITEM'));
4098         $this->addToTemplate($templateid, 'BLOGLIST_FOOTER', postVar('BLOGLIST_FOOTER'));
4099         $this->addToTemplate($templateid, 'CATLIST_HEADER', postVar('CATLIST_HEADER'));
4100         $this->addToTemplate($templateid, 'CATLIST_LISTITEM', postVar('CATLIST_LISTITEM'));
4101         $this->addToTemplate($templateid, 'CATLIST_FOOTER', postVar('CATLIST_FOOTER'));
4102         $this->addToTemplate($templateid, 'DATE_HEADER', postVar('DATE_HEADER'));
4103         $this->addToTemplate($templateid, 'DATE_FOOTER', postVar('DATE_FOOTER'));
4104         $this->addToTemplate($templateid, 'FORMAT_DATE', postVar('FORMAT_DATE'));
4105         $this->addToTemplate($templateid, 'FORMAT_TIME', postVar('FORMAT_TIME'));
4106         $this->addToTemplate($templateid, 'LOCALE', postVar('LOCALE'));
4107         $this->addToTemplate($templateid, 'SEARCH_HIGHLIGHT', postVar('SEARCH_HIGHLIGHT'));
4108         $this->addToTemplate($templateid, 'SEARCH_NOTHINGFOUND', postVar('SEARCH_NOTHINGFOUND'));
4109         $this->addToTemplate($templateid, 'POPUP_CODE', postVar('POPUP_CODE'));
4110         $this->addToTemplate($templateid, 'MEDIA_CODE', postVar('MEDIA_CODE'));
4111         $this->addToTemplate($templateid, 'IMAGE_CODE', postVar('IMAGE_CODE'));
4112
4113         $pluginfields = array();
4114         $manager->notify('TemplateExtraFields',array('fields'=>&$pluginfields));
4115         foreach ($pluginfields as $pfkey=>$pfvalue) {
4116             foreach ($pfvalue as $pffield=>$pfdesc) {
4117                 $this->addToTemplate($templateid, $pffield, postVar($pffield));
4118             }
4119         }
4120
4121         // jump back to template edit
4122         $this->action_templateedit(_TEMPLATE_UPDATED);
4123
4124     }
4125
4126         /**
4127          * Admin::addToTemplate()
4128          * 
4129          * @param       Integer $id     ID for template
4130          * @param       String  $partname       parts name
4131          * @param       String  $content        template contents
4132          * @return      Integer record index
4133          * 
4134          */
4135         function addToTemplate($id, $partname, $content)
4136         {
4137                 // don't add empty parts:
4138                 if ( !trim($content) )
4139                 {
4140                         return -1;
4141                 }
4142                 
4143                 $partname = sql_real_escape_string($partname);
4144                 $content = sql_real_escape_string($content);
4145                 
4146                 $query = "INSERT INTO %s (tdesc, tpartname, tcontent) VALUES (%d, '%s', '%s')";
4147                 $query = sprintf($query, sql_table('template'), (integer) $id, $partname, $content);
4148                 sql_query($query) or exit(_ADMIN_SQLDIE_QUERYERROR . sql_error());
4149                 return sql_insert_id();
4150         }
4151         
4152     /**
4153      * @todo document this
4154      */
4155     function action_templatedelete() {
4156         global $member, $manager;
4157
4158         $member->isAdmin() or $this->disallow();
4159
4160         $templateid = intRequestVar('templateid');
4161         // TODO: check if template can be deleted
4162
4163         $this->pagehead();
4164
4165         $name = Template::getNameFromId($templateid);
4166         $desc = Template::getDesc($templateid);
4167
4168         ?>
4169             <h2><?php echo _DELETE_CONFIRM?></h2>
4170
4171             <p>
4172             <?php echo _CONFIRMTXT_TEMPLATE?><b><?php echo Entity::hsc($name)?></b> (<?php echo  Entity::hsc($desc) ?>)
4173             </p>
4174
4175             <form method="post" action="index.php"><div>
4176                 <input type="hidden" name="action" value="templatedeleteconfirm" />
4177                 <?php $manager->addTicketHidden() ?>
4178                 <input type="hidden" name="templateid" value="<?php echo  $templateid ?>" />
4179                 <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
4180             </div></form>
4181         <?php
4182         $this->pagefoot();
4183     }
4184
4185     /**
4186      * @todo document this
4187      */
4188     function action_templatedeleteconfirm() {
4189         global $member, $manager;
4190
4191         $templateid = intRequestVar('templateid');
4192
4193         $member->isAdmin() or $this->disallow();
4194
4195         $manager->notify('PreDeleteTemplate', array('templateid' => $templateid));
4196
4197         // 1. delete description
4198         sql_query('DELETE FROM '.sql_table('template_desc').' WHERE tdnumber=' . $templateid);
4199
4200         // 2. delete parts
4201         sql_query('DELETE FROM '.sql_table('template').' WHERE tdesc=' . $templateid);
4202
4203         $manager->notify('PostDeleteTemplate', array('templateid' => $templateid));
4204
4205         $this->action_templateoverview();
4206     }
4207
4208     /**
4209      * @todo document this
4210      */
4211     function action_templatenew() {
4212         global $member;
4213
4214         $member->isAdmin() or $this->disallow();
4215
4216         $name = postVar('name');
4217         $desc = postVar('desc');
4218
4219         if (!isValidTemplateName($name))
4220             $this->error(_ERROR_BADTEMPLATENAME);
4221
4222         if (Template::exists($name))
4223             $this->error(_ERROR_DUPTEMPLATENAME);
4224
4225         $newTemplateId = Template::createNew($name, $desc);
4226
4227         $this->action_templateoverview();
4228     }
4229
4230     /**
4231      * @todo document this
4232      */
4233     function action_templateclone() {
4234         global $member;
4235
4236         $templateid = intRequestVar('templateid');
4237
4238         $member->isAdmin() or $this->disallow();
4239
4240         // 1. read old template
4241         $name = Template::getNameFromId($templateid);
4242         $desc = Template::getDesc($templateid);
4243
4244         // 2. create desc thing
4245         $name = "cloned" . $name;
4246
4247         // if a template with that name already exists:
4248         if (Template::exists($name)) {
4249             $i = 1;
4250             while (Template::exists($name . $i))
4251                 $i++;
4252             $name .= $i;
4253         }
4254
4255         $newid = Template::createNew($name, $desc);
4256
4257         // 3. create clone
4258         // go through parts of old template and add them to the new one
4259         $res = sql_query('SELECT tpartname, tcontent FROM '.sql_table('template').' WHERE tdesc=' . $templateid);
4260         while ($o = sql_fetch_object($res)) {
4261             $this->addToTemplate($newid, $o->tpartname, $o->tcontent);
4262         }
4263
4264         $this->action_templateoverview();
4265     }
4266
4267         /**
4268          * Admin::action_skinoverview()
4269          * 
4270          * @param       void
4271          * @return      void
4272          */
4273         public function action_skinoverview()
4274         {
4275                 global $member, $manager;
4276                 
4277                 $member->isAdmin() or $this->disallow();
4278                 
4279                 $this->pagehead();
4280                 
4281                 echo '<p><a href="index.php?action=manage">(' . _BACKTOMANAGE . ")</a></p>\n";
4282                 echo '<h2>' . _SKIN_EDIT_TITLE . "</h2>\n";
4283                 echo '<h3>' . _SKIN_AVAILABLE_TITLE . "</h3>\n";
4284                 
4285                 $query = 'SELECT * FROM '.sql_table('skin_desc').' ORDER BY sdname;';
4286                 $template['content'] = 'skinlist';
4287                 $template['tabindex'] = 10;
4288                 $template['friendly_names'] = Skin::getFriendlyNames('Actions');
4289                 showlist($query,'table',$template);
4290                 
4291                 echo '<h3>' . _SKIN_NEW_TITLE . "</h3>\n";
4292                 echo "<form method=\"post\" action=\"index.php\">\n";
4293                 echo "<div>\n";
4294                 echo "<input name=\"action\" value=\"skinnew\" type=\"hidden\" />\n";
4295                 
4296                 $manager->addTicketHidden() . "\n";
4297                 
4298                 echo "<table frame=\"box\" rules=\"all\" summary=\"skinoverview\">\n";
4299                 echo "<tr>\n";
4300                 echo "<td>" . _SKIN_NAME;
4301                 echo help('shortnames');
4302                 echo "</td>\n";
4303                 echo "<td><input name=\"name\" tabindex=\"10010\" maxlength=\"20\" size=\"20\" /></td>\n";
4304                 echo "</tr>\n";
4305                 echo "<tr>\n";
4306                 echo "<td>" . _SKIN_DESC . "</td>\n";
4307                 echo "<td><input name=\"desc\" tabindex=\"10020\" maxlength=\"200\" size=\"50\" /></td>\n";
4308                 echo "</tr>\n";
4309                 echo "<tr>\n";
4310                 echo '<td>' . _SKIN_CREATE . "</td>\n";
4311                 echo '<td><input type="submit" tabindex="10030" value="' . _SKIN_CREATE_BTN . '" onclick="return checkSubmit();" />' . "</td>\n";
4312                 echo "</tr>\n";
4313                 echo "</table>\n";
4314                 
4315                 echo "</div>\n";
4316                 echo "</form>\n";
4317                 
4318                 $this->pagefoot();
4319                 return;
4320         }
4321
4322     /**
4323      * @todo document this
4324      */
4325     function action_skinnew() {
4326         global $member;
4327
4328         $member->isAdmin() or $this->disallow();
4329
4330         $name = trim(postVar('name'));
4331         $desc = trim(postVar('desc'));
4332
4333         if (!isValidSkinName($name))
4334             $this->error(_ERROR_BADSKINNAME);
4335
4336         if (Skin::exists($name))
4337             $this->error(_ERROR_DUPSKINNAME);
4338
4339         $newId = Skin::createNew($name, $desc);
4340
4341         $this->action_skinoverview();
4342     }
4343
4344     /**
4345      * @todo document this
4346      */
4347     function action_skinedit() {
4348         global $member, $manager;
4349
4350         $skinid = intRequestVar('skinid');
4351
4352         $member->isAdmin() or $this->disallow();
4353
4354         $skin = new SKIN($skinid);
4355
4356         $this->pagehead();
4357         ?>
4358         <p>
4359             <a href="index.php?action=skinoverview">(<?php echo _SKIN_BACK?>)</a>
4360         </p>
4361         <h2><?php echo _SKIN_EDITONE_TITLE?> '<?php echo  $skin->getName() ?>'</h2>
4362
4363         <h3><?php echo _SKIN_PARTS_TITLE?></h3>
4364         <?php echo _SKIN_PARTS_MSG?>
4365         <ul>
4366             <li><a tabindex="10" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=index"><?php echo _SKIN_PART_MAIN?></a> <?php help('skinpartindex')?></li>
4367             <li><a tabindex="20" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=item"><?php echo _SKIN_PART_ITEM?></a> <?php help('skinpartitem')?></li>
4368             <li><a tabindex="30" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=archivelist"><?php echo _SKIN_PART_ALIST?></a> <?php help('skinpartarchivelist')?></li>
4369             <li><a tabindex="40" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=archive"><?php echo _SKIN_PART_ARCHIVE?></a> <?php help('skinpartarchive')?></li>
4370             <li><a tabindex="50" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=search"><?php echo _SKIN_PART_SEARCH?></a> <?php help('skinpartsearch')?></li>
4371             <li><a tabindex="60" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=error"><?php echo _SKIN_PART_ERROR?></a> <?php help('skinparterror')?></li>
4372             <li><a tabindex="70" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=member"><?php echo _SKIN_PART_MEMBER?></a> <?php help('skinpartmember')?></li>
4373             <li><a tabindex="75" href="index.php?action=skinedittype&amp;skinid=<?php echo  $skinid ?>&amp;type=imagepopup"><?php echo _SKIN_PART_POPUP?></a> <?php help('skinpartimagepopup')?></li>
4374         </ul>
4375
4376         <?php
4377
4378         $query = "SELECT stype FROM " . sql_table('skin') . " WHERE stype NOT IN ('index', 'item', 'error', 'search', 'archive', 'archivelist', 'imagepopup', 'member') and sdesc = " . $skinid;
4379         $res = sql_query($query);
4380
4381         echo '<h3>' . _SKIN_PARTS_SPECIAL . '</h3>';
4382         echo '<form method="get" action="index.php">' . "\r\n";
4383         echo '<input type="hidden" name="action" value="skinedittype" />' . "\r\n";
4384         echo '<input type="hidden" name="skinid" value="' . $skinid . '" />' . "\r\n";
4385         echo '<input name="type" tabindex="89" size="20" maxlength="20" />' . "\r\n";
4386         echo '<input type="submit" tabindex="140" value="' . _SKIN_CREATE . '" onclick="return checkSubmit();" />' . "\r\n";
4387         echo '</form>' . "\r\n";
4388
4389         if ($res && sql_num_rows($res) > 0) {
4390             echo '<ul>';
4391             $tabstart = 75;
4392
4393             while ($row = sql_fetch_assoc($res)) {
4394                 echo '<li><a tabindex="' . ($tabstart++) . '" href="index.php?action=skinedittype&amp;skinid=' . $skinid . '&amp;type=' . Entity::hsc(strtolower($row['stype'])) . '">' . Entity::hsc(ucfirst($row['stype'])) . '</a> (<a tabindex="' . ($tabstart++) . '" href="index.php?action=skinremovetype&amp;skinid=' . $skinid . '&amp;type=' . Entity::hsc(strtolower($row['stype'])) . '">remove</a>)</li>';
4395             }
4396
4397             echo '</ul>';
4398         }
4399
4400         ?>
4401
4402         <h3><?php echo _SKIN_GENSETTINGS_TITLE; ?></h3>
4403         <form method="post" action="index.php">
4404         <div>
4405
4406         <input type="hidden" name="action" value="skineditgeneral" />
4407         <?php $manager->addTicketHidden() ?>
4408         <input type="hidden" name="skinid" value="<?php echo  $skinid ?>" />
4409         <table><tr>
4410             <td><?php echo _SKIN_NAME?> <?php help('shortnames');?></td>
4411             <td><input name="name" tabindex="90" value="<?php echo  Entity::hsc($skin->getName()) ?>" maxlength="20" size="20" /></td>
4412         </tr><tr>
4413             <td><?php echo _SKIN_DESC?></td>
4414             <td><input name="desc" tabindex="100" value="<?php echo  Entity::hsc($skin->getDescription()) ?>" maxlength="200" size="50" /></td>
4415         </tr><tr>
4416             <td><?php echo _SKIN_TYPE?></td>
4417             <td><input name="type" tabindex="110" value="<?php echo  Entity::hsc($skin->getContentType()) ?>" maxlength="40" size="20" /></td>
4418         </tr><tr>
4419             <td><?php echo _SKIN_INCLUDE_MODE?> <?php help('includemode')?></td>
4420             <td><?php $this->input_yesno('inc_mode',$skin->getIncludeMode(),120,'skindir','normal',_PARSER_INCMODE_SKINDIR,_PARSER_INCMODE_NORMAL);?></td>
4421         </tr><tr>
4422             <td><?php echo _SKIN_INCLUDE_PREFIX?> <?php help('includeprefix')?></td>
4423             <td><input name="inc_prefix" tabindex="130" value="<?php echo  Entity::hsc($skin->getIncludePrefix()) ?>" maxlength="40" size="20" /></td>
4424         </tr><tr>
4425             <td><?php echo _SKIN_CHANGE?></td>
4426             <td><input type="submit" tabindex="140" value="<?php echo _SKIN_CHANGE_BTN?>" onclick="return checkSubmit();" /></td>
4427         </tr></table>
4428
4429         </div>
4430         </form>
4431
4432
4433         <?php       $this->pagefoot();
4434     }
4435
4436     /**
4437      * @todo document this
4438      */
4439     function action_skineditgeneral() {
4440         global $member;
4441
4442         $skinid = intRequestVar('skinid');
4443
4444         $member->isAdmin() or $this->disallow();
4445
4446         $name = postVar('name');
4447         $desc = postVar('desc');
4448         $type = postVar('type');
4449         $inc_mode = postVar('inc_mode');
4450         $inc_prefix = postVar('inc_prefix');
4451
4452         $skin = new SKIN($skinid);
4453
4454         // 1. Some checks
4455         if (!isValidSkinName($name))
4456             $this->error(_ERROR_BADSKINNAME);
4457
4458         if (($skin->getName() != $name) && Skin::exists($name))
4459             $this->error(_ERROR_DUPSKINNAME);
4460
4461         if (!$type) $type = 'text/html';
4462         if (!$inc_mode) $inc_mode = 'normal';
4463
4464         // 2. Update description
4465         $skin->updateGeneralInfo($name, $desc, $type, $inc_mode, $inc_prefix);
4466
4467         $this->action_skinedit();
4468
4469     }
4470
4471         /**
4472          * Admin::action_skinedittype()
4473          * 
4474          * @param       string  $msg    message for pageheader
4475          * @return      void
4476          */
4477         public function action_skinedittype($msg = '')
4478         {
4479                 global $member, $manager;
4480                 
4481                 $skinid = intRequestVar('skinid');
4482                 $type = requestVar('type');
4483                 
4484                 $member->isAdmin() or $this->disallow();
4485                 
4486                 $type = trim($type);
4487                 $type = strtolower($type);
4488                 
4489                 if ( !isValidShortName($type) )
4490                 {
4491                         $this->error(_ERROR_SKIN_PARTS_SPECIAL_FORMAT);
4492                 }
4493                 
4494                 $skin = new SKIN($skinid);
4495                 $friendlyNames = Skin::getFriendlyNames();
4496                 
4497                 $this->pagehead();
4498                 
4499                 echo '<p>(<a href="index.php?action=skinoverview">' . _SKIN_GOBACK . "</a>)</p>\n";
4500                 
4501                 if ( !array_key_exists($type, $friendlyNames) || !isset($friendlyNames[$type]) )
4502                 {
4503                         echo '<h2>' . _SKIN_EDITPART_TITLE . Entity::hsc($skin->getName()) . ':' . Entity::hsc(ucfirst($type)) . "</h2>\n";
4504                 }
4505                 else
4506                 {
4507                         echo '<h2>' . _SKIN_EDITPART_TITLE . Entity::hsc($skin->getName()) . ':' . Entity::hsc($friendlyNames[$type]) . "</h2>\n";
4508                 }
4509                 
4510                 if ( isset($msg) )
4511                 {
4512                         echo "<p>"._MESSAGE.": $msg</p>\n";
4513                 }
4514                 
4515                 echo "<form method=\"post\" action=\"index.php\">\n";
4516                 echo "<div>\n";
4517                 
4518                 echo "<input type=\"hidden\" name=\"action\" value=\"skinupdate\" />\n";
4519                 $manager->addTicketHidden() . "\n";
4520                 echo "<input type=\"hidden\" name=\"skinid\" value=\"{$skinid}\" />\n";
4521                 echo "<input type=\"hidden\" name=\"type\" value=\"{$type}\" />\n";
4522                 
4523                 echo '<input type="submit" value="' . _SKIN_UPDATE_BTN . '" onclick="return checkSubmit();" />' . "\n";
4524                 echo '<input type="reset" value="' . _SKIN_RESET_BTN . '" />' . "\n";
4525                 
4526                 if ( !array_key_exists($type, $friendlyNames) || !isset($friendlyNames[$type]) )
4527                 {
4528                         echo '(skin type: ' . Entity::hsc(ucfirst($type)) . ")\n";
4529                 }
4530                 else
4531                 {
4532                         echo '(skin type: ' . Entity::hsc($friendlyNames[$type]) . ")\n";
4533                 }
4534                 
4535                 if ( !in_array($type, array('index', 'item', 'archivelist', 'archive', 'search', 'error', 'member', 'imagepopup')) )
4536                 {
4537                         help('skinpartspecial');
4538                 }
4539                 else
4540                 {
4541                         help('skinpart' . $type);
4542                 }
4543                 echo "<br />\n";
4544                 
4545                 echo "<textarea class=\"skinedit\" tabindex=\"10\" rows=\"20\" cols=\"80\" name=\"content\">\n";
4546                 echo Entity::hsc($skin->getContent($type)) . "\n";
4547                 echo "</textarea>\n";
4548                 
4549                 echo "<br />\n";
4550                 echo '<input type="submit" tabindex="20" value="' . _SKIN_UPDATE_BTN . '" onclick="return checkSubmit();" />' . "\n";
4551                 echo '<input type="reset" value="' . _SKIN_RESET_BTN . '" />' . "\n";
4552                 if ( !array_key_exists($type, $friendlyNames) || !isset($friendlyNames[$type]) )
4553                 {
4554                         echo '(skin type: ' . Entity::hsc(ucfirst($type)) . ")\n";
4555                 }
4556                 else
4557                 {
4558                         echo '(skin type: ' . Entity::hsc($friendlyNames[$type]) . ")\n";
4559                 }
4560                 
4561                 echo "<br />\n";
4562                 echo "<br />\n";
4563                 echo _SKIN_ALLOWEDVARS;
4564                 
4565                 $actions = $skin->getAllowedActionsForType($type);
4566                 
4567                 sort($actions);
4568                 
4569                 while ($current = array_shift($actions))
4570                 {
4571                         // skip deprecated vars
4572                         if ( in_array($current, array('ifcat', 'imagetext', 'vars')) )
4573                         {
4574                                 continue;
4575                         }
4576                         
4577                         echo helplink("skinvar-{$current}") . "{$current}</a>\n";
4578                         
4579                         if ( count($actions) != 0 )
4580                         {
4581                                 echo ", ";
4582                         }
4583                 }
4584                 
4585                 echo "<br />\n";
4586                 echo "<br />\n";
4587                 echo _SKINEDIT_ALLOWEDBLOGS;
4588                 
4589                 $query = 'SELECT bshortname, bname FROM '.sql_table('blog');
4590                 showlist($query, 'table', array('content'=>'shortblognames'));
4591                 
4592                 echo "<br />\n";
4593                 echo _SKINEDIT_ALLOWEDTEMPLATESS;
4594                 
4595                 $query = 'SELECT tdname as name, tddesc as description FROM '.sql_table('template_desc');
4596                 showlist($query, 'table', array('content'=>'shortnames'));
4597                 
4598                 echo "</div>\n";
4599                 echo "</form>\n";
4600                 
4601                 $this->pagefoot();
4602                 
4603                 return;
4604         }
4605
4606     /**
4607      * @todo document this
4608      */
4609     function action_skinupdate() {
4610         global $member;
4611
4612         $skinid = intRequestVar('skinid');
4613         $content = trim(postVar('content'));
4614         $type = postVar('type');
4615
4616         $member->isAdmin() or $this->disallow();
4617
4618         $skin = new SKIN($skinid);
4619         $skin->update($type, $content);
4620
4621         $this->action_skinedittype(_SKIN_UPDATED);
4622     }
4623
4624     /**
4625      * @todo document this
4626      */
4627     function action_skindelete() {
4628         global $member, $manager, $CONF;
4629
4630         $skinid = intRequestVar('skinid');
4631
4632         $member->isAdmin() or $this->disallow();
4633
4634         // don't allow default skin to be deleted
4635         if ($skinid == $CONF['BaseSkin'])
4636             $this->error(_ERROR_DEFAULTSKIN);
4637
4638         // don't allow deletion of default skins for blogs
4639         $query = 'SELECT bname FROM '.sql_table('blog').' WHERE bdefskin=' . $skinid;
4640         $r = sql_query($query);
4641         if ($o = sql_fetch_object($r))
4642             $this->error(_ERROR_SKINDEFDELETE . Entity::hsc($o->bname));
4643
4644         $this->pagehead();
4645
4646         $skin = new SKIN($skinid);
4647         $name = $skin->getName();
4648         $desc = $skin->getDescription();
4649
4650         ?>
4651             <h2><?php echo _DELETE_CONFIRM?></h2>
4652
4653             <p>
4654                 <?php echo _CONFIRMTXT_SKIN?><b><?php echo Entity::hsc($name) ?></b> (<?php echo  Entity::hsc($desc)?>)
4655             </p>
4656
4657             <form method="post" action="index.php"><div>
4658                 <input type="hidden" name="action" value="skindeleteconfirm" />
4659                 <?php $manager->addTicketHidden() ?>
4660                 <input type="hidden" name="skinid" value="<?php echo  $skinid ?>" />
4661                 <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
4662             </div></form>
4663         <?php
4664         $this->pagefoot();
4665     }
4666
4667     /**
4668      * @todo document this
4669      */
4670     function action_skindeleteconfirm() {
4671         global $member, $CONF, $manager;
4672
4673         $skinid = intRequestVar('skinid');
4674
4675         $member->isAdmin() or $this->disallow();
4676
4677         // don't allow default skin to be deleted
4678         if ($skinid == $CONF['BaseSkin'])
4679             $this->error(_ERROR_DEFAULTSKIN);
4680
4681         // don't allow deletion of default skins for blogs
4682         $query = 'SELECT bname FROM '.sql_table('blog').' WHERE bdefskin=' . $skinid;
4683         $r = sql_query($query);
4684         if ($o = sql_fetch_object($r))
4685             $this->error(_ERROR_SKINDEFDELETE .$o->bname);
4686
4687         $manager->notify('PreDeleteSkin', array('skinid' => $skinid));
4688
4689         // 1. delete description
4690         sql_query('DELETE FROM '.sql_table('skin_desc').' WHERE sdnumber=' . $skinid);
4691
4692         // 2. delete parts
4693         sql_query('DELETE FROM '.sql_table('skin').' WHERE sdesc=' . $skinid);
4694
4695         $manager->notify('PostDeleteSkin', array('skinid' => $skinid));
4696
4697         $this->action_skinoverview();
4698     }
4699
4700     /**
4701      * @todo document this
4702      */
4703     function action_skinremovetype() {
4704         global $member, $manager, $CONF;
4705
4706         $skinid = intRequestVar('skinid');
4707         $skintype = requestVar('type');
4708
4709         if (!isValidShortName($skintype)) {
4710             $this->error(_ERROR_SKIN_PARTS_SPECIAL_DELETE);
4711         }
4712
4713         $member->isAdmin() or $this->disallow();
4714
4715         // don't allow default skinparts to be deleted
4716         if (in_array($skintype, array('index', 'item', 'archivelist', 'archive', 'search', 'error', 'member', 'imagepopup'))) {
4717             $this->error(_ERROR_SKIN_PARTS_SPECIAL_DELETE);
4718         }
4719
4720         $this->pagehead();
4721
4722         $skin = new SKIN($skinid);
4723         $name = $skin->getName();
4724         $desc = $skin->getDescription();
4725
4726         ?>
4727             <h2><?php echo _DELETE_CONFIRM?></h2>
4728
4729             <p>
4730                 <?php echo _CONFIRMTXT_SKIN_PARTS_SPECIAL; ?> <b><?php echo Entity::hsc($skintype); ?> (<?php echo Entity::hsc($name); ?>)</b> (<?php echo  Entity::hsc($desc)?>)
4731             </p>
4732
4733             <form method="post" action="index.php"><div>
4734                 <input type="hidden" name="action" value="skinremovetypeconfirm" />
4735                 <?php $manager->addTicketHidden() ?>
4736                 <input type="hidden" name="skinid" value="<?php echo $skinid; ?>" />
4737                 <input type="hidden" name="type" value="<?php echo Entity::hsc($skintype); ?>" />
4738                 <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
4739             </div></form>
4740         <?php
4741         $this->pagefoot();
4742     }
4743
4744     /**
4745      * @todo document this
4746      */
4747     function action_skinremovetypeconfirm() {
4748         global $member, $CONF, $manager;
4749
4750         $skinid = intRequestVar('skinid');
4751         $skintype = requestVar('type');
4752
4753         if (!isValidShortName($skintype)) {
4754             $this->error(_ERROR_SKIN_PARTS_SPECIAL_DELETE);
4755         }
4756
4757         $member->isAdmin() or $this->disallow();
4758
4759         // don't allow default skinparts to be deleted
4760         if (in_array($skintype, array('index', 'item', 'archivelist', 'archive', 'search', 'error', 'member', 'imagepopup'))) {
4761             $this->error(_ERROR_SKIN_PARTS_SPECIAL_DELETE);
4762         }
4763
4764         $manager->notify('PreDeleteSkinPart', array('skinid' => $skinid, 'skintype' => $skintype));
4765
4766         // delete part
4767         sql_query('DELETE FROM '.sql_table('skin').' WHERE sdesc=' . $skinid . ' AND stype=\'' . $skintype . '\'');
4768
4769         $manager->notify('PostDeleteSkinPart', array('skinid' => $skinid, 'skintype' => $skintype));
4770
4771         $this->action_skinedit();
4772     }
4773
4774     /**
4775      * @todo document this
4776      */
4777     function action_skinclone() {
4778         global $member;
4779
4780         $skinid = intRequestVar('skinid');
4781
4782         $member->isAdmin() or $this->disallow();
4783
4784         // 1. read skin to clone
4785         $skin = new SKIN($skinid);
4786
4787         $name = "clone_" . $skin->getName();
4788
4789         // if a skin with that name already exists:
4790         if (Skin::exists($name)) {
4791             $i = 1;
4792             while (Skin::exists($name . $i))
4793                 $i++;
4794             $name .= $i;
4795         }
4796
4797         // 2. create skin desc
4798         $newid = Skin::createNew(
4799             $name,
4800             $skin->getDescription(),
4801             $skin->getContentType(),
4802             $skin->getIncludeMode(),
4803             $skin->getIncludePrefix()
4804         );
4805
4806
4807         // 3. clone
4808         /*
4809         $this->skinclonetype($skin, $newid, 'index');
4810         $this->skinclonetype($skin, $newid, 'item');
4811         $this->skinclonetype($skin, $newid, 'archivelist');
4812         $this->skinclonetype($skin, $newid, 'archive');
4813         $this->skinclonetype($skin, $newid, 'search');
4814         $this->skinclonetype($skin, $newid, 'error');
4815         $this->skinclonetype($skin, $newid, 'member');
4816         $this->skinclonetype($skin, $newid, 'imagepopup');
4817         */
4818
4819         $query = "SELECT stype FROM " . sql_table('skin') . " WHERE sdesc = " . $skinid;
4820         $res = sql_query($query);
4821         while ($row = sql_fetch_assoc($res)) {
4822             $this->skinclonetype($skin, $newid, $row['stype']);
4823         }
4824
4825         $this->action_skinoverview();
4826
4827     }
4828
4829         /**
4830          * Admin::skinclonetype()
4831          * 
4832          * @param       String  $skin   Skin object
4833          * @param       Integer $newid  ID for this clone
4834          * @param       String  $type   type of skin
4835          * @return      Void
4836          */
4837         function skinclonetype($skin, $newid, $type)
4838         {
4839                 $newid = intval($newid);
4840                 $content = $skin->getContent($type);
4841                 
4842                 if ( $content )
4843                 {
4844                         $query = "INSERT INTO %s (sdesc, scontent, stype) VALUES (%d, '%s', '%s')";
4845                         $query = sprintf($query, sql_table('skin'), (integer) $newid, $content, $type);
4846                         sql_query($query);
4847                 }
4848                 return;
4849         }
4850         
4851         /**
4852          * Admin::action_settingsedit()
4853          * 
4854          * @param       Void
4855          * @return      Void
4856          */
4857         function action_settingsedit() {
4858                 global $member, $manager, $CONF, $DIR_NUCLEUS, $DIR_MEDIA;
4859
4860                 $member->isAdmin() or $this->disallow();
4861
4862                 $this->pagehead();
4863
4864                 echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
4865                 ?>
4866
4867                 <h2><?php echo _SETTINGS_TITLE?></h2>
4868
4869                 <form action="index.php" method="post">
4870                 <div>
4871
4872                 <input type="hidden" name="action" value="settingsupdate" />
4873                 <?php $manager->addTicketHidden() ?>
4874
4875                 <table><tr>
4876                         <th colspan="2"><?php echo _SETTINGS_SUB_GENERAL?></th>
4877                 </tr><tr>
4878                         <td><?php echo _SETTINGS_DEFBLOG?> <?php help('defaultblog'); ?></td>
4879                         <td>
4880                                 <?php
4881                                         $query =  'SELECT bname as text, bnumber as value'
4882                                                    . ' FROM '.sql_table('blog');
4883                                         $template['name'] = 'DefaultBlog';
4884                                         $template['selected'] = $CONF['DefaultBlog'];
4885                                         $template['tabindex'] = 10;
4886                                         showlist($query,'select',$template);
4887                                 ?>
4888                         </td>
4889                 </tr><tr>
4890                         <td><?php echo _SETTINGS_BASESKIN?> <?php help('baseskin'); ?></td>
4891                         <td>
4892                                 <?php
4893                                         $query =  'SELECT sdname as text, sdnumber as value'
4894                                                    . ' FROM '.sql_table('skin_desc');
4895                                         $template['name'] = 'BaseSkin';
4896                                         $template['selected'] = $CONF['BaseSkin'];
4897                                         $template['tabindex'] = 1;
4898                                         showlist($query,'select',$template);
4899                                 ?>
4900                         </td>
4901                 </tr><tr>
4902                         <td><?php echo _SETTINGS_ADMINMAIL?></td>
4903                         <td><input name="AdminEmail" tabindex="10010" size="40" value="<?php echo  Entity::hsc($CONF['AdminEmail']) ?>" /></td>
4904                 </tr><tr>
4905                         <td><?php echo _SETTINGS_SITENAME?></td>
4906                         <td><input name="SiteName" tabindex="10020" size="40" value="<?php echo  Entity::hsc($CONF['SiteName']) ?>" /></td>
4907                 </tr><tr>
4908                         <td><?php echo _SETTINGS_SITEURL?></td>
4909                         <td><input name="IndexURL" tabindex="10030" size="40" value="<?php echo  Entity::hsc($CONF['IndexURL']) ?>" /></td>
4910                 </tr><tr>
4911                         <td><?php echo _SETTINGS_ADMINURL?></td>
4912                         <td><input name="AdminURL" tabindex="10040" size="40" value="<?php echo  Entity::hsc($CONF['AdminURL']) ?>" /></td>
4913                 </tr><tr>
4914                         <td><?php echo _SETTINGS_PLUGINURL?> <?php help('pluginurl');?></td>
4915                         <td><input name="PluginURL" tabindex="10045" size="40" value="<?php echo  Entity::hsc($CONF['PluginURL']) ?>" /></td>
4916                 </tr><tr>
4917                         <td><?php echo _SETTINGS_SKINSURL?> <?php help('skinsurl');?></td>
4918                         <td><input name="SkinsURL" tabindex="10046" size="40" value="<?php echo  Entity::hsc($CONF['SkinsURL']) ?>" /></td>
4919                 </tr><tr>
4920                         <td><?php echo _SETTINGS_ACTIONSURL?> <?php help('actionurl');?></td>
4921                         <td><input name="ActionURL" tabindex="10047" size="40" value="<?php echo  Entity::hsc($CONF['ActionURL']) ?>" /></td>
4922                 </tr><tr>
4923                         <td><?php echo _SETTINGS_LOCALE?> <?php help('locale'); ?>
4924                         </td>
4925                         <td>
4926                                 <select name="Locale" tabindex="10050">
4927                         <?php
4928                                 $locales = i18n::get_available_locale_list();
4929                                 if ( !i18n::get_current_locale() || !in_array(i18n::get_current_locale(), $locales) )
4930                                 {
4931                                         echo "<option value=\"\" selected=\"selected\">en_Latn_US</option>\n";
4932                                 }
4933                                 else
4934                                 {
4935                                         echo "<option value=\"\">en_Latn_US</option>\n";
4936                                 }
4937                                 
4938                                 foreach ( $locales as $locale )
4939                                 {
4940                                         if ( $locale == 'en_Latn_US' )
4941                                         {
4942                                                 continue;
4943                                         }
4944                                         if ( $locale == i18n::get_current_locale() )
4945                                         {
4946                                                 echo "<option value=\"{$locale}\" selected=\"selected\">{$locale}</option>\n";
4947                                         }
4948                                         else
4949                                         {
4950                                                 echo "<option value=\"{$locale}\">{$locale}</option>\n";
4951                                         }
4952                                 }
4953                         ?>
4954                         </select>
4955
4956                         </td>
4957                 </tr><tr>
4958                         <td><?php echo _SETTINGS_DISABLESITE?> <?php help('disablesite'); ?>
4959                         </td>
4960                         <td><?php $this->input_yesno('DisableSite',$CONF['DisableSite'],10060); ?>
4961                                         <br />
4962                                 <?php echo _SETTINGS_DISABLESITEURL ?> <input name="DisableSiteURL" tabindex="10070" size="40" value="<?php echo  Entity::hsc($CONF['DisableSiteURL'])?>" />
4963                         </td>
4964                 </tr><tr>
4965                         <td><?php echo _SETTINGS_DIRS?></td>
4966                         <td><?php echo  Entity::hsc($DIR_NUCLEUS) ?>
4967                                 <i><?php echo _SETTINGS_SEECONFIGPHP?></i></td>
4968                 </tr><tr>
4969                         <td><?php echo _SETTINGS_DBLOGIN?></td>
4970                         <td><i><?php echo _SETTINGS_SEECONFIGPHP?></i></td>
4971                 </tr><tr>
4972                         <td>
4973                         <?php
4974                                 echo _SETTINGS_JSTOOLBAR
4975                                 /* =_SETTINGS_DISABLEJS
4976
4977                                         I temporary changed the meaning of DisableJsTools, until I can find a good
4978                                         way to select the javascript version to use
4979
4980                                         now, its:
4981                                                 0 : IE
4982                                                 1 : all javascript disabled
4983                                                 2 : 'simpler' javascript (for mozilla/opera/mac)
4984                                 */
4985                            ?>
4986                         </td>
4987                         <td><?php /* $this->input_yesno('DisableJsTools',$CONF['DisableJsTools'],10075); */?>
4988                                 <select name="DisableJsTools" tabindex="10075">
4989                         <?php                              $extra = ($CONF['DisableJsTools'] == 1) ? 'selected="selected"' : '';
4990                                         echo "<option $extra value='1'>",_SETTINGS_JSTOOLBAR_NONE,"</option>";
4991                                         $extra = ($CONF['DisableJsTools'] == 2) ? 'selected="selected"' : '';
4992                                         echo "<option $extra value='2'>",_SETTINGS_JSTOOLBAR_SIMPLE,"</option>";
4993                                         $extra = ($CONF['DisableJsTools'] == 0) ? 'selected="selected"' : '';
4994                                         echo "<option $extra value='0'>",_SETTINGS_JSTOOLBAR_FULL,"</option>";
4995                         ?>
4996                                 </select>
4997                         </td>
4998                 </tr><tr>
4999                         <td><?php echo _SETTINGS_URLMODE?> <?php help('urlmode');?></td>
5000                                            <td><?php
5001
5002                                            $this->input_yesno('URLMode',$CONF['URLMode'],10077,
5003                                                           'normal','pathinfo',_SETTINGS_URLMODE_NORMAL,_SETTINGS_URLMODE_PATHINFO);
5004
5005                                            echo ' ', _SETTINGS_URLMODE_HELP;
5006
5007                                                          ?>
5008
5009                                            </td>
5010                 </tr><tr>
5011                         <td><?php echo _SETTINGS_DEBUGVARS?> <?php help('debugvars');?></td>
5012                                            <td><?php
5013
5014                                                 $this->input_yesno('DebugVars',$CONF['DebugVars'],10078);
5015
5016                                                          ?>
5017
5018                                            </td>
5019                 </tr><tr>
5020                         <td><?php echo _SETTINGS_DEFAULTLISTSIZE?> <?php help('defaultlistsize');?></td>
5021                         <td>
5022                         <?php
5023                                 if (!array_key_exists('DefaultListSize',$CONF)) {
5024                                         sql_query("INSERT INTO ".sql_table('config')." VALUES ('DefaultListSize', '10')");
5025                                         $CONF['DefaultListSize'] = 10;
5026                                 }
5027                         ?>
5028                                 <input name="DefaultListSize" tabindex="10079" size="40" value="<?php echo  Entity::hsc((intval($CONF['DefaultListSize']) < 1 ? '10' : $CONF['DefaultListSize'])) ?>" />
5029                         </td>
5030                 </tr><tr>
5031                         <td><?php echo _SETTINGS_ADMINCSS?> 
5032                         </td>
5033                         <td>
5034
5035                                 <select name="AdminCSS" tabindex="10080">
5036                                 <?php                      // show a dropdown list of all available admin css files
5037                                 global $DIR_NUCLEUS;
5038                                 
5039                                 $dirhandle = opendir($DIR_NUCLEUS."styles/");
5040
5041                                 while ($filename = readdir($dirhandle) )
5042                                 {
5043
5044                                         # replaced ereg() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
5045                                         # original ereg: ereg("^(.*)\.php$",$filename,$matches)
5046
5047                                         if (preg_match('#^admin_(.*)\.css$#', $filename, $matches) )
5048                                         {
5049
5050                                                 $name = $matches[1];
5051                                                 echo "<option value=\"$name\"";
5052
5053                                                 if ($name == $CONF['AdminCSS'])
5054                                                 {
5055                                                         echo " selected=\"selected\"";
5056                                                 }
5057
5058                                                 echo ">$name</option>";
5059
5060                                         }
5061
5062                                 }
5063
5064                                 closedir($dirhandle);
5065
5066                                 ?>
5067                                 </select>
5068
5069                         </td>
5070                 </tr><tr>
5071                         <th colspan="2"><?php echo _SETTINGS_MEDIA?> <?php help('media'); ?></th>
5072                 </tr><tr>
5073                         <td><?php echo _SETTINGS_MEDIADIR?></td>
5074                         <td><?php echo  Entity::hsc($DIR_MEDIA) ?>
5075                                 <i><?php echo _SETTINGS_SEECONFIGPHP?></i>
5076                                 <?php                              if (!is_dir($DIR_MEDIA))
5077                                                 echo "<br /><b>" . _WARNING_NOTADIR . "</b>";
5078                                         if (!is_readable($DIR_MEDIA))
5079                                                 echo "<br /><b>" . _WARNING_NOTREADABLE . "</b>";
5080                                         if (!is_writeable($DIR_MEDIA))
5081                                                 echo "<br /><b>" . _WARNING_NOTWRITABLE . "</b>";
5082                                 ?>
5083                         </td>
5084                 </tr><tr>
5085                         <td><?php echo _SETTINGS_MEDIAURL?></td>
5086                         <td>
5087                                 <input name="MediaURL" tabindex="10090" size="40" value="<?php echo  Entity::hsc($CONF['MediaURL']) ?>" />
5088                         </td>
5089                 </tr><tr>
5090                         <td><?php echo _SETTINGS_ALLOWUPLOAD?></td>
5091                         <td><?php $this->input_yesno('AllowUpload',$CONF['AllowUpload'],10090); ?></td>
5092                 </tr><tr>
5093                         <td><?php echo _SETTINGS_ALLOWUPLOADTYPES?></td>
5094                         <td>
5095                                 <input name="AllowedTypes" tabindex="10100" size="40" value="<?php echo  Entity::hsc($CONF['AllowedTypes']) ?>" />
5096                         </td>
5097                 </tr><tr>
5098                         <td><?php echo _SETTINGS_MAXUPLOADSIZE?></td>
5099                         <td>
5100                                 <input name="MaxUploadSize" tabindex="10105" size="40" value="<?php echo  Entity::hsc($CONF['MaxUploadSize']) ?>" />
5101                         </td>
5102                 </tr><tr>
5103                         <td><?php echo _SETTINGS_MEDIAPREFIX?></td>
5104                         <td><?php $this->input_yesno('MediaPrefix',$CONF['MediaPrefix'],10110); ?></td>
5105
5106                 </tr><tr>
5107                         <th colspan="2"><?php echo _SETTINGS_MEMBERS?></th>
5108                 </tr><tr>
5109                         <td><?php echo _SETTINGS_CHANGELOGIN?></td>
5110                         <td><?php $this->input_yesno('AllowLoginEdit',$CONF['AllowLoginEdit'],10120); ?></td>
5111                 </tr><tr>
5112                         <td><?php echo _SETTINGS_ALLOWCREATE?>
5113                                 <?php help('allowaccountcreation'); ?>
5114                         </td>
5115                         <td><?php $this->input_yesno('AllowMemberCreate',$CONF['AllowMemberCreate'],10130); ?>
5116                         </td>
5117                 </tr><tr>
5118                         <td><?php echo _SETTINGS_NEWLOGIN?> <?php help('allownewmemberlogin'); ?>
5119                                 <br /><?php echo _SETTINGS_NEWLOGIN2?>
5120                         </td>
5121                         <td><?php $this->input_yesno('NewMemberCanLogon',$CONF['NewMemberCanLogon'],10140); ?>
5122                         </td>
5123                 </tr><tr>
5124                         <td><?php echo _SETTINGS_MEMBERMSGS?>
5125                                 <?php help('messageservice'); ?>
5126                         </td>
5127                         <td><?php $this->input_yesno('AllowMemberMail',$CONF['AllowMemberMail'],10150); ?>
5128                         </td>
5129                 </tr><tr>
5130                         <td><?php echo _SETTINGS_NONMEMBERMSGS?>
5131                                 <?php help('messageservice'); ?>
5132                         </td>
5133                         <td><?php $this->input_yesno('NonmemberMail',$CONF['NonmemberMail'],10155); ?>
5134                         </td>
5135                 </tr><tr>
5136                         <td><?php echo _SETTINGS_PROTECTMEMNAMES?>
5137                                 <?php help('protectmemnames'); ?>
5138                         </td>
5139                         <td><?php $this->input_yesno('ProtectMemNames',$CONF['ProtectMemNames'],10156); ?>
5140                         </td>
5141
5142
5143
5144                 </tr><tr>
5145                         <th colspan="2"><?php echo _SETTINGS_COOKIES_TITLE?> <?php help('cookies'); ?></th>
5146                 </tr><tr>
5147                         <td><?php echo _SETTINGS_COOKIEPREFIX?></td>
5148                         <td><input name="CookiePrefix" tabindex="10159" size="40" value="<?php echo  Entity::hsc($CONF['CookiePrefix'])?>" /></td>
5149                 </tr><tr>
5150                         <td><?php echo _SETTINGS_COOKIEDOMAIN?></td>
5151                         <td><input name="CookieDomain" tabindex="10160" size="40" value="<?php echo  Entity::hsc($CONF['CookieDomain'])?>" /></td>
5152                 </tr><tr>
5153                         <td><?php echo _SETTINGS_COOKIEPATH?></td>
5154                         <td><input name="CookiePath" tabindex="10170" size="40" value="<?php echo  Entity::hsc($CONF['CookiePath'])?>" /></td>
5155                 </tr><tr>
5156                         <td><?php echo _SETTINGS_COOKIESECURE?></td>
5157                         <td><?php $this->input_yesno('CookieSecure',$CONF['CookieSecure'],10180); ?></td>
5158                 </tr><tr>
5159                         <td><?php echo _SETTINGS_COOKIELIFE?></td>
5160                         <td><?php $this->input_yesno('SessionCookie',$CONF['SessionCookie'],10190,
5161                                                           1,0,_SETTINGS_COOKIESESSION,_SETTINGS_COOKIEMONTH); ?>
5162                         </td>
5163                 </tr><tr>
5164                         <td><?php echo _SETTINGS_LASTVISIT?></td>
5165                         <td><?php $this->input_yesno('LastVisit',$CONF['LastVisit'],10200); ?></td>
5166
5167
5168
5169                 </tr><tr>
5170                         <th colspan="2"><?php echo _SETTINGS_UPDATE?></th>
5171                 </tr><tr>
5172                         <td><?php echo _SETTINGS_UPDATE?></td>
5173                         <td><input type="submit" tabindex="10210" value="<?php echo _SETTINGS_UPDATE_BTN?>" onclick="return checkSubmit();" /></td>
5174                 </tr></table>
5175
5176                 </div>
5177                 </form>
5178
5179                 <?php
5180                         echo '<h2>',_PLUGINS_EXTRA,'</h2>';
5181
5182                         $manager->notify(
5183                                 'GeneralSettingsFormExtras',
5184                                 array()
5185                         );
5186
5187                 $this->pagefoot();
5188         }
5189         
5190         /**
5191          * Admin::action_settingsupdate()
5192          * Update $CONFIG and redirect
5193          * 
5194          * @param       void
5195          * @return      void
5196          */
5197         function action_settingsupdate() {
5198                 global $member, $CONF;
5199                 
5200                 $member->isAdmin() or $this->disallow();
5201                 
5202                 // check if email address for admin is valid
5203                 if ( !NOTIFICATION::address_validation(postVar('AdminEmail')) )
5204                 {
5205                         $this->error(_ERROR_BADMAILADDRESS);
5206                 }
5207                 
5208                 // save settings
5209                 $this->updateConfig('DefaultBlog',        postVar('DefaultBlog'));
5210                 $this->updateConfig('BaseSkin',          postVar('BaseSkin'));
5211                 $this->updateConfig('IndexURL',          postVar('IndexURL'));
5212                 $this->updateConfig('AdminURL',          postVar('AdminURL'));
5213                 $this->updateConfig('PluginURL',                postVar('PluginURL'));
5214                 $this->updateConfig('SkinsURL',          postVar('SkinsURL'));
5215                 $this->updateConfig('ActionURL',                postVar('ActionURL'));
5216                 $this->updateConfig('Locale',              postVar('Locale'));
5217                 $this->updateConfig('AdminEmail',          postVar('AdminEmail'));
5218                 $this->updateConfig('SessionCookie',    postVar('SessionCookie'));
5219                 $this->updateConfig('AllowMemberCreate',postVar('AllowMemberCreate'));
5220                 $this->updateConfig('AllowMemberMail',  postVar('AllowMemberMail'));
5221                 $this->updateConfig('NonmemberMail',    postVar('NonmemberMail'));
5222                 $this->updateConfig('ProtectMemNames',  postVar('ProtectMemNames'));
5223                 $this->updateConfig('SiteName',          postVar('SiteName'));
5224                 $this->updateConfig('NewMemberCanLogon',postVar('NewMemberCanLogon'));
5225                 $this->updateConfig('DisableSite',        postVar('DisableSite'));
5226                 $this->updateConfig('DisableSiteURL',   postVar('DisableSiteURL'));
5227                 $this->updateConfig('LastVisit',                postVar('LastVisit'));
5228                 $this->updateConfig('MediaURL',          postVar('MediaURL'));
5229                 $this->updateConfig('AllowedTypes',      postVar('AllowedTypes'));
5230                 $this->updateConfig('AllowUpload',        postVar('AllowUpload'));
5231                 $this->updateConfig('MaxUploadSize',    postVar('MaxUploadSize'));
5232                 $this->updateConfig('MediaPrefix',        postVar('MediaPrefix'));
5233                 $this->updateConfig('AllowLoginEdit',   postVar('AllowLoginEdit'));
5234                 $this->updateConfig('DisableJsTools',   postVar('DisableJsTools'));
5235                 $this->updateConfig('CookieDomain',      postVar('CookieDomain'));
5236                 $this->updateConfig('CookiePath',          postVar('CookiePath'));
5237                 $this->updateConfig('CookieSecure',      postVar('CookieSecure'));
5238                 $this->updateConfig('URLMode',            postVar('URLMode'));
5239                 $this->updateConfig('CookiePrefix',      postVar('CookiePrefix'));
5240                 $this->updateConfig('DebugVars',                        postVar('DebugVars'));
5241                 $this->updateConfig('DefaultListSize',            postVar('DefaultListSize'));
5242                 $this->updateConfig('AdminCSS',           postVar('AdminCSS'));
5243                 
5244                 // load new config and redirect (this way, the new locale will be used is necessary)
5245                 // note that when changing cookie settings, this redirect might cause the user
5246                 // to have to log in again.
5247                 getConfig();
5248                 redirect($CONF['AdminURL'] . '?action=manage');
5249                 exit;
5250         }
5251
5252         /**
5253          * Admin::action_systemoverview()
5254          * Output system overview
5255          * 
5256          * @param       void
5257          * @return      void
5258          */
5259         function action_systemoverview()
5260         {
5261                 global $member, $nucleus, $CONF;
5262                 
5263                 $this->pagehead();
5264                 
5265                 echo '<h2>' . _ADMIN_SYSTEMOVERVIEW_HEADING . "</h2>\n";
5266                 
5267                 if ( $member->isLoggedIn() && $member->isAdmin() )
5268                 {
5269                         // Information about the used PHP and MySQL installation
5270                         echo '<h3>' . _ADMIN_SYSTEMOVERVIEW_PHPANDMYSQL . "</h3>\n\n";
5271                         
5272                         // Version of PHP MySQL
5273                         echo '<table frame="box" rules="all" summary="' . _ADMIN_SYSTEMOVERVIEW_VERSIONS . "\" class=\"systemoverview\">\n";
5274                         echo "<thead>\n";
5275                         echo "<tr>\n";
5276                         echo '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_VERSIONS . "</th>\n";
5277                         echo "</tr>\n";
5278                         echo "</thead>\n";
5279                         echo "<tbody>\n";
5280                         echo "<tr>\n";
5281                         echo '<td>' . _ADMIN_SYSTEMOVERVIEW_PHPVERSION . "</td>\n";
5282                         echo '<td>' . phpversion() . "</td>\n";
5283                         echo "</tr>\n";
5284                         echo "<tr>\n";
5285                         echo '<td>' . _ADMIN_SYSTEMOVERVIEW_MYSQLVERSION . "</td>\n";
5286                         echo '<td>' . sql_get_server_info() . ' (' . sql_get_client_info() . ')' . "</td>\n";
5287                         echo "</tr>\n";
5288                         echo "</tbody>\n";
5289                         echo "</table>\n\n";
5290                         
5291                         // Important PHP settings
5292                         echo '<table frame="box" rules="all" summary="' . _ADMIN_SYSTEMOVERVIEW_SETTINGS . "\" class=\"systemoverview\">\n";
5293                         echo "<thead>\n";
5294                         echo "<tr>\n";
5295                         echo '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_SETTINGS . "</th>\n";
5296                         echo "</tr>\n";
5297                         echo "</thead>\n";
5298                         echo "<tbody>\n";
5299                         echo "<tr>\n";
5300                         echo '<td>magic_quotes_gpc' . "</td>\n";
5301                         $mqg = get_magic_quotes_gpc() ? 'On' : 'Off';
5302                         echo '<td>' . $mqg . "</td>\n";
5303                         echo "</tr>\n";
5304                         echo "<tr>\n";
5305                         echo '<td>magic_quotes_runtime' . "</td>\n";
5306                         $mqr = get_magic_quotes_runtime() ? 'On' : 'Off';
5307                         echo '<td>' . $mqr . "</td>\n";
5308                         echo "</tr>\n";
5309                         echo "<tr>\n";
5310                         echo '<td>register_globals' . "</td>\n";
5311                         $rg = ini_get('register_globals') ? 'On' : 'Off';
5312                         echo '<td>' . $rg . "</td>\n";
5313                         echo "</tr>\n";
5314                         echo "</tbody>\n";
5315                         echo "</table>\n\n";
5316                         
5317                         // Information about GD library
5318                         $gdinfo = gd_info();
5319                         echo '<table frame="box" rules="all" summary="' . _ADMIN_SYSTEMOVERVIEW_GDLIBRALY . "\" class=\"systemoverview\">\n";
5320                         echo "<thead>\n";
5321                         echo "<tr>\n";
5322                         echo '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_GDLIBRALY . "</th>\n";
5323                         echo "</tr>\n";
5324                         echo "</thead>\n";
5325                         echo "<tbody>\n";
5326                         foreach ( $gdinfo as $key=>$value )
5327                         {
5328                                 if ( is_bool($value) )
5329                                 {
5330                                         $value = $value ? _ADMIN_SYSTEMOVERVIEW_ENABLE : _ADMIN_SYSTEMOVERVIEW_DISABLE;
5331                                 }
5332                                 else
5333                                 {
5334                                         $value = Entity::hsc($value);
5335                                 }
5336                                 echo "<tr>\n";
5337                                 echo '<td>' . $key . "</td>\n";
5338                                 echo '<td>' . $value . "</td>\n";
5339                                 echo "</tr>\n";
5340                         }
5341                         echo "</tbody>\n";
5342                         echo "</table>\n\n";
5343
5344                         // Check if special modules are loaded
5345                         ob_start();
5346                         phpinfo(INFO_MODULES);
5347                         $im = ob_get_contents();
5348                         ob_clean();
5349                         echo '<table frame="box" rules="all" summary="' . _ADMIN_SYSTEMOVERVIEW_MODULES . "\" class=\"systemoverview\">\n";
5350                         echo "<thead>\n";
5351                         echo "<tr>";
5352                         echo '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_MODULES . "</th>\n";
5353                         echo "</tr>\n";
5354                         echo "<tbody>\n";
5355                         echo "<tr>\n";
5356                         echo '<td>mod_rewrite' . "</td>\n";
5357                         $modrewrite = (strstr($im, 'mod_rewrite') != '') ?
5358                                                 _ADMIN_SYSTEMOVERVIEW_ENABLE :
5359                                                 _ADMIN_SYSTEMOVERVIEW_DISABLE;
5360                         echo '<td>' . $modrewrite . "</td>\n";
5361                         echo "</tr>\n";
5362                         echo "</tbody>\n";
5363                         echo "</table>\n\n";
5364
5365                         // Information about the used Nucleus CMS
5366                         echo '<h3>' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSSYSTEM . "</h3>\n";
5367                         global $nucleus;
5368                         $nv = getNucleusVersion() / 100 . '(' . $nucleus['version'] . ')';
5369                         $np = getNucleusPatchLevel();
5370                         echo "<table frame=\"box\" rules=\"all\" summary=\"Nucleus CMS\" class=\"systemoverview\" class=\"systemoverview\">\n";
5371                         echo "<thead>\n";
5372                         echo "<tr>\n";
5373                         echo '<th colspan="2">Nucleus CMS' . "</th>\n";
5374                         echo "</tr>\n";
5375                         echo "</thead>\n";
5376                         echo "<tbody>\n";
5377                         echo "<tr>\n";
5378                         echo '<td>' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSVERSION . "</td>\n";
5379                         echo '<td>' . $nv . "</td>\n";
5380                         echo "</tr>\n";
5381                         echo "<tr>\n";
5382                         echo '<td>' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSPATCHLEVEL . "</td>\n";
5383                         echo '<td>' . $np . "</td>\n";
5384                         echo "</tr>\n";
5385                         echo "</tbody>\n";
5386                         echo "</table>\n\n";
5387
5388                         // Important settings of the installation
5389                         echo '<table frame="box" rules="all" summary="' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSSETTINGS . "\" class=\"systemoverview\">\n";
5390                         echo "<thead>\n";
5391                         echo "<tr>\n";
5392                         echo '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSSETTINGS . "</th>\n";
5393                         echo "</tr>\n";
5394                         echo "</thead>\n";
5395                         echo "<tbody>\n";
5396                         echo "<tr>\n";
5397                         echo '<td>' . '$CONF[' . "'Self']</td>\n";
5398                         echo '<td>' . $CONF['Self'] . "</td>\n";
5399                         echo "</tr>\n";
5400                         echo "<tr>\n";
5401                         echo '<td>' . '$CONF[' . "'ItemURL']</td>\n";
5402                         echo '<td>' . $CONF['ItemURL'] . "</td>\n";
5403                         echo "</tr>\n";
5404                         echo "<tr>\n";
5405                         echo '<td>' . '$CONF[' . "'alertOnHeadersSent']</td>\n";
5406                         $ohs = $CONF['alertOnHeadersSent'] ?
5407                                                 _ADMIN_SYSTEMOVERVIEW_ENABLE :
5408                                                 _ADMIN_SYSTEMOVERVIEW_DISABLE;
5409                         echo '<td>' . $ohs . "</td>\n";
5410                         echo "</tr>\n";
5411                         echo "<tr>\n";
5412                         echo "<td>i18n::get_current_charset()</td>\n";
5413                         echo '<td>' . i18n::get_current_charset() . "</td>\n";
5414                         echo "</tr>\n";
5415                         echo "</tbody>\n";
5416                         echo "</table>\n\n";
5417
5418                         // Link to the online version test at the Nucleus CMS website
5419                         echo '<h3>' . _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK . "</h3>\n";
5420                         if ( $nucleus['codename'] != '')
5421                         {
5422                                 $codenamestring = ' &quot;' . $nucleus['codename'] . '&quot;';
5423                         }
5424                         else
5425                         {
5426                                 $codenamestring = '';
5427                         }
5428                         echo _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_TXT;
5429                         $checkURL = sprintf(_ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_URL, getNucleusVersion(), getNucleusPatchLevel());
5430                         echo '<a href="' . $checkURL . '" title="' . _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_TITLE . '">';
5431                         echo 'Nucleus CMS ' . $nv . $codenamestring;
5432                         echo '</a>';
5433                 }
5434                 else
5435                 {
5436                         echo _ADMIN_SYSTEMOVERVIEW_NOT_ADMIN;
5437                 }
5438                 $this->pagefoot();
5439         }
5440
5441         /**
5442          * Admin::updateConfig()
5443          * 
5444          * @param       string  $name   
5445          * @param       string  $val    
5446          * @return      integer return the ID in which the latest query posted
5447          */
5448         function updateConfig($name, $val)
5449         {
5450                 $name = sql_real_escape_string($name);
5451                 $val = trim(sql_real_escape_string($val));
5452                 
5453                 $query = "UPDATE %s SET value='%s' WHERE name='%s'";
5454                 $query = sprintf($query, sql_table('config'), $val, $name);
5455                 sql_query($query) or die("Query error: " . sql_error());
5456                 return sql_insert_id();
5457         }
5458         
5459         /**
5460          * Error message
5461          * @param string $msg message that will be shown
5462          */
5463         function error($msg)
5464         {
5465                 $this->pagehead();
5466                 
5467                 echo "<h2>Error!</h2>\n";
5468                 echo $msg;
5469                 echo "<br />\n";
5470                 echo '<a href="index.php" onclick="history.back()">' . _BACK . "</a>\n";
5471                 $this->pagefoot();
5472                 exit;
5473         }
5474         
5475         /**
5476          * Admin::disallow()
5477          * add error log and show error page 
5478          * 
5479          * @param       void
5480          * @return      void
5481          */
5482         function disallow()
5483         {
5484                 ActionLog::add(WARNING, _ACTIONLOG_DISALLOWED . serverVar('REQUEST_URI'));
5485                 $this->error(_ERROR_DISALLOWED);
5486         }
5487         
5488         /**
5489          * Admin::pagehead()
5490          * Output admin page head
5491          * 
5492          * @param       void
5493          * @return      void
5494          */
5495         function pagehead($extrahead = '')
5496         {
5497                 global $member, $nucleus, $CONF, $manager;
5498                 
5499                 $manager->notify(
5500                         'AdminPrePageHead',
5501                         array(
5502                                 'extrahead' => &$extrahead,
5503                                 'action' => $this->action));
5504                 
5505                 $baseUrl = Entity::hsc($CONF['AdminURL']);
5506                 if ( !array_key_exists('AdminCSS',$CONF) )
5507                 {
5508                         sql_query("INSERT INTO ".sql_table('config')." VALUES ('AdminCSS', 'original')");
5509                         $CONF['AdminCSS'] = 'original';
5510                 }
5511                 
5512                 /* HTTP 1.1 application for no caching */
5513                 header("Cache-Control: no-cache, must-revalidate");
5514                 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
5515                 
5516                 $root_element = 'html';
5517                 $charset = i18n::get_current_charset();
5518                 $locale = preg_replace('#_#', '-', i18n::get_current_locale());
5519                 
5520                 echo "<?xml version=\"{$this->xml_version_info}\" encoding=\"{$charset}\" ?>\n";
5521                 echo "<!DOCTYPE {$root_element} PUBLIC \"{$this->formal_public_identifier}\" \"{$this->system_identifier}\">\n";
5522                 echo "<{$root_element} xmlns=\"{$this->xhtml_namespace}\" xml:lang=\"{$locale}\" lang=\"{$locale}\">\n";
5523                 echo "<head>\n";
5524                 echo '<title>' . Entity::hsc($CONF['SiteName']) . " - Admin</title>\n";
5525                 echo "<link rel=\"stylesheet\" title=\"Nucleus Admin Default\" type=\"text/css\" href=\"{$baseUrl}styles/admin_{$CONF["AdminCSS"]}.css\" />\n";
5526                 echo "<link rel=\"stylesheet\" title=\"Nucleus Admin Default\" type=\"text/css\" href=\"{$baseUrl}styles/addedit.css\" />\n";
5527                 echo "<script type=\"text/javascript\" src=\"{$baseUrl}javascript/edit.js\"></script>\n";
5528                 echo "<script type=\"text/javascript\" src=\"{$baseUrl}javascript/admin.js\"></script>\n";
5529                 echo "<script type=\"text/javascript\" src=\"{$baseUrl}javascript/compatibility.js\"></script>\n";
5530                 echo "{$extrahead}\n";
5531                 echo "</head>\n\n";
5532                 echo "<body>\n";
5533                 echo "<div id=\"adminwrapper\">\n";
5534                 echo "<div class=\"header\">\n";
5535                 echo '<h1>' . Entity::hsc($CONF['SiteName']) . "</h1>\n";
5536                 echo "</div>\n";
5537                 echo "<div id=\"container\">\n";
5538                 echo "<div id=\"content\">\n";
5539                 echo "<div class=\"loginname\">\n";
5540                 if ( $member->isLoggedIn() )
5541                 {
5542                         echo _LOGGEDINAS . ' ' . $member->getDisplayName() ." - <a href='index.php?action=logout'>" . _LOGOUT. "</a><br />\n";
5543                         echo "<a href='index.php?action=overview'>" . _ADMINHOME . "</a> - ";
5544                 }
5545                 else
5546                 {
5547                         echo '<a href="index.php?action=showlogin" title="Log in">' . _NOTLOGGEDIN . "</a><br />\n";
5548                 }
5549                 echo "<a href='".$CONF['IndexURL']."'>"._YOURSITE."</a><br />\n";
5550                 echo '(';
5551                 
5552                 if (array_key_exists('codename', $nucleus) && $nucleus['codename'] != '' )
5553                 {
5554                         $codenamestring = ' &quot;' . $nucleus['codename'].'&quot;';
5555                 }
5556                 else
5557                 {
5558                         $codenamestring = '';
5559                 }
5560                 
5561                 if ( $member->isLoggedIn() && $member->isAdmin() )
5562                 {
5563                         $checkURL = sprintf(_ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_URL, getNucleusVersion(), getNucleusPatchLevel());
5564                         echo '<a href="' . $checkURL . '" title="' . _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_TITLE . '">Nucleus CMS ' . $nucleus['version'] . $codenamestring . '</a>';
5565                         
5566                         $newestVersion = getLatestVersion();
5567                         $newestCompare = str_replace('/','.',$newestVersion);
5568                         $currentVersion = str_replace(array('/','v'),array('.',''),$nucleus['version']);
5569                         if ( $newestVersion && version_compare($newestCompare, $currentVersion) > 0 )
5570                         {
5571                                 echo "<br />\n";
5572                                 echo '<a style="color:red" href="http://nucleuscms.org/upgrade.php" title="' . _ADMIN_SYSTEMOVERVIEW_LATESTVERSION_TITLE . '">';
5573                                 echo _ADMIN_SYSTEMOVERVIEW_LATESTVERSION_TEXT . $newestVersion;
5574                                 echo "</a>";
5575                         }
5576                 }
5577                 else
5578                 {
5579                         echo 'Nucleus CMS ' . $nucleus['version'] . $codenamestring;
5580                 }
5581                 echo ')';
5582                 echo '</div>';
5583                 return;
5584         }
5585         
5586         /**
5587          * Admin::pagefoot()
5588          * Output admin page foot include quickmenu
5589          * 
5590          * @param       void
5591          * @return      void
5592          */
5593         function pagefoot()
5594         {
5595                 global $action, $member, $manager;
5596                 
5597                 $manager->notify(
5598                         'AdminPrePageFoot',
5599                         array('action' => $this->action)
5600                 );
5601                 
5602                 if ( $member->isLoggedIn() && ($action != 'showlogin') )
5603                 {
5604                         echo '<h2>' . _LOGOUT . "</h2>\n";
5605                         echo "<ul>\n";
5606                         echo '<li><a href="index.php?action=overview">' . _BACKHOME . "</a></li>\n";
5607                         echo '<li><a href="index.php?action=logout">' .  _LOGOUT . "</a></li>\n";
5608                         echo "</ul>\n";
5609                 }
5610                 
5611                 echo "<div class=\"foot\">\n";
5612                 echo '<a href="' . _ADMINPAGEFOOT_OFFICIALURL . '">Nucleus CMS</a> &copy; 2002-' . date('Y') . ' ' . _ADMINPAGEFOOT_COPYRIGHT;
5613                 echo '-';
5614                 echo '<a href="' . _ADMINPAGEFOOT_DONATEURL . '">' . _ADMINPAGEFOOT_DONATE . "</a>\n";
5615                 echo "</div>\n";
5616                 
5617                 echo "<!-- content -->\n";
5618                 echo "<div id=\"quickmenu\">\n";
5619                 
5620                 if ( ($action != 'showlogin') && ($member->isLoggedIn()) )
5621                 {
5622                         echo "<ul>\n";
5623                         echo '<li><a href="index.php?action=overview">' . _QMENU_HOME . "</a></li>\n";
5624                         echo "</ul>\n";
5625                         
5626                         echo '<h2>' . _QMENU_ADD . "</h2>\n";
5627                         echo "<form method=\"get\" action=\"index.php\">\n";
5628                         echo "<p>\n";
5629                         echo "<input type=\"hidden\" name=\"action\" value=\"createitem\" />\n";
5630                         
5631                         $showAll = requestVar('showall');
5632                         
5633                         if ( ($member->isAdmin()) && ($showAll == 'yes') )
5634                         {
5635                                 // Super-Admins have access to all blogs! (no add item support though)
5636                                 $query =  'SELECT bnumber as value, bname as text'
5637                                                 . ' FROM ' . sql_table('blog')
5638                                                 . ' ORDER BY bname';
5639                         }
5640                         else
5641                         {
5642                                 $query =  'SELECT bnumber as value, bname as text'
5643                                                 . ' FROM ' . sql_table('blog') . ', ' . sql_table('team')
5644                                                 . ' WHERE tblog=bnumber and tmember=' . $member->getID()
5645                                                 . ' ORDER BY bname';
5646                         }
5647                         $template['name'] = 'blogid';
5648                         $template['tabindex'] = 15000;
5649                         $template['extra'] = _QMENU_ADD_SELECT;
5650                         $template['selected'] = -1;
5651                         $template['shorten'] = 10;
5652                         $template['shortenel'] = '';
5653                         $template['javascript'] = 'onchange="return form.submit()"';
5654                         showlist($query,'select',$template);
5655                         
5656                         echo "</p>\n";
5657                         echo "</form>\n";
5658                         
5659                         echo "<h2>{$member->getDisplayName()}</h2>\n";
5660                         echo "<ul>\n";
5661                         echo '<li><a href="index.php?action=editmembersettings">' . _QMENU_USER_SETTINGS . "</a></li>\n";
5662                         echo '<li><a href="index.php?action=browseownitems">' . _QMENU_USER_ITEMS . "</a></li>\n";
5663                         echo '<li><a href="index.php?action=browseowncomments">' . _QMENU_USER_COMMENTS . "</a></li>\n";
5664                         echo "</ul>\n";
5665                         
5666                         // ---- general settings ----
5667                         if ( $member->isAdmin() )
5668                         {
5669                                 echo '<h2>' . _QMENU_MANAGE . "</h2>\n";
5670                                 echo "<ul>\n";
5671                                 echo '<li><a href="index.php?action=actionlog">' . _QMENU_MANAGE_LOG . "</a></li>\n";
5672                                 echo '<li><a href="index.php?action=settingsedit">' . _QMENU_MANAGE_SETTINGS . "</a></li>\n";
5673                                 echo '<li><a href="index.php?action=systemoverview">' . _QMENU_MANAGE_SYSTEM . "</a></li>\n";
5674                                 echo '<li><a href="index.php?action=usermanagement">' . _QMENU_MANAGE_MEMBERS . "</a></li>\n";
5675                                 echo '<li><a href="index.php?action=createnewlog">' . _QMENU_MANAGE_NEWBLOG . "</a></li>\n";
5676                                 echo '<li><a href="index.php?action=backupoverview">' . _QMENU_MANAGE_BACKUPS . "</a></li>\n";
5677                                 echo '<li><a href="index.php?action=pluginlist">' . _QMENU_MANAGE_PLUGINS . "</a></li>\n";
5678                                 echo "</ul>\n";
5679                                 
5680                                 echo "<h2>" . _QMENU_LAYOUT . "</h2>\n";
5681                                 echo "<ul>\n";
5682                                 echo '<li><a href="index.php?action=skinoverview">' . _QMENU_LAYOUT_SKINS . "</a></li>\n";
5683                                 echo '<li><a href="index.php?action=templateoverview">' . _QMENU_LAYOUT_TEMPL . "</a></li>\n";
5684                                 echo '<li><a href="index.php?action=skinieoverview">' . _QMENU_LAYOUT_IEXPORT . "</a></li>\n";
5685                                 echo "</ul>\n";
5686                         }
5687                         
5688                         $aPluginExtras = array();
5689                         $manager->notify(
5690                                 'QuickMenu',
5691                                 array(
5692                                         'options' => &$aPluginExtras));
5693                         
5694                         if ( count($aPluginExtras) > 0 )
5695                         {
5696                                 echo "<h2>" . _QMENU_PLUGINS . "</h2>\n";
5697                                 echo "<ul>\n";
5698                                 foreach ( $aPluginExtras as $aInfo )
5699                                 {
5700                                         echo '<li><a href="' . Entity::hsc($aInfo['url']) . '" title="' . Entity::hsc($aInfo['tooltip']) . '">' . Entity::hsc($aInfo['title']) . "</a></li>\n";
5701                                 }
5702                                 echo "</ul>\n";
5703                         }
5704                 }
5705                 else if ( ($action == 'activate') || ($action == 'activatesetpwd') )
5706                 {
5707                 
5708                         echo '<h2>' . _QMENU_ACTIVATE . '</h2>' . _QMENU_ACTIVATE_TEXT;
5709                 }
5710                 else
5711                 {
5712                         // introduction text on login screen
5713                         echo '<h2>' . _QMENU_INTRO . '</h2>' . _QMENU_INTRO_TEXT;
5714                 }
5715                 
5716                 echo "<!-- quickmenu -->\n";
5717                 echo "</div>\n";
5718                 
5719                 echo "<!-- content -->\n";
5720                 echo "</div>\n";
5721                 
5722                 echo "<!-- container -->\n";
5723                 echo "</div>\n";
5724                 
5725                 echo "<!-- adminwrapper -->\n";
5726                 echo "</div>\n";
5727                 
5728                 echo "</body>\n";
5729                 echo "</html>\n";
5730                 return;
5731         }
5732         
5733     /**
5734      * @todo document this
5735      */
5736     function action_regfile() {
5737         global $member, $CONF;
5738
5739         $blogid = intRequestVar('blogid');
5740
5741         $member->teamRights($blogid) or $this->disallow();
5742
5743         // header-code stolen from phpMyAdmin
5744         // REGEDIT and bookmarklet code stolen from GreyMatter
5745
5746         $sjisBlogName = sprintf(_WINREGFILE_TEXT, getBlogNameFromID($blogid));
5747
5748
5749         header('Content-Type: application/octetstream');
5750         header('Content-Disposition: filename="nucleus.reg"');
5751         header('Pragma: no-cache');
5752         header('Expires: 0');
5753
5754         echo "REGEDIT4\n";
5755         echo "[HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\MenuExt\\" . $sjisBlogName . "]\n";
5756         echo '@="' . $CONF['AdminURL'] . "bookmarklet.php?action=contextmenucode&blogid=".intval($blogid)."\"\n";
5757         echo '"contexts"=hex:31';
5758     }
5759
5760     /**
5761      * @todo document this
5762      */
5763     function action_bookmarklet() {
5764         global $member, $manager;
5765
5766         $blogid = intRequestVar('blogid');
5767
5768         $member->teamRights($blogid) or $this->disallow();
5769
5770         $blog =& $manager->getBlog($blogid);
5771         $bm = getBookmarklet($blogid);
5772
5773         $this->pagehead();
5774
5775         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
5776
5777         ?>
5778
5779         <h2><?php echo _BOOKMARKLET_TITLE ?></h2>
5780
5781         <p>
5782         <?php echo _BOOKMARKLET_DESC1 . _BOOKMARKLET_DESC2 . _BOOKMARKLET_DESC3 . _BOOKMARKLET_DESC4 . _BOOKMARKLET_DESC5 ?>
5783         </p>
5784
5785         <h3><?php echo _BOOKMARKLET_BOOKARKLET ?></h3>
5786         <p>
5787             <?php echo _BOOKMARKLET_BMARKTEXT ?><small><?php echo _BOOKMARKLET_BMARKTEST ?></small>
5788             <br />
5789             <br />
5790             <?php echo '<a href="' . Entity::hsc($bm) . '">' . sprintf(_BOOKMARKLET_ANCHOR, Entity::hsc($blog->getName())) . '</a>' . _BOOKMARKLET_BMARKFOLLOW; ?>
5791         </p>
5792
5793         <h3><?php echo _BOOKMARKLET_RIGHTCLICK ?></h3>
5794         <p>
5795             <?php
5796                 $url = 'index.php?action=regfile&blogid=' . intval($blogid);
5797                 $url = $manager->addTicketToUrl($url);
5798             ?>
5799             <?php echo _BOOKMARKLET_RIGHTTEXT1 . '<a href="' . Entity::hsc($url, ENT_QUOTES, "SJIS") . '">' . _BOOKMARKLET_RIGHTLABEL . '</a>' . _BOOKMARKLET_RIGHTTEXT2; ?>
5800         </p>
5801
5802         <p>
5803             <?php echo _BOOKMARKLET_RIGHTTEXT3 ?>
5804         </p>
5805
5806         <h3><?php echo _BOOKMARKLET_UNINSTALLTT ?></h3>
5807         <p>
5808             <?php echo _BOOKMARKLET_DELETEBAR ?>
5809         </p>
5810
5811         <p>
5812             <?php echo _BOOKMARKLET_DELETERIGHTT ?>
5813         </p>
5814
5815         <ol>
5816             <li><?php echo _BOOKMARKLET_DELETERIGHT1 ?></li>
5817             <li><?php echo _BOOKMARKLET_DELETERIGHT2 ?></li>
5818             <li><?php echo _BOOKMARKLET_DELETERIGHT3 ?></li>
5819             <li><?php echo _BOOKMARKLET_DELETERIGHT4 ?></li>
5820             <li><?php echo _BOOKMARKLET_DELETERIGHT5 ?></li>
5821         </ol>
5822
5823         <?php
5824         $this->pagefoot();
5825
5826     }
5827
5828     /**
5829      * @todo document this
5830      */
5831     function action_actionlog() {
5832         global $member, $manager;
5833
5834         $member->isAdmin() or $this->disallow();
5835
5836         $this->pagehead();
5837
5838         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
5839
5840         $url = $manager->addTicketToUrl('index.php?action=clearactionlog');
5841
5842         ?>
5843             <h2><?php echo _ACTIONLOG_CLEAR_TITLE?></h2>
5844             <p><a href="<?php echo Entity::hsc($url)?>"><?php echo _ACTIONLOG_CLEAR_TEXT?></a></p>
5845         <?php
5846         echo '<h2>' . _ACTIONLOG_TITLE . '</h2>';
5847
5848         $query =  'SELECT * FROM '.sql_table('actionlog').' ORDER BY timestamp DESC';
5849         $template['content'] = 'actionlist';
5850         $amount = showlist($query,'table',$template);
5851
5852         $this->pagefoot();
5853
5854     }
5855
5856     /**
5857      * @todo document this
5858      */
5859     function action_banlist() {
5860         global $member, $manager;
5861
5862         $blogid = intRequestVar('blogid');
5863
5864         $member->blogAdminRights($blogid) or $this->disallow();
5865
5866         $blog =& $manager->getBlog($blogid);
5867
5868         $this->pagehead();
5869
5870         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
5871
5872         echo '<h2>' . _BAN_TITLE . " '". $this->bloglink($blog) ."'</h2>";
5873
5874         $query =  'SELECT * FROM '.sql_table('ban').' WHERE blogid='.$blogid.' ORDER BY iprange';
5875         $template['content'] = 'banlist';
5876         $amount = showlist($query,'table',$template);
5877
5878         if ($amount == 0)
5879             echo _BAN_NONE;
5880
5881         echo '<h2>'._BAN_NEW_TITLE.'</h2>';
5882         echo "<p><a href='index.php?action=banlistnew&amp;blogid=$blogid'>"._BAN_NEW_TEXT."</a></p>";
5883
5884
5885         $this->pagefoot();
5886
5887     }
5888
5889     /**
5890      * @todo document this
5891      */
5892     function action_banlistdelete() {
5893         global $member, $manager;
5894
5895         $blogid = intRequestVar('blogid');
5896         $iprange = requestVar('iprange');
5897
5898         $member->blogAdminRights($blogid) or $this->disallow();
5899
5900         $blog =& $manager->getBlog($blogid);
5901         $banBlogName =  Entity::hsc($blog->getName());
5902
5903         $this->pagehead();
5904         ?>
5905             <h2><?php echo _BAN_REMOVE_TITLE?></h2>
5906
5907             <form method="post" action="index.php">
5908
5909             <h3><?php echo _BAN_IPRANGE?></h3>
5910
5911             <p>
5912                 <?php echo _CONFIRMTXT_BAN?> <?php echo Entity::hsc($iprange) ?>
5913                 <input name="iprange" type="hidden" value="<?php echo Entity::hsc($iprange)?>" />
5914             </p>
5915
5916             <h3><?php echo _BAN_BLOGS?></h3>
5917
5918             <div>
5919                 <input type="hidden" name="blogid" value="<?php echo $blogid?>" />
5920                 <input name="allblogs" type="radio" value="0" id="allblogs_one" />
5921                 <label for="allblogs_one"><?php echo sprintf(_BAN_BANBLOGNAME, $banBlogName) ?></label>
5922                 <br />
5923                 <input name="allblogs" type="radio" value="1" checked="checked" id="allblogs_all" /><label for="allblogs_all"><?php echo _BAN_ALLBLOGS?></label>
5924             </div>
5925
5926             <h3><?php echo _BAN_DELETE_TITLE?></h3>
5927
5928             <div>
5929                 <?php $manager->addTicketHidden() ?>
5930                 <input type="hidden" name="action" value="banlistdeleteconfirm" />
5931                 <input type="submit" value="<?php echo _DELETE_CONFIRM_BTN?>" />
5932             </div>
5933
5934             </form>
5935         <?php
5936         $this->pagefoot();
5937     }
5938
5939     /**
5940      * @todo document this
5941      */
5942     function action_banlistdeleteconfirm() {
5943         global $member, $manager;
5944
5945         $blogid = intPostVar('blogid');
5946         $allblogs = postVar('allblogs');
5947         $iprange = postVar('iprange');
5948
5949         $member->blogAdminRights($blogid) or $this->disallow();
5950
5951         $deleted = array();
5952
5953         if (!$allblogs) {
5954             if (Ban::removeBan($blogid, $iprange))
5955                 array_push($deleted, $blogid);
5956         } else {
5957             // get blogs fot which member has admin rights
5958             $adminblogs = $member->getAdminBlogs();
5959             foreach ($adminblogs as $blogje) {
5960                 if (Ban::removeBan($blogje, $iprange))
5961                     array_push($deleted, $blogje);
5962             }
5963         }
5964
5965         if (sizeof($deleted) == 0)
5966             $this->error(_ERROR_DELETEBAN);
5967
5968         $this->pagehead();
5969
5970         echo '<a href="index.php?action=banlist&amp;blogid=',$blogid,'">(',_BACK,')</a>';
5971         echo '<h2>'._BAN_REMOVED_TITLE.'</h2>';
5972         echo "<p>"._BAN_REMOVED_TEXT."</p>";
5973
5974         echo "<ul>";
5975         foreach ($deleted as $delblog) {
5976             $b =& $manager->getBlog($delblog);
5977             echo "<li>" . Entity::hsc($b->getName()). "</li>";
5978         }
5979         echo "</ul>";
5980
5981         $this->pagefoot();
5982
5983     }
5984
5985     /**
5986      * @todo document this
5987      */
5988     function action_banlistnewfromitem() {
5989         $this->action_banlistnew(getBlogIDFromItemID(intRequestVar('itemid')));
5990     }
5991
5992     /**
5993      * @todo document this
5994      */
5995     function action_banlistnew($blogid = '') {
5996         global $member, $manager;
5997
5998         if ($blogid == '')
5999             $blogid = intRequestVar('blogid');
6000
6001         $ip = requestVar('ip');
6002
6003         $member->blogAdminRights($blogid) or $this->disallow();
6004
6005         $blog =& $manager->getBlog($blogid);
6006
6007         $this->pagehead();
6008         ?>
6009         <h2><?php echo _BAN_ADD_TITLE?></h2>
6010
6011
6012         <form method="post" action="index.php">
6013
6014         <h3><?php echo _BAN_IPRANGE?></h3>
6015
6016         <p><?php echo _BAN_IPRANGE_TEXT?></p>
6017
6018         <div class="note">
6019             <strong><?php echo _BAN_EXAMPLE_TITLE ?></strong>
6020             <?php echo _BAN_EXAMPLE_TEXT ?>
6021         </div>
6022
6023         <div>
6024         <?php
6025         if ($ip) {
6026             $iprangeVal = Entity::hsc($ip);
6027         ?>
6028             <input name="iprange" type="radio" value="<?php echo $iprangeVal ?>" checked="checked" id="ip_fixed" />
6029             <label for="ip_fixed"><?php echo $iprangeVal ?></label>
6030             <br />
6031             <input name="iprange" type="radio" value="custom" id="ip_custom" />
6032             <label for="ip_custom"><?php echo _BAN_IP_CUSTOM ?></label>
6033             <input name='customiprange' value='<?php echo $iprangeVal ?>' maxlength='15' size='15' />
6034         <?php
6035         } else {
6036             echo "<input name='iprange' value='custom' type='hidden' />";
6037             echo "<input name='customiprange' value='' maxlength='15' size='15' />";
6038         }
6039         ?>
6040         </div>
6041
6042         <h3><?php echo _BAN_BLOGS?></h3>
6043
6044         <p><?php echo _BAN_BLOGS_TEXT?></p>
6045
6046         <div>
6047             <input type="hidden" name="blogid" value="<?php echo $blogid?>" />
6048             <input name="allblogs" type="radio" value="0" id="allblogs_one" /><label for="allblogs_one">'<?php echo Entity::hsc($blog->getName())?>'</label>
6049             <br />
6050             <input name="allblogs" type="radio" value="1" checked="checked" id="allblogs_all" /><label for="allblogs_all"><?php echo _BAN_ALLBLOGS?></label>
6051         </div>
6052
6053         <h3><?php echo _BAN_REASON_TITLE?></h3>
6054
6055         <p><?php echo _BAN_REASON_TEXT?></p>
6056
6057         <div><textarea name="reason" cols="40" rows="5"></textarea></div>
6058
6059         <h3><?php echo _BAN_ADD_TITLE?></h3>
6060
6061         <div>
6062             <input name="action" type="hidden" value="banlistadd" />
6063             <?php $manager->addTicketHidden() ?>
6064             <input type="submit" value="<?php echo _BAN_ADD_BTN?>" />
6065         </div>
6066
6067         </form>
6068
6069         <?php       $this->pagefoot();
6070     }
6071
6072     /**
6073      * @todo document this
6074      */
6075     function action_banlistadd() {
6076         global $member;
6077
6078         $blogid =       intPostVar('blogid');
6079         $allblogs =     postVar('allblogs');
6080         $iprange =      postVar('iprange');
6081         if ($iprange == "custom")
6082             $iprange = postVar('customiprange');
6083         $reason =       postVar('reason');
6084
6085         $member->blogAdminRights($blogid) or $this->disallow();
6086
6087         // TODO: check IP range validity
6088
6089         if (!$allblogs) {
6090             if (!Ban::addBan($blogid, $iprange, $reason))
6091                 $this->error(_ERROR_ADDBAN);
6092         } else {
6093             // get blogs fot which member has admin rights
6094             $adminblogs = $member->getAdminBlogs();
6095             $failed = 0;
6096             foreach ($adminblogs as $blogje) {
6097                 if (!Ban::addBan($blogje, $iprange, $reason))
6098                     $failed = 1;
6099             }
6100             if ($failed)
6101                 $this->error(_ERROR_ADDBAN);
6102         }
6103
6104         $this->action_banlist();
6105
6106     }
6107
6108     /**
6109      * @todo document this
6110      */
6111     function action_clearactionlog() {
6112         global $member;
6113
6114         $member->isAdmin() or $this->disallow();
6115
6116         ActionLog::clear();
6117
6118         $this->action_manage(_MSG_ACTIONLOGCLEARED);
6119     }
6120
6121     /**
6122      * @todo document this
6123      */
6124     function action_backupoverview() {
6125         global $member, $manager;
6126
6127         $member->isAdmin() or $this->disallow();
6128
6129         $this->pagehead();
6130
6131         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
6132         ?>
6133         <h2><?php echo _BACKUPS_TITLE?></h2>
6134
6135         <h3><?php echo _BACKUP_TITLE?></h3>
6136
6137         <p><?php echo _BACKUP_INTRO?></p>
6138
6139         <form method="post" action="index.php"><p>
6140         <input type="hidden" name="action" value="backupcreate" />
6141         <?php $manager->addTicketHidden() ?>
6142
6143         <input type="radio" name="gzip" value="1" checked="checked" id="gzip_yes" tabindex="10" /><label for="gzip_yes"><?php echo _BACKUP_ZIP_YES?></label>
6144         <br />
6145         <input type="radio" name="gzip" value="0" id="gzip_no" tabindex="10" /><label for="gzip_no" ><?php echo _BACKUP_ZIP_NO?></label>
6146         <br /><br />
6147         <input type="submit" value="<?php echo _BACKUP_BTN?>" tabindex="20" />
6148
6149         </p></form>
6150
6151         <div class="note"><?php echo _BACKUP_NOTE?></div>
6152
6153
6154         <h3><?php echo _RESTORE_TITLE?></h3>
6155
6156         <div class="note"><?php echo _RESTORE_NOTE?></div>
6157
6158         <p><?php echo _RESTORE_INTRO?></p>
6159
6160         <form method="post" action="index.php" enctype="multipart/form-data"><p>
6161             <input type="hidden" name="action" value="backuprestore" />
6162             <?php $manager->addTicketHidden() ?>
6163             <input name="backup_file" type="file" tabindex="30" />
6164             <br /><br />
6165             <input type="submit" value="<?php echo _RESTORE_BTN?>" tabindex="40" />
6166             <br /><input type="checkbox" name="letsgo" value="1" id="letsgo" tabindex="50" /><label for="letsgo"><?php echo _RESTORE_IMSURE?></label>
6167             <br /><?php echo _RESTORE_WARNING?>
6168         </p></form>
6169
6170         <?php       $this->pagefoot();
6171     }
6172
6173         /**
6174          * Admin::action_backupcreate()
6175          * create file for backup
6176          * 
6177          * @param               void
6178          * @return      void
6179          * 
6180          */
6181         function action_backupcreate()
6182         {
6183                 global $member, $DIR_LIBS;
6184                 
6185                 $member->isAdmin() or $this->disallow();
6186                 
6187                 // use compression ?
6188                 $useGzip = (integer) postVar('gzip');
6189                 
6190                 include($DIR_LIBS . 'backup.php');
6191                 
6192                 // try to extend time limit
6193                 // (creating/restoring dumps might take a while)
6194                 @set_time_limit(1200);
6195                 
6196                 Backup::do_backup($useGzip);
6197                 exit;
6198         }
6199         
6200         /**
6201          * Admin::action_backuprestore()
6202          * restoring from uploaded file
6203          * 
6204          * @param               void
6205          * @return      void
6206          */
6207         function action_backuprestore()
6208         {
6209                 global $member, $DIR_LIBS;
6210                 
6211                 $member->isAdmin() or $this->disallow();
6212                 
6213                 if ( intPostVar('letsgo') != 1 )
6214                 {
6215                         $this->error(_ERROR_BACKUP_NOTSURE);
6216                 }
6217                 
6218                 include($DIR_LIBS . 'backup.php');
6219                 
6220                 // try to extend time limit
6221                 // (creating/restoring dumps might take a while)
6222                 @set_time_limit(1200);
6223                 
6224                 $message = Backup::do_restore();
6225                 if ( $message != '' )
6226                 {
6227                         $this->error($message);
6228                 }
6229                 $this->pagehead();
6230                 echo '<h2>' . _RESTORE_COMPLETE . "</h2>\n";
6231                 $this->pagefoot();
6232                 return;
6233         }
6234         
6235         /**
6236          * Admin::action_pluginlist()
6237          * output the list of installed plugins
6238          * 
6239          * @param       void
6240          * @return      void
6241          * 
6242          */
6243         function action_pluginlist()
6244         {
6245                 global $DIR_PLUGINS, $member, $manager;
6246                 
6247                 // check if allowed
6248                 $member->isAdmin() or $this->disallow();
6249                 
6250                 $this->pagehead();
6251                 
6252                 echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
6253                 
6254                 echo '<h2>' , _PLUGS_TITLE_MANAGE , ' ', help('plugins'), '</h2>';
6255                 
6256                 echo '<h3>' , _PLUGS_TITLE_INSTALLED , ' &nbsp;&nbsp;<span style="font-size:smaller">', helplink('getplugins'), _PLUGS_TITLE_GETPLUGINS, '</a></span></h3>';
6257                 
6258                 $query =  'SELECT * FROM '.sql_table('plugin').' ORDER BY porder ASC';
6259                 
6260                 $template['content'] = 'pluginlist';
6261                 $template['tabindex'] = 10;
6262                 showlist($query, 'table', $template);
6263                 
6264                 echo '<h3>' . _PLUGS_TITLE_UPDATE . "</h3>\n";
6265                 echo '<p>' . _PLUGS_TEXT_UPDATE . "</p>\n";
6266                 echo '<form method="post" action="index.php">' . "\n";
6267                 echo "<div>\n";
6268                 echo '<input type="hidden" name="action" value="pluginupdate" />' . "\n";
6269                 $manager->addTicketHidden();
6270                 echo '<input type="submit" value="' . _PLUGS_BTN_UPDATE . '" tabindex="20" />' . "\n";
6271                 echo "</div>\n";
6272                 echo "</form>\n";
6273                 
6274                 echo '<h3>' . _PLUGS_TITLE_NEW . "</h3>\n";
6275                 
6276                 // find a list of possibly non-installed plugins
6277                 $candidates = array();
6278                 $dirhandle = opendir($DIR_PLUGINS);
6279                 
6280                 while ( $filename = readdir($dirhandle) )
6281                 {
6282                         if ( preg_match('#^NP_(.*)\.php$#', $filename, $matches) )
6283                         {
6284                                 $name = $matches[1];
6285                                 
6286                                 // only show in list when not yet installed
6287                                 $query = 'SELECT * FROM %s WHERE pfile = "NP_%s"';
6288                                 $query = sprintf($query, sql_table('plugin'), sql_real_escape_string($name));
6289                                 $res = sql_query($query);
6290                                 
6291                                 if ( sql_num_rows($res) == 0 )
6292                                 {
6293                                         array_push($candidates, $name);
6294                                 }
6295                         }
6296                 }
6297                 
6298                 closedir($dirhandle);
6299                 
6300                 if ( sizeof($candidates) > 0 )
6301                 {
6302                         echo '<p>' . _PLUGS_ADD_TEXT . "</p>\n";
6303                         
6304                         echo '<form method="post" action="index.php">' . "\n";
6305                         echo "<div>\n";
6306                         echo '<input type="hidden" name="action" value="pluginadd" />' . "\n";
6307                         $manager->addTicketHidden();
6308                         echo '<select name="filename" tabindex="30">' . "\n";
6309                         
6310                         foreach ( $candidates as $name )
6311                         {
6312                                 echo '<option value="NP_',$name,'">',Entity::hsc($name),'</option>';
6313                         }
6314                         
6315                         echo "</select>\n";
6316                         echo '<input type="submit" tabindex="40" value="' . _PLUGS_BTN_INSTALL ."\" />\n";
6317                         echo "</div>\n";
6318                         echo "</form>\n";
6319                 }
6320                 else
6321                 {
6322                         echo '<p>', _PLUGS_NOCANDIDATES, '</p>';
6323                 }
6324                 
6325                 $this->pagefoot();
6326                 return;
6327         }
6328         
6329     /**
6330      * @todo document this
6331      */
6332     function action_pluginhelp() {
6333         global $member, $manager, $DIR_PLUGINS, $CONF;
6334
6335         // check if allowed
6336         $member->isAdmin() or $this->disallow();
6337
6338         $plugid = intGetVar('plugid');
6339
6340         if (!$manager->pidInstalled($plugid))
6341             $this->error(_ERROR_NOSUCHPLUGIN);
6342
6343         $plugName = getPluginNameFromPid($plugid);
6344
6345         $this->pagehead();
6346
6347         echo '<p><a href="index.php?action=pluginlist">(',_PLUGS_BACK,')</a></p>';
6348
6349         echo '<h2>',_PLUGS_HELP_TITLE,': ',Entity::hsc($plugName),'</h2>';
6350
6351         $plug =& $manager->getPlugin($plugName);
6352         $helpFile = $DIR_PLUGINS.$plug->getShortName().'/help.html';
6353
6354         if (($plug->supportsFeature('HelpPage') > 0) && (@file_exists($helpFile))) {
6355             @readfile($helpFile);
6356         } else {
6357             echo '<p>Error: ', _ERROR_PLUGNOHELPFILE,'</p>';
6358             echo '<p><a href="index.php?action=pluginlist">(',_BACK,')</a></p>';
6359         }
6360
6361
6362         $this->pagefoot();
6363     }
6364
6365         /**
6366          * Admin::action_pluginadd()
6367          * 
6368          * @param       Void
6369          * @return      Void
6370          * 
6371          */
6372         function action_pluginadd()
6373         {
6374                 global $member, $manager, $DIR_PLUGINS;
6375                 
6376                 // check if allowed
6377                 $member->isAdmin() or $this->disallow();
6378                 
6379                 $name = postVar('filename');
6380                 
6381                 if ( $manager->pluginInstalled($name) )
6382                 {
6383                         $this->error(_ERROR_DUPPLUGIN);
6384                 }
6385                 
6386                 if ( !checkPlugin($name) )
6387                 {
6388                         $this->error(_ERROR_PLUGFILEERROR . ' (' . Entity::hsc($name) . ')');
6389                 }
6390                 
6391                 // get number of currently installed plugins
6392                 $res = sql_query('SELECT * FROM '.sql_table('plugin'));
6393                 $numCurrent = sql_num_rows($res);
6394                 
6395                 // plugin will be added as last one in the list
6396                 $newOrder = $numCurrent + 1;
6397                 
6398                 $manager->notify(
6399                         'PreAddPlugin',
6400                         array(
6401                                 'file' => &$name
6402                         )
6403                 );
6404                 
6405                 // do this before calling getPlugin (in case the plugin id is used there)
6406                 $query = 'INSERT INTO '.sql_table('plugin').' (porder, pfile) VALUES ('.$newOrder.',"'.sql_real_escape_string($name).'")';
6407                 sql_query($query);
6408                 $iPid = sql_insert_id();
6409                 
6410                 $manager->clearCachedInfo('installedPlugins');
6411                 
6412                 // Load the plugin for condition checking and instalation
6413                 $plugin =& $manager->getPlugin($name);
6414                 
6415                 // check if it got loaded (could have failed)
6416                 if ( !$plugin )
6417                 {
6418                         sql_query('DELETE FROM ' . sql_table('plugin') . ' WHERE pid='. intval($iPid));
6419                         $manager->clearCachedInfo('installedPlugins');
6420                         $this->error(_ERROR_PLUGIN_LOAD);
6421                 }
6422                 
6423                 // check if plugin needs a newer Nucleus version
6424                 if ( getNucleusVersion() < $plugin->getMinNucleusVersion() )
6425                 {
6426                         // uninstall plugin again...
6427                         $this->deleteOnePlugin($plugin->getID());
6428                         
6429                         // ...and show error
6430                         $this->error(_ERROR_NUCLEUSVERSIONREQ . Entity::hsc($plugin->getMinNucleusVersion()));
6431                 }
6432                 
6433                 // check if plugin needs a newer Nucleus version
6434                 if ( (getNucleusVersion() == $plugin->getMinNucleusVersion()) && (getNucleusPatchLevel() < $plugin->getMinNucleusPatchLevel()) )
6435                 {
6436                         // uninstall plugin again...
6437                         $this->deleteOnePlugin($plugin->getID());
6438                         
6439                         // ...and show error
6440                         $this->error(_ERROR_NUCLEUSVERSIONREQ . Entity::hsc( $plugin->getMinNucleusVersion() . ' patch ' . $plugin->getMinNucleusPatchLevel() ) );
6441                 }
6442                 
6443                 $pluginList = $plugin->getPluginDep();
6444                 foreach ( $pluginList as $pluginName )
6445                 {
6446                         $res = sql_query('SELECT * FROM '.sql_table('plugin') . ' WHERE pfile="' . $pluginName . '"');
6447                         if (sql_num_rows($res) == 0)
6448                         {
6449                                 // uninstall plugin again...
6450                                 $this->deleteOnePlugin($plugin->getID());
6451                                 $this->error(sprintf(_ERROR_INSREQPLUGIN, Entity::hsc($pluginName)));
6452                         }
6453                 }
6454                 
6455                 // call the install method of the plugin
6456                 $plugin->install();
6457                 
6458                 $manager->notify(
6459                         'PostAddPlugin',
6460                         array(
6461                                 'plugin' => &$plugin
6462                         )
6463                 );
6464                 
6465                 // update all events
6466                 $this->action_pluginupdate();
6467                 return;
6468         }
6469         
6470         /**
6471          * ADMIN:action_pluginupdate():
6472          * 
6473          * @param       Void
6474          * @return      Void
6475          * 
6476          */
6477         function action_pluginupdate()
6478         {
6479                 global $member, $manager, $CONF;
6480                 
6481                 // check if allowed
6482                 $member->isAdmin() or $this->disallow();
6483                 
6484                 // delete everything from plugin_events
6485                 sql_query('DELETE FROM '.sql_table('plugin_event'));
6486                 
6487                 // loop over all installed plugins
6488                 $res = sql_query('SELECT pid, pfile FROM '.sql_table('plugin'));
6489                 while ( $o = sql_fetch_object($res) )
6490                 {
6491                         $pid = $o->pid;
6492                         $plug =& $manager->getPlugin($o->pfile);
6493                         if ( $plug )
6494                         {
6495                                 $eventList = $plug->getEventList();
6496                                 foreach ( $eventList as $eventName )
6497                                 {
6498                                         $query = "INSERT INTO %s (pid, event) VALUES (%d, '%s')";
6499                                         $query = sprintf($query, sql_table('plugin_event'), (integer) $pid, sql_real_escape_string($eventName));
6500                                         sql_query($query);
6501                                 }
6502                         }
6503                 }
6504                 redirect($CONF['AdminURL'] . '?action=pluginlist');
6505                 return;
6506         }
6507         
6508     /**
6509      * @todo document this
6510      */
6511     function action_plugindelete() {
6512         global $member, $manager;
6513
6514         // check if allowed
6515         $member->isAdmin() or $this->disallow();
6516
6517         $pid = intGetVar('plugid');
6518
6519         if (!$manager->pidInstalled($pid))
6520             $this->error(_ERROR_NOSUCHPLUGIN);
6521
6522         $this->pagehead();
6523         ?>
6524             <h2><?php echo _DELETE_CONFIRM?></h2>
6525
6526             <p><?php echo _CONFIRMTXT_PLUGIN?> <strong><?php echo getPluginNameFromPid($pid)?></strong>?</p>
6527
6528             <form method="post" action="index.php"><div>
6529             <?php $manager->addTicketHidden() ?>
6530             <input type="hidden" name="action" value="plugindeleteconfirm" />
6531             <input type="hidden" name="plugid" value="<?php echo $pid; ?>" />
6532             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN?>" />
6533             </div></form>
6534         <?php
6535         $this->pagefoot();
6536     }
6537
6538     /**
6539      * @todo document this
6540      */
6541     function action_plugindeleteconfirm() {
6542         global $member, $manager, $CONF;
6543
6544         // check if allowed
6545         $member->isAdmin() or $this->disallow();
6546
6547         $pid = intPostVar('plugid');
6548
6549         $error = $this->deleteOnePlugin($pid, 1);
6550         if ($error) {
6551             $this->error($error);
6552         }
6553
6554         redirect($CONF['AdminURL'] . '?action=pluginlist');
6555 //              $this->action_pluginlist();
6556     }
6557
6558     /**
6559      * @todo document this
6560      */
6561     function deleteOnePlugin($pid, $callUninstall = 0) {
6562         global $manager;
6563
6564         $pid = intval($pid);
6565
6566         if (!$manager->pidInstalled($pid))
6567             return _ERROR_NOSUCHPLUGIN;
6568
6569         $name = quickQuery('SELECT pfile as result FROM '.sql_table('plugin').' WHERE pid='.$pid);
6570
6571 /*              // call the unInstall method of the plugin
6572         if ($callUninstall) {
6573             $plugin =& $manager->getPlugin($name);
6574             if ($plugin) $plugin->unInstall();
6575         }*/
6576
6577         // check dependency before delete
6578         $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));
6579         while($o = sql_fetch_object($res)) {
6580             $plug =& $manager->getPlugin($o->pfile);
6581             if ($plug)
6582             {
6583                 $depList = $plug->getPluginDep();
6584                 foreach ($depList as $depName)
6585                 {
6586                     if ($name == $depName)
6587                     {
6588                         return sprintf(_ERROR_DELREQPLUGIN, $o->pfile);
6589                     }
6590                 }
6591             }
6592         }
6593
6594         $manager->notify('PreDeletePlugin', array('plugid' => $pid));
6595
6596         // call the unInstall method of the plugin
6597         if ($callUninstall) {
6598             $plugin =& $manager->getPlugin($name);
6599             if ($plugin) $plugin->unInstall();
6600         }
6601
6602         // delete all subscriptions
6603         sql_query('DELETE FROM '.sql_table('plugin_event').' WHERE pid=' . $pid);
6604
6605         // delete all options
6606         // get OIDs from plugin_option_desc
6607         $res = sql_query('SELECT oid FROM ' . sql_table('plugin_option_desc') . ' WHERE opid=' . $pid);
6608         $aOIDs = array();
6609         while ($o = sql_fetch_object($res)) {
6610             array_push($aOIDs, $o->oid);
6611         }
6612
6613         // delete from plugin_option and plugin_option_desc
6614         sql_query('DELETE FROM '.sql_table('plugin_option_desc').' WHERE opid=' . $pid);
6615         if (count($aOIDs) > 0)
6616             sql_query('DELETE FROM '.sql_table('plugin_option').' WHERE oid in ('.implode(',',$aOIDs).')');
6617
6618         // update order numbers
6619         $res = sql_query('SELECT porder FROM '.sql_table('plugin').' WHERE pid=' . $pid);
6620         $o = sql_fetch_object($res);
6621         sql_query('UPDATE '.sql_table('plugin').' SET porder=(porder - 1) WHERE porder>'.$o->porder);
6622
6623         // delete row
6624         sql_query('DELETE FROM '.sql_table('plugin').' WHERE pid='.$pid);
6625
6626         $manager->clearCachedInfo('installedPlugins');
6627         $manager->notify('PostDeletePlugin', array('plugid' => $pid));
6628
6629         return '';
6630     }
6631
6632     /**
6633      * @todo document this
6634      */
6635     function action_pluginup() {
6636         global $member, $manager, $CONF;
6637
6638         // check if allowed
6639         $member->isAdmin() or $this->disallow();
6640
6641         $plugid = intGetVar('plugid');
6642
6643         if (!$manager->pidInstalled($plugid))
6644             $this->error(_ERROR_NOSUCHPLUGIN);
6645
6646         // 1. get old order number
6647         $res = sql_query('SELECT porder FROM '.sql_table('plugin').' WHERE pid='.$plugid);
6648         $o = sql_fetch_object($res);
6649         $oldOrder = $o->porder;
6650
6651         // 2. calculate new order number
6652         $newOrder = ($oldOrder > 1) ? ($oldOrder - 1) : 1;
6653
6654         // 3. update plug numbers
6655         sql_query('UPDATE '.sql_table('plugin').' SET porder='.$oldOrder.' WHERE porder='.$newOrder);
6656         sql_query('UPDATE '.sql_table('plugin').' SET porder='.$newOrder.' WHERE pid='.$plugid);
6657
6658         //$this->action_pluginlist();
6659         // To avoid showing ticket in the URL, redirect to pluginlist, instead.
6660         redirect($CONF['AdminURL'] . '?action=pluginlist');
6661     }
6662
6663     /**
6664      * @todo document this
6665      */
6666     function action_plugindown() {
6667         global $member, $manager, $CONF;
6668
6669         // check if allowed
6670         $member->isAdmin() or $this->disallow();
6671
6672         $plugid = intGetVar('plugid');
6673         if (!$manager->pidInstalled($plugid))
6674             $this->error(_ERROR_NOSUCHPLUGIN);
6675
6676         // 1. get old order number
6677         $res = sql_query('SELECT porder FROM '.sql_table('plugin').' WHERE pid='.$plugid);
6678         $o = sql_fetch_object($res);
6679         $oldOrder = $o->porder;
6680
6681         $res = sql_query('SELECT * FROM '.sql_table('plugin'));
6682         $maxOrder = sql_num_rows($res);
6683
6684         // 2. calculate new order number
6685         $newOrder = ($oldOrder < $maxOrder) ? ($oldOrder + 1) : $maxOrder;
6686
6687         // 3. update plug numbers
6688         sql_query('UPDATE '.sql_table('plugin').' SET porder='.$oldOrder.' WHERE porder='.$newOrder);
6689         sql_query('UPDATE '.sql_table('plugin').' SET porder='.$newOrder.' WHERE pid='.$plugid);
6690
6691         //$this->action_pluginlist();
6692         // To avoid showing ticket in the URL, redirect to pluginlist, instead.
6693         redirect($CONF['AdminURL'] . '?action=pluginlist');
6694     }
6695         
6696         /**
6697          * Admin::action_pluginoptions()
6698          * 
6699          * Output Plugin option page
6700          * 
6701          * @access      public
6702          * @param       string $message message when fallbacked
6703          * @return      void
6704          * 
6705          */
6706         public function action_pluginoptions($message = '')
6707         {
6708                 global $member, $manager;
6709                 
6710                 // check if allowed
6711                 $member->isAdmin() or $this->disallow();
6712                 
6713                 $pid = (integer) requestVar('plugid');
6714                 if ( !$manager->pidInstalled($pid) )
6715                 {
6716                         $this->error(_ERROR_NOSUCHPLUGIN);
6717                 }
6718                 
6719                 $pname = getPluginNameFromPid($pid);
6720                 
6721                 /* just for including translation */
6722                 $manager->getPlugin($pname);
6723                 
6724                 $extrahead = "<script type=\"text/javascript\" src=\"javascript/numbercheck.js\"></script>\n";
6725                 $this->pagehead($extrahead);
6726                 echo '<p><a href="index.php?action=pluginlist">(' . _PLUGS_BACK . ")</a></p>\n";
6727                 echo '<h2>' . sprintf(_PLUGIN_OPTIONS_TITLE, Entity::hsc($pname)) . "</h2>\n";
6728                 
6729                 if ( isset($message) )
6730                 {
6731                         echo $message;
6732                 }
6733                 
6734                 echo "<form action=\"index.php\" method=\"post\">\n";
6735                 echo "<div>\n";
6736                 echo "<input type=\"hidden\" name=\"action\" value=\"pluginoptionsupdate\" />\n";
6737                 echo "<input type=\"hidden\" name=\"plugid\" value=\"{$pid}\" />\n";
6738                 $manager->addTicketHidden();
6739                 
6740                 $aOptions = array();
6741                 $aOIDs = array();
6742                 $query = "SELECT * FROM %s WHERE ocontext='global' and opid=%d ORDER BY oid ASC";
6743                 $query = sprintf($query, sql_table('plugin_option_desc'), $pid);
6744                 $result = sql_query($query);
6745                 while ( $object = sql_fetch_object($result) )
6746                 {
6747                         array_push($aOIDs, $object->oid);
6748                         $aOptions[$object->oid] = array(
6749                                                 'oid' => $object->oid,
6750                                                 'value' => $object->odef,
6751                                                 'name' => $object->oname,
6752                                                 'description' => $object->odesc,
6753                                                 'type' => $object->otype,
6754                                                 'typeinfo' => $object->oextra,
6755                                                 'contextid' => 0
6756                         );
6757                 }
6758                 // fill out actual values
6759                 if ( count($aOIDs) > 0 )
6760                 {
6761                         $query = "SELECT oid, ovalue FROM %s WHERE oid in (%s)";
6762                         $query = sprintf($query, sql_table('plugin_option'), implode(',',$aOIDs));
6763                         $result = sql_query($query);
6764                         while ( $object = sql_fetch_object($result) )
6765                         {
6766                                 $aOptions[$object->oid]['value'] = $object->ovalue;
6767                         }
6768                 }
6769                 
6770                 // call plugins
6771                 $data = array('context' => 'global', 'plugid' => $pid, 'options'=>&$aOptions);
6772                 $manager->notify('PrePluginOptionsEdit',$data);
6773                 
6774                 $template['content'] = 'plugoptionlist';
6775                 $amount = showlist($aOptions,'table',$template);
6776                 if ( $amount == 0 )
6777                 {
6778                         echo '<p>',_ERROR_NOPLUGOPTIONS,'</p>';
6779                 }
6780                 echo "</div>\n";
6781                 echo "</form>\n";
6782                 $this->pagefoot();
6783                 
6784                 return;
6785         }
6786         
6787         /**
6788          * Admin::action_pluginoptionsupdate()
6789          * 
6790          * Update plugin options and fallback to plugin option page
6791          * 
6792          * @access      public
6793          * @param       void
6794          * @return      void
6795          */
6796         public function action_pluginoptionsupdate()
6797         {
6798                 global $member, $manager;
6799                 
6800                 // check if allowed
6801                 $member->isAdmin() or $this->disallow();
6802                 
6803                 $pid = (integer) requestVar('plugid');
6804                 if ( !$manager->pidInstalled($pid) )
6805                 {
6806                         $this->error(_ERROR_NOSUCHPLUGIN);
6807                 }
6808                 
6809                 $aOptions = requestArray('plugoption');
6810                 NucleusPlugin::apply_plugin_options($aOptions);
6811                 
6812                 $manager->notify('PostPluginOptionsUpdate',array('context' => 'global', 'plugid' => $pid));
6813                 
6814                 $this->action_pluginoptions(_PLUGS_OPTIONS_UPDATED);
6815                 return;
6816         }
6817         
6818         /**
6819          * Admin::_insertPluginOptions()
6820          * 
6821          * Output plugin option field
6822          * 
6823          * @access      public
6824          * @param string        $context        plugin option context
6825          * @param integer       $contextid      plugin option context id
6826          * @return      void
6827          */
6828         public function _insertPluginOptions($context, $contextid = 0)
6829         {
6830                 // get all current values for this contextid
6831                 // (note: this might contain doubles for overlapping contextids)
6832                 $aIdToValue = array();
6833                 $res = sql_query('SELECT oid, ovalue FROM ' . sql_table('plugin_option') . ' WHERE ocontextid=' . intval($contextid));
6834                 while ( $object = sql_fetch_object($res) )
6835                 {
6836                         $aIdToValue[$object->oid] = $object->ovalue;
6837                 }
6838                 
6839                 // get list of oids per pid
6840                 $query = 'SELECT * FROM ' . sql_table('plugin_option_desc') . ',' . sql_table('plugin')
6841                            . ' WHERE opid=pid and ocontext=\''.sql_real_escape_string($context).'\' ORDER BY porder, oid ASC';
6842                 $res = sql_query($query);
6843                 $aOptions = array();
6844                 while ( $object = sql_fetch_object($res) )
6845                 {
6846                         if (in_array($object->oid, array_keys($aIdToValue)))
6847                         {
6848                                 $value = $aIdToValue[$object->oid];
6849                         }
6850                         else
6851                         {
6852                                 $value = $object->odef;
6853                         }
6854                         
6855                         array_push($aOptions, array(
6856                                 'pid' => $object->pid,
6857                                 'pfile' => $object->pfile,
6858                                 'oid' => $object->oid,
6859                                 'value' => $value,
6860                                 'name' => $object->oname,
6861                                 'description' => $object->odesc,
6862                                 'type' => $object->otype,
6863                                 'typeinfo' => $object->oextra,
6864                                 'contextid' => $contextid,
6865                                 'extra' => ''));
6866                 }
6867                 
6868                 global $manager;
6869                 $manager->notify('PrePluginOptionsEdit',array('context' => $context, 'contextid' => $contextid, 'options'=>&$aOptions));
6870                 
6871                 $iPrevPid = -1;
6872                 foreach ($aOptions as $aOption)
6873                 {
6874                         // new plugin?
6875                         if ( $iPrevPid != $aOption['pid'] )
6876                         {
6877                                 $iPrevPid = $aOption['pid'];
6878                                 if ( !defined('_PLUGIN_OPTIONS_TITLE') )
6879                                 {
6880                                         define('_PLUGIN_OPTIONS_TITLE', 'Options for %s');
6881                                 }
6882                                 echo '<tr><th colspan="2">'.sprintf(_PLUGIN_OPTIONS_TITLE, Entity::hsc($aOption['pfile'])).'</th></tr>';
6883                         }
6884                         
6885                         $meta = NucleusPlugin::getOptionMeta($aOption['typeinfo']);
6886                         if ( @$meta['access'] != 'hidden' )
6887                         {
6888                                 echo '<tr>';
6889                                 listplug_plugOptionRow($aOption);
6890                                 echo '</tr>';
6891                         }
6892                 }
6893                 return;
6894         }
6895         
6896         /**
6897          * Admin::input_yesno()
6898          * Output input elements with radio attribute for yes/no options
6899          * 
6900          * @param       string  $name   name attribute
6901          * @param       string  $value_current  current value attribute
6902          * @param       integer $tabindex       tab index
6903          * @param       string  $value_yes      value attribute for yes option
6904          * @param       string  $value_no       value attribute for no option
6905          * @param       string  $text_yes       child text element for yes option
6906          * @param       string  $text_no        child text element for no option
6907          * @param       boolean $isAdmin        have admin right or not
6908          * @return      void
6909          */
6910         function input_yesno($name, $value_current, $tabindex = 0, $value_yes = 1, $value_no = 0, $text_yes = _YES, $text_no = _NO, $isAdmin = 0)
6911         {
6912                 $id = preg_replace('#\[|\]#', '-', $name);
6913                 $id_yes = $id . $value_yes;
6914                 $id_no  = $id . $value_no;
6915                 
6916                 /* yes option */
6917                 echo '<input type="radio" id="' . Entity::hsc($id_yes) . '" name="' . Entity::hsc($name) . '" value="' . Entity::hsc($value_yes) . '"';
6918                 if ( $name=="admin" )
6919                 {
6920                         echo ' onclick="selectCanLogin(true);"';
6921                 }
6922                 if ( $value_current == $value_yes )
6923                 {
6924                         echo " tabindex='$tabindex' checked='checked'";
6925                 }
6926                 echo " />\n";
6927                 echo '<label for="' . Entity::hsc($id_yes) . '">' . Entity::hsc($text_yes) . "</label>\n";
6928                 
6929                 /* no option */
6930                 echo '<input type="radio" id="' . Entity::hsc($id_no) . '" name="' . Entity::hsc($name) . '" value="' . Entity::hsc($value_no) . '"';
6931                 if ( $name=="admin" )
6932                 {
6933                         echo ' onclick="selectCanLogin(false);"';
6934                 }
6935                 if ( $value_current != $value_yes )
6936                 {
6937                         echo " tabindex='$tabindex' checked='checked'";
6938                 }
6939                 if ($isAdmin && $name=="canlogin")
6940                 {
6941                         echo ' disabled="disabled"';
6942                 }
6943                 echo " />\n";
6944                 echo '<label for="' . Entity::hsc($id_no) . '">' . Entity::hsc($text_no) . "</label>\n";
6945                 
6946                 return;
6947         }
6948 }