OSDN Git Service

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