OSDN Git Service

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