OSDN Git Service

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