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