OSDN Git Service

FIX:変数名の誤記を修正
[nucleus-jp/nucleus-next.git] / nucleus / libs / ADMIN.php
1 <?php
2 /*
3  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4  * Copyright (C) 2002-2009 The Nucleus Group
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * (see nucleus/documentation/index.html#license for more info)
11  */
12 /**
13  * The code for the Nucleus admin area
14  *
15  * @license http://nucleuscms.org/license.txt GNU General Public License
16  * @copyright Copyright (C) 2002-2009 The Nucleus Group
17  * @version $Id: ADMIN.php 1661 2012-02-12 11:55:39Z sakamocchi $
18
19  */
20
21 if ( !function_exists('requestVar') ) exit;
22 require_once dirname(__FILE__) . '/showlist.php';
23
24 /**
25  * Builds the admin area and executes admin actions
26  */
27 class Admin
28 {
29         private $xml_version_info = '1.0';
30         private $formal_public_identifier = '-//W3C//DTD XHTML 1.0 Strict//EN';
31         private $system_identifier = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd';
32         private $xhtml_namespace = 'http://www.w3.org/1999/xhtml';
33         
34     /**
35      * @var string $action action currently being executed ($action=xxxx -> action_xxxx method)
36      */
37     var $action;
38
39     /**
40      * Class constructor
41      */
42     function ADMIN() {
43
44     }
45
46     /**
47      * Executes an action
48      *
49      * @param string $action action to be performed
50      */
51     function action($action) {
52         global $CONF, $manager;
53
54         // list of action aliases
55         $alias = array(
56             'login' => 'overview',
57             '' => 'overview'
58         );
59
60         if (isset($alias[$action]))
61             $action = $alias[$action];
62
63         $methodName = 'action_' . $action;
64
65         $this->action = strtolower($action);
66
67         // check ticket. All actions need a ticket, unless they are considered to be safe (a safe action
68         // is an action that requires user interaction before something is actually done)
69         // all safe actions are in this array:
70         $aActionsNotToCheck = array(
71             'showlogin',
72             'login',
73             'overview',
74             'itemlist',
75             'blogcommentlist',
76             'bookmarklet',
77             'blogsettings',
78             'banlist',
79             'deleteblog',
80             'editmembersettings',
81             'browseownitems',
82             'browseowncomments',
83             'createitem',
84             'itemedit',
85             'itemmove',
86             'categoryedit',
87             'categorydelete',
88             'manage',
89             'actionlog',
90             'settingsedit',
91             'backupoverview',
92             'pluginlist',
93             'createnewlog',
94             'usermanagement',
95             'skinoverview',
96             'templateoverview',
97             'skinieoverview',
98             'itemcommentlist',
99             'commentedit',
100             'commentdelete',
101             'banlistnewfromitem',
102             'banlistdelete',
103             'itemdelete',
104             'manageteam',
105             'teamdelete',
106             'banlistnew',
107             'memberedit',
108             'memberdelete',
109             'pluginhelp',
110             'pluginoptions',
111             'plugindelete',
112             'skinedittype',
113             'skinremovetype',
114             'skindelete',
115             'skinedit',
116             'templateedit',
117             'templatedelete',
118             'activate',
119             'systemoverview'
120         );
121 /*
122         // the rest of the actions needs to be checked
123         $aActionsToCheck = array('additem', 'itemupdate', 'itemmoveto', 'categoryupdate', 'categorydeleteconfirm', 'itemdeleteconfirm', 'commentdeleteconfirm', 'teamdeleteconfirm', 'memberdeleteconfirm', 'templatedeleteconfirm', 'skindeleteconfirm', 'banlistdeleteconfirm', 'plugindeleteconfirm', 'batchitem', 'batchcomment', 'batchmember', 'batchcategory', 'batchteam', 'commentupdate', 'banlistadd', 'changemembersettings', 'clearactionlog', 'settingsupdate', 'blogsettingsupdate', 'categorynew', 'teamchangeadmin', 'teamaddmember', 'memberadd', 'addnewlog', 'addnewlog2', 'backupcreate', 'backuprestore', 'pluginup', 'plugindown', 'pluginupdate', 'pluginadd', 'pluginoptionsupdate', 'skinupdate', 'skinclone', 'skineditgeneral', 'templateclone', 'templatenew', 'templateupdate', 'skinieimport', 'skinieexport', 'skiniedoimport', 'skinnew', 'deleteblogconfirm', 'activatesetpwd');
124 */
125         if (!in_array($this->action, $aActionsNotToCheck))
126         {
127             if (!$manager->checkTicket())
128                 $this->error(_ERROR_BADTICKET);
129         }
130
131         if (method_exists($this, $methodName))
132             call_user_func(array(&$this, $methodName));
133         else
134             $this->error(_BADACTION . Entity::hsc(" ($action)"));
135
136     }
137
138     /**
139      * @todo document this
140      */
141     function action_showlogin() {
142         global $error;
143         $this->action_login($error);
144     }
145
146     /**
147      * @todo document this
148      */
149     function action_login($msg = '', $passvars = 1) {
150         global $member;
151
152         // skip to overview when allowed
153         if ($member->isLoggedIn() && $member->canLogin()) {
154             $this->action_overview();
155             exit;
156         }
157
158         $this->pagehead();
159
160         echo '<h2>', _LOGIN ,'</h2>';
161         if ($msg) echo _MESSAGE , ': ', Entity::hsc($msg);
162         ?>
163
164         <form action="index.php" method="post"><p>
165         <?php echo _LOGIN_NAME; ?> <br /><input name="login"  tabindex="10" />
166         <br />
167         <?php echo _LOGIN_PASSWORD; ?> <br /><input name="password"  tabindex="20" type="password" />
168         <br />
169         <input name="action" value="login" type="hidden" />
170         <br />
171         <input type="submit" value="<?php echo _LOGIN ?>" tabindex="30" />
172         <br />
173         <small>
174             <input type="checkbox" value="1" name="shared" tabindex="40" id="shared" /><label for="shared"><?php echo _LOGIN_SHARED ?></label>
175             <br /><a href="forgotpassword.html"><?php echo _LOGIN_FORGOT ?></a>
176         </small>
177         <?php           // pass through vars
178
179             $oldaction = postVar('oldaction');
180             if (  ($oldaction != 'logout')  && ($oldaction != 'login')  && $passvars ) {
181                 passRequestVars();
182             }
183
184
185         ?>
186         </p></form>
187         <?php       $this->pagefoot();
188     }
189
190
191     /**
192      * provides a screen with the overview of the actions available
193      * @todo document parameter
194      */
195     function action_overview($msg = '') {
196         global $member;
197
198         $this->pagehead();
199
200         if ($msg)
201             echo _MESSAGE , ': ', $msg;
202
203         /* ---- add items ---- */
204         echo '<h2>' . _OVERVIEW_YRBLOGS . '</h2>';
205
206         $showAll = requestVar('showall');
207
208         if (($member->isAdmin()) && ($showAll == 'yes')) {
209             // Super-Admins have access to all blogs! (no add item support though)
210             $query =  'SELECT bnumber, bname, 1 as tadmin, burl, bshortname'
211                    . ' FROM ' . sql_table('blog')
212                    . ' ORDER BY bname';
213         } else {
214             $query =  'SELECT bnumber, bname, tadmin, burl, bshortname'
215                    . ' FROM ' . sql_table('blog') . ', ' . sql_table('team')
216                    . ' WHERE tblog=bnumber and tmember=' . $member->getID()
217                    . ' ORDER BY bname';
218         }
219         $template['content'] = 'bloglist';
220         $template['superadmin'] = $member->isAdmin();
221         $amount = showlist($query,'table',$template);
222
223         if (($showAll != 'yes') && ($member->isAdmin())) {
224             $total = DB::getValue('SELECT COUNT(*) as result FROM ' . sql_table('blog'));
225             if ($total > $amount)
226                 echo '<p><a href="index.php?action=overview&amp;showall=yes">' . _OVERVIEW_SHOWALL . '</a></p>';
227         }
228
229         if ($amount == 0)
230             echo _OVERVIEW_NOBLOGS;
231
232         if ($amount != 0) {
233             echo '<h2>' . _OVERVIEW_YRDRAFTS . '</h2>';
234             $query =  'SELECT ititle, inumber, bshortname'
235                    . ' FROM ' . sql_table('item'). ', ' . sql_table('blog')
236                    . ' WHERE iauthor='.$member->getID().' and iblog=bnumber and idraft=1';
237             $template['content'] = 'draftlist';
238             $amountdrafts = showlist($query, 'table', $template);
239             if ($amountdrafts == 0)
240                 echo _OVERVIEW_NODRAFTS;
241         }
242                                 
243                 if ($amount != 0) {
244                         $yrBlogs = $member->getAdminBlogs();
245                         if ($showAll != 'yes') {
246                                 $admBlogs = array();
247                                 foreach ($yrBlogs as $value) {
248                                         if ($member->isBlogAdmin(intval($value))) {
249                                                 $admBlogs[] = intval($value);
250                                         }
251                                 }
252                                 $yrBlogs = $admBlogs;
253                         }
254                         
255                         if (count($yrBlogs) > 0) {
256                                 echo '<h2>' . _OVERVIEW_OTHER_DRAFTS . '</h2>';
257                                 $query =  'SELECT ititle, inumber, bshortname, mname'
258                                            . ' FROM ' . sql_table('item'). ', ' . sql_table('blog'). ', ' . sql_table('member')
259                                            . ' WHERE iauthor<>'.$member->getID().' and iblog IN ('.implode(",",$yrBlogs).') and iblog=bnumber and iauthor=mnumber and idraft=1'
260                                            . ' ORDER BY iblog ASC';
261                                 $template['content'] = 'otherdraftlist';
262                                 $amountdrafts = showlist($query, 'table', $template);
263                                 if ($amountdrafts == 0)
264                                         echo _OVERVIEW_NODRAFTS;
265                         }
266         }
267
268         /* ---- user settings ---- */
269         echo '<h2>' . _OVERVIEW_YRSETTINGS . '</h2>';
270         echo '<ul>';
271         echo '<li><a href="index.php?action=editmembersettings">' . _OVERVIEW_EDITSETTINGS. '</a></li>';
272         echo '<li><a href="index.php?action=browseownitems">' . _OVERVIEW_BROWSEITEMS.'</a></li>';
273         echo '<li><a href="index.php?action=browseowncomments">'._OVERVIEW_BROWSECOMM.'</a></li>';
274         echo '</ul>';
275
276         /* ---- general settings ---- */
277         if ($member->isAdmin()) {
278             echo '<h2>' . _OVERVIEW_MANAGEMENT. '</h2>';
279             echo '<ul>';
280             echo '<li><a href="index.php?action=manage">',_OVERVIEW_MANAGE,'</a></li>';
281             echo '</ul>';
282         }
283
284
285         $this->pagefoot();
286     }
287
288     /**
289      * Returns a link to a weblog
290      * @param object BLOG
291      */
292     function bloglink(&$blog) {
293         return '<a href="'.Entity::hsc($blog->getURL()).'" title="'._BLOGLIST_TT_VISIT.'">'. Entity::hsc( $blog->getName() ) .'</a>';
294     }
295
296     /**
297      * @todo document this
298      */
299     function action_manage($msg = '') {
300         global $member;
301
302         $member->isAdmin() or $this->disallow();
303
304         $this->pagehead();
305
306         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
307
308         if ($msg)
309             echo '<p>' , _MESSAGE , ': ', $msg , '</p>';
310
311
312         echo '<h2>' . _MANAGE_GENERAL. '</h2>';
313
314         echo '<ul>';
315         echo '<li><a href="index.php?action=createnewlog">'._OVERVIEW_NEWLOG.'</a></li>';
316         echo '<li><a href="index.php?action=settingsedit">'._OVERVIEW_SETTINGS.'</a></li>';
317         echo '<li><a href="index.php?action=usermanagement">'._OVERVIEW_MEMBERS.'</a></li>';
318         echo '<li><a href="index.php?action=actionlog">'._OVERVIEW_VIEWLOG.'</a></li>';
319         echo '</ul>';
320
321         echo '<h2>' . _MANAGE_SKINS . '</h2>';
322         echo '<ul>';
323         echo '<li><a href="index.php?action=skinoverview">'._OVERVIEW_SKINS.'</a></li>';
324         echo '<li><a href="index.php?action=templateoverview">'._OVERVIEW_TEMPLATES.'</a></li>';
325         echo '<li><a href="index.php?action=skinieoverview">'._OVERVIEW_SKINIMPORT.'</a></li>';
326         echo '</ul>';
327
328         echo '<h2>' . _MANAGE_EXTRA . '</h2>';
329         echo '<ul>';
330         echo '<li><a href="index.php?action=backupoverview">'._OVERVIEW_BACKUP.'</a></li>';
331         echo '<li><a href="index.php?action=pluginlist">'._OVERVIEW_PLUGINS.'</a></li>';
332         echo '</ul>';
333
334         $this->pagefoot();
335     }
336
337         /**
338          * Admin::action_itemlist()
339          * 
340          * @param       integer $blogid ID for weblog
341          * @return      void
342          */
343         public function action_itemlist($blogid = '')
344         {
345                 global $member, $manager, $CONF;
346                 
347                 if ( $blogid == '' )
348                 {
349                         $blogid = intRequestVar('blogid');
350                 }
351                 
352                 $member->teamRights($blogid) or $member->isAdmin() or $this->disallow();
353                 
354                 $this->pagehead();
355                 $blog =& $manager->getBlog($blogid);
356                 
357                 echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
358                 echo '<h2>' . _ITEMLIST_BLOG . ' ' . $this->bloglink($blog) . '</h2>';
359                 
360                 // start index
361                 if ( postVar('start') )
362                 {
363                         $start = intPostVar('start');
364                 }
365                 else
366                 {
367                         $start = 0;
368                 }
369                 
370                 if ( $start == 0 )
371                 {
372                         echo '<p><a href="index.php?action=createitem&amp;blogid='.$blogid.'">' . _ITEMLIST_ADDNEW . "</a></p>\n";
373                 }
374                 
375                 // amount of items to show
376                 if ( postVar('amount') )
377                 {
378                         $amount = intPostVar('amount');
379                 }
380                 else
381                 {
382                         $amount = intval($CONF['DefaultListSize']);
383                         if ( $amount < 1 )
384                         {
385                                 $amount = 10;
386                         }
387                 }
388                 
389                 $search = postVar('search');    // search through items
390                 
391                 $query = 'SELECT bshortname, cname, mname, ititle, ibody, inumber, idraft, itime'
392                        . ' FROM ' . sql_table('item') . ', ' . sql_table('blog') . ', ' . sql_table('member') . ', ' . sql_table('category')
393                        . ' WHERE iblog=bnumber and iauthor=mnumber and icat=catid and iblog=' . $blogid;
394                 
395                 if ( $search )
396                 {
397                         $query .= " AND ((ititle LIKE " . DB::quoteValue('%'.$search.'%') . ") OR (ibody LIKE " . DB::quoteValue('%'.$search.'%') . ") OR (imore LIKE " . DB::quoteValue('%'.$search.'%') . "))";
398                 }
399                 
400                 // non-blog-admins can only edit/delete their own items
401                 if ( !$member->blogAdminRights($blogid) )
402                 {
403                         $query .= ' and iauthor=' . $member->getID();
404                 }
405                 
406                 $query .= ' ORDER BY itime DESC'
407                         . " LIMIT $start, $amount";
408                 
409                 $template['content'] = 'itemlist';
410                 $template['now'] = $blog->getCorrectTime(time());
411                 
412                 $manager->loadClass("ENCAPSULATE");
413                 $navList = new NavList('itemlist', $start, $amount, 0, 1000, $blogid, $search, 0);
414                 $navList->showBatchList('item',$query,'table',$template);
415                 
416                 $this->pagefoot();
417                 return;
418         }
419
420     /**
421      * @todo document this
422      */
423     function action_batchitem() {
424         global $member, $manager;
425
426         // check if logged in
427         $member->isLoggedIn() or $this->disallow();
428
429         // more precise check will be done for each performed operation
430
431         // get array of itemids from request
432         $selected = requestIntArray('batch');
433         $action = requestVar('batchaction');
434
435         // Show error when no items were selected
436         if (!is_array($selected) || sizeof($selected) == 0)
437             $this->error(_BATCH_NOSELECTION);
438
439         // On move: when no destination blog/category chosen, show choice now
440         $destCatid = intRequestVar('destcatid');
441         if (($action == 'move') && (!$manager->existsCategory($destCatid)))
442             $this->batchMoveSelectDestination('item',$selected);
443
444         // On delete: check if confirmation has been given
445         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
446             $this->batchAskDeleteConfirmation('item',$selected);
447
448         $this->pagehead();
449
450         echo '<a href="index.php?action=overview">(',_BACKHOME,')</a>';
451         echo '<h2>',_BATCH_ITEMS,'</h2>';
452         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
453         echo '<ul>';
454
455
456         // walk over all itemids and perform action
457         foreach ($selected as $itemid) {
458             $itemid = intval($itemid);
459             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONITEM,' <b>', $itemid, '</b>...';
460
461             // perform action, display errors if needed
462             switch($action) {
463                 case 'delete':
464                     $error = $this->deleteOneItem($itemid);
465                     break;
466                 case 'move':
467                     $error = $this->moveOneItem($itemid, $destCatid);
468                     break;
469                 default:
470                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
471             }
472
473             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
474             echo '</li>';
475         }
476
477         echo '</ul>';
478         echo '<b>',_BATCH_DONE,'</b>';
479
480         $this->pagefoot();
481
482
483     }
484
485     /**
486      * @todo document this
487      */
488     function action_batchcomment() {
489         global $member;
490
491         // check if logged in
492         $member->isLoggedIn() or $this->disallow();
493
494         // more precise check will be done for each performed operation
495
496         // get array of itemids from request
497         $selected = requestIntArray('batch');
498         $action = requestVar('batchaction');
499
500         // Show error when no items were selected
501         if (!is_array($selected) || sizeof($selected) == 0)
502             $this->error(_BATCH_NOSELECTION);
503
504         // On delete: check if confirmation has been given
505         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
506             $this->batchAskDeleteConfirmation('comment',$selected);
507
508         $this->pagehead();
509
510         echo '<a href="index.php?action=overview">(',_BACKHOME,')</a>';
511         echo '<h2>',_BATCH_COMMENTS,'</h2>';
512         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
513         echo '<ul>';
514
515         // walk over all itemids and perform action
516         foreach ($selected as $commentid) {
517             $commentid = intval($commentid);
518             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONCOMMENT,' <b>', $commentid, '</b>...';
519
520             // perform action, display errors if needed
521             switch($action) {
522                 case 'delete':
523                     $error = $this->deleteOneComment($commentid);
524                     break;
525                 default:
526                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
527             }
528
529             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
530             echo '</li>';
531         }
532
533         echo '</ul>';
534         echo '<b>',_BATCH_DONE,'</b>';
535
536         $this->pagefoot();
537
538
539     }
540
541     /**
542      * @todo document this
543      */
544     function action_batchmember() {
545         global $member;
546
547         // check if logged in and admin
548         ($member->isLoggedIn() && $member->isAdmin()) or $this->disallow();
549
550         // get array of itemids from request
551         $selected = requestIntArray('batch');
552         $action = requestVar('batchaction');
553
554         // Show error when no members selected
555         if (!is_array($selected) || sizeof($selected) == 0)
556             $this->error(_BATCH_NOSELECTION);
557
558         // On delete: check if confirmation has been given
559         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
560             $this->batchAskDeleteConfirmation('member',$selected);
561
562         $this->pagehead();
563
564         echo '<a href="index.php?action=usermanagement">(',_MEMBERS_BACKTOOVERVIEW,')</a>';
565         echo '<h2>',_BATCH_MEMBERS,'</h2>';
566         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
567         echo '<ul>';
568
569         // walk over all itemids and perform action
570         foreach ($selected as $memberid) {
571             $memberid = intval($memberid);
572             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONMEMBER,' <b>', $memberid, '</b>...';
573
574             // perform action, display errors if needed
575             switch($action) {
576                 case 'delete':
577                     $error = $this->deleteOneMember($memberid);
578                     break;
579                 case 'setadmin':
580                     // always succeeds
581                     DB::execute('UPDATE ' . sql_table('member') . ' SET madmin=1 WHERE mnumber='.$memberid);
582                     $error = '';
583                     break;
584                 case 'unsetadmin':
585                     // there should always remain at least one super-admin
586                     $r = DB::getResult('SELECT * FROM '.sql_table('member'). ' WHERE madmin=1 and mcanlogin=1');
587                     if ($r->rowCount() < 2)
588                         $error = _ERROR_ATLEASTONEADMIN;
589                     else
590                         DB::execute('UPDATE ' . sql_table('member') .' SET madmin=0 WHERE mnumber='.$memberid);
591                     break;
592                 default:
593                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
594             }
595
596             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
597             echo '</li>';
598         }
599
600         echo '</ul>';
601         echo '<b>',_BATCH_DONE,'</b>';
602
603         $this->pagefoot();
604
605
606     }
607
608     /**
609      * @todo document this
610      */
611     function action_batchteam() {
612         global $member;
613
614         $blogid = intRequestVar('blogid');
615
616         // check if logged in and admin
617         ($member->isLoggedIn() && $member->blogAdminRights($blogid)) or $this->disallow();
618
619         // get array of itemids from request
620         $selected = requestIntArray('batch');
621         $action = requestVar('batchaction');
622
623         // Show error when no members selected
624         if (!is_array($selected) || sizeof($selected) == 0)
625             $this->error(_BATCH_NOSELECTION);
626
627         // On delete: check if confirmation has been given
628         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
629             $this->batchAskDeleteConfirmation('team',$selected);
630
631         $this->pagehead();
632
633         echo '<p><a href="index.php?action=manageteam&amp;blogid=',$blogid,'">(',_BACK,')</a></p>';
634
635         echo '<h2>',_BATCH_TEAM,'</h2>';
636         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
637         echo '<ul>';
638
639         // walk over all itemids and perform action
640         foreach ($selected as $memberid) {
641             $memberid = intval($memberid);
642             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONTEAM,' <b>', $memberid, '</b>...';
643
644             // perform action, display errors if needed
645             switch($action) {
646                 case 'delete':
647                     $error = $this->deleteOneTeamMember($blogid, $memberid);
648                     break;
649                 case 'setadmin':
650                     // always succeeds
651                     DB::execute('UPDATE '.sql_table('team').' SET tadmin=1 WHERE tblog='.$blogid.' and tmember='.$memberid);
652                     $error = '';
653                     break;
654                 case 'unsetadmin':
655                     // there should always remain at least one admin
656                     $r = DB::getResult('SELECT * FROM '.sql_table('team').' WHERE tadmin=1 and tblog='.$blogid);
657                     if ($r->rowCount() < 2)
658                         $error = _ERROR_ATLEASTONEBLOGADMIN;
659                     else
660                         DB::execute('UPDATE '.sql_table('team').' SET tadmin=0 WHERE tblog='.$blogid.' and tmember='.$memberid);
661                     break;
662                 default:
663                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
664             }
665
666             echo '<b>',($error ? $error : _BATCH_SUCCESS),'</b>';
667             echo '</li>';
668         }
669
670         echo '</ul>';
671         echo '<b>',_BATCH_DONE,'</b>';
672
673         $this->pagefoot();
674
675
676     }
677
678     /**
679      * @todo document this
680      */
681     function action_batchcategory() {
682         global $member, $manager;
683
684         // check if logged in
685         $member->isLoggedIn() or $this->disallow();
686
687         // more precise check will be done for each performed operation
688
689         // get array of itemids from request
690         $selected = requestIntArray('batch');
691         $action = requestVar('batchaction');
692
693         // Show error when no items were selected
694         if (!is_array($selected) || sizeof($selected) == 0)
695             $this->error(_BATCH_NOSELECTION);
696
697         // On move: when no destination blog chosen, show choice now
698         $destBlogId = intRequestVar('destblogid');
699         if (($action == 'move') && (!$manager->existsBlogID($destBlogId)))
700             $this->batchMoveCategorySelectDestination('category',$selected);
701
702         // On delete: check if confirmation has been given
703         if (($action == 'delete') && (requestVar('confirmation') != 'yes'))
704             $this->batchAskDeleteConfirmation('category',$selected);
705
706         $this->pagehead();
707
708         echo '<a href="index.php?action=overview">(',_BACKHOME,')</a>';
709         echo '<h2>',BATCH_CATEGORIES,'</h2>';
710         echo '<p>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b></p>';
711         echo '<ul>';
712
713         // walk over all itemids and perform action
714         foreach ($selected as $catid) {
715             $catid = intval($catid);
716             echo '<li>',_BATCH_EXECUTING,' <b>',Entity::hsc($action),'</b> ',_BATCH_ONCATEGORY,' <b>', $catid, '</b>...';
717
718             // perform action, display errors if needed
719             switch($action) {
720                 case 'delete':
721                     $error = $this->deleteOneCategory($catid);
722                     break;
723                 case 'move':
724                     $error = $this->moveOneCategory($catid, $destBlogId);
725                     break;
726                 default:
727                     $error = _BATCH_UNKNOWN . Entity::hsc($action);
728             }
729
730             echo '<b>',($error ? _ERROR . ': '.$error : _BATCH_SUCCESS),'</b>';
731             echo '</li>';
732         }
733
734         echo '</ul>';
735         echo '<b>',_BATCH_DONE,'</b>';
736
737         $this->pagefoot();
738
739     }
740
741     /**
742      * @todo document this
743      */
744     function batchMoveSelectDestination($type, $ids) {
745         global $manager;
746         $this->pagehead();
747         ?>
748         <h2><?php echo _MOVE_TITLE ?></h2>
749         <form method="post" action="index.php"><div>
750
751             <input type="hidden" name="action" value="batch<?php echo $type ?>" />
752             <input type="hidden" name="batchaction" value="move" />
753             <?php
754                 $manager->addTicketHidden();
755
756                 // insert selected item numbers
757                 $idx = 0;
758                 foreach ($ids as $id)
759                     echo '<input type="hidden" name="batch[',($idx++),']" value="',intval($id),'" />';
760
761                 // show blog/category selection list
762                 $this->selectBlogCategory('destcatid');
763
764             ?>
765
766
767             <input type="submit" value="<?php echo _MOVE_BTN ?>" onclick="return checkSubmit();" />
768
769         </div></form>
770         <?php       $this->pagefoot();
771         exit;
772     }
773
774     /**
775      * @todo document this
776      */
777     function batchMoveCategorySelectDestination($type, $ids) {
778         global $manager;
779         $this->pagehead();
780         ?>
781         <h2><?php echo _MOVECAT_TITLE ?></h2>
782         <form method="post" action="index.php"><div>
783
784             <input type="hidden" name="action" value="batch<?php echo $type ?>" />
785             <input type="hidden" name="batchaction" value="move" />
786             <?php
787                 $manager->addTicketHidden();
788
789                 // insert selected item numbers
790                 $idx = 0;
791                 foreach ($ids as $id)
792                     echo '<input type="hidden" name="batch[',($idx++),']" value="',intval($id),'" />';
793
794                 // show blog/category selection list
795                 $this->selectBlog('destblogid');
796
797             ?>
798
799
800             <input type="submit" value="<?php echo _MOVECAT_BTN ?>" onclick="return checkSubmit();" />
801
802         </div></form>
803         <?php       $this->pagefoot();
804         exit;
805     }
806
807     /**
808      * @todo document this
809      */
810     function batchAskDeleteConfirmation($type, $ids) {
811         global $manager;
812
813         $this->pagehead();
814         ?>
815         <h2><?php echo _BATCH_DELETE_CONFIRM ?></h2>
816         <form method="post" action="index.php"><div>
817
818             <input type="hidden" name="action" value="batch<?php echo $type ?>" />
819             <?php $manager->addTicketHidden() ?>
820             <input type="hidden" name="batchaction" value="delete" />
821             <input type="hidden" name="confirmation" value="yes" />
822             <?php               // insert selected item numbers
823                 $idx = 0;
824                 foreach ($ids as $id)
825                     echo '<input type="hidden" name="batch[',($idx++),']" value="',intval($id),'" />';
826
827                 // add hidden vars for team & comment
828                 if ($type == 'team')
829                 {
830                     echo '<input type="hidden" name="blogid" value="',intRequestVar('blogid'),'" />';
831                 }
832                 if ($type == 'comment')
833                 {
834                     echo '<input type="hidden" name="itemid" value="',intRequestVar('itemid'),'" />';
835                 }
836
837             ?>
838
839             <input type="submit" value="<?php echo _BATCH_DELETE_CONFIRM_BTN ?>" onclick="return checkSubmit();" />
840
841         </div></form>
842         <?php       $this->pagefoot();
843         exit;
844     }
845
846
847     /**
848      * Inserts a HTML select element with choices for all categories to which the current
849      * member has access
850      * @see function selectBlog
851      */
852     function selectBlogCategory($name, $selected = 0, $tabindex = 0, $showNewCat = 0, $iForcedBlogInclude = -1) {
853         Admin::selectBlog($name, 'category', $selected, $tabindex, $showNewCat, $iForcedBlogInclude);
854     }
855
856         /**
857          * Admin::selectBlog()
858          * Inserts a HTML select element with choices for all blogs to which the user has access
859          *  mode = 'blog' => shows blognames and values are blogids
860          *  mode = 'category' => show category names and values are catids
861          * 
862          * @param       string  $name                           name of 
863          * @param       string  $mode                           blog/category
864          * @param       integer $selected                       category ID to be selected
865          * @param       integer $tabindex                       tab index value
866          * @param       integer $showNewCat                     show category to newly be created
867          * @param       integer $iForcedBlogInclude     ID of a blog that always needs to be included,
868          *                                              without checking if the member is on the blog team (-1 = none)
869          * @return      void
870          */
871         public function selectBlog($name, $mode='blog', $selected = 0, $tabindex = 0, $showNewCat = 0, $iForcedBlogInclude = -1)
872         {
873                 global $member, $CONF;
874                 
875                 // 0. get IDs of blogs to which member can post items (+ forced blog)
876                 $aBlogIds = array();
877                 if ( $iForcedBlogInclude != -1 )
878                 {
879                         $aBlogIds[] = intval($iForcedBlogInclude);
880                 }
881                 
882                 if ( !$member->isAdmin() || !array_key_exists('ShowAllBlogs', $CONF) || !$CONF['ShowAllBlogs'] )
883                 {
884                         $query = "SELECT bnumber FROM %s,%s WHERE tblog=bnumber and tmember=%d;";
885                         $query = sprintf($query, sql_table('blog'), sql_table('team'), (integer) $member->getID());
886                 }
887                 else
888                 {
889                         $query = "SELECT bnumber FROM %s ORDER BY bname;";
890                         $query = sprintf($query, sql_table('blog'));
891                 }
892                 
893                 $rblogids = DB::getResult($query);
894                 foreach ( $rblogids as $row )
895                 {
896                         if ( $row['bnumber'] != $iForcedBlogInclude )
897                         {
898                                 $aBlogIds[] = (integer) $row['bnumber'];
899                         }
900                 }
901                 if ( count($aBlogIds) == 0 )
902                 {
903                         return;
904                 }
905                 
906                 echo "<select name=\"{$name}\" tabindex=\"{$tabindex}\">\n";
907                 
908                 // 1. select blogs (we'll create optiongroups)
909                 // (only select those blogs that have the user on the team)
910                 $query = "SELECT bnumber, bname FROM %s WHERE bnumber in (%s) ORDER BY bname;";
911                 $query = sprintf($query, sql_table('blog'), implode(',',$aBlogIds));
912                 $blogs = DB::getResult($query);
913                 
914                 if ( $mode == 'category' )
915                 {
916                         $multipleBlogs = ($blogs->rowCount() > 1);
917                         
918                         foreach ( $blogs as $row )
919                         {
920                                 if ( $multipleBlogs )
921                                 {
922                                         echo '<optgroup label="' . Entity::hsc($row['bname']) . '">' . "\n";
923                                 }
924                                 
925                                 // show selection to create new category when allowed/wanted
926                                 if ( $showNewCat )
927                                 {
928                                         // check if allowed to do so
929                                         if ( $member->blogAdminRights($row['bnumber']) )
930                                         {
931                                                 echo "<option value=\"newcat-{$row['bnumber']}\">" . _ADD_NEWCAT . "</option>\n";
932                                         }
933                                 }
934                                 
935                                 // 2. for each category in that blog
936                                 $query = "SELECT cname, catid FROM %s WHERE cblog=%d ORDER BY cname ASC;";
937                                 $query = sprintf($query, sql_table('category'), (integer) $row['bnumber']);
938                                 $categories = DB::getResult($query);
939                                 foreach ( $categories as $cat )
940                                 {
941                                         if ( $cat['catid'] != $selected )
942                                         {
943                                         echo "<option value=\"{$cat['catid']}\" {$selectText} >" . Entity::hsc($cat['cname']) . "</option>\n";
944                                         }
945                                         else
946                                         {
947                                         echo "<option value=\"{$cat['catid']}\" selected=\"selected\" >" . Entity::hsc($cat['cname']) . "</option>\n";
948                                         }
949                                 }
950                                 
951                                 if ( $multipleBlogs )
952                                 {
953                                         echo "</optgroup>\n";
954                                 }
955                         }
956                 }
957                 else
958                 {
959                         // blog mode
960                         foreach ( $blogs as $row )
961                         {
962                                 if ( $row['bnumber'] != $selected )
963                                 {
964                                         echo "<option value=\"{$row['bnumber']}\">" . Entity::hsc($row['bname']) . "</option>\n";
965                                 }
966                                 else
967                                 {
968                                         echo "<option value=\"{$row['bnumber']}\" selected=\"selected\">" . Entity::hsc($row['bname']) . "</option>\n";
969                                 }
970                         }
971                 }
972                 echo "</select>\n";
973                 return;
974         }
975         
976         /**
977          * Admin::action_browseownitems()
978          * 
979          * @param       void
980          * @return      void
981          */
982         public function action_browseownitems()
983         {
984                 global $member, $manager, $CONF;
985                 
986                 $this->pagehead();
987                 
988                 echo '<p><a href="index.php?action=overview">(' . _BACKHOME . ")</a></p>\n";
989                 echo '<h2>' . _ITEMLIST_YOUR . "</h2>\n";
990                 
991                 // start index
992                 if ( postVar('start') )
993                 {
994                         $start = intPostVar('start');
995                 }
996                 else
997                 {
998                         $start = 0;
999                 }
1000                 
1001                 // amount of items to show
1002                 if ( postVar('amount') )
1003                 {
1004                         $amount = intPostVar('amount');
1005                 }
1006                 else
1007                 {
1008                         $amount = (integer) $CONF['DefaultListSize'];
1009                         if ( $amount < 1 )
1010                         {
1011                                 $amount = 10;
1012                         }
1013                 }
1014                 
1015                 $search = postVar('search');    // search through items
1016                 
1017                 $query = 'SELECT bshortname, cname, mname, ititle, ibody, idraft, inumber, itime'
1018                        . ' FROM '.sql_table('item').', '.sql_table('blog') . ', '.sql_table('member') . ', '.sql_table('category')
1019                        . ' WHERE iauthor='. $member->getID() .' and iauthor=mnumber and iblog=bnumber and icat=catid';
1020                 
1021                 if ( $search )
1022                 {
1023                         $query .= " and ((ititle LIKE " . DB::quoteValue('%'.$search.'%') . ") or (ibody LIKE " . DB::quoteValue('%'.$search.'%') . ") or (imore LIKE " . DB::quoteValue('%'.$search.'%') . "))";
1024                 }
1025                 
1026                 $query .= ' ORDER BY itime DESC'
1027                         . " LIMIT $start, $amount";
1028                 
1029                 $template['content'] = 'itemlist';
1030                 $template['now'] = time();
1031                 
1032                 $manager->loadClass("ENCAPSULATE");
1033                 $navList = new NavList('browseownitems', $start, $amount, 0, 1000, /*$blogid*/ 0, $search, 0);
1034                 $navList->showBatchList('item',$query,'table',$template);
1035                 
1036                 $this->pagefoot();
1037                 return;
1038         }
1039         
1040         /**
1041          * Admin::action_itemcommentlist()
1042          * 
1043          * Show all the comments for a given item
1044          * @param       integer $itemid ID for item
1045          * @return      void
1046          */
1047         public function action_itemcommentlist($itemid = '')
1048         {
1049                 global $member, $manager, $CONF;
1050                 
1051                 if ( $itemid == '' )
1052                 {
1053                         $itemid = intRequestVar('itemid');
1054                 }
1055                 
1056                 // only allow if user is allowed to alter item
1057                 $member->canAlterItem($itemid) or $this->disallow();
1058                 
1059                 $blogid = getBlogIdFromItemId($itemid);
1060                 
1061                 $this->pagehead();
1062                 
1063                 // start index
1064                 if ( postVar('start') )
1065                 {
1066                         $start = intPostVar('start');
1067                 }
1068                 else
1069                 {
1070                         $start = 0;
1071                 }
1072                 
1073                 // amount of items to show
1074                 if ( postVar('amount') )
1075                 {
1076                         $amount = intPostVar('amount');
1077                 }
1078                 else
1079                 {
1080                         $amount = (integer) $CONF['DefaultListSize'];
1081                         if ( $amount < 1 )
1082                         {
1083                                 $amount = 10;
1084                         }
1085                 }
1086                 
1087                 $search = postVar('search');
1088                 
1089                 echo '<p>(<a href="index.php?action=itemlist&amp;blogid=' . $blogid . '">' . _BACKTOOVERVIEW . "</a>)</p>\n";
1090                 echo '<h2>',_COMMENTS,'</h2>';
1091                 
1092                 $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;
1093                 
1094                 if ( $search )
1095                 {
1096                         $query .= " and cbody LIKE " . DB::quoteValue('%'.$search.'%');
1097                 }
1098                 
1099                 $query .= ' ORDER BY ctime ASC'
1100                         . " LIMIT $start,$amount";
1101                 
1102                 $template['content'] = 'commentlist';
1103                 $template['canAddBan'] = $member->blogAdminRights(getBlogIDFromItemID($itemid));
1104                 
1105                 $manager->loadClass("ENCAPSULATE");
1106                 $navList = new NavList('itemcommentlist', $start, $amount, 0, 1000, 0, $search, $itemid);
1107                 $navList->showBatchList('comment',$query,'table',$template,_NOCOMMENTS);
1108                 
1109                 $this->pagefoot();
1110                 return;
1111         }
1112         
1113         /**
1114          * Admin::action_browseowncomments()
1115          * Browse own comments
1116          * 
1117          * @param       void
1118          * @return      void
1119          */
1120         public function action_browseowncomments()
1121         {
1122                 global $member, $manager, $CONF;
1123                 
1124                 // start index
1125                 if ( postVar('start') )
1126                 {
1127                         $start = intPostVar('start');
1128                 }
1129                 else
1130                 {
1131                         $start = 0;
1132                 }
1133                 
1134                 // amount of items to show
1135                 if ( postVar('amount') )
1136                 {
1137                         $amount = intPostVar('amount');
1138                 }
1139                 else
1140                 {
1141                         $amount = intval($CONF['DefaultListSize']);
1142                         if ( $amount < 1 )
1143                         {
1144                                 $amount = 10;
1145                         }
1146                 }
1147                 
1148                 $search = postVar('search');
1149                 
1150                 $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();
1151                 
1152                 if ( $search )
1153                 {
1154                         $query .= " and cbody LIKE " . DB::quoteValue('%'.$search.'%');
1155                 }
1156                 
1157                 $query .= ' ORDER BY ctime DESC'
1158                         . " LIMIT $start,$amount";
1159                 
1160                 $this->pagehead();
1161                 
1162                 echo '<p><a href="index.php?action=overview">(' . _BACKHOME . ")</a></p>\n";
1163                 echo '<h2>' . _COMMENTS_YOUR . "</h2>\n";
1164                 
1165                 $template['content'] = 'commentlist';
1166                 $template['canAddBan'] = 0; // doesn't make sense to allow banning yourself
1167                 
1168                 $manager->loadClass("ENCAPSULATE");
1169                 $navList = new NavList('browseowncomments', $start, $amount, 0, 1000, 0, $search, 0);
1170                 $navList->showBatchList('comment',$query,'table',$template,_NOCOMMENTS_YOUR);
1171                 
1172                 $this->pagefoot();
1173                 return;
1174         }
1175         
1176         /**
1177          * Admin::action_blogcommentlist()
1178          * 
1179          * Browse all comments for a weblog
1180          * @param       integer $blogid ID for weblog
1181          * @return      void
1182          */
1183         function action_blogcommentlist($blogid = '')
1184         {
1185                 global $member, $manager, $CONF;
1186                 
1187                 if ( $blogid == '' )
1188                 {
1189                         $blogid = intRequestVar('blogid');
1190                 }
1191                 else
1192                 {
1193                         $blogid = intval($blogid);
1194                 }
1195                 
1196                 $member->teamRights($blogid) or $member->isAdmin() or $this->disallow();
1197                 
1198                 // start index
1199                 if ( postVar('start') )
1200                 {
1201                         $start = intPostVar('start');
1202                 }
1203                 else
1204                 {
1205                         $start = 0;
1206                 }
1207                 
1208                 // amount of items to show
1209                 if ( postVar('amount') )
1210                 {
1211                         $amount = intPostVar('amount');
1212                 }
1213                 else
1214                 {
1215                         $amount = intval($CONF['DefaultListSize']);
1216                         if ( $amount < 1 )
1217                         {
1218                                 $amount = 10;
1219                         }
1220                 }
1221                 
1222                 $search = postVar('search');            // search through comments
1223                 
1224                 $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);
1225                 
1226                 if ( $search != '' )
1227                 {
1228                         $query .= " and cbody LIKE " . DB::quoteValue('%'.$search.'%');
1229                 }
1230                 
1231                 $query .= ' ORDER BY ctime DESC'
1232                         . " LIMIT $start,$amount";
1233                 
1234                 $blog =& $manager->getBlog($blogid);
1235                 
1236                 $this->pagehead();
1237                 
1238                 echo '<p><a href="index.php?action=overview">(' . _BACKHOME . ")</a></p>\n";
1239                 echo '<h2>', _COMMENTS_BLOG , ' ' , $this->bloglink($blog), '</h2>';
1240                 
1241                 $template['content'] = 'commentlist';
1242                 $template['canAddBan'] = $member->blogAdminRights($blogid);
1243                 
1244                 $manager->loadClass("ENCAPSULATE");
1245                 $navList = new NavList('blogcommentlist', $start, $amount, 0, 1000, $blogid, $search, 0);
1246                 $navList->showBatchList('comment',$query,'table',$template, _NOCOMMENTS_BLOG);
1247                 
1248                 $this->pagefoot();
1249                 return;
1250         }
1251         
1252         /**
1253          * Admin::action_createitem()
1254          * Provide a page to item a new item to the given blog
1255          * 
1256          * @param       void
1257          * @return      void
1258          */
1259         public function action_createitem()
1260         {
1261                 global $member, $manager;
1262                 
1263                 $blogid = intRequestVar('blogid');
1264                 
1265                 // check if allowed
1266                 $member->teamRights($blogid) or $this->disallow();
1267                 
1268                 $memberid = $member->getID();
1269                 
1270                 $blog =& $manager->getBlog($blogid);
1271                 
1272                 // generate the add-item form
1273                 $handler = new PageFactory($blog);
1274                 
1275                 $contents = $handler->getTemplateFor('admin', 'add');
1276                 $manager->notify('PreAddItemForm', array('contents' => &$contents, 'blog' => &$blog));
1277                 
1278                 $parser = new Parser($handler);
1279                 
1280                 $this->pagehead();
1281                 $parser->parse($contents);
1282                 $this->pagefoot();
1283                 
1284                 return;
1285         }
1286         
1287         /**
1288          * Admin::action_itemedit()
1289          * 
1290          * @param       void
1291          * @return      void
1292          */
1293         public function action_itemedit()
1294         {
1295                 global $member, $manager;
1296                 
1297                 $itemid = intRequestVar('itemid');
1298                 
1299                 // only allow if user is allowed to alter item
1300                 $member->canAlterItem($itemid) or $this->disallow();
1301                 
1302                 $variables =& $manager->getItem($itemid, 1, 1);
1303                 $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
1304                 
1305                 $manager->notify('PrepareItemForEdit', array('item' => &$variables));
1306                 
1307                 if ( $blog->convertBreaks() )
1308                 {
1309                         $variables['body'] = removeBreaks($variables['body']);
1310                         $variables['more'] = removeBreaks($variables['more']);
1311                 }
1312                 
1313                 // form to edit blog items
1314                 $handler = new PageFactory($blog);
1315                 $handler->setVariables($variables);
1316                 
1317                 $content = $handler->getTemplateFor('admin', 'edit');
1318                 
1319                 $parser = new Parser($handler);
1320                 
1321                 $this->pagehead();
1322                 $parser->parse($content);
1323                 $this->pagefoot();
1324                 return;
1325         }
1326         
1327     /**
1328      * @todo document this
1329      */
1330     function action_itemupdate() {
1331         global $member, $manager, $CONF;
1332
1333         $itemid = intRequestVar('itemid');
1334         $catid = postVar('catid');
1335
1336         // only allow if user is allowed to alter item
1337         $member->canUpdateItem($itemid, $catid) or $this->disallow();
1338
1339         $actiontype = postVar('actiontype');
1340
1341         // delete actions are handled by itemdelete (which has confirmation)
1342         if ($actiontype == 'delete') {
1343             $this->action_itemdelete();
1344             return;
1345         }
1346
1347         $body   = postVar('body');
1348         $title  = postVar('title');
1349         $more   = postVar('more');
1350         $closed = intPostVar('closed');
1351         $draftid = intPostVar('draftid');
1352
1353         // default action = add now
1354         if (!$actiontype)
1355             $actiontype='addnow';
1356
1357         // create new category if needed
1358         if ( i18n::strpos($catid,'newcat') === 0 ) {
1359             // get blogid
1360             list($blogid) = sscanf($catid,"newcat-%d");
1361
1362             // create
1363             $blog =& $manager->getBlog($blogid);
1364             $catid = $blog->createNewCategory();
1365
1366             // show error when sth goes wrong
1367             if (!$catid)
1368                 $this->doError(_ERROR_CATCREATEFAIL);
1369         }
1370
1371         /*
1372             set some variables based on actiontype
1373
1374             actiontypes:
1375                 draft items -> addnow, addfuture, adddraft, delete
1376                 non-draft items -> edit, changedate, delete
1377
1378             variables set:
1379                 $timestamp: set to a nonzero value for future dates or date changes
1380                 $wasdraft: set to 1 when the item used to be a draft item
1381                 $publish: set to 1 when the edited item is not a draft
1382         */
1383         $blogid =  getBlogIDFromItemID($itemid);
1384         $blog   =& $manager->getBlog($blogid);
1385
1386         $wasdrafts = array('adddraft', 'addfuture', 'addnow');
1387         $wasdraft  = in_array($actiontype, $wasdrafts) ? 1 : 0;
1388         $publish   = ($actiontype != 'adddraft' && $actiontype != 'backtodrafts') ? 1 : 0;
1389         if ($actiontype == 'addfuture' || $actiontype == 'changedate') {
1390             $timestamp = mktime(intPostVar('hour'), intPostVar('minutes'), 0, intPostVar('month'), intPostVar('day'), intPostVar('year'));
1391         } else {
1392             $timestamp =0;
1393         }
1394
1395         // edit the item for real
1396         Item::update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp);
1397
1398         $this->updateFuturePosted($blogid);
1399
1400         if ($draftid > 0) {
1401             // delete permission is checked inside Item::delete()
1402             Item::delete($draftid);
1403         }
1404
1405         // show category edit window when we created a new category
1406         // ($catid will then be a new category ID, while postVar('catid') will be 'newcat-x')
1407         if ($catid != intPostVar('catid')) {
1408             $this->action_categoryedit(
1409                 $catid,
1410                 $blog->getID(),
1411                 $CONF['AdminURL'] . 'index.php?action=itemlist&blogid=' . getBlogIDFromItemID($itemid)
1412             );
1413         } else {
1414             // TODO: set start item correctly for itemlist
1415             $this->action_itemlist(getBlogIDFromItemID($itemid));
1416         }
1417     }
1418         
1419         /**
1420          * Admin::action_itemdelete()
1421          * Delete item
1422          * 
1423          * @param       Void
1424          * @return      Void
1425          */
1426         function action_itemdelete()
1427         {
1428                 global $member, $manager;
1429                 
1430                 $itemid = intRequestVar('itemid');
1431                 
1432                 // only allow if user is allowed to alter item
1433                 $member->canAlterItem($itemid) or $this->disallow();
1434                 
1435                 if ( !$manager->existsItem($itemid,1,1) )
1436                 {
1437                         $this->error(_ERROR_NOSUCHITEM);
1438                 }
1439                 
1440                 $item =& $manager->getItem($itemid,1,1);
1441                 $title = Entity::hsc(strip_tags($item['title']));
1442                 $body = strip_tags($item['body']);
1443                 $body = Entity::hsc(Entity::shorten($body,300,'...'));
1444                 
1445                 $this->pagehead();
1446                 echo '<h2>' . _DELETE_CONFIRM . "</h2>\n";
1447                 echo '<p>' . _CONFIRMTXT_ITEM . "</p>\n";
1448                 echo "<div class=\"note\">\n";
1449                 echo "<b>{$title}</b>\n";
1450                 echo "<br />\n";
1451                 echo "{$body}\n";
1452                 echo "</div>\n";
1453                 echo "<form method=\"post\" action=\"index.php\">\n";
1454                 echo "<div>\n";
1455                 echo "<input type=\"hidden\" name=\"action\" value=\"itemdeleteconfirm\" />\n";
1456                 echo $manager->addTicketHidden() . "\n";
1457                 echo "<input type=\"hidden\" name=\"itemid\" value=\"{$itemid}\" />\n";
1458                 echo '<input type="submit" value="' . _DELETE_CONFIRM_BTN . "\"  tabindex=\"10\" />\n";
1459                 echo "</div>\n";
1460                 echo "</form>\n";
1461                 $this->pagefoot();
1462                 return;
1463         }
1464         
1465     /**
1466      * @todo document this
1467      */
1468     function action_itemdeleteconfirm() {
1469         global $member;
1470
1471         $itemid = intRequestVar('itemid');
1472
1473         // only allow if user is allowed to alter item
1474         $member->canAlterItem($itemid) or $this->disallow();
1475
1476         // get blogid first
1477         $blogid = getBlogIdFromItemId($itemid);
1478
1479         // delete item (note: some checks will be performed twice)
1480         $this->deleteOneItem($itemid);
1481
1482         $this->action_itemlist($blogid);
1483     }
1484
1485     /**
1486      * Deletes one item and returns error if something goes wrong
1487      * @param int $itemid
1488      */
1489     function deleteOneItem($itemid) {
1490         global $member, $manager;
1491
1492         // only allow if user is allowed to alter item (also checks if itemid exists)
1493         if (!$member->canAlterItem($itemid))
1494             return _ERROR_DISALLOWED;
1495
1496         // need to get blogid before the item is deleted
1497         $blogid = getBlogIDFromItemId($itemid);
1498
1499         $manager->loadClass('ITEM');
1500         Item::delete($itemid);
1501
1502         // update blog's futureposted
1503         $this->updateFuturePosted($blogid);
1504     }
1505
1506         /**
1507          * Admin::updateFuturePosted()
1508          * Update a blog's future posted flag
1509          * 
1510          * @param integer $blogid
1511          * @return      void
1512          * 
1513          */
1514         function updateFuturePosted($blogid)
1515         {
1516                 global $manager;
1517                 
1518                 $blog =& $manager->getBlog($blogid);
1519                 $currenttime = $blog->getCorrectTime(time());
1520                 
1521                 $query = "SELECT * FROM %s WHERE iblog=%d AND iposted=0 AND itime>%s";
1522                 $query = sprintf($query, sql_table('item'), (integer) $blogid, DB::formatDateTime($currenttime));
1523                 $result = DB::getResult($query);
1524                 
1525                 if ( $result->rowCount() > 0 )
1526                 {
1527                                 $blog->setFuturePost();
1528                 }
1529                 else
1530                 {
1531                                 $blog->clearFuturePost();
1532                 }
1533                 return;
1534         }
1535
1536     /**
1537      * @todo document this
1538      */
1539     function action_itemmove() {
1540         global $member, $manager;
1541
1542         $itemid = intRequestVar('itemid');
1543
1544         // only allow if user is allowed to alter item
1545         $member->canAlterItem($itemid) or $this->disallow();
1546
1547         $item =& $manager->getItem($itemid,1,1);
1548
1549         $this->pagehead();
1550         ?>
1551             <h2><?php echo _MOVE_TITLE ?></h2>
1552             <form method="post" action="index.php"><div>
1553                 <input type="hidden" name="action" value="itemmoveto" />
1554                 <input type="hidden" name="itemid" value="<?php echo  $itemid; ?>" />
1555
1556                 <?php
1557
1558                     $manager->addTicketHidden();
1559                     $this->selectBlogCategory('catid',$item['catid'],10,1);
1560                 ?>
1561
1562                 <input type="submit" value="<?php echo _MOVE_BTN ?>" tabindex="10000" onclick="return checkSubmit();" />
1563             </div></form>
1564         <?php
1565         $this->pagefoot();
1566     }
1567
1568     /**
1569      * @todo document this
1570      */
1571     function action_itemmoveto() {
1572         global $member, $manager;
1573
1574         $itemid = intRequestVar('itemid');
1575         $catid = requestVar('catid');
1576
1577         // create new category if needed
1578         if ( i18n::strpos($catid,'newcat') === 0 ) {
1579             // get blogid
1580             list($blogid) = sscanf($catid,'newcat-%d');
1581
1582             // create
1583             $blog =& $manager->getBlog($blogid);
1584             $catid = $blog->createNewCategory();
1585
1586             // show error when sth goes wrong
1587             if (!$catid)
1588                 $this->doError(_ERROR_CATCREATEFAIL);
1589         }
1590
1591         // only allow if user is allowed to alter item
1592         $member->canUpdateItem($itemid, $catid) or $this->disallow();
1593
1594         $old_blogid = getBlogIDFromItemId($itemid);
1595
1596         Item::move($itemid, $catid);
1597
1598         // set the futurePosted flag on the blog
1599         $this->updateFuturePosted(getBlogIDFromItemId($itemid));
1600
1601         // reset the futurePosted in case the item is moved from one blog to another
1602         $this->updateFuturePosted($old_blogid);
1603
1604         if ($catid != intRequestVar('catid'))
1605             $this->action_categoryedit($catid, $blog->getID());
1606         else
1607             $this->action_itemlist(getBlogIDFromCatID($catid));
1608     }
1609
1610     /**
1611      * Moves one item to a given category (category existance should be checked by caller)
1612      * errors are returned
1613      * @param int $itemid
1614      * @param int $destCatid category ID to which the item will be moved
1615      */
1616     function moveOneItem($itemid, $destCatid) {
1617         global $member;
1618
1619         // only allow if user is allowed to move item
1620         if (!$member->canUpdateItem($itemid, $destCatid))
1621             return _ERROR_DISALLOWED;
1622
1623         Item::move($itemid, $destCatid);
1624     }
1625
1626     /**
1627      * Adds a item to the chosen blog
1628      */
1629     function action_additem() {
1630         global $manager, $CONF;
1631
1632         $manager->loadClass('ITEM');
1633
1634         $result = Item::createFromRequest();
1635
1636         if ($result['status'] == 'error')
1637             $this->error($result['message']);
1638
1639         $blogid = getBlogIDFromItemID($result['itemid']);
1640         $blog =& $manager->getBlog($blogid);
1641         $btimestamp = $blog->getCorrectTime();
1642         $item       = $manager->getItem(intval($result['itemid']), 1, 1);
1643
1644         if ($result['status'] == 'newcategory') {
1645             $distURI = $manager->addTicketToUrl($CONF['AdminURL'] . 'index.php?action=itemList&blogid=' . intval($blogid));
1646             $this->action_categoryedit($result['catid'], $blogid, $distURI);
1647         } else {
1648             $methodName = 'action_itemList';
1649             call_user_func(array(&$this, $methodName), $blogid);
1650         }
1651     }
1652
1653         /**
1654          * Allows to edit previously made comments
1655          **/
1656         function action_commentedit() {
1657
1658                 global $member, $manager;
1659
1660                 $commentid = intRequestVar('commentid');
1661
1662                 $member->canAlterComment($commentid) or $this->disallow();
1663
1664                 $comment = Comment::getComment($commentid);
1665
1666                 $manager->notify('PrepareCommentForEdit', array('comment' => &$comment) );
1667
1668                 // change <br /> to \n
1669                 $comment['body'] = str_replace('<br />', '', $comment['body']);
1670
1671                 // replaced eregi_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
1672                 /* original eregi_replace: eregi_replace("<a href=['\"]([^'\"]+)['\"]( rel=\"nofollow\") ?>[^<]*</a>", "\\1", $comment['body']) */
1673
1674         $comment['body'] = preg_replace("#<a href=['\"]([^'\"]+)['\"]( rel=\"nofollow\") ?>[^<]*</a>#i", "\\1", $comment['body']);
1675
1676         $this->pagehead();
1677
1678         ?>
1679         <h2><?php echo _EDITC_TITLE ?></h2>
1680
1681         <form action="index.php" method="post"><div>
1682
1683         <input type="hidden" name="action" value="commentupdate" />
1684         <?php $manager->addTicketHidden(); ?>
1685         <input type="hidden" name="commentid" value="<?php echo  $commentid; ?>" />
1686         <table><tr>
1687             <th colspan="2"><?php echo _EDITC_TITLE ?></th>
1688         </tr><tr>
1689             <td><?php echo _EDITC_WHO ?></td>
1690             <td>
1691             <?php               if ($comment['member'])
1692                     echo $comment['member'] . " (" . _EDITC_MEMBER . ")";
1693                 else
1694                     echo $comment['user'] . " (" . _EDITC_NONMEMBER . ")";
1695             ?>
1696             </td>
1697         </tr><tr>
1698             <td><?php echo _EDITC_WHEN ?></td>
1699             <td><?php echo  date("Y-m-d @ H:i",$comment['timestamp']); ?></td>
1700         </tr><tr>
1701             <td><?php echo _EDITC_HOST ?></td>
1702             <td><?php echo  $comment['host']; ?></td>
1703         </tr>
1704         <tr>
1705             <td><?php echo _EDITC_URL; ?></td>
1706             <td><input type="text" name="url" size="30" tabindex="6" value="<?php echo $comment['userid']; ?>" /></td>
1707         </tr>
1708         <tr>
1709             <td><?php echo _EDITC_EMAIL; ?></td>
1710             <td><input type="text" name="email" size="30" tabindex="8" value="<?php echo $comment['email']; ?>" /></td>
1711         </tr>
1712         <tr>
1713             <td><?php echo _EDITC_TEXT ?></td>
1714             <td>
1715                 <textarea name="body" tabindex="10" rows="10" cols="50"><?php                   // htmlspecialchars not needed (things should be escaped already)
1716                     echo $comment['body'];
1717                 ?></textarea>
1718             </td>
1719         </tr><tr>
1720             <td><?php echo _EDITC_EDIT ?></td>
1721             <td><input type="submit"  tabindex="20" value="<?php echo _EDITC_EDIT ?>" onclick="return checkSubmit();" /></td>
1722         </tr></table>
1723
1724         </div></form>
1725         <?php
1726         $this->pagefoot();
1727     }
1728
1729     /**
1730      * @todo document this
1731      */
1732     function action_commentupdate() {
1733         global $member, $manager;
1734
1735         $commentid = intRequestVar('commentid');
1736
1737         $member->canAlterComment($commentid) or $this->disallow();
1738
1739         $url = postVar('url');
1740         $email = postVar('email');
1741         $body = postVar('body');
1742
1743                 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
1744                 # original eregi: eregi("[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}", $body) != FALSE
1745                 # important note that '\' must be matched with '\\\\' in preg* expressions
1746
1747                 // intercept words that are too long
1748                 if (preg_match('#[a-zA-Z0-9|\.,;:!\?=\/\\\\]{90,90}#', $body) != FALSE)
1749                 {
1750                         $this->error(_ERROR_COMMENT_LONGWORD);
1751                 }
1752
1753                 // check length
1754                 if (i18n::strlen($body) < 3)
1755                 {
1756                         $this->error(_ERROR_COMMENT_NOCOMMENT);
1757                 }
1758
1759                 if (i18n::strlen($body) > 5000)
1760                 {
1761                         $this->error(_ERROR_COMMENT_TOOLONG);
1762                 }
1763
1764                 // prepare body
1765                 $body = Comment::prepareBody($body);
1766
1767                 // call plugins
1768                 $manager->notify('PreUpdateComment',array('body' => &$body));
1769
1770                 $query = 'UPDATE ' . sql_table('comment')
1771                         . ' SET cmail = ' . DB::quoteValue($url) . ', cemail = ' . DB::quoteValue($email) . ', cbody = ' . DB::quoteValue($body)
1772                         . ' WHERE cnumber = ' . $commentid;
1773                 DB::execute($query);
1774
1775                 // get itemid
1776                 $res = DB::getValue('SELECT citem FROM '.sql_table('comment').' WHERE cnumber=' . $commentid);
1777                 $itemid = $res;
1778
1779                 if ($member->canAlterItem($itemid))
1780                         $this->action_itemcommentlist($itemid);
1781                 else
1782                         $this->action_browseowncomments();
1783
1784     }
1785         
1786         /**
1787          * Admin::action_commentdelete()
1788          * Update comment
1789          * 
1790          * @param       Void
1791          * @return      Void
1792          */
1793         function action_commentdelete()
1794         {
1795                 global $member, $manager;
1796                 
1797                 $commentid = intRequestVar('commentid');
1798                 $member->canAlterComment($commentid) or $this->disallow();
1799                 $comment = Comment::getComment($commentid);
1800                 
1801                 $body = strip_tags($comment['body']);
1802                 $body = Entity::hsc(Entity::shorten($body, 300, '...'));
1803                 
1804                 if ( $comment['member'] )
1805                 {
1806                         $author = $comment['member'];
1807                 }
1808                 else
1809                 {
1810                         $author = $comment['user'];
1811                 }
1812                 
1813                 $this->pagehead();
1814                 
1815                 echo '<h2>' . _DELETE_CONFIRM . "</h2>\n";
1816                 echo '<p>' . _CONFIRMTXT_COMMENT . "</p>\n";
1817                 echo "<div class=\"note\">\n";
1818                 echo '<b>' . _EDITC_WHO . ":</b>{$author}<br />\n";
1819                 echo '<b>' . _EDITC_TEXT . ":</b>{$body}\n";
1820                 echo "</div>\n";
1821                 echo "<form method=\"post\" action=\"index.php\">\n";
1822                 echo "<div>\n";
1823                 echo "<input type=\"hidden\" name=\"action\" value=\"commentdeleteconfirm\" />\n";
1824                 echo $manager->addTicketHidden() . "\n";
1825                 echo "<input type=\"hidden\" name=\"commentid\" value=\"{$commentid}\" />\n";
1826                 echo '<input type="submit" tabindex="10" value="'. _DELETE_CONFIRM_BTN . "\" />\n";
1827                 echo "</div>\n";
1828                 echo "</form>\n";
1829                 $this->pagefoot();
1830                 return;
1831         }
1832         
1833     /**
1834      * @todo document this
1835      */
1836     function action_commentdeleteconfirm() {
1837         global $member;
1838
1839         $commentid = intRequestVar('commentid');
1840
1841         // get item id first
1842         $res = DB::getValue('SELECT citem FROM '.sql_table('comment') .' WHERE cnumber=' . $commentid);
1843         $itemid = $res;
1844
1845         $error = $this->deleteOneComment($commentid);
1846         if ($error)
1847             $this->doError($error);
1848
1849         if ($member->canAlterItem($itemid))
1850             $this->action_itemcommentlist($itemid);
1851         else
1852             $this->action_browseowncomments();
1853     }
1854
1855     /**
1856      * @todo document this
1857      */
1858     function deleteOneComment($commentid) {
1859         global $member, $manager;
1860
1861         $commentid = intval($commentid);
1862
1863         if (!$member->canAlterComment($commentid))
1864             return _ERROR_DISALLOWED;
1865
1866         $manager->notify('PreDeleteComment', array('commentid' => $commentid));
1867
1868         // delete the comments associated with the item
1869         $query = 'DELETE FROM '.sql_table('comment').' WHERE cnumber=' . $commentid;
1870         DB::execute($query);
1871
1872         $manager->notify('PostDeleteComment', array('commentid' => $commentid));
1873
1874         return '';
1875     }
1876
1877         /**
1878          * Admin::action_usermanagement()
1879          * 
1880          * Usermanagement main
1881          * @param       void
1882          * @return      void
1883          */
1884         public function action_usermanagement()
1885         {
1886                 global $member, $manager;
1887                 
1888                 // check if allowed
1889                 $member->isAdmin() or $this->disallow();
1890                 
1891                 $this->pagehead();
1892                 
1893                 echo '<p><a href="index.php?action=manage">(' . _BACKTOMANAGE . ")</a></p>\n";
1894                 
1895                 echo '<h2>' . _MEMBERS_TITLE . "</h2>\n";
1896                 
1897                 echo '<h3>' . _MEMBERS_CURRENT . "</h3>\n";
1898                 
1899                 // show list of members with actions
1900                 $query =  'SELECT * FROM '.sql_table('member');
1901                 $template['content'] = 'memberlist';
1902                 $template['tabindex'] = 10;
1903                 
1904                 $manager->loadClass("ENCAPSULATE");
1905                 $batch = new Batch('member');
1906                 $batch->showlist($query,'table',$template);
1907                 
1908                 echo '<h3>' . _MEMBERS_NEW .'</h3>';
1909                 echo "<form method=\"post\" action=\"index.php\" name=\"memberedit\">\n";
1910                 echo "<div>\n";
1911                 echo "<input type=\"hidden\" name=\"action\" value=\"memberadd\" />\n";
1912                 $manager->addTicketHidden();
1913                 
1914                 echo '<table frame="box" rules="rules" summary="' . _MEMBERS_NEW . '">' ."\n";
1915                 echo "<tr>\n";
1916                 echo '<th colspan="2">' . _MEMBERS_NEW . "</th>\n";
1917                 echo "</tr>\n";
1918                 echo "<tr>\n";
1919                 echo '<td>' . _MEMBERS_DISPLAY;
1920                 help('shortnames');
1921                 echo '<br />';
1922                 echo '<small>' . _MEMBERS_DISPLAY_INFO . '</small>';
1923                 echo "</td>\n";
1924                 echo "<td><input tabindex=\"10010\" name=\"name\" size=\"32\" maxlength=\"32\" /></td>\n";
1925                 echo "</tr>\n";
1926                 echo "<tr>\n";
1927                 echo '<td>' . _MEMBERS_REALNAME . "</td>\n";
1928                 echo "<td><input name=\"realname\" tabindex=\"10020\" size=\"40\" maxlength=\"60\" /></td>\n";
1929                 echo "</tr>\n";
1930                 echo "<tr>\n";
1931                 echo '<td>' . _MEMBERS_PWD . "</td>\n";
1932                 echo "<td><input name=\"password\" tabindex=\"10030\" size=\"16\" maxlength=\"40\" type=\"password\" /></td>\n";
1933                 echo "</tr>\n";
1934                 echo "<tr>\n";
1935                 echo '<td>' . _MEMBERS_REPPWD . "</td>\n";
1936                 echo "<td><input name=\"repeatpassword\" tabindex=\"10035\" size=\"16\" maxlength=\"40\" type=\"password\" /></td>\n";
1937                 echo "</tr>\n";
1938                 echo "<tr>\n";
1939                 echo '<td>' . _MEMBERS_EMAIL . "</td>\n";
1940                 echo "<td><input name=\"email\" tabindex=\"10040\" size=\"40\" maxlength=\"60\" /></td>\n";
1941                 echo "</tr>\n";
1942                 echo "<tr>\n";
1943                 echo '<td>' . _MEMBERS_URL . "</td>\n";
1944                 echo "<td><input name=\"url\" tabindex=\"10050\" size=\"40\" maxlength=\"100\" /></td>\n";
1945                 echo "</tr>\n";
1946                 echo "<tr>\n";
1947                 echo '<td>' . _MEMBERS_SUPERADMIN;
1948                 help('superadmin');
1949                 echo "</td>\n";
1950                 echo '<td>';
1951                 $this->input_yesno('admin',0,10060);
1952                 echo "</td>\n";
1953                 echo "</tr>\n";
1954                 echo "<tr>\n";
1955                 echo '<td>' . _MEMBERS_CANLOGIN;
1956                 help('canlogin');
1957                 echo "</td>\n";
1958                 echo '<td>';
1959                 $this->input_yesno('canlogin',1,10070);
1960                 echo "</td>\n";
1961                 echo "</tr>\n";
1962                 echo "<tr>\n";
1963                 echo '<td>' . _MEMBERS_NOTES . "</td>\n";
1964                 echo "<td><input name=\"notes\" maxlength=\"100\" size=\"40\" tabindex=\"10080\" /></td>\n";
1965                 echo "</tr>\n";
1966                 echo "<tr>\n";
1967                 echo '<td>' . _MEMBERS_NEW . "</td>\n";
1968                 echo '<td><input type="submit" value="' . _MEMBERS_NEW_BTN . '" tabindex="10090" onclick="return checkSubmit();" />' . "</td>\n";
1969                 echo "</tr>\n";
1970                 echo "</table>\n";
1971                 echo "</div>\n";
1972                 echo "</form>\n";
1973                 $this->pagefoot();
1974                 return;
1975         }
1976         
1977     /**
1978      * Edit member settings
1979      */
1980     function action_memberedit() {
1981         $this->action_editmembersettings(intRequestVar('memberid'));
1982     }
1983
1984         /**
1985          * @todo document this
1986          */
1987         function action_editmembersettings($memberid = '') {
1988                 global $member, $manager, $CONF;
1989                 
1990                 if ($memberid == '')
1991                 {
1992                         $memberid = $member->getID();
1993                 }
1994                 
1995                 // check if allowed
1996                 ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
1997                 
1998                 $extrahead = '<script type="text/javascript" src="javascript/numbercheck.js"></script>';
1999                 $this->pagehead($extrahead);
2000                 
2001                 // show message to go back to member overview (only for admins)
2002                 if ($member->isAdmin())
2003                 {
2004                         echo '<a href="index.php?action=usermanagement">(' ._MEMBERS_BACKTOOVERVIEW. ')</a>';
2005                 }
2006                 else
2007                 {
2008                         echo '<a href="index.php?action=overview">(' ._BACKHOME. ')</a>';
2009                 }
2010                 echo '<h2>' . _MEMBERS_EDIT . '</h2>';
2011                 
2012                 $mem =& $manager->getMember($memberid);
2013                 ?>
2014                 <form method="post" action="index.php" name="memberedit"><div>
2015                 
2016                 <input type="hidden" name="action" value="changemembersettings" />
2017                 <input type="hidden" name="memberid" value="<?php echo  $memberid; ?>" />
2018                 <?php $manager->addTicketHidden() ?>
2019                 
2020                 <table><tr>
2021                         <th colspan="2"><?php echo _MEMBERS_EDIT ?></th>
2022                 </tr><tr>
2023                         <td><?php echo _MEMBERS_DISPLAY ?> <?php help('shortnames'); ?>
2024                                 <br /><small><?php echo _MEMBERS_DISPLAY_INFO ?></small>
2025                         </td>
2026                         <td>
2027                         <?php if ($CONF['AllowLoginEdit'] || $member->isAdmin()) { ?>
2028                                 <input name="name" tabindex="10" maxlength="32" size="32" value="<?php echo  Entity::hsc($mem->getDisplayName()); ?>" />
2029                         <?php } else {
2030                                 echo Entity::hsc($member->getDisplayName());
2031                            }
2032                         ?>
2033                         </td>
2034                 </tr><tr>
2035                         <td><?php echo _MEMBERS_REALNAME ?></td>
2036                         <td><input name="realname" tabindex="20" maxlength="60" size="40" value="<?php echo  Entity::hsc($mem->getRealName()); ?>" /></td>
2037                 </tr><tr>
2038                 <?php if ($CONF['AllowLoginEdit'] || $member->isAdmin()) { ?>
2039                         <td><?php echo _MEMBERS_PWD ?></td>
2040                         <td><input type="password" tabindex="30" maxlength="40" size="16" name="password" /></td>
2041                 </tr><tr>
2042                         <td><?php echo _MEMBERS_REPPWD ?></td>
2043                         <td><input type="password" tabindex="35" maxlength="40" size="16" name="repeatpassword" /></td>
2044                 <?php } ?>
2045                 </tr><tr>
2046                         <td><?php echo _MEMBERS_EMAIL ?>
2047                                 <br /><small><?php echo _MEMBERS_EMAIL_EDIT ?></small>
2048                         </td>
2049                         <td><input name="email" tabindex="40" size="40" maxlength="60" value="<?php echo  Entity::hsc($mem->getEmail()); ?>" /></td>
2050                 </tr><tr>
2051                         <td><?php echo _MEMBERS_URL ?></td>
2052                         <td><input name="url" tabindex="50" size="40" maxlength="100" value="<?php echo  Entity::hsc($mem->getURL()); ?>" /></td>
2053                 <?php // only allow to change this by super-admins
2054                    // we don't want normal users to 'upgrade' themselves to super-admins, do we? ;-)
2055                    if ($member->isAdmin()) {
2056                 ?>
2057                         </tr><tr>
2058                                 <td><?php echo _MEMBERS_SUPERADMIN ?> <?php help('superadmin'); ?></td>
2059                                 <td><?php $this->input_yesno('admin',$mem->isAdmin(),60); ?></td>
2060                         </tr><tr>
2061                                 <td><?php echo _MEMBERS_CANLOGIN ?> <?php help('canlogin'); ?></td>
2062                                 <td><?php $this->input_yesno('canlogin',$mem->canLogin(),70,1,0,_YES,_NO,$mem->isAdmin()); ?></td>
2063                 <?php } ?>
2064                 </tr><tr>
2065                         <td><?php echo _MEMBERS_NOTES ?></td>
2066                         <td><input name="notes" tabindex="80" size="40" maxlength="100" value="<?php echo  Entity::hsc($mem->getNotes()); ?>" /></td>
2067                 </tr><tr>
2068                         <td><?php echo _MEMBERS_LOCALE ?> <?php help('locale'); ?>
2069                         </td>
2070                         <td>
2071                         
2072                                 <select name="locale" tabindex="85">
2073                                 <?php
2074                                 $locales = i18n::get_available_locale_list();
2075                                 if ( !$mem->getLocale() || !in_array($mem->getLocale(), $locales) )
2076                                 {
2077                                         echo "<option value=\"\" selected=\"selected\">" . Entity::hsc(_MEMBERS_USESITELANG) . "</option>\n";
2078                                 }
2079                                 else
2080                                 {
2081                                         echo "<option value=\"\">" . Entity::hsc(_MEMBERS_USESITELANG) . "</option>\n";
2082                                 }
2083                                 
2084                                 foreach( $locales as $locale )
2085                                 {
2086                                         if( $locale == $mem->getLocale() )
2087                                         {
2088                                                 echo "<option value=\"{$locale}\" selected=\"selected\">{$locale}</option>\n";
2089                                         }
2090                                         else
2091                                         {
2092                                                 echo "<option value=\"{$locale}\">{$locale}</option>\n";
2093                                         }
2094                                 }
2095                                 ?>
2096                                 </select>
2097                                 
2098                         </td>
2099                 </tr>
2100                 <tr>
2101                         <td><?php echo _MEMBERS_USEAUTOSAVE ?> <?php help('autosave'); ?></td>
2102                         <td><?php $this->input_yesno('autosave', $mem->getAutosave(), 87); ?></td>
2103                 </tr>
2104                 <?php
2105                         // plugin options
2106                         $this->_insertPluginOptions('member',$memberid);
2107                 ?>
2108                 <tr>
2109                         <th colspan="2"><?php echo _MEMBERS_EDIT ?></th>
2110                 </tr><tr>
2111                         <td><?php echo _MEMBERS_EDIT ?></td>
2112                         <td><input type="submit" tabindex="90" value="<?php echo _MEMBERS_EDIT_BTN ?>" onclick="return checkSubmit();" /></td>
2113                 </tr></table>
2114                 
2115                 </div></form>
2116                 
2117                 <?php
2118                         echo '<h3>',_PLUGINS_EXTRA,'</h3>';
2119                         
2120                         $manager->notify(
2121                                 'MemberSettingsFormExtras',
2122                                 array(
2123                                         'member' => &$mem
2124                                 )
2125                         );
2126                 $this->pagefoot();
2127         }
2128         
2129     /**
2130      * @todo document this
2131      */
2132     function action_changemembersettings() {
2133         global $member, $CONF, $manager;
2134
2135         $memberid = intRequestVar('memberid');
2136
2137         // check if allowed
2138         ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
2139
2140         $name           = trim(strip_tags(postVar('name')));
2141         $realname       = trim(strip_tags(postVar('realname')));
2142         $password       = postVar('password');
2143         $repeatpassword = postVar('repeatpassword');
2144         $email          = strip_tags(postVar('email'));
2145         $url            = strip_tags(postVar('url'));
2146
2147                 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
2148                 # original eregi: !eregi("^https?://", $url)
2149
2150                 // begin if: sometimes user didn't prefix the URL with http:// or https://, this cause a malformed URL. Let's fix it.
2151                 if (!preg_match('#^https?://#', $url) )
2152                 {
2153                         $url = 'http://' . $url;
2154                 }
2155
2156         $admin          = postVar('admin');
2157         $canlogin       = postVar('canlogin');
2158         $notes          = strip_tags(postVar('notes'));
2159         $locale        = postVar('locale');
2160
2161         $mem =& $manager->getMember($memberid);
2162
2163         if ($CONF['AllowLoginEdit'] || $member->isAdmin()) {
2164
2165             if (!isValidDisplayName($name))
2166                 $this->error(_ERROR_BADNAME);
2167
2168             if (($name != $mem->getDisplayName()) && Member::exists($name))
2169                 $this->error(_ERROR_NICKNAMEINUSE);
2170
2171             if ($password != $repeatpassword)
2172                 $this->error(_ERROR_PASSWORDMISMATCH);
2173
2174             if ($password && (i18n::strlen($password) < 6))
2175                 $this->error(_ERROR_PASSWORDTOOSHORT);
2176                 
2177             if ($password) {
2178                                 $pwdvalid = true;
2179                                 $pwderror = '';
2180                                 $manager->notify('PrePasswordSet',array('password' => $password, 'errormessage' => &$pwderror, 'valid' => &$pwdvalid));
2181                                 if (!$pwdvalid) {
2182                                         $this->error($pwderror);
2183                                 }
2184                         }
2185                 }
2186                 
2187                 if ( !NOTIFICATION::address_validation($email) )
2188                 {
2189                         $this->error(_ERROR_BADMAILADDRESS);
2190                 }
2191                 if ( !$realname )
2192                 {
2193                         $this->error(_ERROR_REALNAMEMISSING);
2194                 }
2195         if ( ($locale != '') && (!in_array($locale, i18n::get_available_locale_list())) )
2196             $this->error(_ERROR_NOSUCHTRANSLATION);
2197
2198         // check if there will remain at least one site member with both the logon and admin rights
2199         // (check occurs when taking away one of these rights from such a member)
2200         if (    (!$admin && $mem->isAdmin() && $mem->canLogin())
2201              || (!$canlogin && $mem->isAdmin() && $mem->canLogin())
2202            )
2203         {
2204             $r = DB::getResult('SELECT * FROM '.sql_table('member').' WHERE madmin=1 and mcanlogin=1');
2205             if ($r->rowCount() < 2)
2206                 $this->error(_ERROR_ATLEASTONEADMIN);
2207         }
2208
2209         if ($CONF['AllowLoginEdit'] || $member->isAdmin()) {
2210             $mem->setDisplayName($name);
2211             if ($password)
2212                 $mem->setPassword($password);
2213         }
2214
2215         $oldEmail = $mem->getEmail();
2216
2217         $mem->setRealName($realname);
2218         $mem->setEmail($email);
2219         $mem->setURL($url);
2220         $mem->setNotes($notes);
2221         $mem->setLocale($locale);
2222
2223
2224         // only allow super-admins to make changes to the admin status
2225         if ($member->isAdmin()) {
2226             $mem->setAdmin($admin);
2227             $mem->setCanLogin($canlogin);
2228         }
2229
2230         $autosave = postVar ('autosave');
2231         $mem->setAutosave($autosave);
2232
2233         $mem->write();
2234
2235         // store plugin options
2236         $aOptions = requestArray('plugoption');
2237         NucleusPlugin::apply_plugin_options($aOptions);
2238         $manager->notify('PostPluginOptionsUpdate',array('context' => 'member', 'memberid' => $memberid, 'member' => &$mem));
2239
2240         // if email changed, generate new password
2241         if ($oldEmail != $mem->getEmail())
2242         {
2243             $mem->sendActivationLink('addresschange', $oldEmail);
2244             // logout member
2245             $mem->newCookieKey();
2246
2247             // only log out if the member being edited is the current member.
2248             if ($member->getID() == $memberid)
2249                 $member->logout();
2250             $this->action_login(_MSG_ACTIVATION_SENT, 0);
2251             return;
2252         }
2253
2254
2255         if (  ( $mem->getID() == $member->getID() )
2256            && ( $mem->getDisplayName() != $member->getDisplayName() )
2257            ) {
2258             $mem->newCookieKey();
2259             $member->logout();
2260             $this->action_login(_MSG_LOGINAGAIN, 0);
2261         } else {
2262             $this->action_overview(_MSG_SETTINGSCHANGED);
2263         }
2264     }
2265
2266         /**
2267          * Admin::action_memberadd()
2268          * 
2269          * @param       void
2270          * @return      void
2271          * 
2272         */
2273         function action_memberadd()
2274         {
2275                 global $member, $manager;
2276                 
2277                 // check if allowed
2278                 $member->isAdmin() or $this->disallow();
2279                 
2280                 if ( postVar('password') != postVar('repeatpassword') )
2281                 {
2282                         $this->error(_ERROR_PASSWORDMISMATCH);
2283                 }
2284                 
2285                 if ( i18n::strlen(postVar('password')) < 6 )
2286                 {
2287                         $this->error(_ERROR_PASSWORDTOOSHORT);
2288                 }
2289                 
2290                 $res = Member::create(postVar('name'), postVar('realname'), postVar('password'), postVar('email'), postVar('url'), postVar('admin'), postVar('canlogin'), postVar('notes'));
2291                 if ( $res != 1 )
2292                 {
2293                         $this->error($res);
2294                 }
2295                 
2296                 // fire PostRegister event
2297                 $newmem = new Member();
2298                 $newmem->readFromName(postVar('name'));
2299                 $manager->notify('PostRegister',array('member' => &$newmem));
2300                 
2301                 $this->action_usermanagement();
2302                 return;
2303         }
2304
2305     /**
2306      * Account activation
2307      *
2308      * @author dekarma
2309      */
2310     function action_activate() {
2311
2312         $key = getVar('key');
2313         $this->_showActivationPage($key);
2314     }
2315
2316     /**
2317      * @todo document this
2318      */
2319     function _showActivationPage($key, $message = '')
2320     {
2321         global $manager;
2322
2323         // clean up old activation keys
2324         Member::cleanupActivationTable();
2325
2326         // get activation info
2327         $info = Member::getActivationInfo($key);
2328
2329         if (!$info)
2330             $this->error(_ERROR_ACTIVATE);
2331
2332         $mem =& $manager->getMember($info['vmember']);
2333
2334         if (!$mem)
2335             $this->error(_ERROR_ACTIVATE);
2336
2337         $text = '';
2338         $title = '';
2339         $bNeedsPasswordChange = true;
2340
2341         switch ($info['vtype'])
2342         {
2343             case 'forgot':
2344                 $title = _ACTIVATE_FORGOT_TITLE;
2345                 $text = _ACTIVATE_FORGOT_TEXT;
2346                 break;
2347             case 'register':
2348                 $title = _ACTIVATE_REGISTER_TITLE;
2349                 $text = _ACTIVATE_REGISTER_TEXT;
2350                 break;
2351             case 'addresschange':
2352                 $title = _ACTIVATE_CHANGE_TITLE;
2353                 $text = _ACTIVATE_CHANGE_TEXT;
2354                 $bNeedsPasswordChange = false;
2355                 Member::activate($key);
2356                 break;
2357         }
2358
2359         $aVars = array(
2360             'memberName' => Entity::hsc($mem->getDisplayName())
2361         );
2362         $title = Template::fill($title, $aVars);
2363         $text = Template::fill($text, $aVars);
2364
2365         $this->pagehead();
2366
2367             echo '<h2>' , $title, '</h2>';
2368             echo '<p>' , $text, '</p>';
2369
2370             if ($message != '')
2371             {
2372                 echo '<p class="error">',$message,'</p>';
2373             }
2374
2375             if ($bNeedsPasswordChange)
2376             {
2377                 ?>
2378                     <div><form action="index.php" method="post">
2379
2380                         <input type="hidden" name="action" value="activatesetpwd" />
2381                         <?php $manager->addTicketHidden() ?>
2382                         <input type="hidden" name="key" value="<?php echo Entity::hsc($key) ?>" />
2383
2384                         <table><tr>
2385                             <td><?php echo _MEMBERS_PWD ?></td>
2386                             <td><input type="password" maxlength="40" size="16" name="password" /></td>
2387                         </tr><tr>
2388                             <td><?php echo _MEMBERS_REPPWD ?></td>
2389                             <td><input type="password" maxlength="40" size="16" name="repeatpassword" /></td>
2390                         <?php
2391
2392                             global $manager;
2393                             $manager->notify('FormExtra', array('type' => 'activation', 'member' => $mem));
2394
2395                         ?>
2396                         </tr><tr>
2397                             <td><?php echo _MEMBERS_SETPWD ?></td>
2398                             <td><input type='submit' value='<?php echo _MEMBERS_SETPWD_BTN ?>' /></td>
2399                         </tr></table>
2400
2401
2402                     </form></div>
2403
2404                 <?php
2405
2406             }
2407
2408         $this->pagefoot();
2409
2410     }
2411
2412     /**
2413      * Account activation - set password part
2414      *
2415      * @author dekarma
2416      */
2417     function action_activatesetpwd()
2418     {
2419                 global $manager;
2420         $key = postVar('key');
2421
2422         // clean up old activation keys
2423         Member::cleanupActivationTable();
2424
2425         // get activation info
2426         $info = Member::getActivationInfo($key);
2427
2428         if (!$info || ($info['type'] == 'addresschange'))
2429             return $this->_showActivationPage($key, _ERROR_ACTIVATE);
2430
2431         $mem =& $manager->getMember($info['vmember']);
2432
2433         if (!$mem)
2434             return $this->_showActivationPage($key, _ERROR_ACTIVATE);
2435
2436         $password       = postVar('password');
2437         $repeatpassword = postVar('repeatpassword');
2438
2439         if ($password != $repeatpassword)
2440             return $this->_showActivationPage($key, _ERROR_PASSWORDMISMATCH);
2441
2442         if ($password && (i18n::strlen($password) < 6))
2443             return $this->_showActivationPage($key, _ERROR_PASSWORDTOOSHORT);
2444             
2445         if ($password) {
2446                         $pwdvalid = true;
2447                         $pwderror = '';
2448                         global $manager;
2449                         $manager->notify('PrePasswordSet',array('password' => $password, 'errormessage' => &$pwderror, 'valid' => &$pwdvalid));
2450                         if (!$pwdvalid) {
2451                                 return $this->_showActivationPage($key,$pwderror);
2452                         }
2453                 }
2454
2455         $error = '';
2456         
2457         $manager->notify('ValidateForm', array('type' => 'activation', 'member' => $mem, 'error' => &$error));
2458         if ($error != '')
2459             return $this->_showActivationPage($key, $error);
2460
2461
2462         // set password
2463         $mem->setPassword($password);
2464         $mem->write();
2465
2466         // do the activation
2467         Member::activate($key);
2468
2469         $this->pagehead();
2470             echo '<h2>',_ACTIVATE_SUCCESS_TITLE,'</h2>';
2471             echo '<p>',_ACTIVATE_SUCCESS_TEXT,'</p>';
2472         $this->pagefoot();
2473     }
2474
2475         /**
2476          * Admin::action_manageteam()
2477          * 
2478          * Manage team
2479          * @param       void
2480          * @return      void
2481          */
2482         public function action_manageteam()
2483         {
2484                 global $member, $manager;
2485                 
2486                 $blogid = intRequestVar('blogid');
2487                 
2488                 // check if allowed
2489                 $member->blogAdminRights($blogid) or $this->disallow();
2490                 
2491                 $this->pagehead();
2492                 
2493                 echo "<p><a href='index.php?action=blogsettings&amp;blogid=$blogid'>(" . _BACK_TO_BLOGSETTINGS . ")</a></p>\n";
2494                 
2495                 echo '<h2>' . _TEAM_TITLE . getBlogNameFromID($blogid) . "</h2>\n";
2496                 
2497                 echo '<h3>' . _TEAM_CURRENT . "</h3>\n";
2498                 
2499                 $query = 'SELECT tblog, tmember, mname, mrealname, memail, tadmin'
2500                        . ' FROM '.sql_table('member').', '.sql_table('team')
2501                        . ' WHERE tmember=mnumber and tblog=' . $blogid;
2502                 
2503                 $template['content'] = 'teamlist';
2504                 $template['tabindex'] = 10;
2505                 
2506                 $manager->loadClass("ENCAPSULATE");
2507                 $batch = new Batch('team');
2508                 $batch->showlist($query, 'table', $template);
2509                 
2510                 echo '<h3>' . _TEAM_ADDNEW . "</h3>\n";
2511                         
2512                 echo "<form method=\"post\" action=\"index.php\">\n";
2513                 echo "<div>\n";
2514                 
2515                 echo "<input type=\"hidden\" name=\"action\" value=\"teamaddmember\" />\n";
2516                 echo "<input type=\"hidden\" name=\"blogid\" value=\"{$blogid}\" />\n";
2517                 $manager->addTicketHidden();
2518                         
2519                 echo '<table frame="box" rules="all" summary="' . _TEAM_ADDNEW . '">' . "\n";
2520                 echo "<tr>\n";
2521                 echo '<td>' . _TEAM_CHOOSEMEMBER . "</td>\n";
2522                 
2523                 // TODO: try to make it so only non-team-members are listed
2524                 echo "<td>\n";
2525                 
2526                 $query =  'SELECT mname as text, mnumber as value FROM '.sql_table('member');
2527                 $template['name'] = 'memberid';
2528                 $template['tabindex'] = 10000;
2529                 showlist($query,'select',$template);
2530                 
2531                 echo "</td>\n";
2532                 echo "</tr>\n";
2533                 echo "<tr>\n";
2534                 echo '<td>' . _TEAM_ADMIN;
2535                 help('teamadmin');
2536                 echo "</td>\n";
2537                 echo '<td>';
2538                 $this->input_yesno('admin',0,10020);
2539                 echo "</td>\n";
2540                 echo "</tr>\n";
2541                 echo "<tr>\n";
2542                 echo '<td>' . _TEAM_ADD . "</td>\n";
2543                 echo '<td><input type="submit" value="' . _TEAM_ADD_BTN . '" tabindex="10030" />' . "</td>\n";
2544                 echo "</tr>\n";
2545                 echo "</table>\n";
2546                 
2547                 echo "</div>\n";
2548                 echo "</form>\n";
2549                 
2550                 $this->pagefoot();
2551                 return;
2552         }
2553         
2554     /**
2555      * Add member to team
2556      */
2557     function action_teamaddmember() {
2558         global $member, $manager;
2559
2560         $memberid = intPostVar('memberid');
2561         $blogid = intPostVar('blogid');
2562         $admin = intPostVar('admin');
2563
2564         // check if allowed
2565         $member->blogAdminRights($blogid) or $this->disallow();
2566
2567         $blog =& $manager->getBlog($blogid);
2568         if (!$blog->addTeamMember($memberid, $admin))
2569             $this->error(_ERROR_ALREADYONTEAM);
2570
2571         $this->action_manageteam();
2572
2573     }
2574
2575     /**
2576      * @todo document this
2577      */
2578     function action_teamdelete() {
2579         global $member, $manager;
2580
2581         $memberid = intRequestVar('memberid');
2582         $blogid = intRequestVar('blogid');
2583
2584         // check if allowed
2585         $member->blogAdminRights($blogid) or $this->disallow();
2586
2587         $teammem =& $manager->getMember($memberid);
2588         $blog =& $manager->getBlog($blogid);
2589
2590         $this->pagehead();
2591         ?>
2592             <h2><?php echo _DELETE_CONFIRM ?></h2>
2593
2594             <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>
2595             </p>
2596
2597
2598             <form method="post" action="index.php"><div>
2599             <input type="hidden" name="action" value="teamdeleteconfirm" />
2600             <?php $manager->addTicketHidden() ?>
2601             <input type="hidden" name="memberid" value="<?php echo  $memberid; ?>" />
2602             <input type="hidden" name="blogid" value="<?php echo  $blogid; ?>" />
2603             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN ?>" />
2604             </div></form>
2605         <?php
2606         $this->pagefoot();
2607     }
2608
2609     /**
2610      * @todo document this
2611      */
2612     function action_teamdeleteconfirm() {
2613         global $member;
2614
2615         $memberid = intRequestVar('memberid');
2616         $blogid = intRequestVar('blogid');
2617
2618         $error = $this->deleteOneTeamMember($blogid, $memberid);
2619         if ($error)
2620             $this->error($error);
2621
2622
2623         $this->action_manageteam();
2624     }
2625
2626     /**
2627      * @todo document this
2628      */
2629     function deleteOneTeamMember($blogid, $memberid) {
2630         global $member, $manager;
2631
2632         $blogid = intval($blogid);
2633         $memberid = intval($memberid);
2634
2635         // check if allowed
2636         if (!$member->blogAdminRights($blogid))
2637             return _ERROR_DISALLOWED;
2638
2639         // check if: - there remains at least one blog admin
2640         //           - (there remains at least one team member)
2641         $tmem =& $manager->getMember($memberid);
2642
2643         $manager->notify('PreDeleteTeamMember', array('member' => &$tmem, 'blogid' => $blogid));
2644
2645         if ($tmem->isBlogAdmin($blogid)) {
2646             // check if there are more blog members left and at least one admin
2647             // (check for at least two admins before deletion)
2648             $query = 'SELECT * FROM '.sql_table('team') . ' WHERE tblog='.$blogid.' and tadmin=1';
2649             $r = DB::getResult($query);
2650             if ($r->rowCount() < 2)
2651                 return _ERROR_ATLEASTONEBLOGADMIN;
2652         }
2653
2654         $query = 'DELETE FROM '.sql_table('team')." WHERE tblog=$blogid and tmember=$memberid";
2655         DB::execute($query);
2656
2657         $manager->notify('PostDeleteTeamMember', array('member' => &$tmem, 'blogid' => $blogid));
2658
2659         return '';
2660     }
2661
2662     /**
2663      * @todo document this
2664      */
2665     function action_teamchangeadmin() {
2666         global $manager, $member;
2667
2668         $blogid = intRequestVar('blogid');
2669         $memberid = intRequestVar('memberid');
2670
2671         // check if allowed
2672         $member->blogAdminRights($blogid) or $this->disallow();
2673
2674         $mem =& $manager->getMember($memberid);
2675
2676         // don't allow when there is only one admin at this moment
2677         if ($mem->isBlogAdmin($blogid)) {
2678             $r = DB::getResult('SELECT * FROM '.sql_table('team') . " WHERE tblog=$blogid and tadmin=1");
2679             if ($r->rowCount() == 1)
2680                 $this->error(_ERROR_ATLEASTONEBLOGADMIN);
2681         }
2682
2683         if ($mem->isBlogAdmin($blogid))
2684             $newval = 0;
2685         else
2686             $newval = 1;
2687
2688         $query = 'UPDATE '.sql_table('team') ." SET tadmin=$newval WHERE tblog=$blogid and tmember=$memberid";
2689         DB::execute($query);
2690
2691         // only show manageteam if member did not change its own admin privileges
2692         if ($member->isBlogAdmin($blogid))
2693             $this->action_manageteam();
2694         else
2695             $this->action_overview(_MSG_ADMINCHANGED);
2696     }
2697         
2698         /**
2699          * Admin::action_blogsettings()
2700          * 
2701          * @param       void
2702          * @return      void
2703          */
2704         public function action_blogsettings()
2705         {
2706                 global $member, $manager;
2707                 
2708                 $blogid = intRequestVar('blogid');
2709                 
2710                 // check if allowed
2711                 $member->blogAdminRights($blogid) or $this->disallow();
2712                 
2713                 $blog =& $manager->getBlog($blogid);
2714                 
2715                 $extrahead = "<script type=\"text/javascript\" src=\"javascript/numbercheck.js\"></script>\n";
2716                 $this->pagehead($extrahead);
2717                 
2718                 echo '<p><a href="index.php?action=overview">(' . _BACKHOME . ")</a></p>\n";
2719                 echo '<h2>' . _EBLOG_TITLE . ": '{$this->bloglink($blog)}'</h2>\n";
2720                 
2721                 echo '<h3>' . _EBLOG_TEAM_TITLE . "</h3>\n";
2722                 
2723                 echo '<p>' . _EBLOG_CURRENT_TEAM_MEMBER;
2724                 
2725                 $query = "SELECT mname, mrealname FROM %s, %s WHERE mnumber=tmember AND tblog=%d;";
2726                 $query = sprintf($query, sql_table('member'), sql_table('team'), (integer) $blogid);
2727                 $res = DB::getResult($query);
2728                 $aMemberNames = array();
2729                 foreach ( $res as $row )
2730                 {
2731                         $aMemberNames[] = Entity::hsc($row['mname']) . ' (' . Entity::hsc($row['mrealname']). ')';
2732                 }
2733                 echo implode(',', $aMemberNames);
2734                         
2735                 echo "</p>\n";
2736                 echo '<p>';
2737                 echo '<a href="index.php?action=manageteam&amp;blogid=' . $blogid . '">' . _EBLOG_TEAM_TEXT . '</a>';
2738                 echo "</p>\n";
2739                 
2740                 echo '<h3>' . _EBLOG_SETTINGS_TITLE . "</h3>\n";
2741                 
2742                 echo "<form method=\"post\" action=\"index.php\">\n";
2743                 echo "<div>\n";
2744                 
2745                 echo "<input type=\"hidden\" name=\"action\" value=\"blogsettingsupdate\" />\n";
2746                 $manager->addTicketHidden() . "\n";
2747                 echo "<input type=\"hidden\" name=\"blogid\" value=\"{$blogid}\" />\n";
2748                 
2749                 echo '<table frame="box" rules="all" summary="' . _EBLOG_SETTINGS_TITLE . '">' . "\n";
2750                 echo "<tfoot>\n";
2751                 echo "<tr>\n";
2752                 echo '<th colspan="2">' . _EBLOG_CHANGE . "</th>\n";
2753                 echo "</tr>\n";
2754                 echo "<tr>\n";
2755                 echo '<td>' . _EBLOG_CHANGE . "</td>\n";
2756                 echo '<td><input type="submit" tabindex="130" value="' . _EBLOG_CHANGE_BTN . '" onclick="return checkSubmit();" />' . "</td>\n";
2757                 echo "</tr>\n";
2758                 echo "</tfoot>\n";
2759                 echo "<tbody>\n";
2760                 echo "<tr>\n";
2761                 echo '<td>' . _EBLOG_NAME . "</td>\n";
2762                 echo '<td><input name="name" tabindex="10" size="40" maxlength="60" value="' . Entity::hsc($blog->getName()) . '" />' . "</td>\n";
2763                 echo "</tr>\n";
2764                 echo "<tr>\n";
2765                 echo '<td>' . _EBLOG_SHORTNAME;
2766                 help('shortblogname');
2767                 echo _EBLOG_SHORTNAME_EXTRA;
2768                 echo "</td>\n";
2769                 echo '<td><input name="shortname" tabindex="20" maxlength="15" size="15" value="' . Entity::hsc($blog->getShortName()) .'" />' . "</td>\n";
2770                 echo "</tr>\n";
2771                 echo "<tr>\n";
2772                 echo '<td>' . _EBLOG_DESC . "</td>\n";
2773                 echo '<td><input name="desc" tabindex="30" maxlength="200" size="40" value="' . Entity::hsc($blog->getDescription()) . '" />' . "</td>\n";
2774                 echo "</tr>\n";
2775                 echo "<tr>\n";
2776                 echo '<td>' . _EBLOG_URL . "</td>\n";
2777                 echo '<td><input name="url" tabindex="40" size="40" maxlength="100" value="' . Entity::hsc($blog->getURL()) . '" />' . "</td>\n";
2778                 echo "</tr>\n";
2779                 echo "<tr>\n";
2780                 echo '<td>' . _EBLOG_DEFSKIN;
2781                 help('blogdefaultskin');
2782                 echo "</td>\n";
2783                 echo "<td>\n";
2784                 
2785                 $query = 'SELECT sdname as text, sdnumber as value FROM ' . sql_table('skin_desc');
2786                 $template['name'] = 'defskin';
2787                 $template['selected'] = $blog->getDefaultSkin();
2788                 $template['tabindex'] = 50;
2789                 showlist($query, 'select', $template);
2790                 
2791                 echo "</td>\n";
2792                 echo "</tr>\n";
2793                 echo "<tr>\n";
2794                 echo '<td>' . _EBLOG_LINEBREAKS;
2795                 help('convertbreaks');
2796                 echo "</td>\n";
2797                 echo '<td>';
2798                 $this->input_yesno('convertbreaks',$blog->convertBreaks(),55);
2799                 echo "</td>\n";
2800                 echo "</tr>\n";
2801                 
2802                 echo "<tr>\n";
2803                 echo '<td>' . _EBLOG_ALLOWPASTPOSTING;
2804                 help('allowpastposting');
2805                 echo "</td>\n";
2806                 echo '<td>';
2807                 $this->input_yesno('allowpastposting',$blog->allowPastPosting(),57);
2808                 echo "</td>\n";
2809                 echo "</tr>\n";
2810                 echo "<tr>\n";
2811                 echo '<td>' . _EBLOG_DISABLECOMMENTS;
2812                 echo "</td>\n";
2813                 echo '<td>';
2814                 $this->input_yesno('comments', $blog->commentsEnabled(), 60);
2815                 echo "</td>\n";
2816                 echo "</tr>\n";
2817                 echo "<tr>\n";
2818                 echo '<td>' . _EBLOG_ANONYMOUS . "</td>\n";
2819                 echo '<td>';
2820                 $this->input_yesno('public',$blog->isPublic(),70);
2821                 echo "</td>\n";
2822                 echo "</tr>\n";
2823                 echo "<tr>\n";
2824                 echo '<td>' . _EBLOG_REQUIREDEMAIL . "</td>\n";
2825                 echo '<td>';
2826                 $this->input_yesno('reqemail', $blog->emailRequired(),72);
2827                 echo "</td>\n";
2828                 echo "</tr>\n";
2829                 echo "<tr>\n";
2830                 echo '<td>' . _EBLOG_NOTIFY;
2831                 help('blognotify');
2832                 echo "</td>\n";
2833                 echo '<td><input name="notify" tabindex="80" maxlength="128" size="40" value="' . Entity::hsc($blog->getNotifyAddress()) . '" />' . "</td>\n";
2834                 echo "</tr>\n";
2835                 
2836                 echo "<tr>\n";
2837                 echo '<td>' . _EBLOG_NOTIFY_ON . "</td>\n";
2838                 echo "<td>\n";
2839                 
2840                 if ( !$blog->notifyOnComment() )
2841                 {
2842                         echo "<input name=\"notifyComment\" value=\"3\" type=\"checkbox\" tabindex=\"81\" id=\"notifyComment\" />\n";
2843                 }
2844                 else
2845                 {
2846                         echo "<input name=\"notifyComment\" value=\"3\" type=\"checkbox\" tabindex=\"81\" id=\"notifyComment\" checked=\"checked\"/>\n";
2847                 }
2848                 echo '<label for="notifyComment">' . _EBLOG_NOTIFY_COMMENT . "</label><br />\n";
2849                 
2850                 if ( !$blog->notifyOnVote() )
2851                 {
2852                         echo "<input name=\"notifyVote\" value=\"5\" type=\"checkbox\" tabindex=\"82\" id=\"notifyVote\" />\n";
2853                 }
2854                 else
2855                 {
2856                         echo "<input name=\"notifyVote\" value=\"5\" type=\"checkbox\" tabindex=\"82\" id=\"notifyVote\" checked=\"checked\" />\n";
2857                 }
2858                 
2859                 echo '<label for="notifyVote">' . _EBLOG_NOTIFY_KARMA . "</label><br />\n";
2860                 
2861                 if ( !$blog->notifyOnNewItem() )
2862                 {
2863                         echo "<input name=\"notifyNewItem\" value=\"7\" type=\"checkbox\" tabindex=\"83\" id=\"notifyNewItem\" />\n";
2864                 
2865                 }
2866                 else
2867                 {
2868                         echo "<input name=\"notifyNewItem\" value=\"7\" type=\"checkbox\" tabindex=\"83\" id=\"notifyNewItem\" checked=\"checked\" />\n";
2869                 }
2870                 
2871                 echo '<label for="notifyNewItem">' . _EBLOG_NOTIFY_ITEM . "</label>\n";
2872                 
2873                 echo "</td>\n";
2874                 echo "</tr>\n";
2875                 echo "<tr>\n";
2876                 echo '<td>' . _EBLOG_MAXCOMMENTS;
2877                 help('blogmaxcomments');
2878                 echo "</td>\n";
2879                 echo '<td><input name="maxcomments" tabindex="90" size="3" value="' . Entity::hsc($blog->getMaxComments()) . '" />' . "</td>\n";
2880                 echo "</tr>\n";
2881                 echo "<tr>\n";
2882                 echo '<td>' . _EBLOG_UPDATE;
2883                 help('blogupdatefile');
2884                 echo "</td>\n";
2885                 echo '<td><input name="update" tabindex="100" size="40" maxlength="60" value="' . Entity::hsc($blog->getUpdateFile()) .'" />' . "</td>\n";
2886                 echo "</tr>\n";
2887                 echo "<tr>\n";
2888                 echo '<td>' . _EBLOG_DEFCAT . "</td>\n";
2889                 echo "<td>\n";
2890                 $query =  "SELECT cname as text, catid as value FROM %s WHERE cblog=%d;";
2891                 $query = sprintf($query, sql_table('category'), (integer) $blog->getID());
2892                 $template['name'] = 'defcat';
2893                 $template['selected'] = $blog->getDefaultCategory();
2894                 $template['tabindex'] = 110;
2895                 showlist($query, 'select', $template);
2896                 echo "</td>\n";
2897                 echo "</tr>\n";
2898                 echo "<tr>\n";
2899                 echo '<td>' . _EBLOG_OFFSET;
2900                 help('blogtimeoffset');
2901                 echo "<br />\n";
2902                 echo _EBLOG_STIME;
2903                 echo ' <b>' . i18n::formatted_datetime('%H:%M', time()) . '</b><br />';
2904                 echo _EBLOG_BTIME;
2905                 echo '<b>' . i18n::formatted_datetime('%H:%M', $blog->getCorrectTime()) . '</b>';
2906                 echo "</td>\n";
2907                 echo '<td><input name="timeoffset" tabindex="120" size="3" value="' . Entity::hsc($blog->getTimeOffset()) .'" />' . "</td>\n";
2908                 echo "</tr>\n";
2909                 echo "<tr>\n";
2910                 echo '<td>' . _EBLOG_SEARCH;
2911                 help('blogsearchable');
2912                 echo "</td>\n";
2913                 echo '<td>';
2914                 $this->input_yesno('searchable', $blog->getSearchable(), 122);
2915                 echo "</td>\n";
2916                 echo "</tr>\n";
2917                 
2918                 // plugin options
2919                 $this->_insertPluginOptions('blog', $blogid);
2920                 
2921                 echo "</tbody>\n";
2922                 echo "</table>\n";
2923                 
2924                 echo "</div>\n";
2925                 echo "</form>\n";
2926                 
2927                 echo '<h3>' . _EBLOG_CAT_TITLE . "</h3>\n";
2928                 
2929                 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog='.$blog->getID().' ORDER BY cname';
2930                 $template['content'] = 'categorylist';
2931                 $template['tabindex'] = 200;
2932                 
2933                 $manager->loadClass("ENCAPSULATE");
2934                 $batch = new Batch('category');
2935                 $batch->showlist($query,'table',$template);
2936                 
2937                 echo "<form action=\"index.php\" method=\"post\">\n";
2938                 echo "<div>\n";
2939                 echo "<input name=\"action\" value=\"categorynew\" type=\"hidden\" />\n";
2940                 $manager->addTicketHidden() . "\n";
2941                 echo "<input name=\"blogid\" value=\"{$blog->getID()}\" type=\"hidden\" />\n";
2942                 
2943                 echo '<table frame="box" rules="all" summary="' . _EBLOG_CAT_CREATE . '">' . "\n";
2944                 echo "<thead>\n";
2945                 echo "<tr>\n";
2946                 echo '<th colspan="2">' . _EBLOG_CAT_CREATE . "</th>\n";
2947                 echo "</tr>\n";
2948                 echo "</thead>\n";
2949                 echo "<tbody>\n";
2950                 echo "<tr>\n";
2951                 echo '<td>' . _EBLOG_CAT_NAME . "</td>\n";
2952                 echo "<td><input name=\"cname\" size=\"40\" maxlength=\"40\" tabindex=\"300\" /></td>\n";
2953                 echo "</tr>\n";
2954                 echo "<tr>\n";
2955                 echo '<td>' . _EBLOG_CAT_DESC . "</td>\n";
2956                 echo "<td><input name=\"cdesc\" size=\"40\" maxlength=\"200\" tabindex=\"310\" /></td>\n";
2957                 echo "</tr>\n";
2958                 echo "<tr>\n";
2959                 echo '<td>' . _EBLOG_CAT_CREATE . "</td>\n";
2960                 echo '<td><input type="submit" value="' . _EBLOG_CAT_CREATE . '" tabindex="320" />' . "</td>\n";
2961                 echo "</tr>\n";
2962                 echo "</tbody>\n";
2963                 echo "</table>\n";
2964                 echo "</div>\n";
2965                 echo "</form>\n";
2966                 
2967                 echo '<h3>' . _PLUGINS_EXTRA . "</h3>\n";
2968                 $manager->notify('BlogSettingsFormExtras', array('blog' => &$blog));
2969                 
2970                 $this->pagefoot();
2971                 return;
2972         }
2973
2974     /**
2975      * @todo document this
2976      */
2977     function action_categorynew() {
2978         global $member, $manager;
2979
2980         $blogid = intRequestVar('blogid');
2981
2982         $member->blogAdminRights($blogid) or $this->disallow();
2983
2984         $cname = postVar('cname');
2985         $cdesc = postVar('cdesc');
2986
2987         if (!isValidCategoryName($cname))
2988             $this->error(_ERROR_BADCATEGORYNAME);
2989
2990         $query = 'SELECT * FROM '.sql_table('category') . ' WHERE cname=' . DB::quoteValue($cname).' and cblog=' . intval($blogid);
2991         $res = DB::getResult($query);
2992         if ($res->rowCount() > 0)
2993             $this->error(_ERROR_DUPCATEGORYNAME);
2994
2995         $blog       =& $manager->getBlog($blogid);
2996         $newCatID   =  $blog->createNewCategory($cname, $cdesc);
2997
2998         $this->action_blogsettings();
2999     }
3000
3001     /**
3002      * @todo document this
3003      */
3004     function action_categoryedit($catid = '', $blogid = '', $desturl = '') {
3005         global $member, $manager;
3006
3007         if ($blogid == '')
3008             $blogid = intGetVar('blogid');
3009         else
3010             $blogid = intval($blogid);
3011         if ($catid == '')
3012             $catid = intGetVar('catid');
3013         else
3014             $catid = intval($catid);
3015
3016         $member->blogAdminRights($blogid) or $this->disallow();
3017
3018         $res = DB::getRow('SELECT * FROM '.sql_table('category')." WHERE cblog=$blogid AND catid=$catid");
3019
3020         $cname = $res['cname'];
3021         $cdesc = $res['cdesc'];
3022
3023         $extrahead = '<script type="text/javascript" src="javascript/numbercheck.js"></script>';
3024         $this->pagehead($extrahead);
3025
3026         echo "<p><a href='index.php?action=blogsettings&amp;blogid=$blogid'>(",_BACK_TO_BLOGSETTINGS,")</a></p>";
3027
3028         ?>
3029         <h2><?php echo _EBLOG_CAT_UPDATE ?> '<?php echo Entity::hsc($cname) ?>'</h2>
3030         <form method='post' action='index.php'><div>
3031         <input name="blogid" type="hidden" value="<?php echo $blogid ?>" />
3032         <input name="catid" type="hidden" value="<?php echo $catid ?>" />
3033         <input name="desturl" type="hidden" value="<?php echo Entity::hsc($desturl) ?>" />
3034         <input name="action" type="hidden" value="categoryupdate" />
3035         <?php $manager->addTicketHidden(); ?>
3036
3037         <table><tr>
3038             <th colspan="2"><?php echo _EBLOG_CAT_UPDATE ?></th>
3039         </tr><tr>
3040             <td><?php echo _EBLOG_CAT_NAME ?></td>
3041             <td><input type="text" name="cname" value="<?php echo Entity::hsc($cname) ?>" size="40" maxlength="40" /></td>
3042         </tr><tr>
3043             <td><?php echo _EBLOG_CAT_DESC ?></td>
3044             <td><input type="text" name="cdesc" value="<?php echo Entity::hsc($cdesc) ?>" size="40" maxlength="200" /></td>
3045         </tr>
3046         <?php
3047             // insert plugin options
3048             $this->_insertPluginOptions('category',$catid);
3049         ?>
3050         <tr>
3051             <th colspan="2"><?php echo _EBLOG_CAT_UPDATE ?></th>
3052         </tr><tr>
3053             <td><?php echo _EBLOG_CAT_UPDATE ?></td>
3054             <td><input type="submit" value="<?php echo _EBLOG_CAT_UPDATE_BTN ?>" /></td>
3055         </tr></table>
3056
3057         </div></form>
3058         <?php
3059         $this->pagefoot();
3060     }
3061
3062     /**
3063      * @todo document this
3064      */
3065     function action_categoryupdate() {
3066         global $member, $manager;
3067
3068         $blogid = intPostVar('blogid');
3069         $catid = intPostVar('catid');
3070         $cname = postVar('cname');
3071         $cdesc = postVar('cdesc');
3072         $desturl = postVar('desturl');
3073
3074         $member->blogAdminRights($blogid) or $this->disallow();
3075
3076         if (!isValidCategoryName($cname))
3077             $this->error(_ERROR_BADCATEGORYNAME);
3078
3079         $query = 'SELECT * FROM '.sql_table('category').' WHERE cname=' . DB::quoteValue($cname).' and cblog=' . intval($blogid) . " and not(catid=$catid)";
3080         $res = DB::getResult($query);
3081         if ($res->rowCount() > 0)
3082             $this->error(_ERROR_DUPCATEGORYNAME);
3083
3084         $query =  'UPDATE '.sql_table('category').' SET'
3085                . ' cname=' . DB::quoteValue($cname) . ','
3086                . ' cdesc=' . DB::quoteValue($cdesc)
3087                . ' WHERE catid=' . $catid;
3088
3089         DB::execute($query);
3090
3091         // store plugin options
3092         $aOptions = requestArray('plugoption');
3093         NucleusPlugin::apply_plugin_options($aOptions);
3094         $manager->notify('PostPluginOptionsUpdate',array('context' => 'category', 'catid' => $catid));
3095
3096
3097         if ($desturl) {
3098             redirect($desturl);
3099             exit;
3100         } else {
3101             $this->action_blogsettings();
3102         }
3103     }
3104
3105     /**
3106      * @todo document this
3107      */
3108     function action_categorydelete() {
3109         global $member, $manager;
3110
3111         $blogid = intRequestVar('blogid');
3112         $catid = intRequestVar('catid');
3113
3114         $member->blogAdminRights($blogid) or $this->disallow();
3115
3116         $blog =& $manager->getBlog($blogid);
3117
3118         // check if the category is valid
3119         if (!$blog->isValidCategory($catid))
3120             $this->error(_ERROR_NOSUCHCATEGORY);
3121
3122         // don't allow deletion of default category
3123         if ($blog->getDefaultCategory() == $catid)
3124             $this->error(_ERROR_DELETEDEFCATEGORY);
3125
3126         // check if catid is the only category left for blogid
3127         $query = 'SELECT catid FROM '.sql_table('category').' WHERE cblog=' . $blogid;
3128         $res = DB::getResult($query);
3129         if ($res->rowCount() == 1)
3130             $this->error(_ERROR_DELETELASTCATEGORY);
3131
3132
3133         $this->pagehead();
3134         ?>
3135             <h2><?php echo _DELETE_CONFIRM ?></h2>
3136
3137             <div>
3138             <?php echo _CONFIRMTXT_CATEGORY ?><b><?php echo  Entity::hsc($blog->getCategoryName($catid)) ?></b>
3139             </div>
3140
3141             <form method="post" action="index.php"><div>
3142             <input type="hidden" name="action" value="categorydeleteconfirm" />
3143             <?php $manager->addTicketHidden() ?>
3144             <input type="hidden" name="blogid" value="<?php echo $blogid ?>" />
3145             <input type="hidden" name="catid" value="<?php echo $catid ?>" />
3146             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN ?>" />
3147             </div></form>
3148         <?php
3149         $this->pagefoot();
3150     }
3151
3152     /**
3153      * @todo document this
3154      */
3155     function action_categorydeleteconfirm() {
3156         global $member, $manager;
3157
3158         $blogid = intRequestVar('blogid');
3159         $catid = intRequestVar('catid');
3160
3161         $member->blogAdminRights($blogid) or $this->disallow();
3162
3163         $error = $this->deleteOneCategory($catid);
3164         if ($error)
3165             $this->error($error);
3166
3167         $this->action_blogsettings();
3168     }
3169         
3170         /**
3171          * Admin::deleteOneCategory()
3172          * Delete a category by its id
3173          * 
3174          * @param       String  $catid  category id for deleting
3175          * @return      Void
3176          */
3177         function deleteOneCategory($catid)
3178         {
3179                 global $manager, $member;
3180                 
3181                 $catid = intval($catid);
3182                 $blogid = getBlogIDFromCatID($catid);
3183                 
3184                 if ( !$member->blogAdminRights($blogid) )
3185                 {
3186                         return ERROR_DISALLOWED;
3187                 }
3188                 
3189                 // get blog
3190                 $blog =& $manager->getBlog($blogid);
3191                 
3192                 // check if the category is valid
3193                 if ( !$blog || !$blog->isValidCategory($catid) )
3194                 {
3195                         return _ERROR_NOSUCHCATEGORY;
3196                 }
3197                 
3198                 $destcatid = $blog->getDefaultCategory();
3199                 
3200                 // don't allow deletion of default category
3201                 if ( $blog->getDefaultCategory() == $catid )
3202                 {
3203                         return _ERROR_DELETEDEFCATEGORY;
3204                 }
3205                 
3206                 // check if catid is the only category left for blogid
3207                 $query = 'SELECT catid FROM '.sql_table('category').' WHERE cblog=' . $blogid;
3208                 $res = DB::getResult($query);
3209                 if ( $res->rowCount() == 1 )
3210                 {
3211                         return _ERROR_DELETELASTCATEGORY;
3212                 }
3213                 
3214                 $manager->notify('PreDeleteCategory', array('catid' => $catid));
3215                 
3216                 // change category for all items to the default category
3217                 $query = 'UPDATE '.sql_table('item')." SET icat=$destcatid WHERE icat=$catid";
3218                 DB::execute($query);
3219                 
3220                 // delete all associated plugin options
3221                 NucleusPlugin::delete_option_values('category', $catid);
3222                 
3223                 // delete category
3224                 $query = 'DELETE FROM '.sql_table('category').' WHERE catid=' .$catid;
3225                 DB::execute($query);
3226                 
3227                 $manager->notify('PostDeleteCategory', array('catid' => $catid));
3228                 return;
3229         }
3230         
3231         /**
3232          * Admin::action_blogsettingsupdate
3233          * Updating blog settings
3234          * 
3235          * @param       Void
3236          * @return      Void
3237          */
3238         function action_blogsettingsupdate()
3239         {
3240                 global $member, $manager;
3241                 
3242                 $blogid = intRequestVar('blogid');
3243                 
3244                 $member->blogAdminRights($blogid) or $this->disallow();
3245                 
3246                 $blog =& $manager->getBlog($blogid);
3247                 
3248                 $notify_address = trim(postVar('notify'));
3249                 $shortname              = trim(postVar('shortname'));
3250                 $updatefile     = trim(postVar('update'));
3251                 
3252                 $notifyComment  = intPostVar('notifyComment');
3253                 $notifyVote             = intPostVar('notifyVote');
3254                 $notifyNewItem  = intPostVar('notifyNewItem');
3255                 
3256                 if ( $notifyComment == 0 )
3257                 {
3258                         $notifyComment = 1;
3259                 }
3260                 if ( $notifyVote == 0 )
3261                 {
3262                         $notifyVote = 1;
3263                 }
3264                 if ( $notifyNewItem == 0 )
3265                 {
3266                         $notifyNewItem = 1;
3267                 }
3268                 $notifyType = $notifyComment * $notifyVote * $notifyNewItem;
3269                 
3270                 if ( $notify_address && !NOTIFICATION::address_validation($notify_address) )
3271                 {
3272                         $this->error(_ERROR_BADNOTIFY);
3273                 }
3274                 
3275                 if ( !isValidShortName($shortname) )
3276                 {
3277                         $this->error(_ERROR_BADSHORTBLOGNAME);
3278                 }
3279                 
3280                 if ( ($blog->getShortName() != $shortname) && $manager->existsBlog($shortname) )
3281                 {
3282                         $this->error(_ERROR_DUPSHORTBLOGNAME);
3283                 }
3284                 // check if update file is writable
3285                 if ( $updatefile && !is_writeable($updatefile) )
3286                 {
3287                         $this->error(_ERROR_UPDATEFILE);
3288                 }
3289                 
3290                 $blog->setName(trim(postVar('name')));
3291                 $blog->setShortName($shortname);
3292                 $blog->setNotifyAddress($notify_address);
3293                 $blog->setNotifyType($notifyType);
3294                 $blog->setMaxComments(postVar('maxcomments'));
3295                 $blog->setCommentsEnabled(postVar('comments'));
3296                 $blog->setTimeOffset(postVar('timeoffset'));
3297                 $blog->setUpdateFile($updatefile);
3298                 $blog->setURL(trim(postVar('url')));
3299                 $blog->setDefaultSkin(intPostVar('defskin'));
3300                 $blog->setDescription(trim(postVar('desc')));
3301                 $blog->setPublic(postVar('public'));
3302                 $blog->setConvertBreaks(intPostVar('convertbreaks'));
3303                 $blog->setAllowPastPosting(intPostVar('allowpastposting'));
3304                 $blog->setDefaultCategory(intPostVar('defcat'));
3305                 $blog->setSearchable(intPostVar('searchable'));
3306                 $blog->setEmailRequired(intPostVar('reqemail'));
3307                 $blog->writeSettings();
3308                 
3309                 // store plugin options
3310                 $aOptions = requestArray('plugoption');
3311                 NucleusPlugin::apply_plugin_options($aOptions);
3312                 $manager->notify('PostPluginOptionsUpdate',array('context' => 'blog', 'blogid' => $blogid, 'blog' => &$blog));
3313                 
3314                 $this->action_overview(_MSG_SETTINGSCHANGED);
3315                 return;
3316         }
3317
3318     /**
3319      * @todo document this
3320      */
3321     function action_deleteblog() {
3322         global $member, $CONF, $manager;
3323
3324         $blogid = intRequestVar('blogid');
3325
3326         $member->blogAdminRights($blogid) or $this->disallow();
3327
3328         // check if blog is default blog
3329         if ($CONF['DefaultBlog'] == $blogid)
3330             $this->error(_ERROR_DELDEFBLOG);
3331
3332         $blog =& $manager->getBlog($blogid);
3333
3334         $this->pagehead();
3335         ?>
3336             <h2><?php echo _DELETE_CONFIRM ?></h2>
3337
3338             <p><?php echo _WARNINGTXT_BLOGDEL ?>
3339             </p>
3340
3341             <div>
3342             <?php echo _CONFIRMTXT_BLOG ?><b><?php echo  Entity::hsc($blog->getName()) ?></b>
3343             </div>
3344
3345             <form method="post" action="index.php"><div>
3346             <input type="hidden" name="action" value="deleteblogconfirm" />
3347             <?php $manager->addTicketHidden() ?>
3348             <input type="hidden" name="blogid" value="<?php echo  $blogid; ?>" />
3349             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN ?>" />
3350             </div></form>
3351         <?php
3352         $this->pagefoot();
3353     }
3354         
3355         /**
3356          * Admin::action_deleteblogconfirm()
3357          * Delete Blog
3358          * 
3359          * @param       Void
3360          * @return      Void
3361          */
3362         function action_deleteblogconfirm()
3363         {
3364                 global $member, $CONF, $manager;
3365                 
3366                 $blogid = intRequestVar('blogid');
3367                 $manager->notify('PreDeleteBlog', array('blogid' => $blogid));
3368                 $member->blogAdminRights($blogid) or $this->disallow();
3369                 
3370                 // check if blog is default blog
3371                 if ( $CONF['DefaultBlog'] == $blogid )
3372                 {
3373                         $this->error(_ERROR_DELDEFBLOG);
3374                 }
3375                 
3376                 // delete all comments
3377                 $query = 'DELETE FROM '.sql_table('comment').' WHERE cblog='.$blogid;
3378                 DB::execute($query);
3379                 
3380                 // delete all items
3381                 $query = 'DELETE FROM '.sql_table('item').' WHERE iblog='.$blogid;
3382                 DB::execute($query);
3383                 
3384                 // delete all team members
3385                 $query = 'DELETE FROM '.sql_table('team').' WHERE tblog='.$blogid;
3386                 DB::execute($query);
3387                 
3388                 // delete all bans
3389                 $query = 'DELETE FROM '.sql_table('ban').' WHERE blogid='.$blogid;
3390                 DB::execute($query);
3391                 
3392                 // delete all categories
3393                 $query = 'DELETE FROM '.sql_table('category').' WHERE cblog='.$blogid;
3394                 DB::execute($query);
3395                 
3396                 // delete all associated plugin options
3397                 NucleusPlugin::delete_option_values('blog', $blogid);
3398                 
3399                 // delete the blog itself
3400                 $query = 'DELETE FROM '.sql_table('blog').' WHERE bnumber='.$blogid;
3401                 DB::execute($query);
3402                 
3403                 $manager->notify('PostDeleteBlog', array('blogid' => $blogid));
3404                 
3405                 $this->action_overview(_DELETED_BLOG);
3406                 return;
3407         }
3408         
3409     /**
3410      * @todo document this
3411      */
3412     function action_memberdelete() {
3413         global $member, $manager;
3414
3415         $memberid = intRequestVar('memberid');
3416
3417         ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
3418
3419         $mem =& $manager->getMember($memberid);
3420
3421         $this->pagehead();
3422         ?>
3423             <h2><?php echo _DELETE_CONFIRM ?></h2>
3424
3425             <p><?php echo _CONFIRMTXT_MEMBER ?><b><?php echo Entity::hsc($mem->getDisplayName()) ?></b>
3426             </p>
3427
3428             <p>
3429             <?php echo _WARNINGTXT_NOTDELMEDIAFILES ?>
3430             </p>
3431
3432             <form method="post" action="index.php"><div>
3433             <input type="hidden" name="action" value="memberdeleteconfirm" />
3434             <?php $manager->addTicketHidden() ?>
3435             <input type="hidden" name="memberid" value="<?php echo  $memberid; ?>" />
3436             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN ?>" />
3437             </div></form>
3438         <?php
3439         $this->pagefoot();
3440     }
3441
3442     /**
3443      * @todo document this
3444      */
3445     function action_memberdeleteconfirm() {
3446         global $member;
3447
3448         $memberid = intRequestVar('memberid');
3449
3450         ($member->getID() == $memberid) or $member->isAdmin() or $this->disallow();
3451
3452         $error = $this->deleteOneMember($memberid);
3453         if ($error)
3454             $this->error($error);
3455
3456         if ($member->isAdmin())
3457             $this->action_usermanagement();
3458         else
3459             $this->action_overview(_DELETED_MEMBER);
3460     }
3461         
3462         /**
3463          * Admin::deleteOneMember()
3464          * Delete a member by id
3465          * 
3466          * @static
3467          * @params      Integer $memberid       member id
3468          * @return      String  null string or error messages
3469          */
3470         function deleteOneMember($memberid)
3471         {
3472                 global $manager;
3473                 
3474                 $memberid = intval($memberid);
3475                 $mem =& $manager->getMember($memberid);
3476                 
3477                 if ( !$mem->canBeDeleted() )
3478                 {
3479                         return _ERROR_DELETEMEMBER;
3480                 }
3481                 
3482                 $manager->notify('PreDeleteMember', array('member' => &$mem));
3483                 
3484                 /* unlink comments from memberid */
3485                 if ( $memberid )
3486                 {
3487                         $query = "UPDATE %s SET cmember=0, cuser=%s WHERE cmember=%d";
3488                         $query = sprintf($query, sql_table('comment'), DB::quoteValue($mem->getDisplayName()), $memberid);
3489                         DB::execute($query);
3490                 }
3491                 
3492                 $query = 'DELETE FROM '.sql_table('member').' WHERE mnumber='.$memberid;
3493                 DB::execute($query);
3494                 
3495                 $query = 'DELETE FROM '.sql_table('team').' WHERE tmember='.$memberid;
3496                 DB::execute($query);
3497                 
3498                 $query = 'DELETE FROM '.sql_table('activation').' WHERE vmember='.$memberid;
3499                 DB::execute($query);
3500                 
3501                 // delete all associated plugin options
3502                 NucleusPlugin::delete_option_values('member', $memberid);
3503                 
3504                 $manager->notify('PostDeleteMember', array('member' => &$mem));
3505                 
3506                 return '';
3507         }
3508         
3509     /**
3510      * @todo document this
3511      */
3512     function action_createnewlog() {
3513         global $member, $CONF, $manager;
3514
3515         // Only Super-Admins can do this
3516         $member->isAdmin() or $this->disallow();
3517
3518         $this->pagehead();
3519
3520         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
3521         ?>
3522         <h2><?php echo _EBLOG_CREATE_TITLE ?></h2>
3523
3524         <h3><?php echo _ADMIN_NOTABILIA ?></h3>
3525
3526         <p><?php echo _ADMIN_PLEASE_READ ?></p>
3527
3528         <p><?php echo _ADMIN_HOW_TO_ACCESS ?></p>
3529
3530         <ol>
3531             <li><?php echo _ADMIN_SIMPLE_WAY ?></li>
3532             <li><?php echo _ADMIN_ADVANCED_WAY ?></li>
3533         </ol>
3534
3535         <h3><?php echo _ADMIN_HOW_TO_CREATE ?></h3>
3536
3537         <p>
3538         <?php echo _EBLOG_CREATE_TEXT ?>
3539         </p>
3540
3541         <form method="post" action="index.php"><div>
3542
3543         <input type="hidden" name="action" value="addnewlog" />
3544         <?php $manager->addTicketHidden() ?>
3545
3546
3547         <table><tr>
3548             <td><?php echo _EBLOG_NAME ?></td>
3549             <td><input name="name" tabindex="10" size="40" maxlength="60" /></td>
3550         </tr><tr>
3551             <td><?php echo _EBLOG_SHORTNAME ?>
3552                 <?php help('shortblogname'); ?>
3553             </td>
3554             <td><input name="shortname" tabindex="20" maxlength="15" size="15" /></td>
3555         </tr><tr>
3556             <td><?php echo _EBLOG_DESC ?></td>
3557             <td><input name="desc" tabindex="30" maxlength="200" size="40" /></td>
3558         </tr><tr>
3559             <td><?php echo _EBLOG_DEFSKIN ?>
3560                 <?php help('blogdefaultskin'); ?>
3561             </td>
3562             <td>
3563                 <?php
3564                     $query =  'SELECT sdname as text, sdnumber as value'
3565                            . ' FROM '.sql_table('skin_desc');
3566                     $template['name'] = 'defskin';
3567                     $template['tabindex'] = 50;
3568                     $template['selected'] = $CONF['BaseSkin'];  // set default selected skin to be globally defined base skin
3569                     showlist($query,'select',$template);
3570                 ?>
3571             </td>
3572         </tr><tr>
3573             <td><?php echo _EBLOG_OFFSET ?>
3574                 <?php help('blogtimeoffset'); ?>
3575                 <br /><?php echo _EBLOG_STIME ?> <b><?php echo i18n::formatted_datetime('%H:%M',time()); ?></b>
3576             </td>
3577             <td><input name="timeoffset" tabindex="110" size="3" value="0" /></td>
3578         </tr><tr>
3579             <td><?php echo _EBLOG_ADMIN ?>
3580                 <?php help('teamadmin'); ?>
3581             </td>
3582             <td><?php echo _EBLOG_ADMIN_MSG ?></td>
3583         </tr><tr>
3584             <td><?php echo _EBLOG_CREATE ?></td>
3585             <td><input type="submit" tabindex="120" value="<?php echo _EBLOG_CREATE_BTN ?>" onclick="return checkSubmit();" /></td>
3586         </tr></table>
3587
3588         </div></form>
3589         <?php
3590         $this->pagefoot();
3591     }
3592
3593     /**
3594      * @todo document this
3595      */
3596     function action_addnewlog() {
3597         global $member, $manager, $CONF;
3598
3599         // Only Super-Admins can do this
3600         $member->isAdmin() or $this->disallow();
3601
3602         $bname          = trim(postVar('name'));
3603         $bshortname     = trim(postVar('shortname'));
3604         $btimeoffset    = postVar('timeoffset');
3605         $bdesc          = trim(postVar('desc'));
3606         $bdefskin       = postVar('defskin');
3607
3608         if (!isValidShortName($bshortname))
3609             $this->error(_ERROR_BADSHORTBLOGNAME);
3610
3611         if ($manager->existsBlog($bshortname))
3612             $this->error(_ERROR_DUPSHORTBLOGNAME);
3613
3614         $manager->notify(
3615             'PreAddBlog',
3616             array(
3617                 'name' => &$bname,
3618                 'shortname' => &$bshortname,
3619                 'timeoffset' => &$btimeoffset,
3620                 'description' => &$bdesc,
3621                 'defaultskin' => &$bdefskin
3622             )
3623         );
3624
3625
3626         // create blog
3627                 $query = sprintf('INSERT INTO %s (bname, bshortname, bdesc, btimeoffset, bdefskin) VALUES (%s, %s, %s, %s, %s)',
3628                         sql_table('blog'),
3629                         DB::quoteValue($bname),
3630                         DB::quoteValue($bshortname),
3631                         DB::quoteValue($bdesc),
3632                         DB::quoteValue($btimeoffset),
3633                         DB::quoteValue($bdefskin)
3634                 );
3635         DB::execute($query);
3636         $blogid = DB::getInsertId();
3637         $blog   =& $manager->getBlog($blogid);
3638
3639         // create new category
3640         $catdefname = (defined('_EBLOGDEFAULTCATEGORY_NAME') ? _EBLOGDEFAULTCATEGORY_NAME : 'General');
3641         $catdefdesc = (defined('_EBLOGDEFAULTCATEGORY_DESC') ? _EBLOGDEFAULTCATEGORY_DESC : 'Items that do not fit in other categories');
3642                 $query = sprintf('INSERT INTO %s (cblog, cname, cdesc) VALUES (%d, %s, %s)',
3643                         sql_table('category'),
3644                         $blogid,
3645                         DB::quoteValue($catdefname),
3646                         DB::quoteValue($catdefdesc)
3647                 );
3648         DB::execute($query);
3649         $catid = DB::getInsertId();
3650
3651         // set as default category
3652         $blog->setDefaultCategory($catid);
3653         $blog->writeSettings();
3654
3655         // create team member
3656         $memberid = $member->getID();
3657         $query = sprintf('INSERT INTO %s (tmember, tblog, tadmin) VALUES (%d, %d, 1)', sql_table('team'), $memberid, $blogid);
3658         DB::execute($query);
3659
3660         $itemdeftitle = (defined('_EBLOG_FIRSTITEM_TITLE') ? _EBLOG_FIRSTITEM_TITLE : 'First Item');
3661         $itemdefbody = (defined('_EBLOG_FIRSTITEM_BODY') ? _EBLOG_FIRSTITEM_BODY : 'This is the first item in your weblog. Feel free to delete it.');
3662
3663         $blog->additem($blog->getDefaultCategory(),$itemdeftitle,$itemdefbody,'',$blogid, $memberid,$blog->getCorrectTime(),0,0,0);
3664
3665         
3666         $manager->notify(
3667             'PostAddBlog',
3668             array(
3669                 'blog' => &$blog
3670             )
3671         );
3672
3673         $manager->notify(
3674             'PostAddCategory',
3675             array(
3676                 'blog' => &$blog,
3677                 'name' => _EBLOGDEFAULTCATEGORY_NAME,
3678                 'description' => _EBLOGDEFAULTCATEGORY_DESC,
3679                 'catid' => $catid
3680             )
3681         );
3682
3683         $this->pagehead();
3684         ?>
3685         <h2><?php echo _BLOGCREATED_TITLE ?></h2>
3686
3687         <p><?php echo sprintf(_BLOGCREATED_ADDEDTXT, Entity::hsc($bname)) ?></p>
3688
3689         <ol>
3690             <li><a href="#index_php"><?php echo sprintf(_BLOGCREATED_SIMPLEWAY, Entity::hsc($bshortname)) ?></a></li>
3691             <li><a href="#skins"><?php echo _BLOGCREATED_ADVANCEDWAY ?></a></li>
3692         </ol>
3693
3694         <h3><a id="index_php"><?php echo sprintf(_BLOGCREATED_SIMPLEDESC1, Entity::hsc($bshortname)) ?></a></h3>
3695
3696         <p><?php echo sprintf(_BLOGCREATED_SIMPLEDESC2, Entity::hsc($bshortname)) ?></p>
3697 <pre><code>&lt;?php
3698
3699 $CONF['Self'] = '<b><?php echo Entity::hsc($bshortname) ?>.php</b>';
3700
3701 include('<i>./config.php</i>');
3702
3703 selectBlog('<b><?php echo Entity::hsc($bshortname) ?></b>');
3704 selector();
3705
3706 ?&gt;</code></pre>
3707
3708         <p><?php echo _BLOGCREATED_SIMPLEDESC3 ?></p>
3709
3710         <p><?php echo _BLOGCREATED_SIMPLEDESC4 ?></p>
3711
3712         <form action="index.php" method="post"><div>
3713             <input type="hidden" name="action" value="addnewlog2" />
3714             <?php $manager->addTicketHidden() ?>
3715             <input type="hidden" name="blogid" value="<?php echo intval($blogid) ?>" />
3716             <table><tr>
3717                 <td><?php echo _EBLOG_URL ?></td>
3718                 <td><input name="url" maxlength="100" size="40" value="<?php echo Entity::hsc($CONF['IndexURL'].$bshortname.'.php') ?>" /></td>
3719             </tr><tr>
3720                 <td><?php echo _EBLOG_CREATE ?></td>
3721                 <td><input type="submit" value="<?php echo _EBLOG_CREATE_BTN ?>" onclick="return checkSubmit();" /></td>
3722             </tr></table>
3723         </div></form>
3724
3725         <h3><a id="skins"><?php echo _BLOGCREATED_ADVANCEDWAY2 ?></a></h3>
3726
3727         <p><?php echo _BLOGCREATED_ADVANCEDWAY3 ?></p>
3728
3729         <form action="index.php" method="post"><div>
3730             <input type="hidden" name="action" value="addnewlog2" />
3731             <?php $manager->addTicketHidden() ?>
3732             <input type="hidden" name="blogid" value="<?php echo intval($blogid) ?>" />
3733             <table><tr>
3734                 <td><?php echo _EBLOG_URL ?></td>
3735                 <td><input name="url" maxlength="100" size="40" /></td>
3736             </tr><tr>
3737                 <td><?php echo _EBLOG_CREATE ?></td>
3738                 <td><input type="submit" value="<?php echo _EBLOG_CREATE_BTN ?>" onclick="return checkSubmit();" /></td>
3739             </tr></table>
3740         </div></form>
3741
3742         <?php       $this->pagefoot();
3743
3744     }
3745
3746     /**
3747      * @todo document this
3748      */
3749     function action_addnewlog2() {
3750         global $member, $manager;
3751
3752         $member->blogAdminRights($blogid) or $this->disallow();
3753
3754         $burl   = requestVar('url');
3755         $blogid = intRequestVar('blogid');
3756
3757         $blog =& $manager->getBlog($blogid);
3758         $blog->setURL(trim($burl));
3759         $blog->writeSettings();
3760
3761         $this->action_overview(_MSG_NEWBLOG);
3762     }
3763
3764     /**
3765      * @todo document this
3766      */
3767     function action_skinieoverview() {
3768         global $member, $DIR_LIBS, $manager;
3769
3770         $member->isAdmin() or $this->disallow();
3771
3772         // load skinie class
3773         include_once($DIR_LIBS . 'skinie.php');
3774
3775         $this->pagehead();
3776
3777         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
3778
3779     ?>
3780         <h2><?php echo _SKINIE_TITLE_IMPORT ?></h2>
3781
3782                 <p><label for="skinie_import_local"><?php echo _SKINIE_LOCAL ?></label>
3783                 <?php                   global $DIR_SKINS;
3784
3785                     $candidates = SkinImport::searchForCandidates($DIR_SKINS);
3786
3787                     if (sizeof($candidates) > 0) {
3788                         ?>
3789                             <form method="post" action="index.php"><div>
3790                                 <input type="hidden" name="action" value="skinieimport" />
3791                                 <?php $manager->addTicketHidden() ?>
3792                                 <input type="hidden" name="mode" value="file" />
3793                                 <select name="skinfile" id="skinie_import_local">
3794                                 <?php                                   foreach ($candidates as $skinname => $skinfile) {
3795                                         $html = Entity::hsc($skinfile);
3796                                         echo '<option value="',$html,'">',$skinname,'</option>';
3797                                     }
3798                                 ?>
3799                                 </select>
3800                                 <input type="submit" value="<?php echo _SKINIE_BTN_IMPORT ?>" />
3801                             </div></form>
3802                         <?php                   } else {
3803                         echo _SKINIE_NOCANDIDATES;
3804                     }
3805                 ?>
3806                 </p>
3807
3808                 <p><em><?php echo _OR ?></em></p>
3809
3810                 <form method="post" action="index.php"><p>
3811                     <?php $manager->addTicketHidden() ?>
3812                     <input type="hidden" name="action" value="skinieimport" />
3813                     <input type="hidden" name="mode" value="url" />
3814                     <label for="skinie_import_url"><?php echo _SKINIE_FROMURL ?></label>
3815                     <input type="text" name="skinfile" id="skinie_import_url" size="60" value="http://" />
3816                     <input type="submit" value="<?php echo _SKINIE_BTN_IMPORT ?>" />
3817                 </p></form>
3818
3819
3820         <h2><?php echo _SKINIE_TITLE_EXPORT ?></h2>
3821         <form method="post" action="index.php"><div>
3822             <input type="hidden" name="action" value="skinieexport" />
3823             <?php $manager->addTicketHidden() ?>
3824
3825             <p><?php echo _SKINIE_EXPORT_INTRO ?></p>
3826
3827             <table><tr>
3828                 <th colspan="2"><?php echo _SKINIE_EXPORT_SKINS ?></th>
3829             </tr><tr>
3830     <?php       // show list of skins
3831         $res = DB::getResult('SELECT * FROM '.sql_table('skin_desc'));
3832         foreach ( $res as $row) {
3833             $id = 'skinexp' . $row['sdnumber'];
3834             echo '<td><input type="checkbox" name="skin[',$row['sdnumber'],']"  id="',$id,'" />';
3835             echo '<label for="',$id,'">',Entity::hsc($row['sdname']),'</label></td>';
3836             echo '<td>',Entity::hsc($row['sddesc']),'</td>';
3837             echo '</tr><tr>';
3838         }
3839
3840         echo '<th colspan="2">',_SKINIE_EXPORT_TEMPLATES,'</th></tr><tr>';
3841
3842         // show list of templates
3843         $res = DB::getResult('SELECT * FROM '.sql_table('template_desc'));
3844         foreach ( $res as $row ) {
3845             $id = 'templateexp' . $row['tdnumber'];
3846             echo '<td><input type="checkbox" name="template[',$row['tdnumber'],']" id="',$id,'" />';
3847             echo '<label for="',$id,'">',Entity::hsc($row['tdname']),'</label></td>';
3848             echo '<td>',Entity::hsc($row['tddesc']),'</td>';
3849             echo '</tr><tr>';
3850         }
3851
3852     ?>
3853                 <th colspan="2"><?php echo _SKINIE_EXPORT_EXTRA ?></th>
3854             </tr><tr>
3855                 <td colspan="2"><textarea cols="40" rows="5" name="info"></textarea></td>
3856             </tr><tr>
3857                 <th colspan="2"><?php echo _SKINIE_TITLE_EXPORT ?></th>
3858             </tr><tr>
3859                 <td colspan="2"><input type="submit" value="<?php echo _SKINIE_BTN_EXPORT ?>" /></td>
3860             </tr></table>
3861         </div></form>
3862
3863     <?php
3864         $this->pagefoot();
3865
3866     }
3867
3868     /**
3869      * @todo document this
3870      */
3871     function action_skinieimport() {
3872         global $member, $DIR_LIBS, $DIR_SKINS, $manager;
3873
3874         $member->isAdmin() or $this->disallow();
3875
3876         // load skinie class
3877         include_once($DIR_LIBS . 'skinie.php');
3878
3879         $skinFileRaw= postVar('skinfile');
3880         $mode       = postVar('mode');
3881
3882         $importer = new SkinImport();
3883
3884         // get full filename
3885         if ($mode == 'file')
3886         {
3887             $skinFile = $DIR_SKINS . $skinFileRaw . '/skinbackup.xml';
3888
3889             // backwards compatibilty (in v2.0, exports were saved as skindata.xml)
3890             if (!file_exists($skinFile))
3891                 $skinFile = $DIR_SKINS . $skinFileRaw . '/skindata.xml';
3892         } else {
3893             $skinFile = $skinFileRaw;
3894         }
3895
3896         // read only metadata
3897         $error = $importer->readFile($skinFile, 1);
3898
3899         // clashes
3900         $skinNameClashes = $importer->checkSkinNameClashes();
3901         $templateNameClashes = $importer->checkTemplateNameClashes();
3902         $hasNameClashes = (count($skinNameClashes) > 0) || (count($templateNameClashes) > 0);
3903
3904         if ($error) $this->error($error);
3905
3906         $this->pagehead();
3907
3908         echo '<p><a href="index.php?action=skinieoverview">(',_BACK,')</a></p>';
3909         ?>
3910         <h2><?php echo _SKINIE_CONFIRM_TITLE ?></h2>
3911
3912         <ul>
3913             <li><p><strong><?php echo _SKINIE_INFO_GENERAL ?></strong> <?php echo Entity::hsc($importer->getInfo()) ?></p></li>
3914             <li><p><strong><?php echo _SKINIE_INFO_SKINS ?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getSkinNames()) ?></p></li>
3915             <li><p><strong><?php echo _SKINIE_INFO_TEMPLATES ?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getTemplateNames()) ?></p></li>
3916             <?php
3917                 if ($hasNameClashes)
3918                 {
3919             ?>
3920             <li><p><strong style="color: red;"><?php echo _SKINIE_INFO_SKINCLASH ?></strong> <?php echo implode(' <em>'._AND.'</em> ',$skinNameClashes) ?></p></li>
3921             <li><p><strong style="color: red;"><?php echo _SKINIE_INFO_TEMPLCLASH ?></strong> <?php echo implode(' <em>'._AND.'</em> ',$templateNameClashes) ?></p></li>
3922             <?php
3923                 } // if (hasNameClashes)
3924             ?>
3925         </ul>
3926
3927         <form method="post" action="index.php"><div>
3928             <input type="hidden" name="action" value="skiniedoimport" />
3929             <?php $manager->addTicketHidden() ?>
3930             <input type="hidden" name="skinfile" value="<?php echo Entity::hsc(postVar('skinfile')) ?>" />
3931             <input type="hidden" name="mode" value="<?php echo Entity::hsc($mode) ?>" />
3932             <input type="submit" value="<?php echo _SKINIE_CONFIRM_IMPORT ?>" />
3933             <?php
3934                 if ($hasNameClashes)
3935                 {
3936             ?>
3937             <br />
3938             <input type="checkbox" name="overwrite" value="1" id="cb_overwrite" /><label for="cb_overwrite"><?php echo _SKINIE_CONFIRM_OVERWRITE ?></label>
3939             <?php
3940                 } // if (hasNameClashes)
3941             ?>
3942         </div></form>
3943
3944
3945         <?php
3946         $this->pagefoot();
3947     }
3948
3949     /**
3950      * @todo document this
3951      */
3952     function action_skiniedoimport() {
3953         global $member, $DIR_LIBS, $DIR_SKINS;
3954
3955         $member->isAdmin() or $this->disallow();
3956
3957         // load skinie class
3958         include_once($DIR_LIBS . 'skinie.php');
3959
3960         $skinFileRaw= postVar('skinfile');
3961         $mode       = postVar('mode');
3962
3963         $allowOverwrite = intPostVar('overwrite');
3964
3965         // get full filename
3966         if ($mode == 'file')
3967         {
3968             $skinFile = $DIR_SKINS . $skinFileRaw . '/skinbackup.xml';
3969
3970             // backwards compatibilty (in v2.0, exports were saved as skindata.xml)
3971             if (!file_exists($skinFile))
3972                 $skinFile = $DIR_SKINS . $skinFileRaw . '/skindata.xml';
3973
3974         } else {
3975             $skinFile = $skinFileRaw;
3976         }
3977
3978         $importer = new SkinImport();
3979
3980         $error = $importer->readFile($skinFile);
3981
3982         if ($error)
3983             $this->error($error);
3984
3985         $error = $importer->writeToDatabase($allowOverwrite);
3986
3987         if ($error)
3988             $this->error($error);
3989
3990         $this->pagehead();
3991
3992         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
3993     ?>
3994         <h2><?php echo _SKINIE_DONE ?></h2>
3995
3996         <ul>
3997             <li><p><strong><?php echo _SKINIE_INFO_GENERAL ?></strong> <?php echo Entity::hsc($importer->getInfo()) ?></p></li>
3998             <li><p><strong><?php echo _SKINIE_INFO_IMPORTEDSKINS ?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getSkinNames()) ?></p></li>
3999             <li><p><strong><?php echo _SKINIE_INFO_IMPORTEDTEMPLS ?></strong> <?php echo implode(' <em>'._AND.'</em> ',$importer->getTemplateNames()) ?></p></li>
4000         </ul>
4001
4002     <?php       $this->pagefoot();
4003
4004     }
4005
4006     /**
4007      * @todo document this
4008      */
4009     function action_skinieexport() {
4010         global $member, $DIR_LIBS;
4011
4012         $member->isAdmin() or $this->disallow();
4013
4014         // load skinie class
4015         include_once($DIR_LIBS . 'skinie.php');
4016
4017         $aSkins = requestIntArray('skin');
4018         $aTemplates = requestIntArray('template');
4019
4020         if (!is_array($aTemplates)) $aTemplates = array();
4021         if (!is_array($aSkins)) $aSkins = array();
4022
4023         $skinList = array_keys($aSkins);
4024         $templateList = array_keys($aTemplates);
4025
4026         $info = postVar('info');
4027
4028         $exporter = new SkinExport();
4029         foreach ($skinList as $skinId) {
4030             $exporter->addSkin($skinId);
4031         }
4032         foreach ($templateList as $templateId) {
4033             $exporter->addTemplate($templateId);
4034         }
4035         $exporter->setInfo($info);
4036
4037         $exporter->export();
4038     }
4039
4040     /**
4041      * @todo document this
4042      */
4043     function action_templateoverview() {
4044         global $member, $manager;
4045
4046         $member->isAdmin() or $this->disallow();
4047
4048         $this->pagehead();
4049
4050         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
4051
4052         echo '<h2>' . _TEMPLATE_TITLE . '</h2>';
4053         echo '<h3>' . _TEMPLATE_AVAILABLE_TITLE . '</h3>';
4054
4055         $query = 'SELECT * FROM '.sql_table('template_desc').' ORDER BY tdname';
4056         $template['content'] = 'templatelist';
4057         $template['tabindex'] = 10;
4058         showlist($query,'table',$template);
4059
4060         echo '<h3>' . _TEMPLATE_NEW_TITLE . '</h3>';
4061
4062         ?>
4063         <form method="post" action="index.php"><div>
4064
4065         <input name="action" value="templatenew" type="hidden" />
4066         <?php $manager->addTicketHidden() ?>
4067         <table><tr>
4068             <td><?php echo _TEMPLATE_NAME ?> <?php help('shortnames'); ?></td>
4069             <td><input name="name" tabindex="10010" maxlength="20" size="20" /></td>
4070         </tr><tr>
4071             <td><?php echo _TEMPLATE_DESC ?></td>
4072             <td><input name="desc" tabindex="10020" maxlength="200" size="50" /></td>
4073         </tr><tr>
4074             <td><?php echo _TEMPLATE_CREATE ?></td>
4075             <td><input type="submit" tabindex="10030" value="<?php echo _TEMPLATE_CREATE_BTN ?>" onclick="return checkSubmit();" /></td>
4076         </tr></table>
4077
4078         </div></form>
4079
4080         <?php
4081         $this->pagefoot();
4082     }
4083
4084     /**
4085      * @todo document this
4086      */
4087     function action_templateedit($msg = '') {
4088         global $member, $manager;
4089
4090         $templateid = intRequestVar('templateid');
4091
4092         $member->isAdmin() or $this->disallow();
4093
4094         $extrahead = '<script type="text/javascript" src="javascript/templateEdit.js"></script>';
4095         $extrahead .= '<script type="text/javascript">setTemplateEditText('.DB::quoteValue(_EDITTEMPLATE_EMPTY).');</script>';
4096
4097         $this->pagehead($extrahead);
4098
4099         $templatename = Template::getNameFromId($templateid);
4100         $templatedescription = Template::getDesc($templateid);
4101         $template =& $manager->getTemplate($templatename);
4102
4103         ?>
4104         <p>
4105         <a href="index.php?action=templateoverview">(<?php echo _TEMPLATE_BACK ?>)</a>
4106         </p>
4107
4108         <h2><?php echo _TEMPLATE_EDIT_TITLE ?> '<?php echo  Entity::hsc($templatename); ?>'</h2>
4109
4110         <?php                   if ($msg) echo "<p>"._MESSAGE.": $msg</p>";
4111         ?>
4112
4113         <p><?php echo _TEMPLATE_EDIT_MSG ?></p>
4114
4115         <form method="post" action="index.php">
4116         <div>
4117
4118         <input type="hidden" name="action" value="templateupdate" />
4119         <?php $manager->addTicketHidden() ?>
4120         <input type="hidden" name="templateid" value="<?php echo  $templateid; ?>" />
4121
4122         <table><tr>
4123             <th colspan="2"><?php echo _TEMPLATE_SETTINGS ?></th>
4124         </tr><tr>
4125             <td><?php echo _TEMPLATE_NAME ?> <?php help('shortnames'); ?></td>
4126             <td><input name="tname" tabindex="4" size="20" maxlength="20" value="<?php echo  Entity::hsc($templatename) ?>" /></td>
4127         </tr><tr>
4128             <td><?php echo _TEMPLATE_DESC ?></td>
4129             <td><input name="tdesc" tabindex="5" size="50" maxlength="200" value="<?php echo  Entity::hsc($templatedescription) ?>" /></td>
4130         </tr><tr>
4131             <th colspan="2"><?php echo _TEMPLATE_UPDATE ?></th>
4132         </tr><tr>
4133             <td><?php echo _TEMPLATE_UPDATE ?></td>
4134             <td>
4135                 <input type="submit" tabindex="6" value="<?php echo _TEMPLATE_UPDATE_BTN ?>" onclick="return checkSubmit();" />
4136                 <input type="reset" tabindex="7" value="<?php echo _TEMPLATE_RESET_BTN ?>" />
4137             </td>
4138         </tr><tr>
4139             <th colspan="2"><?php echo _TEMPLATE_ITEMS ?> <?php help('templateitems'); ?></th>
4140 <?php   $this->_templateEditRow($template, _TEMPLATE_ITEMHEADER, 'ITEM_HEADER', '', 8);
4141     $this->_templateEditRow($template, _TEMPLATE_ITEMBODY, 'ITEM', '', 9, 1);
4142     $this->_templateEditRow($template, _TEMPLATE_ITEMFOOTER, 'ITEM_FOOTER', '', 10);
4143     $this->_templateEditRow($template, _TEMPLATE_MORELINK, 'MORELINK', 'morelink', 20);
4144     $this->_templateEditRow($template, _TEMPLATE_EDITLINK, 'EDITLINK', 'editlink', 25);
4145     $this->_templateEditRow($template, _TEMPLATE_NEW, 'NEW', 'new', 30);
4146 ?>
4147         </tr><tr>
4148             <th colspan="2"><?php echo _TEMPLATE_COMMENTS_ANY ?> <?php help('templatecomments'); ?></th>
4149 <?php   $this->_templateEditRow($template, _TEMPLATE_CHEADER, 'COMMENTS_HEADER', 'commentheaders', 40);
4150     $this->_templateEditRow($template, _TEMPLATE_CBODY, 'COMMENTS_BODY', 'commentbody', 50, 1);
4151     $this->_templateEditRow($template, _TEMPLATE_CFOOTER, 'COMMENTS_FOOTER', 'commentheaders', 60);
4152     $this->_templateEditRow($template, _TEMPLATE_CONE, 'COMMENTS_ONE', 'commentwords', 70);
4153     $this->_templateEditRow($template, _TEMPLATE_CMANY, 'COMMENTS_MANY', 'commentwords', 80);
4154     $this->_templateEditRow($template, _TEMPLATE_CMORE, 'COMMENTS_CONTINUED', 'commentcontinued', 90);
4155     $this->_templateEditRow($template, _TEMPLATE_CMEXTRA, 'COMMENTS_AUTH', 'memberextra', 100);
4156 ?>
4157         </tr><tr>
4158             <th colspan="2"><?php echo _TEMPLATE_COMMENTS_NONE ?> <?php help('templatecomments'); ?></th>
4159 <?php
4160     $this->_templateEditRow($template, _TEMPLATE_CNONE, 'COMMENTS_NONE', '', 110);
4161 ?>
4162         </tr><tr>
4163             <th colspan="2"><?php echo _TEMPLATE_COMMENTS_TOOMUCH ?> <?php help('templatecomments'); ?></th>
4164 <?php   $this->_templateEditRow($template, _TEMPLATE_CTOOMUCH, 'COMMENTS_TOOMUCH', '', 120);
4165 ?>
4166         </tr><tr>
4167             <th colspan="2"><?php echo _TEMPLATE_ARCHIVELIST ?> <?php help('templatearchivelists'); ?></th>
4168 <?php   $this->_templateEditRow($template, _TEMPLATE_AHEADER, 'ARCHIVELIST_HEADER', '', 130);
4169     $this->_templateEditRow($template, _TEMPLATE_AITEM, 'ARCHIVELIST_LISTITEM', '', 140);
4170     $this->_templateEditRow($template, _TEMPLATE_AFOOTER, 'ARCHIVELIST_FOOTER', '', 150);
4171 ?>
4172         </tr><tr>
4173             <th colspan="2"><?php echo _TEMPLATE_BLOGLIST ?> <?php help('templatebloglists'); ?></th>
4174 <?php   $this->_templateEditRow($template, _TEMPLATE_BLOGHEADER, 'BLOGLIST_HEADER', '', 160);
4175     $this->_templateEditRow($template, _TEMPLATE_BLOGITEM, 'BLOGLIST_LISTITEM', '', 170);
4176     $this->_templateEditRow($template, _TEMPLATE_BLOGFOOTER, 'BLOGLIST_FOOTER', '', 180);
4177 ?>
4178         </tr><tr>
4179             <th colspan="2"><?php echo _TEMPLATE_CATEGORYLIST ?> <?php help('templatecategorylists'); ?></th>
4180 <?php   $this->_templateEditRow($template, _TEMPLATE_CATHEADER, 'CATLIST_HEADER', '', 190);
4181     $this->_templateEditRow($template, _TEMPLATE_CATITEM, 'CATLIST_LISTITEM', '', 200);
4182     $this->_templateEditRow($template, _TEMPLATE_CATFOOTER, 'CATLIST_FOOTER', '', 210);
4183 ?>
4184         </tr><tr>
4185             <th colspan="2"><?php echo _TEMPLATE_DATETIME ?></th>
4186 <?php   $this->_templateEditRow($template, _TEMPLATE_DHEADER, 'DATE_HEADER', 'dateheads', 220);
4187     $this->_templateEditRow($template, _TEMPLATE_DFOOTER, 'DATE_FOOTER', 'dateheads', 230);
4188     $this->_templateEditRow($template, _TEMPLATE_DFORMAT, 'FORMAT_DATE', 'datetime', 240);
4189     $this->_templateEditRow($template, _TEMPLATE_TFORMAT, 'FORMAT_TIME', 'datetime', 250);
4190     $this->_templateEditRow($template, _TEMPLATE_LOCALE, 'LOCALE', 'locale', 260);
4191 ?>
4192         </tr><tr>
4193             <th colspan="2"><?php echo _TEMPLATE_IMAGE ?> <?php help('templatepopups'); ?></th>
4194 <?php   $this->_templateEditRow($template, _TEMPLATE_PCODE, 'POPUP_CODE', '', 270);
4195     $this->_templateEditRow($template, _TEMPLATE_ICODE, 'IMAGE_CODE', '', 280);
4196     $this->_templateEditRow($template, _TEMPLATE_MCODE, 'MEDIA_CODE', '', 290);
4197 ?>
4198         </tr><tr>
4199             <th colspan="2"><?php echo _TEMPLATE_SEARCH ?></th>
4200 <?php   $this->_templateEditRow($template, _TEMPLATE_SHIGHLIGHT, 'SEARCH_HIGHLIGHT', 'highlight',300);
4201     $this->_templateEditRow($template, _TEMPLATE_SNOTFOUND, 'SEARCH_NOTHINGFOUND', 'nothingfound',310);
4202 ?>
4203         </tr><tr>
4204             <th colspan="2"><?php echo _TEMPLATE_PLUGIN_FIELDS ?></th>
4205 <?php
4206         $tab = 600;
4207         $pluginfields = array();
4208         $manager->notify('TemplateExtraFields',array('fields'=>&$pluginfields));
4209
4210         foreach ($pluginfields as $pfkey=>$pfvalue) {
4211             echo "</tr><tr>\n";
4212             echo '<th colspan="2">' . Entity::hen($pfkey) . "</th>\n";
4213             foreach ($pfvalue as $pffield=>$pfdesc) {
4214                 $this->_templateEditRow($template, $pfdesc, $pffield, '',++$tab,0);
4215             }
4216         }
4217 ?>
4218         </tr><tr>
4219             <th colspan="2"><?php echo _TEMPLATE_UPDATE ?></th>
4220         </tr><tr>
4221             <td><?php echo _TEMPLATE_UPDATE ?></td>
4222             <td>
4223                 <input type="submit" tabindex="800" value="<?php echo _TEMPLATE_UPDATE_BTN ?>" onclick="return checkSubmit();" />
4224                 <input type="reset" tabindex="810" value="<?php echo _TEMPLATE_RESET_BTN ?>" />
4225             </td>
4226         </tr></table>
4227
4228         </div>
4229         </form>
4230         <?php
4231         $this->pagefoot();
4232     }
4233
4234     /**
4235      * @todo document this
4236      */
4237     function _templateEditRow(&$template, $description, $name, $help = '', $tabindex = 0, $big = 0) {
4238         static $count = 1;
4239         if (!isset($template[$name])) $template[$name] = '';
4240     ?>
4241         </tr><tr>
4242             <td><?php echo $description ?> <?php if ($help) help('template'.$help); ?></td>
4243             <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>
4244     <?php       $count++;
4245     }
4246
4247     /**
4248      * @todo document this
4249      */
4250     function action_templateupdate() {
4251         global $member,$manager;
4252
4253         $templateid = intRequestVar('templateid');
4254
4255         $member->isAdmin() or $this->disallow();
4256
4257         $name = postVar('tname');
4258         $desc = postVar('tdesc');
4259
4260         if (!isValidTemplateName($name))
4261             $this->error(_ERROR_BADTEMPLATENAME);
4262
4263         if ((Template::getNameFromId($templateid) != $name) && Template::exists($name))
4264             $this->error(_ERROR_DUPTEMPLATENAME);
4265
4266
4267         $name = DB::quoteValue($name);
4268         $desc = DB::quoteValue($desc);
4269
4270         // 1. Remove all template parts
4271         $query = 'DELETE FROM '.sql_table('template').' WHERE tdesc=' . $templateid;
4272         DB::execute($query);
4273
4274         // 2. Update description
4275         $query =  'UPDATE '.sql_table('template_desc').' SET'
4276                . ' tdname=' . $name . ','
4277                . ' tddesc=' . $desc
4278                . ' WHERE tdnumber=' . $templateid;
4279         DB::execute($query);
4280
4281         // 3. Add non-empty template parts
4282         $this->addToTemplate($templateid, 'ITEM_HEADER', postVar('ITEM_HEADER'));
4283         $this->addToTemplate($templateid, 'ITEM', postVar('ITEM'));
4284         $this->addToTemplate($templateid, 'ITEM_FOOTER', postVar('ITEM_FOOTER'));
4285         $this->addToTemplate($templateid, 'MORELINK', postVar('MORELINK'));
4286         $this->addToTemplate($templateid, 'EDITLINK', postVar('EDITLINK'));
4287         $this->addToTemplate($templateid, 'NEW', postVar('NEW'));
4288         $this->addToTemplate($templateid, 'COMMENTS_HEADER', postVar('COMMENTS_HEADER'));
4289         $this->addToTemplate($templateid, 'COMMENTS_BODY', postVar('COMMENTS_BODY'));
4290         $this->addToTemplate($templateid, 'COMMENTS_FOOTER', postVar('COMMENTS_FOOTER'));
4291         $this->addToTemplate($templateid, 'COMMENTS_CONTINUED', postVar('COMMENTS_CONTINUED'));
4292         $this->addToTemplate($templateid, 'COMMENTS_TOOMUCH', postVar('COMMENTS_TOOMUCH'));
4293         $this->addToTemplate($templateid, 'COMMENTS_AUTH', postVar('COMMENTS_AUTH'));
4294         $this->addToTemplate($templateid, 'COMMENTS_ONE', postVar('COMMENTS_ONE'));
4295         $this->addToTemplate($templateid, 'COMMENTS_MANY', postVar('COMMENTS_MANY'));
4296         $this->addToTemplate($templateid, 'COMMENTS_NONE', postVar('COMMENTS_NONE'));
4297         $this->addToTemplate($templateid, 'ARCHIVELIST_HEADER', postVar('ARCHIVELIST_HEADER'));
4298         $this->addToTemplate($templateid, 'ARCHIVELIST_LISTITEM', postVar('ARCHIVELIST_LISTITEM'));
4299         $this->addToTemplate($templateid, 'ARCHIVELIST_FOOTER', postVar('ARCHIVELIST_FOOTER'));
4300         $this->addToTemplate($templateid, 'BLOGLIST_HEADER', postVar('BLOGLIST_HEADER'));
4301         $this->addToTemplate($templateid, 'BLOGLIST_LISTITEM', postVar('BLOGLIST_LISTITEM'));
4302         $this->addToTemplate($templateid, 'BLOGLIST_FOOTER', postVar('BLOGLIST_FOOTER'));
4303         $this->addToTemplate($templateid, 'CATLIST_HEADER', postVar('CATLIST_HEADER'));
4304         $this->addToTemplate($templateid, 'CATLIST_LISTITEM', postVar('CATLIST_LISTITEM'));
4305         $this->addToTemplate($templateid, 'CATLIST_FOOTER', postVar('CATLIST_FOOTER'));
4306         $this->addToTemplate($templateid, 'DATE_HEADER', postVar('DATE_HEADER'));
4307         $this->addToTemplate($templateid, 'DATE_FOOTER', postVar('DATE_FOOTER'));
4308         $this->addToTemplate($templateid, 'FORMAT_DATE', postVar('FORMAT_DATE'));
4309         $this->addToTemplate($templateid, 'FORMAT_TIME', postVar('FORMAT_TIME'));
4310         $this->addToTemplate($templateid, 'LOCALE', postVar('LOCALE'));
4311         $this->addToTemplate($templateid, 'SEARCH_HIGHLIGHT', postVar('SEARCH_HIGHLIGHT'));
4312         $this->addToTemplate($templateid, 'SEARCH_NOTHINGFOUND', postVar('SEARCH_NOTHINGFOUND'));
4313         $this->addToTemplate($templateid, 'POPUP_CODE', postVar('POPUP_CODE'));
4314         $this->addToTemplate($templateid, 'MEDIA_CODE', postVar('MEDIA_CODE'));
4315         $this->addToTemplate($templateid, 'IMAGE_CODE', postVar('IMAGE_CODE'));
4316
4317         $pluginfields = array();
4318         $manager->notify('TemplateExtraFields',array('fields'=>&$pluginfields));
4319         foreach ($pluginfields as $pfkey=>$pfvalue) {
4320             foreach ($pfvalue as $pffield=>$pfdesc) {
4321                 $this->addToTemplate($templateid, $pffield, postVar($pffield));
4322             }
4323         }
4324
4325         // jump back to template edit
4326         $this->action_templateedit(_TEMPLATE_UPDATED);
4327
4328     }
4329
4330         /**
4331          * Admin::addToTemplate()
4332          * 
4333          * @param       Integer $id     ID for template
4334          * @param       String  $partname       parts name
4335          * @param       String  $content        template contents
4336          * @return      Integer record index
4337          * 
4338          */
4339         function addToTemplate($id, $partname, $content)
4340         {
4341                 // don't add empty parts:
4342                 if ( !trim($content) )
4343                 {
4344                         return -1;
4345                 }
4346                 
4347                 $partname = DB::quoteValue($partname);
4348                 $content = DB::quoteValue($content);
4349                 
4350                 $query = "INSERT INTO %s (tdesc, tpartname, tcontent) VALUES (%d, %s, %s)";
4351                 $query = sprintf($query, sql_table('template'), (integer) $id, $partname, $content);
4352                 if ( DB::execute($query) === FALSE )
4353                 {
4354                         $err = DB::getError();
4355                         exit(_ADMIN_SQLDIE_QUERYERROR . $err[2]);
4356                 }
4357                 return DB::getInsertId();
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         DB::execute('DELETE FROM '.sql_table('template_desc').' WHERE tdnumber=' . $templateid);
4407
4408         // 2. delete parts
4409         DB::execute('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 = DB::getResult('SELECT tpartname, tcontent FROM '.sql_table('template').' WHERE tdesc=' . $templateid);
4468         foreach ( $res as $row ) {
4469             $this->addToTemplate($newid, $row['tpartname'], $row['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->getContentFromDB($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 = DB::getValue($query);
4868         if ( $r )
4869             $this->error(_ERROR_SKINDEFDELETE . Entity::hsc($r));
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 = DB::getValue($query);
4911         if ($r)
4912             $this->error(_ERROR_SKINDEFDELETE .$r);
4913
4914         $manager->notify('PreDeleteSkin', array('skinid' => $skinid));
4915
4916         // 1. delete description
4917         DB::execute('DELETE FROM '.sql_table('skin_desc').' WHERE sdnumber=' . $skinid);
4918
4919         // 2. delete parts
4920         DB::execute('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                 DB::execute($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 = DB::getResult($query);
5064         foreach ( $res as $row) {
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->getContentFromDB($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                         DB::execute($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                                         DB::execute("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>' . DB::getAttribute(PDO::ATTR_SERVER_VERSION) . ' (' . DB::getAttribute(PDO::ATTR_CLIENT_VERSION) . ')' . "</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 = DB::quoteValue($name);
5694                 $val = DB::quoteValue(trim($val));
5695                 
5696                 $query = "UPDATE %s SET value=%s WHERE name=%s";
5697                 $query = sprintf($query, sql_table('config'), $val, $name);
5698                 if ( DB::execute($query) === FALSE )
5699                 {
5700                         $err = DB::getError();
5701                         die("Query error: " . $err[2]);
5702                 }
5703                 return DB::getInsertId();
5704         }
5705         
5706         /**
5707          * Error message
5708          * @param string $msg message that will be shown
5709          */
5710         function error($msg)
5711         {
5712                 $this->pagehead();
5713                 
5714                 echo "<h2>Error!</h2>\n";
5715                 echo $msg;
5716                 echo "<br />\n";
5717                 echo '<a href="index.php" onclick="history.back()">' . _BACK . "</a>\n";
5718                 $this->pagefoot();
5719                 exit;
5720         }
5721         
5722         /**
5723          * Admin::disallow()
5724          * add error log and show error page 
5725          * 
5726          * @param       void
5727          * @return      void
5728          */
5729         function disallow()
5730         {
5731                 ActionLog::add(WARNING, _ACTIONLOG_DISALLOWED . serverVar('REQUEST_URI'));
5732                 $this->error(_ERROR_DISALLOWED);
5733         }
5734         
5735         /**
5736          * Admin::pagehead()
5737          * Output admin page head
5738          * 
5739          * @param       void
5740          * @return      void
5741          */
5742         function pagehead($extrahead = '')
5743         {
5744                 global $member, $nucleus, $CONF, $manager;
5745                 
5746                 $manager->notify(
5747                         'AdminPrePageHead',
5748                         array(
5749                                 'extrahead' => &$extrahead,
5750                                 'action' => $this->action));
5751                 
5752                 $baseUrl = Entity::hsc($CONF['AdminURL']);
5753                 if ( !array_key_exists('AdminCSS',$CONF) )
5754                 {
5755                         DB::execute("INSERT INTO ".sql_table('config')." VALUES ('AdminCSS', 'original')");
5756                         $CONF['AdminCSS'] = 'original';
5757                 }
5758                 
5759                 /* HTTP 1.1 application for no caching */
5760                 header("Cache-Control: no-cache, must-revalidate");
5761                 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
5762                 
5763                 $root_element = 'html';
5764                 $charset = i18n::get_current_charset();
5765                 $locale = preg_replace('#_#', '-', i18n::get_current_locale());
5766                 
5767                 echo "<?xml version=\"{$this->xml_version_info}\" encoding=\"{$charset}\" ?>\n";
5768                 echo "<!DOCTYPE {$root_element} PUBLIC \"{$this->formal_public_identifier}\" \"{$this->system_identifier}\">\n";
5769                 echo "<{$root_element} xmlns=\"{$this->xhtml_namespace}\" xml:lang=\"{$locale}\" lang=\"{$locale}\">\n";
5770                 echo "<head>\n";
5771                 echo '<title>' . Entity::hsc($CONF['SiteName']) . " - Admin</title>\n";
5772                 echo "<link rel=\"stylesheet\" title=\"Nucleus Admin Default\" type=\"text/css\" href=\"{$baseUrl}styles/admin_{$CONF["AdminCSS"]}.css\" />\n";
5773                 echo "<link rel=\"stylesheet\" title=\"Nucleus Admin Default\" type=\"text/css\" href=\"{$baseUrl}styles/addedit.css\" />\n";
5774                 echo "<script type=\"text/javascript\" src=\"{$baseUrl}javascript/edit.js\"></script>\n";
5775                 echo "<script type=\"text/javascript\" src=\"{$baseUrl}javascript/admin.js\"></script>\n";
5776                 echo "<script type=\"text/javascript\" src=\"{$baseUrl}javascript/compatibility.js\"></script>\n";
5777                 echo "{$extrahead}\n";
5778                 echo "</head>\n\n";
5779                 echo "<body>\n";
5780                 echo "<div id=\"adminwrapper\">\n";
5781                 echo "<div class=\"header\">\n";
5782                 echo '<h1>' . Entity::hsc($CONF['SiteName']) . "</h1>\n";
5783                 echo "</div>\n";
5784                 echo "<div id=\"container\">\n";
5785                 echo "<div id=\"content\">\n";
5786                 echo "<div class=\"loginname\">\n";
5787                 if ( $member->isLoggedIn() )
5788                 {
5789                         echo _LOGGEDINAS . ' ' . $member->getDisplayName() ." - <a href='index.php?action=logout'>" . _LOGOUT. "</a><br />\n";
5790                         echo "<a href='index.php?action=overview'>" . _ADMINHOME . "</a> - ";
5791                 }
5792                 else
5793                 {
5794                         echo '<a href="index.php?action=showlogin" title="Log in">' . _NOTLOGGEDIN . "</a><br />\n";
5795                 }
5796                 echo "<a href='".$CONF['IndexURL']."'>"._YOURSITE."</a><br />\n";
5797                 echo '(';
5798                 
5799                 if (array_key_exists('codename', $nucleus) && $nucleus['codename'] != '' )
5800                 {
5801                         $codenamestring = ' &quot;' . $nucleus['codename'].'&quot;';
5802                 }
5803                 else
5804                 {
5805                         $codenamestring = '';
5806                 }
5807                 
5808                 if ( $member->isLoggedIn() && $member->isAdmin() )
5809                 {
5810                         $checkURL = sprintf(_ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_URL, getNucleusVersion(), getNucleusPatchLevel());
5811                         echo '<a href="' . $checkURL . '" title="' . _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_TITLE . '">Nucleus CMS ' . $nucleus['version'] . $codenamestring . '</a>';
5812                         
5813                         $newestVersion = getLatestVersion();
5814                         $newestCompare = str_replace('/','.',$newestVersion);
5815                         $currentVersion = str_replace(array('/','v'),array('.',''),$nucleus['version']);
5816                         if ( $newestVersion && version_compare($newestCompare, $currentVersion) > 0 )
5817                         {
5818                                 echo "<br />\n";
5819                                 echo '<a style="color:red" href="http://nucleuscms.org/upgrade.php" title="' . _ADMIN_SYSTEMOVERVIEW_LATESTVERSION_TITLE . '">';
5820                                 echo _ADMIN_SYSTEMOVERVIEW_LATESTVERSION_TEXT . $newestVersion;
5821                                 echo "</a>";
5822                         }
5823                 }
5824                 else
5825                 {
5826                         echo 'Nucleus CMS ' . $nucleus['version'] . $codenamestring;
5827                 }
5828                 echo ')';
5829                 echo '</div>';
5830                 return;
5831         }
5832         
5833         /**
5834          * Admin::pagefoot()
5835          * Output admin page foot include quickmenu
5836          * 
5837          * @param       void
5838          * @return      void
5839          */
5840         function pagefoot()
5841         {
5842                 global $action, $member, $manager;
5843                 
5844                 $manager->notify(
5845                         'AdminPrePageFoot',
5846                         array('action' => $this->action)
5847                 );
5848                 
5849                 if ( $member->isLoggedIn() && ($action != 'showlogin') )
5850                 {
5851                         echo '<h2>' . _LOGOUT . "</h2>\n";
5852                         echo "<ul>\n";
5853                         echo '<li><a href="index.php?action=overview">' . _BACKHOME . "</a></li>\n";
5854                         echo '<li><a href="index.php?action=logout">' .  _LOGOUT . "</a></li>\n";
5855                         echo "</ul>\n";
5856                 }
5857                 
5858                 echo "<div class=\"foot\">\n";
5859                 echo '<a href="' . _ADMINPAGEFOOT_OFFICIALURL . '">Nucleus CMS</a> &copy; 2002-' . date('Y') . ' ' . _ADMINPAGEFOOT_COPYRIGHT;
5860                 echo '-';
5861                 echo '<a href="' . _ADMINPAGEFOOT_DONATEURL . '">' . _ADMINPAGEFOOT_DONATE . "</a>\n";
5862                 echo "</div>\n";
5863                 
5864                 echo "<!-- content -->\n";
5865                 echo "<div id=\"quickmenu\">\n";
5866                 
5867                 if ( ($action != 'showlogin') && ($member->isLoggedIn()) )
5868                 {
5869                         echo "<ul>\n";
5870                         echo '<li><a href="index.php?action=overview">' . _QMENU_HOME . "</a></li>\n";
5871                         echo "</ul>\n";
5872                         
5873                         echo '<h2>' . _QMENU_ADD . "</h2>\n";
5874                         echo "<form method=\"get\" action=\"index.php\">\n";
5875                         echo "<p>\n";
5876                         echo "<input type=\"hidden\" name=\"action\" value=\"createitem\" />\n";
5877                         
5878                         $showAll = requestVar('showall');
5879                         
5880                         if ( ($member->isAdmin()) && ($showAll == 'yes') )
5881                         {
5882                                 // Super-Admins have access to all blogs! (no add item support though)
5883                                 $query =  'SELECT bnumber as value, bname as text'
5884                                                 . ' FROM ' . sql_table('blog')
5885                                                 . ' ORDER BY bname';
5886                         }
5887                         else
5888                         {
5889                                 $query =  'SELECT bnumber as value, bname as text'
5890                                                 . ' FROM ' . sql_table('blog') . ', ' . sql_table('team')
5891                                                 . ' WHERE tblog=bnumber and tmember=' . $member->getID()
5892                                                 . ' ORDER BY bname';
5893                         }
5894                         $template['name'] = 'blogid';
5895                         $template['tabindex'] = 15000;
5896                         $template['extra'] = _QMENU_ADD_SELECT;
5897                         $template['selected'] = -1;
5898                         $template['shorten'] = 10;
5899                         $template['shortenel'] = '';
5900                         $template['javascript'] = 'onchange="return form.submit()"';
5901                         showlist($query,'select',$template);
5902                         
5903                         echo "</p>\n";
5904                         echo "</form>\n";
5905                         
5906                         echo "<h2>{$member->getDisplayName()}</h2>\n";
5907                         echo "<ul>\n";
5908                         echo '<li><a href="index.php?action=editmembersettings">' . _QMENU_USER_SETTINGS . "</a></li>\n";
5909                         echo '<li><a href="index.php?action=browseownitems">' . _QMENU_USER_ITEMS . "</a></li>\n";
5910                         echo '<li><a href="index.php?action=browseowncomments">' . _QMENU_USER_COMMENTS . "</a></li>\n";
5911                         echo "</ul>\n";
5912                         
5913                         // ---- general settings ----
5914                         if ( $member->isAdmin() )
5915                         {
5916                                 echo '<h2>' . _QMENU_MANAGE . "</h2>\n";
5917                                 echo "<ul>\n";
5918                                 echo '<li><a href="index.php?action=actionlog">' . _QMENU_MANAGE_LOG . "</a></li>\n";
5919                                 echo '<li><a href="index.php?action=settingsedit">' . _QMENU_MANAGE_SETTINGS . "</a></li>\n";
5920                                 echo '<li><a href="index.php?action=systemoverview">' . _QMENU_MANAGE_SYSTEM . "</a></li>\n";
5921                                 echo '<li><a href="index.php?action=usermanagement">' . _QMENU_MANAGE_MEMBERS . "</a></li>\n";
5922                                 echo '<li><a href="index.php?action=createnewlog">' . _QMENU_MANAGE_NEWBLOG . "</a></li>\n";
5923                                 echo '<li><a href="index.php?action=backupoverview">' . _QMENU_MANAGE_BACKUPS . "</a></li>\n";
5924                                 echo '<li><a href="index.php?action=pluginlist">' . _QMENU_MANAGE_PLUGINS . "</a></li>\n";
5925                                 echo "</ul>\n";
5926                                 
5927                                 echo "<h2>" . _QMENU_LAYOUT . "</h2>\n";
5928                                 echo "<ul>\n";
5929                                 echo '<li><a href="index.php?action=skinoverview">' . _QMENU_LAYOUT_SKINS . "</a></li>\n";
5930                                 echo '<li><a href="index.php?action=templateoverview">' . _QMENU_LAYOUT_TEMPL . "</a></li>\n";
5931                                 echo '<li><a href="index.php?action=skinieoverview">' . _QMENU_LAYOUT_IEXPORT . "</a></li>\n";
5932                                 echo "</ul>\n";
5933                         }
5934                         
5935                         $aPluginExtras = array();
5936                         $manager->notify(
5937                                 'QuickMenu',
5938                                 array(
5939                                         'options' => &$aPluginExtras));
5940                         
5941                         if ( count($aPluginExtras) > 0 )
5942                         {
5943                                 echo "<h2>" . _QMENU_PLUGINS . "</h2>\n";
5944                                 echo "<ul>\n";
5945                                 foreach ( $aPluginExtras as $aInfo )
5946                                 {
5947                                         echo '<li><a href="' . Entity::hsc($aInfo['url']) . '" title="' . Entity::hsc($aInfo['tooltip']) . '">' . Entity::hsc($aInfo['title']) . "</a></li>\n";
5948                                 }
5949                                 echo "</ul>\n";
5950                         }
5951                 }
5952                 else if ( ($action == 'activate') || ($action == 'activatesetpwd') )
5953                 {
5954                 
5955                         echo '<h2>' . _QMENU_ACTIVATE . '</h2>' . _QMENU_ACTIVATE_TEXT;
5956                 }
5957                 else
5958                 {
5959                         // introduction text on login screen
5960                         echo '<h2>' . _QMENU_INTRO . '</h2>' . _QMENU_INTRO_TEXT;
5961                 }
5962                 
5963                 echo "<!-- quickmenu -->\n";
5964                 echo "</div>\n";
5965                 
5966                 echo "<!-- content -->\n";
5967                 echo "</div>\n";
5968                 
5969                 echo "<!-- container -->\n";
5970                 echo "</div>\n";
5971                 
5972                 echo "<!-- adminwrapper -->\n";
5973                 echo "</div>\n";
5974                 
5975                 echo "</body>\n";
5976                 echo "</html>\n";
5977                 return;
5978         }
5979         
5980         /**
5981          * Admin::action_bookmarklet()
5982          * 
5983          * @param       void
5984          * @return      void
5985          */
5986         public function action_bookmarklet()
5987         {
5988                 global $member, $manager;
5989                 
5990                 $blogid = intRequestVar('blogid');
5991                 $member->teamRights($blogid) or $this->disallow();
5992                 $blog =& $manager->getBlog($blogid);
5993                 
5994                 $this->pagehead();
5995                 
5996                 echo '<p><a href="index.php?action=overview">(' . _BACKHOME . ")</a></p>\n";
5997                 
5998                 echo '<h2>' . _BOOKMARKLET_TITLE . "</h2>\n";
5999                 echo '<p>';
6000                 echo _BOOKMARKLET_DESC1 . _BOOKMARKLET_DESC2 . _BOOKMARKLET_DESC3 . _BOOKMARKLET_DESC4 . _BOOKMARKLET_DESC5;
6001                 echo "</p>\n";
6002                 
6003                 echo '<h3>' . _BOOKMARKLET_BOOKARKLET . "</h3>\n";
6004                 echo '<p>';
6005                 echo _BOOKMARKLET_BMARKTEXT . '<small>' . _BOOKMARKLET_BMARKTEST . '</small>';
6006                 echo "</p>\n";
6007                 echo '<p>';
6008                 echo '<a href="javascript:' . rawurlencode(getBookmarklet($blogid)) . '">' . sprintf(_BOOKMARKLET_ANCHOR, Entity::hsc($blog->getName())) . '</a>';
6009                 echo _BOOKMARKLET_BMARKFOLLOW;
6010                 echo "</p>\n";
6011                 
6012                 $this->pagefoot();
6013                 return;
6014         }
6015         
6016     /**
6017      * @todo document this
6018      */
6019     function action_actionlog() {
6020         global $member, $manager;
6021
6022         $member->isAdmin() or $this->disallow();
6023
6024         $this->pagehead();
6025
6026         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
6027
6028         $url = $manager->addTicketToUrl('index.php?action=clearactionlog');
6029
6030         ?>
6031             <h2><?php echo _ACTIONLOG_CLEAR_TITLE ?></h2>
6032             <p><a href="<?php echo Entity::hsc($url) ?>"><?php echo _ACTIONLOG_CLEAR_TEXT ?></a></p>
6033         <?php
6034         echo '<h2>' . _ACTIONLOG_TITLE . '</h2>';
6035
6036         $query =  'SELECT * FROM '.sql_table('actionlog').' ORDER BY timestamp DESC';
6037         $template['content'] = 'actionlist';
6038         $amount = showlist($query,'table',$template);
6039
6040         $this->pagefoot();
6041
6042     }
6043
6044     /**
6045      * @todo document this
6046      */
6047     function action_banlist() {
6048         global $member, $manager;
6049
6050         $blogid = intRequestVar('blogid');
6051
6052         $member->blogAdminRights($blogid) or $this->disallow();
6053
6054         $blog =& $manager->getBlog($blogid);
6055
6056         $this->pagehead();
6057
6058         echo '<p><a href="index.php?action=overview">(',_BACKHOME,')</a></p>';
6059
6060         echo '<h2>' . _BAN_TITLE . " '". $this->bloglink($blog) ."'</h2>";
6061
6062         $query =  'SELECT * FROM '.sql_table('ban').' WHERE blogid='.$blogid.' ORDER BY iprange';
6063         $template['content'] = 'banlist';
6064         $amount = showlist($query,'table',$template);
6065
6066         if ($amount == 0)
6067             echo _BAN_NONE;
6068
6069         echo '<h2>'._BAN_NEW_TITLE.'</h2>';
6070         echo "<p><a href='index.php?action=banlistnew&amp;blogid=$blogid'>"._BAN_NEW_TEXT."</a></p>";
6071
6072
6073         $this->pagefoot();
6074
6075     }
6076
6077     /**
6078      * @todo document this
6079      */
6080     function action_banlistdelete() {
6081         global $member, $manager;
6082
6083         $blogid = intRequestVar('blogid');
6084         $iprange = requestVar('iprange');
6085
6086         $member->blogAdminRights($blogid) or $this->disallow();
6087
6088         $blog =& $manager->getBlog($blogid);
6089         $banBlogName =  Entity::hsc($blog->getName());
6090
6091         $this->pagehead();
6092         ?>
6093             <h2><?php echo _BAN_REMOVE_TITLE ?></h2>
6094
6095             <form method="post" action="index.php">
6096
6097             <h3><?php echo _BAN_IPRANGE ?></h3>
6098
6099             <p>
6100                 <?php echo _CONFIRMTXT_BAN ?> <?php echo Entity::hsc($iprange) ?>
6101                 <input name="iprange" type="hidden" value="<?php echo Entity::hsc($iprange) ?>" />
6102             </p>
6103
6104             <h3><?php echo _BAN_BLOGS ?></h3>
6105
6106             <div>
6107                 <input type="hidden" name="blogid" value="<?php echo $blogid ?>" />
6108                 <input name="allblogs" type="radio" value="0" id="allblogs_one" />
6109                 <label for="allblogs_one"><?php echo sprintf(_BAN_BANBLOGNAME, $banBlogName) ?></label>
6110                 <br />
6111                 <input name="allblogs" type="radio" value="1" checked="checked" id="allblogs_all" /><label for="allblogs_all"><?php echo _BAN_ALLBLOGS ?></label>
6112             </div>
6113
6114             <h3><?php echo _BAN_DELETE_TITLE ?></h3>
6115
6116             <div>
6117                 <?php $manager->addTicketHidden() ?>
6118                 <input type="hidden" name="action" value="banlistdeleteconfirm" />
6119                 <input type="submit" value="<?php echo _DELETE_CONFIRM_BTN ?>" />
6120             </div>
6121
6122             </form>
6123         <?php
6124         $this->pagefoot();
6125     }
6126
6127     /**
6128      * @todo document this
6129      */
6130     function action_banlistdeleteconfirm() {
6131         global $member, $manager;
6132
6133         $blogid = intPostVar('blogid');
6134         $allblogs = postVar('allblogs');
6135         $iprange = postVar('iprange');
6136
6137         $member->blogAdminRights($blogid) or $this->disallow();
6138
6139         $deleted = array();
6140
6141         if (!$allblogs) {
6142             if (Ban::removeBan($blogid, $iprange))
6143                 array_push($deleted, $blogid);
6144         } else {
6145             // get blogs fot which member has admin rights
6146             $adminblogs = $member->getAdminBlogs();
6147             foreach ($adminblogs as $blogje) {
6148                 if (Ban::removeBan($blogje, $iprange))
6149                     array_push($deleted, $blogje);
6150             }
6151         }
6152
6153         if (sizeof($deleted) == 0)
6154             $this->error(_ERROR_DELETEBAN);
6155
6156         $this->pagehead();
6157
6158         echo '<a href="index.php?action=banlist&amp;blogid=',$blogid,'">(',_BACK,')</a>';
6159         echo '<h2>'._BAN_REMOVED_TITLE.'</h2>';
6160         echo "<p>"._BAN_REMOVED_TEXT."</p>";
6161
6162         echo "<ul>";
6163         foreach ($deleted as $delblog) {
6164             $b =& $manager->getBlog($delblog);
6165             echo "<li>" . Entity::hsc($b->getName()). "</li>";
6166         }
6167         echo "</ul>";
6168
6169         $this->pagefoot();
6170
6171     }
6172
6173     /**
6174      * @todo document this
6175      */
6176     function action_banlistnewfromitem() {
6177         $this->action_banlistnew(getBlogIDFromItemID(intRequestVar('itemid')));
6178     }
6179
6180     /**
6181      * @todo document this
6182      */
6183     function action_banlistnew($blogid = '') {
6184         global $member, $manager;
6185
6186         if ($blogid == '')
6187             $blogid = intRequestVar('blogid');
6188
6189         $ip = requestVar('ip');
6190
6191         $member->blogAdminRights($blogid) or $this->disallow();
6192
6193         $blog =& $manager->getBlog($blogid);
6194
6195         $this->pagehead();
6196         ?>
6197         <h2><?php echo _BAN_ADD_TITLE ?></h2>
6198
6199
6200         <form method="post" action="index.php">
6201
6202         <h3><?php echo _BAN_IPRANGE ?></h3>
6203
6204         <p><?php echo _BAN_IPRANGE_TEXT ?></p>
6205
6206         <div class="note">
6207             <strong><?php echo _BAN_EXAMPLE_TITLE ?></strong>
6208             <?php echo _BAN_EXAMPLE_TEXT ?>
6209         </div>
6210
6211         <div>
6212         <?php
6213         if ($ip) {
6214             $iprangeVal = Entity::hsc($ip);
6215         ?>
6216             <input name="iprange" type="radio" value="<?php echo $iprangeVal ?>" checked="checked" id="ip_fixed" />
6217             <label for="ip_fixed"><?php echo $iprangeVal ?></label>
6218             <br />
6219             <input name="iprange" type="radio" value="custom" id="ip_custom" />
6220             <label for="ip_custom"><?php echo _BAN_IP_CUSTOM ?></label>
6221             <input name='customiprange' value='<?php echo $iprangeVal ?>' maxlength='15' size='15' />
6222         <?php
6223         } else {
6224             echo "<input name='iprange' value='custom' type='hidden' />";
6225             echo "<input name='customiprange' value='' maxlength='15' size='15' />";
6226         }
6227         ?>
6228         </div>
6229
6230         <h3><?php echo _BAN_BLOGS ?></h3>
6231
6232         <p><?php echo _BAN_BLOGS_TEXT ?></p>
6233
6234         <div>
6235             <input type="hidden" name="blogid" value="<?php echo $blogid ?>" />
6236             <input name="allblogs" type="radio" value="0" id="allblogs_one" /><label for="allblogs_one">'<?php echo Entity::hsc($blog->getName()) ?>'</label>
6237             <br />
6238             <input name="allblogs" type="radio" value="1" checked="checked" id="allblogs_all" /><label for="allblogs_all"><?php echo _BAN_ALLBLOGS ?></label>
6239         </div>
6240
6241         <h3><?php echo _BAN_REASON_TITLE ?></h3>
6242
6243         <p><?php echo _BAN_REASON_TEXT ?></p>
6244
6245         <div><textarea name="reason" cols="40" rows="5"></textarea></div>
6246
6247         <h3><?php echo _BAN_ADD_TITLE ?></h3>
6248
6249         <div>
6250             <input name="action" type="hidden" value="banlistadd" />
6251             <?php $manager->addTicketHidden() ?>
6252             <input type="submit" value="<?php echo _BAN_ADD_BTN ?>" />
6253         </div>
6254
6255         </form>
6256
6257         <?php       $this->pagefoot();
6258     }
6259
6260     /**
6261      * @todo document this
6262      */
6263     function action_banlistadd() {
6264         global $member;
6265
6266         $blogid =       intPostVar('blogid');
6267         $allblogs =     postVar('allblogs');
6268         $iprange =      postVar('iprange');
6269         if ($iprange == "custom")
6270             $iprange = postVar('customiprange');
6271         $reason =       postVar('reason');
6272
6273         $member->blogAdminRights($blogid) or $this->disallow();
6274
6275         // TODO: check IP range validity
6276
6277         if (!$allblogs) {
6278             if (!Ban::addBan($blogid, $iprange, $reason))
6279                 $this->error(_ERROR_ADDBAN);
6280         } else {
6281             // get blogs fot which member has admin rights
6282             $adminblogs = $member->getAdminBlogs();
6283             $failed = 0;
6284             foreach ($adminblogs as $blogje) {
6285                 if (!Ban::addBan($blogje, $iprange, $reason))
6286                     $failed = 1;
6287             }
6288             if ($failed)
6289                 $this->error(_ERROR_ADDBAN);
6290         }
6291
6292         $this->action_banlist();
6293
6294     }
6295
6296     /**
6297      * @todo document this
6298      */
6299     function action_clearactionlog() {
6300         global $member;
6301
6302         $member->isAdmin() or $this->disallow();
6303
6304         ActionLog::clear();
6305
6306         $this->action_manage(_MSG_ACTIONLOGCLEARED);
6307     }
6308
6309     /**
6310      * @todo document this
6311      */
6312     function action_backupoverview() {
6313         global $member, $manager;
6314
6315         $member->isAdmin() or $this->disallow();
6316
6317         $this->pagehead();
6318
6319         echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
6320         ?>
6321         <h2><?php echo _BACKUPS_TITLE ?></h2>
6322
6323         <h3><?php echo _BACKUP_TITLE ?></h3>
6324
6325         <p><?php echo _BACKUP_INTRO ?></p>
6326
6327         <form method="post" action="index.php"><p>
6328         <input type="hidden" name="action" value="backupcreate" />
6329         <?php $manager->addTicketHidden() ?>
6330
6331         <input type="radio" name="gzip" value="1" checked="checked" id="gzip_yes" tabindex="10" /><label for="gzip_yes"><?php echo _BACKUP_ZIP_YES ?></label>
6332         <br />
6333         <input type="radio" name="gzip" value="0" id="gzip_no" tabindex="10" /><label for="gzip_no" ><?php echo _BACKUP_ZIP_NO ?></label>
6334         <br /><br />
6335         <input type="submit" value="<?php echo _BACKUP_BTN ?>" tabindex="20" />
6336
6337         </p></form>
6338
6339         <div class="note"><?php echo _BACKUP_NOTE ?></div>
6340
6341
6342         <h3><?php echo _RESTORE_TITLE ?></h3>
6343
6344         <div class="note"><?php echo _RESTORE_NOTE ?></div>
6345
6346         <p><?php echo _RESTORE_INTRO ?></p>
6347
6348         <form method="post" action="index.php" enctype="multipart/form-data"><p>
6349             <input type="hidden" name="action" value="backuprestore" />
6350             <?php $manager->addTicketHidden() ?>
6351             <input name="backup_file" type="file" tabindex="30" />
6352             <br /><br />
6353             <input type="submit" value="<?php echo _RESTORE_BTN ?>" tabindex="40" />
6354             <br /><input type="checkbox" name="letsgo" value="1" id="letsgo" tabindex="50" /><label for="letsgo"><?php echo _RESTORE_IMSURE ?></label>
6355             <br /><?php echo _RESTORE_WARNING ?>
6356         </p></form>
6357
6358         <?php       $this->pagefoot();
6359     }
6360
6361         /**
6362          * Admin::action_backupcreate()
6363          * create file for backup
6364          * 
6365          * @param               void
6366          * @return      void
6367          * 
6368          */
6369         function action_backupcreate()
6370         {
6371                 global $member, $DIR_LIBS;
6372                 
6373                 $member->isAdmin() or $this->disallow();
6374                 
6375                 // use compression ?
6376                 $useGzip = (integer) postVar('gzip');
6377                 
6378                 include($DIR_LIBS . 'backup.php');
6379                 
6380                 // try to extend time limit
6381                 // (creating/restoring dumps might take a while)
6382                 @set_time_limit(1200);
6383                 
6384                 Backup::do_backup($useGzip);
6385                 exit;
6386         }
6387         
6388         /**
6389          * Admin::action_backuprestore()
6390          * restoring from uploaded file
6391          * 
6392          * @param               void
6393          * @return      void
6394          */
6395         function action_backuprestore()
6396         {
6397                 global $member, $DIR_LIBS;
6398                 
6399                 $member->isAdmin() or $this->disallow();
6400                 
6401                 if ( intPostVar('letsgo') != 1 )
6402                 {
6403                         $this->error(_ERROR_BACKUP_NOTSURE);
6404                 }
6405                 
6406                 include($DIR_LIBS . 'backup.php');
6407                 
6408                 // try to extend time limit
6409                 // (creating/restoring dumps might take a while)
6410                 @set_time_limit(1200);
6411                 
6412                 $message = Backup::do_restore();
6413                 if ( $message != '' )
6414                 {
6415                         $this->error($message);
6416                 }
6417                 $this->pagehead();
6418                 echo '<h2>' . _RESTORE_COMPLETE . "</h2>\n";
6419                 $this->pagefoot();
6420                 return;
6421         }
6422         
6423         /**
6424          * Admin::action_pluginlist()
6425          * output the list of installed plugins
6426          * 
6427          * @param       void
6428          * @return      void
6429          * 
6430          */
6431         function action_pluginlist()
6432         {
6433                 global $DIR_PLUGINS, $member, $manager;
6434                 
6435                 // check if allowed
6436                 $member->isAdmin() or $this->disallow();
6437                 
6438                 $this->pagehead();
6439                 
6440                 echo '<p><a href="index.php?action=manage">(',_BACKTOMANAGE,')</a></p>';
6441                 
6442                 echo '<h2>' , _PLUGS_TITLE_MANAGE , ' ', help('plugins'), '</h2>';
6443                 
6444                 echo '<h3>' , _PLUGS_TITLE_INSTALLED , ' &nbsp;&nbsp;<span style="font-size:smaller">', helplink('getplugins'), _PLUGS_TITLE_GETPLUGINS, '</a></span></h3>';
6445                 
6446                 $query =  'SELECT * FROM '.sql_table('plugin').' ORDER BY porder ASC';
6447                 
6448                 $template['content'] = 'pluginlist';
6449                 $template['tabindex'] = 10;
6450                 showlist($query, 'table', $template);
6451                 
6452                 echo '<h3>' . _PLUGS_TITLE_UPDATE . "</h3>\n";
6453                 echo '<p>' . _PLUGS_TEXT_UPDATE . "</p>\n";
6454                 echo '<form method="post" action="index.php">' . "\n";
6455                 echo "<div>\n";
6456                 echo '<input type="hidden" name="action" value="pluginupdate" />' . "\n";
6457                 $manager->addTicketHidden();
6458                 echo '<input type="submit" value="' . _PLUGS_BTN_UPDATE . '" tabindex="20" />' . "\n";
6459                 echo "</div>\n";
6460                 echo "</form>\n";
6461                 
6462                 echo '<h3>' . _PLUGS_TITLE_NEW . "</h3>\n";
6463                 
6464                 // find a list of possibly non-installed plugins
6465                 $candidates = array();
6466                 $dirhandle = opendir($DIR_PLUGINS);
6467                 
6468                 while ( $filename = readdir($dirhandle) )
6469                 {
6470                         if ( preg_match('#^NP_(.*)\.php$#', $filename, $matches) )
6471                         {
6472                                 $name = $matches[1];
6473                                 
6474                                 // only show in list when not yet installed
6475                                 $query = 'SELECT * FROM %s WHERE pfile = %s';
6476                                 $query = sprintf($query, sql_table('plugin'), DB::quoteValue('NP_'.$name));
6477                                 $res = DB::getResult($query);
6478                                 
6479                                 if ( $res->rowCount() == 0 )
6480                                 {
6481                                         array_push($candidates, $name);
6482                                 }
6483                         }
6484                 }
6485                 
6486                 closedir($dirhandle);
6487                 
6488                 if ( sizeof($candidates) > 0 )
6489                 {
6490                         echo '<p>' . _PLUGS_ADD_TEXT . "</p>\n";
6491                         
6492                         echo '<form method="post" action="index.php">' . "\n";
6493                         echo "<div>\n";
6494                         echo '<input type="hidden" name="action" value="pluginadd" />' . "\n";
6495                         $manager->addTicketHidden();
6496                         echo '<select name="filename" tabindex="30">' . "\n";
6497                         
6498                         foreach ( $candidates as $name )
6499                         {
6500                                 echo '<option value="NP_',$name,'">',Entity::hsc($name),'</option>';
6501                         }
6502                         
6503                         echo "</select>\n";
6504                         echo '<input type="submit" tabindex="40" value="' . _PLUGS_BTN_INSTALL ."\" />\n";
6505                         echo "</div>\n";
6506                         echo "</form>\n";
6507                 }
6508                 else
6509                 {
6510                         echo '<p>', _PLUGS_NOCANDIDATES, '</p>';
6511                 }
6512                 
6513                 $this->pagefoot();
6514                 return;
6515         }
6516         
6517     /**
6518      * @todo document this
6519      */
6520     function action_pluginhelp() {
6521         global $member, $manager, $DIR_PLUGINS, $CONF;
6522
6523         // check if allowed
6524         $member->isAdmin() or $this->disallow();
6525
6526         $plugid = intGetVar('plugid');
6527
6528         if (!$manager->pidInstalled($plugid))
6529             $this->error(_ERROR_NOSUCHPLUGIN);
6530
6531         $plugName = $manager->getPluginNameFromPid($plugid);
6532
6533         $this->pagehead();
6534
6535         echo '<p><a href="index.php?action=pluginlist">(',_PLUGS_BACK,')</a></p>';
6536
6537         echo '<h2>',_PLUGS_HELP_TITLE,': ',Entity::hsc($plugName),'</h2>';
6538
6539         $plug =& $manager->getPlugin($plugName);
6540         $helpFile = $DIR_PLUGINS.$plug->getShortName().'/help.html';
6541
6542         if (($plug->supportsFeature('HelpPage') > 0) && (@file_exists($helpFile))) {
6543             @readfile($helpFile);
6544         } else {
6545             echo '<p>Error: ', _ERROR_PLUGNOHELPFILE,'</p>';
6546             echo '<p><a href="index.php?action=pluginlist">(',_BACK,')</a></p>';
6547         }
6548
6549
6550         $this->pagefoot();
6551     }
6552
6553         /**
6554          * Admin::action_pluginadd()
6555          * 
6556          * @param       Void
6557          * @return      Void
6558          * 
6559          */
6560         function action_pluginadd()
6561         {
6562                 global $member, $manager, $DIR_PLUGINS;
6563                 
6564                 // check if allowed
6565                 $member->isAdmin() or $this->disallow();
6566                 
6567                 $name = postVar('filename');
6568                 
6569                 if ( $manager->pluginInstalled($name) )
6570                 {
6571                         $this->error(_ERROR_DUPPLUGIN);
6572                 }
6573                 
6574                 if ( !checkPlugin($name) )
6575                 {
6576                         $this->error(_ERROR_PLUGFILEERROR . ' (' . Entity::hsc($name) . ')');
6577                 }
6578                 
6579                 // get number of currently installed plugins
6580                 $res = DB::getResult('SELECT * FROM '.sql_table('plugin'));
6581                 $numCurrent = $res->rowCount();
6582                 
6583                 // plugin will be added as last one in the list
6584                 $newOrder = $numCurrent + 1;
6585                 
6586                 $manager->notify(
6587                         'PreAddPlugin',
6588                         array(
6589                                 'file' => &$name
6590                         )
6591                 );
6592                 
6593                 // do this before calling getPlugin (in case the plugin id is used there)
6594                 $query = 'INSERT INTO '.sql_table('plugin').' (porder, pfile) VALUES ('.$newOrder.','.DB::quoteValue($name).')';
6595                 DB::execute($query);
6596                 $iPid = DB::getInsertId();
6597                 
6598                 $manager->clearCachedInfo('installedPlugins');
6599                 
6600                 // Load the plugin for condition checking and instalation
6601                 $plugin =& $manager->getPlugin($name);
6602                 
6603                 // check if it got loaded (could have failed)
6604                 if ( !$plugin )
6605                 {
6606                         DB::execute('DELETE FROM ' . sql_table('plugin') . ' WHERE pid='. intval($iPid));
6607                         $manager->clearCachedInfo('installedPlugins');
6608                         $this->error(_ERROR_PLUGIN_LOAD);
6609                 }
6610                 
6611                 // check if plugin needs a newer Nucleus version
6612                 if ( getNucleusVersion() < $plugin->getMinNucleusVersion() )
6613                 {
6614                         // uninstall plugin again...
6615                         $this->deleteOnePlugin($plugin->getID());
6616                         
6617                         // ...and show error
6618                         $this->error(_ERROR_NUCLEUSVERSIONREQ . Entity::hsc($plugin->getMinNucleusVersion()));
6619                 }
6620                 
6621                 // check if plugin needs a newer Nucleus version
6622                 if ( (getNucleusVersion() == $plugin->getMinNucleusVersion()) && (getNucleusPatchLevel() < $plugin->getMinNucleusPatchLevel()) )
6623                 {
6624                         // uninstall plugin again...
6625                         $this->deleteOnePlugin($plugin->getID());
6626                         
6627                         // ...and show error
6628                         $this->error(_ERROR_NUCLEUSVERSIONREQ . Entity::hsc( $plugin->getMinNucleusVersion() . ' patch ' . $plugin->getMinNucleusPatchLevel() ) );
6629                 }
6630                 
6631                 $pluginList = $plugin->getPluginDep();
6632                 foreach ( $pluginList as $pluginName )
6633                 {
6634                         $res = DB::getResult('SELECT * FROM '.sql_table('plugin') . ' WHERE pfile=' . DB::quoteValue($pluginName));
6635                         if ($res->rowCount() == 0)
6636                         {
6637                                 // uninstall plugin again...
6638                                 $this->deleteOnePlugin($plugin->getID());
6639                                 $this->error(sprintf(_ERROR_INSREQPLUGIN, Entity::hsc($pluginName)));
6640                         }
6641                 }
6642                 
6643                 // call the install method of the plugin
6644                 $plugin->install();
6645                 
6646                 $manager->notify(
6647                         'PostAddPlugin',
6648                         array(
6649                                 'plugin' => &$plugin
6650                         )
6651                 );
6652                 
6653                 // update all events
6654                 $this->action_pluginupdate();
6655                 return;
6656         }
6657         
6658         /**
6659          * ADMIN:action_pluginupdate():
6660          * 
6661          * @param       Void
6662          * @return      Void
6663          * 
6664          */
6665         function action_pluginupdate()
6666         {
6667                 global $member, $manager, $CONF;
6668                 
6669                 // check if allowed
6670                 $member->isAdmin() or $this->disallow();
6671                 
6672                 // delete everything from plugin_events
6673                 DB::execute('DELETE FROM '.sql_table('plugin_event'));
6674                 
6675                 // loop over all installed plugins
6676                 $res = DB::getResult('SELECT pid, pfile FROM '.sql_table('plugin'));
6677                 foreach ( $res as $row )
6678                 {
6679                         $pid = $row['pid'];
6680                         $plug =& $manager->getPlugin($row['pfile']);
6681                         if ( $plug )
6682                         {
6683                                 $eventList = $plug->getEventList();
6684                                 foreach ( $eventList as $eventName )
6685                                 {
6686                                         $query = "INSERT INTO %s (pid, event) VALUES (%d, %s)";
6687                                         $query = sprintf($query, sql_table('plugin_event'), (integer) $pid, DB::quoteValue($eventName));
6688                                         DB::execute($query);
6689                                 }
6690                         }
6691                 }
6692                 redirect($CONF['AdminURL'] . '?action=pluginlist');
6693                 return;
6694         }
6695         
6696     /**
6697      * @todo document this
6698      */
6699     function action_plugindelete() {
6700         global $member, $manager;
6701
6702         // check if allowed
6703         $member->isAdmin() or $this->disallow();
6704
6705         $pid = intGetVar('plugid');
6706
6707         if (!$manager->pidInstalled($pid))
6708             $this->error(_ERROR_NOSUCHPLUGIN);
6709
6710         $this->pagehead();
6711         ?>
6712             <h2><?php echo _DELETE_CONFIRM ?></h2>
6713
6714             <p><?php echo _CONFIRMTXT_PLUGIN ?> <strong><?php echo $manager->getPluginNameFromPid($pid) ?></strong>?</p>
6715
6716             <form method="post" action="index.php"><div>
6717             <?php $manager->addTicketHidden() ?>
6718             <input type="hidden" name="action" value="plugindeleteconfirm" />
6719             <input type="hidden" name="plugid" value="<?php echo $pid; ?>" />
6720             <input type="submit" tabindex="10" value="<?php echo _DELETE_CONFIRM_BTN ?>" />
6721             </div></form>
6722         <?php
6723         $this->pagefoot();
6724     }
6725
6726     /**
6727      * @todo document this
6728      */
6729     function action_plugindeleteconfirm() {
6730         global $member, $manager, $CONF;
6731
6732         // check if allowed
6733         $member->isAdmin() or $this->disallow();
6734
6735         $pid = intPostVar('plugid');
6736
6737         $error = $this->deleteOnePlugin($pid, 1);
6738         if ($error) {
6739             $this->error($error);
6740         }
6741
6742         redirect($CONF['AdminURL'] . '?action=pluginlist');
6743 //              $this->action_pluginlist();
6744     }
6745
6746     /**
6747      * @todo document this
6748      */
6749     function deleteOnePlugin($pid, $callUninstall = 0) {
6750         global $manager;
6751
6752         $pid = intval($pid);
6753
6754         if (!$manager->pidInstalled($pid))
6755             return _ERROR_NOSUCHPLUGIN;
6756
6757         $name = DB::getValue('SELECT pfile as result FROM '.sql_table('plugin').' WHERE pid='.$pid);
6758
6759 /*              // call the unInstall method of the plugin
6760         if ($callUninstall) {
6761             $plugin =& $manager->getPlugin($name);
6762             if ($plugin) $plugin->unInstall();
6763         }*/
6764
6765         // check dependency before delete
6766         $res = DB::getResult('SELECT pfile FROM '.sql_table('plugin'));
6767         foreach ( $res as $row ) {
6768             $plug =& $manager->getPlugin($row['pfile']);
6769             if ($plug)
6770             {
6771                 $depList = $plug->getPluginDep();
6772                 foreach ($depList as $depName)
6773                 {
6774                     if ($name == $depName)
6775                     {
6776                         return sprintf(_ERROR_DELREQPLUGIN, $row['pfile']);
6777                     }
6778                 }
6779             }
6780         }
6781
6782         $manager->notify('PreDeletePlugin', array('plugid' => $pid));
6783
6784         // call the unInstall method of the plugin
6785         if ($callUninstall) {
6786             $plugin =& $manager->getPlugin($name);
6787             if ($plugin) $plugin->unInstall();
6788         }
6789
6790         // delete all subscriptions
6791         DB::execute('DELETE FROM '.sql_table('plugin_event').' WHERE pid=' . $pid);
6792
6793         // delete all options
6794         // get OIDs from plugin_option_desc
6795         $res = DB::getResult('SELECT oid FROM ' . sql_table('plugin_option_desc') . ' WHERE opid=' . $pid);
6796         $aOIDs = array();
6797         foreach ( $res as $row ) {
6798             array_push($aOIDs, $row['oid']);
6799         }
6800
6801         // delete from plugin_option and plugin_option_desc
6802         DB::execute('DELETE FROM '.sql_table('plugin_option_desc').' WHERE opid=' . $pid);
6803         if (count($aOIDs) > 0)
6804             DB::execute('DELETE FROM '.sql_table('plugin_option').' WHERE oid in ('.implode(',',$aOIDs).')');
6805
6806         // update order numbers
6807         $res = DB::getValue('SELECT porder FROM '.sql_table('plugin').' WHERE pid=' . $pid);
6808         DB::execute('UPDATE '.sql_table('plugin').' SET porder=(porder - 1) WHERE porder>'.$res);
6809
6810         // delete row
6811         DB::execute('DELETE FROM '.sql_table('plugin').' WHERE pid='.$pid);
6812
6813         $manager->clearCachedInfo('installedPlugins');
6814         $manager->notify('PostDeletePlugin', array('plugid' => $pid));
6815
6816         return '';
6817     }
6818
6819     /**
6820      * @todo document this
6821      */
6822     function action_pluginup() {
6823         global $member, $manager, $CONF;
6824
6825         // check if allowed
6826         $member->isAdmin() or $this->disallow();
6827
6828         $plugid = intGetVar('plugid');
6829
6830         if (!$manager->pidInstalled($plugid))
6831             $this->error(_ERROR_NOSUCHPLUGIN);
6832
6833         // 1. get old order number
6834         $oldOrder = DB::getValue('SELECT porder FROM '.sql_table('plugin').' WHERE pid='.$plugid);
6835
6836         // 2. calculate new order number
6837         $newOrder = ($oldOrder > 1) ? ($oldOrder - 1) : 1;
6838
6839         // 3. update plug numbers
6840         DB::execute('UPDATE '.sql_table('plugin').' SET porder='.$oldOrder.' WHERE porder='.$newOrder);
6841         DB::execute('UPDATE '.sql_table('plugin').' SET porder='.$newOrder.' WHERE pid='.$plugid);
6842
6843         //$this->action_pluginlist();
6844         // To avoid showing ticket in the URL, redirect to pluginlist, instead.
6845         redirect($CONF['AdminURL'] . '?action=pluginlist');
6846     }
6847
6848     /**
6849      * @todo document this
6850      */
6851     function action_plugindown() {
6852         global $member, $manager, $CONF;
6853
6854         // check if allowed
6855         $member->isAdmin() or $this->disallow();
6856
6857         $plugid = intGetVar('plugid');
6858         if (!$manager->pidInstalled($plugid))
6859             $this->error(_ERROR_NOSUCHPLUGIN);
6860
6861         // 1. get old order number
6862         $oldOrder = DB::getValue('SELECT porder FROM '.sql_table('plugin').' WHERE pid='.$plugid);
6863
6864         $res = DB::getResult('SELECT * FROM '.sql_table('plugin'));
6865         $maxOrder = $res->rowCount();
6866
6867         // 2. calculate new order number
6868         $newOrder = ($oldOrder < $maxOrder) ? ($oldOrder + 1) : $maxOrder;
6869
6870         // 3. update plug numbers
6871         DB::execute('UPDATE '.sql_table('plugin').' SET porder='.$oldOrder.' WHERE porder='.$newOrder);
6872         DB::execute('UPDATE '.sql_table('plugin').' SET porder='.$newOrder.' WHERE pid='.$plugid);
6873
6874         //$this->action_pluginlist();
6875         // To avoid showing ticket in the URL, redirect to pluginlist, instead.
6876         redirect($CONF['AdminURL'] . '?action=pluginlist');
6877     }
6878         
6879         /**
6880          * Admin::action_pluginoptions()
6881          * 
6882          * Output Plugin option page
6883          * 
6884          * @access      public
6885          * @param       string $message message when fallbacked
6886          * @return      void
6887          * 
6888          */
6889         public function action_pluginoptions($message = '')
6890         {
6891                 global $member, $manager;
6892                 
6893                 // check if allowed
6894                 $member->isAdmin() or $this->disallow();
6895                 
6896                 $pid = (integer) requestVar('plugid');
6897                 if ( !$manager->pidInstalled($pid) )
6898                 {
6899                         $this->error(_ERROR_NOSUCHPLUGIN);
6900                 }
6901                 
6902                 $pname = $manager->getPluginNameFromPid($pid);
6903                 
6904                 /* NOTE: to include translation file */
6905                 $manager->getPlugin($pname);
6906                 
6907                 $extrahead = "<script type=\"text/javascript\" src=\"javascript/numbercheck.js\"></script>\n";
6908                 $this->pagehead($extrahead);
6909                 echo '<p><a href="index.php?action=pluginlist">(' . _PLUGS_BACK . ")</a></p>\n";
6910                 echo '<h2>' . sprintf(_PLUGIN_OPTIONS_TITLE, Entity::hsc($pname)) . "</h2>\n";
6911                 
6912                 if ( isset($message) )
6913                 {
6914                         echo $message;
6915                 }
6916                 
6917                 echo "<form action=\"index.php\" method=\"post\">\n";
6918                 echo "<div>\n";
6919                 echo "<input type=\"hidden\" name=\"action\" value=\"pluginoptionsupdate\" />\n";
6920                 echo "<input type=\"hidden\" name=\"plugid\" value=\"{$pid}\" />\n";
6921                 $manager->addTicketHidden();
6922                 
6923                 $options = array();
6924                 $query = "SELECT * FROM %s WHERE ocontext='global' and opid=%d ORDER BY oid ASC";
6925                 $query = sprintf($query, sql_table('plugin_option_desc'), $pid);
6926                 $result = DB::getResult($query);
6927                 foreach ( $result as $row )
6928                 {
6929                         $options[$row['oid']] = array(
6930                                 'oid'           => $row['oid'],
6931                                 'value'         => $row['odef'],
6932                                 'name'          => $row['oname'],
6933                                 'description' => $row['odesc'],
6934                                 'type'          => $row['otype'],
6935                                 'typeinfo'      => $row['oextra'],
6936                                 'contextid'     => 0
6937                         );
6938                 }
6939                 // fill out actual values
6940                 if ( count($options) > 0 )
6941                 {
6942                         $query = "SELECT oid, ovalue FROM %s WHERE oid in (%s)";
6943                         $query = sprintf($query, sql_table('plugin_option'), implode(',',array_keys($options)));
6944                         $result = DB::getResult($query);
6945                         foreach ( $result as $row )
6946                         {
6947                                 $options[$row['oid']]['value'] = $row['ovalue'];
6948                         }
6949                 }
6950                 
6951                 // call plugins
6952                 $data = array('context' => 'global', 'plugid' => $pid, 'options'=>&$options);
6953                 $manager->notify('PrePluginOptionsEdit',$data);
6954                 
6955                 $template['content'] = 'plugoptionlist';
6956                 $amount = showlist($options,'table', $template);
6957                 if ( $amount == 0 )
6958                 {
6959                         echo '<p>',_ERROR_NOPLUGOPTIONS,'</p>';
6960                 }
6961                 echo "</div>\n";
6962                 echo "</form>\n";
6963                 $this->pagefoot();
6964                 
6965                 return;
6966         }
6967         
6968         /**
6969          * Admin::action_pluginoptionsupdate()
6970          * 
6971          * Update plugin options and fallback to plugin option page
6972          * 
6973          * @access      public
6974          * @param       void
6975          * @return      void
6976          */
6977         public function action_pluginoptionsupdate()
6978         {
6979                 global $member, $manager;
6980                 
6981                 // check if allowed
6982                 $member->isAdmin() or $this->disallow();
6983                 
6984                 $pid = (integer) requestVar('plugid');
6985                 if ( !$manager->pidInstalled($pid) )
6986                 {
6987                         $this->error(_ERROR_NOSUCHPLUGIN);
6988                 }
6989                 
6990                 $aOptions = requestArray('plugoption');
6991                 NucleusPlugin::apply_plugin_options($aOptions);
6992                 
6993                 $manager->notify('PostPluginOptionsUpdate',array('context' => 'global', 'plugid' => $pid));
6994                 
6995                 $this->action_pluginoptions(_PLUGS_OPTIONS_UPDATED);
6996                 return;
6997         }
6998         
6999         /**
7000          * Admin::_insertPluginOptions()
7001          * 
7002          * Output plugin option field
7003          * 
7004          * @access      public
7005          * @param string        $context        plugin option context
7006          * @param integer       $contextid      plugin option context id
7007          * @return      void
7008          */
7009         public function _insertPluginOptions($context, $contextid = 0)
7010         {
7011                 global $manager;
7012                 
7013                 /* get current registered plugin option list in this context even if it's not used */
7014                 $query = 'SELECT * FROM %s AS plugins, %s AS options LEFT OUTER JOIN %s AS added '
7015                        . 'ON ( options.oid=added.oid ) '
7016                        . 'WHERE plugins.pid=options.opid AND options.ocontext=%s AND added.ocontextid=%d '
7017                        . 'ORDER BY options.oid ASC';
7018                 $query = sprintf($query, sql_table('plugin'), sql_table('plugin_option_desc'), sql_table('plugin_option'), DB::quoteValue($context), intval($contextid));
7019                 
7020                 $res = DB::getResult($query);
7021                 
7022                 $options = array();
7023                 foreach ( $res as $row )
7024                 {
7025                         /* NOTE: to include translation file */
7026                         $manager->getPlugin($row['pfile']);
7027                         
7028                         $options[] = array(
7029                                 'pid'           => $row['pid'],
7030                                 'pfile'         => $row['pfile'],
7031                                 'oid'           => $row['oid'],
7032                                 'value'         => ( !$row['ovalue'] ) ? $row['odef'] : $row['ovalue'],
7033                                 'name'          => $row['oname'],
7034                                 'description' => $row['odesc'],
7035                                 'type'          => $row['otype'],
7036                                 'typeinfo'      => $row['oextra'],
7037                                 'contextid'     => $contextid,
7038                                 'extra'         => ''
7039                         );
7040                 }
7041                 
7042                 $manager->notify('PrePluginOptionsEdit',array('context' => $context, 'contextid' => $contextid, 'options'=>&$options));
7043                 
7044                 $iPrevPid = -1;
7045                 foreach ( $options as $option)
7046                 {
7047                         // new plugin?
7048                         if ( $iPrevPid != $option['pid'] )
7049                         {
7050                                 $iPrevPid = $option['pid'];
7051                                 if ( !defined('_PLUGIN_OPTIONS_TITLE') )
7052                                 {
7053                                         define('_PLUGIN_OPTIONS_TITLE', 'Options for %s');
7054                                 }
7055                                 echo "<tr>\n";
7056                                 echo '<th colspan="2">' . sprintf(_PLUGIN_OPTIONS_TITLE, Entity::hsc($option['pfile'])) . "</th>\n";
7057                                 echo "</tr>\n";
7058                         }
7059                         
7060                         $meta = NucleusPlugin::getOptionMeta($option['typeinfo']);
7061                         if ( @$meta['access'] != 'hidden' )
7062                         {
7063                                 echo '<tr>';
7064                                 listplug_plugOptionRow($option);
7065                                 echo '</tr>';
7066                         }
7067                 }
7068                 return;
7069         }
7070         
7071         /**
7072          * Admin::input_yesno()
7073          * Output input elements with radio attribute for yes/no options
7074          * 
7075          * @param       string  $name   name attribute
7076          * @param       string  $value_current  current value attribute
7077          * @param       integer $tabindex       tab index
7078          * @param       string  $value_yes      value attribute for yes option
7079          * @param       string  $value_no       value attribute for no option
7080          * @param       string  $text_yes       child text element for yes option
7081          * @param       string  $text_no        child text element for no option
7082          * @param       boolean $isAdmin        have admin right or not
7083          * @return      void
7084          */
7085         function input_yesno($name, $value_current, $tabindex = 0, $value_yes = 1, $value_no = 0, $text_yes = _YES, $text_no = _NO, $isAdmin = 0)
7086         {
7087                 $id = preg_replace('#\[|\]#', '-', $name);
7088                 $id_yes = $id . $value_yes;
7089                 $id_no  = $id . $value_no;
7090                 
7091                 /* yes option */
7092                 echo '<input type="radio" id="' . Entity::hsc($id_yes) . '" name="' . Entity::hsc($name) . '" value="' . Entity::hsc($value_yes) . '"';
7093                 if ( $name=="admin" )
7094                 {
7095                         echo ' onclick="selectCanLogin(true);"';
7096                 }
7097                 if ( $value_current == $value_yes )
7098                 {
7099                         echo " tabindex='$tabindex' checked='checked'";
7100                 }
7101                 echo " />\n";
7102                 echo '<label for="' . Entity::hsc($id_yes) . '">' . Entity::hsc($text_yes) . "</label>\n";
7103                 
7104                 /* no option */
7105                 echo '<input type="radio" id="' . Entity::hsc($id_no) . '" name="' . Entity::hsc($name) . '" value="' . Entity::hsc($value_no) . '"';
7106                 if ( $name=="admin" )
7107                 {
7108                         echo ' onclick="selectCanLogin(false);"';
7109                 }
7110                 if ( $value_current != $value_yes )
7111                 {
7112                         echo " tabindex='$tabindex' checked='checked'";
7113                 }
7114                 if ($isAdmin && $name=="canlogin")
7115                 {
7116                         echo ' disabled="disabled"';
7117                 }
7118                 echo " />\n";
7119                 echo '<label for="' . Entity::hsc($id_no) . '">' . Entity::hsc($text_no) . "</label>\n";
7120                 
7121                 return;
7122         }
7123 }