plugins/admin/ThemeManager.php
changeset 433 c892b2013d3e
child 465 fe8b8c9b54e8
equal deleted inserted replaced
431:ceff43bbc3d3 433:c892b2013d3e
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
       
     5  * Version 1.1.2 (Caoineag alpha 2)
       
     6  * Copyright (C) 2006-2007 Dan Fuhry
       
     7  *
       
     8  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
       
     9  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
       
    12  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
       
    13  */
       
    14 
       
    15 function page_Admin_ThemeManager()
       
    16 {
       
    17   global $db, $session, $paths, $template, $plugins; // Common objects
       
    18   global $lang;
       
    19   if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
       
    20   {
       
    21     $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
       
    22     echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
       
    23     echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
       
    24     return;
       
    25   }
       
    26   
       
    27   $system_themes = array('admin', 'printable');
       
    28   
       
    29   // Obtain the list of themes (both available and already installed) and the styles available for each
       
    30   $dh = @opendir(ENANO_ROOT . '/themes');
       
    31   if ( !$dh )
       
    32     die('Couldn\'t open themes directory');
       
    33   $themes = array();
       
    34   while ( $dr = @readdir($dh) )
       
    35   {
       
    36     if ( $dr == '.' || $dr == '..' )
       
    37       continue;
       
    38     if ( !is_dir(ENANO_ROOT . "/themes/$dr") )
       
    39       continue;
       
    40     if ( !file_exists(ENANO_ROOT . "/themes/$dr/theme.cfg") || !is_dir(ENANO_ROOT . "/themes/$dr/css") )
       
    41       continue;
       
    42     $cdh = @opendir(ENANO_ROOT . "/themes/$dr/css");
       
    43     if ( !$cdh )
       
    44       continue;
       
    45     
       
    46     require(ENANO_ROOT . "/themes/$dr/theme.cfg");
       
    47     global $theme;
       
    48     
       
    49     $themes[$dr] = array(
       
    50         'css' => array(),
       
    51         'theme_name' => $theme['theme_name']
       
    52       );
       
    53     while ( $cdr = @readdir($cdh) )
       
    54     {
       
    55       if ( $cdr == '.' || $cdr == '..' )
       
    56         continue;
       
    57       if ( preg_match('/\.css$/i', $cdr) )
       
    58         $themes[$dr]['css'][] = substr($cdr, 0, -4);
       
    59     }
       
    60   }
       
    61   
       
    62   // Decide which themes are not installed
       
    63   $installable = array_flip(array_keys($themes));
       
    64   // FIXME: sanitize directory names or check with preg_match()
       
    65   $where_clause = 'theme_id = \'' . implode('\' OR theme_id = \'', array_flip($installable)) . '\'';
       
    66   $q = $db->sql_query('SELECT theme_id, theme_name, enabled FROM ' . table_prefix . "themes WHERE $where_clause;");
       
    67   if ( !$q )
       
    68     $db->_die();
       
    69   
       
    70   while ( $row = $db->fetchrow() )
       
    71   {
       
    72     $tid =& $row['theme_id'];
       
    73     unset($installable[$tid]);
       
    74     $themes[$tid]['theme_name'] = $row['theme_name'];
       
    75     $themes[$tid]['enabled'] = ( $row['enabled'] == 1 );
       
    76   }
       
    77   
       
    78   foreach ( $system_themes as $st )
       
    79   {
       
    80     unset($installable[$st]);
       
    81   }
       
    82   
       
    83   $installable = array_flip($installable);
       
    84   
       
    85   // AJAX code
       
    86   if ( $paths->getParam(0) === 'action.json' )
       
    87   {
       
    88     return ajaxServlet_Admin_ThemeManager($themes);
       
    89   }
       
    90   
       
    91   // List installed themes
       
    92   ?>
       
    93   <div style="float: right;">
       
    94     <a href="#" id="systheme_toggler" onclick="ajaxToggleSystemThemes(); return false;"><?php echo $lang->get('acptm_btn_system_themes_show'); ?></a>
       
    95   </div>
       
    96   <?php
       
    97   echo '<h3>' . $lang->get('acptm_heading_edit_themes') . '</h3>';
       
    98   echo '<div id="theme_list_edit">';
       
    99   foreach ( $themes as $theme_id => $theme_data )
       
   100   {
       
   101     if ( in_array($theme_id, $installable) )
       
   102       continue;
       
   103     if ( file_exists(ENANO_ROOT . "/themes/$theme_id/preview.png") )
       
   104     {
       
   105       $preview_path = scriptPath . "/themes/$theme_id/preview.png";
       
   106     }
       
   107     else
       
   108     {
       
   109       $preview_path = scriptPath . "/images/themepreview.png";
       
   110     }
       
   111     $d = ( @$theme_data['enabled'] ) ? '' : ' themebutton_theme_disabled';
       
   112     $st = ( in_array($theme_id, $system_themes) ) ? ' themebutton_theme_system' : '';
       
   113     echo '<div class="themebutton' . $st . '' . $d . '" id="themebtn_edit_' . $theme_id . '" style="background-image: url(' . $preview_path . ');">';
       
   114     if ( in_array($theme_id, $system_themes) )
       
   115     {
       
   116       echo   '<a class="tb-inner" href="#" onclick="return false;">
       
   117                 ' . $lang->get('acptm_btn_theme_system') . '
       
   118                 <span class="themename">' . htmlspecialchars($theme_data['theme_name']) . '</span>
       
   119               </a>';
       
   120     }
       
   121     else
       
   122     {
       
   123       echo   '<a class="tb-inner" href="#" onclick="ajaxEditTheme(\'' . $theme_id . '\'); return false;">
       
   124                 ' . $lang->get('acptm_btn_theme_edit') . '
       
   125                 <span class="themename">' . htmlspecialchars($theme_data['theme_name']) . '</span>
       
   126               </a>';
       
   127     }
       
   128     echo '</div>';
       
   129   }
       
   130   echo '</div>';
       
   131   echo '<span class="menuclear"></span>';
       
   132   
       
   133   if ( count($installable) > 0 )
       
   134   {
       
   135     echo '<h3>' . $lang->get('acptm_heading_install_themes') . '</h3>';
       
   136   
       
   137     echo '<div id="theme_list_install">';
       
   138     foreach ( $installable as $i => $theme_id )
       
   139     {
       
   140       if ( file_exists(ENANO_ROOT . "/themes/$theme_id/preview.png") )
       
   141       {
       
   142         $preview_path = scriptPath . "/themes/$theme_id/preview.png";
       
   143       }
       
   144       else
       
   145       {
       
   146         $preview_path = scriptPath . "/images/themepreview.png";
       
   147       }
       
   148       echo '<div class="themebutton" id="themebtn_install_' . $theme_id . '" enano:themename="' . htmlspecialchars($themes[$theme_id]['theme_name']) . '" style="background-image: url(' . $preview_path . ');">';
       
   149       echo   '<a class="tb-inner" href="#" onclick="ajaxInstallTheme(\'' . $theme_id . '\'); return false;">
       
   150                 ' . $lang->get('acptm_btn_theme_install') . '
       
   151                 <span class="themename">' . htmlspecialchars($themes[$theme_id]['theme_name']) . '</span>
       
   152               </a>';
       
   153       echo '</div>';
       
   154     }
       
   155     echo '</div>';
       
   156     echo '<span class="menuclear"></span>';
       
   157   }
       
   158 }
       
   159 
       
   160 function ajaxServlet_Admin_ThemeManager(&$themes)
       
   161 {
       
   162   global $db, $session, $paths, $template, $plugins; // Common objects
       
   163   global $lang;
       
   164   if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
       
   165   {
       
   166     $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
       
   167     echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
       
   168     echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
       
   169     return;
       
   170   }
       
   171   
       
   172   if ( !isset($_POST['r']) )
       
   173     return false;
       
   174   
       
   175   try
       
   176   {
       
   177     $request = enano_json_decode($_POST['r']);
       
   178   }
       
   179   catch ( Exception $e )
       
   180   {
       
   181     die('Exception in JSON parser, probably invalid input.');
       
   182   }
       
   183   
       
   184   if ( !isset($request['mode']) )
       
   185   {
       
   186     die('No mode specified in JSON request.');
       
   187   }
       
   188   
       
   189   switch ( $request['mode'] )
       
   190   {
       
   191     case 'fetch_theme':
       
   192       $theme_id = $db->escape($request['theme_id']);
       
   193       if ( empty($theme_id) )
       
   194         die('Invalid theme_id');
       
   195       
       
   196       $q = $db->sql_query("SELECT theme_id, theme_name, default_style, enabled, group_policy, group_list FROM " . table_prefix . "themes WHERE theme_id = '$theme_id';");
       
   197       if ( !$q )
       
   198         $db->die_json();
       
   199       
       
   200       if ( $db->numrows() < 1 )
       
   201         die('BUG: no theme with that theme_id installed.');
       
   202       
       
   203       $row = $db->fetchrow();
       
   204       $row['enabled'] = ( $row['enabled'] == 1 );
       
   205       $row['css'] = @$themes[$theme_id]['css'];
       
   206       $row['default_style'] = preg_replace('/\.css$/', '', $row['default_style']);
       
   207       $row['is_default'] = ( getConfig('theme_default') === $theme_id );
       
   208       $row['group_list'] = ( empty($row['group_list']) ) ? array() : enano_json_decode($row['group_list']);
       
   209       
       
   210       // Build a list of group names
       
   211       $row['group_names'] = array();
       
   212       foreach ( $row['group_list'] as $group_id )
       
   213       {
       
   214         $row['group_names'][$group_id] = '';
       
   215       }
       
   216       if ( count($row['group_names']) > 0 )
       
   217       {
       
   218         $idlist = 'group_id = ' . implode(' OR group_id = ', array_keys($row['group_names']));
       
   219         $q = $db->sql_query('SELECT group_id, group_name FROM ' . table_prefix . "groups WHERE $idlist;");
       
   220         if ( !$q )
       
   221           $db->die_json();
       
   222         while ( $gr = $db->fetchrow_num() )
       
   223         {
       
   224           list($group_id, $group_name) = $gr;
       
   225           $row['group_names'][$group_id] = $group_name;
       
   226         }
       
   227       }
       
   228       
       
   229       echo enano_json_encode($row);
       
   230       break;
       
   231   }
       
   232 }
       
   233 
       
   234 function page_Admin_ThemeManagerOld() 
       
   235 {
       
   236   global $db, $session, $paths, $template, $plugins; // Common objects
       
   237   global $lang;
       
   238   if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
       
   239   {
       
   240     $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
       
   241     echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
       
   242     echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
       
   243     return;
       
   244   }
       
   245   
       
   246   
       
   247   // Get the list of styles in the themes/ dir
       
   248   $h = opendir('./themes');
       
   249   $l = Array();
       
   250   if(!$h) die('Error opening directory "./themes" for reading.');
       
   251   while(false !== ($n = readdir($h))) {
       
   252     if($n != '.' && $n != '..' && is_dir('./themes/'.$n))
       
   253       $l[] = $n;
       
   254   }
       
   255   closedir($h);
       
   256   echo('
       
   257   <h3>Theme Management</h3>
       
   258    <p>Install, uninstall, and manage Enano themes.</p>
       
   259   ');
       
   260   if(isset($_POST['disenable'])) {
       
   261     $q = 'SELECT enabled FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
       
   262     $s = $db->sql_query($q);
       
   263     if(!$s) die('Error selecting enabled/disabled state value: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   264     $r = $db->fetchrow_num($s);
       
   265     $db->free_result();
       
   266     if($r[0] == 1) $e = 0;
       
   267     else $e = 1;
       
   268     $s=true;
       
   269     if($e==0)
       
   270     {
       
   271       $c = $db->sql_query('SELECT * FROM '.table_prefix.'themes WHERE enabled=1');
       
   272       if(!$c) $db->_die('The backup check for having at least on theme enabled failed.');
       
   273       if($db->numrows() <= 1) { echo '<div class="warning-box">You cannot disable the last remaining theme.</div>'; $s=false; }
       
   274     }
       
   275     $db->free_result();
       
   276     if($s) {
       
   277     $q = 'UPDATE '.table_prefix.'themes SET enabled='.$e.' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
       
   278     $a = $db->sql_query($q);
       
   279     if(!$a) die('Error updating enabled/disabled state value: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   280     else echo('<div class="info-box">The theme "'.$_POST['theme_id'].'" has been  '. ( ( $e == '1' ) ? 'enabled' : 'disabled' ).'.</div>');
       
   281     }
       
   282   }
       
   283   elseif(isset($_POST['edit'])) {
       
   284     
       
   285     $dir = './themes/'.$_POST['theme_id'].'/css/';
       
   286     $list = Array();
       
   287     // Open a known directory, and proceed to read its contents
       
   288     if (is_dir($dir)) {
       
   289       if ($dh = opendir($dir)) {
       
   290         while (($file = readdir($dh)) !== false) {
       
   291           if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') {
       
   292             $list[$file] = capitalize_first_letter(substr($file, 0, strlen($file)-4));
       
   293           }
       
   294         }
       
   295         closedir($dh);
       
   296       }
       
   297     }
       
   298     $lk = array_keys($list);
       
   299     
       
   300     $q = 'SELECT theme_name,default_style FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
       
   301     $s = $db->sql_query($q);
       
   302     if(!$s) die('Error selecting name value: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   303     $r = $db->fetchrow_num($s);
       
   304     $db->free_result();
       
   305     acp_start_form();
       
   306     echo('<div class="question-box">
       
   307           Theme name displayed to users: <input type="text" name="name" value="'.$r[0].'" /><br /><br />
       
   308           Default stylesheet: <select name="defaultcss">');
       
   309     foreach ($lk as $l)
       
   310     {
       
   311       if($r[1] == $l) $v = ' selected="selected"';
       
   312       else $v = '';
       
   313       echo "<option value='{$l}'$v>{$list[$l]}</option>";
       
   314     }
       
   315     echo('</select><br /><br />
       
   316           <input type="submit" name="editsave" value="OK" /><input type="hidden" name="theme_id" value="'.$_POST['theme_id'].'" />
       
   317           </div>');
       
   318     echo('</form>');
       
   319   }
       
   320   elseif(isset($_POST['editsave'])) {
       
   321     $q = 'UPDATE '.table_prefix.'themes SET theme_name=\'' . $db->escape($_POST['name']) . '\',default_style=\''.$db->escape($_POST['defaultcss']).'\' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
       
   322     $s = $db->sql_query($q);
       
   323     if(!$s) die('Error updating name value: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   324     else echo('<div class="info-box">Theme data updated.</div>');
       
   325   }
       
   326   elseif(isset($_POST['up'])) {
       
   327     // If there is only one theme or if the selected theme is already at the top, do nothing
       
   328     $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;';
       
   329     $s = $db->sql_query($q);
       
   330     if(!$s) die('Error selecting order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   331     $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
       
   332     $sn = $db->sql_query($q);
       
   333     if(!$sn) die('Error selecting order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   334     $r = $db->fetchrow_num($sn);
       
   335     if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == 1 /* ...and check if this theme is already at the top */ ) { echo('<div class="warning-box">This theme is already at the top of the list, or there is only one theme installed.</div>'); } else {
       
   336       // Get the order IDs of the selected theme and the theme before it
       
   337       $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
       
   338       $s = $db->sql_query($q);
       
   339       if(!$s) die('Error selecting order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   340       $r = $db->fetchrow_num($s);
       
   341       $r = $r[0];
       
   342       $rb = $r - 1;
       
   343       // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;)
       
   344       $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.'';      /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   345       $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   346       $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0';       /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   347       echo('<div class="info-box">Theme moved up.</div>');
       
   348     }
       
   349     $db->free_result($s);
       
   350     $db->free_result($sn);
       
   351   }
       
   352   elseif(isset($_POST['down'])) {
       
   353     // If there is only one theme or if the selected theme is already at the top, do nothing
       
   354     $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;';
       
   355     $s = $db->sql_query($q);
       
   356     if(!$s) die('Error selecting order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   357     $r = $db->fetchrow_num($s);
       
   358     if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == $db->numrows($s) /* ...and check if this theme is already at the bottom */ ) { echo('<div class="warning-box">This theme is already at the bottom of the list, or there is only one theme installed.</div>'); } else {
       
   359       // Get the order IDs of the selected theme and the theme before it
       
   360       $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
       
   361       $s = $db->sql_query($q);
       
   362       if(!$s) die('Error selecting order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   363       $r = $db->fetchrow_num($s);
       
   364       $r = $r[0];
       
   365       $rb = $r + 1;
       
   366       // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;)
       
   367       $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.'';      /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   368       $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   369       $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0';       /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   370       echo('<div class="info-box">Theme moved down.</div>');
       
   371     }
       
   372   }
       
   373   else if(isset($_POST['uninstall'])) 
       
   374   {
       
   375     $q = 'SELECT * FROM '.table_prefix.'themes;';
       
   376     $s = $db->sql_query($q);
       
   377     if ( !$s )
       
   378     {
       
   379       die('Error getting theme count: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   380     }
       
   381     $n = $db->numrows($s);
       
   382     $db->free_result();
       
   383     
       
   384     if ( $_POST['theme_id'] == 'oxygen' )
       
   385     {
       
   386       echo '<div class="error-box">The Oxygen theme is used by Enano for installation, upgrades, and error messages, and cannot be uninstalled.</div>';
       
   387     }
       
   388     else
       
   389     {
       
   390       if($n < 2)
       
   391       {
       
   392         echo '<div class="error-box">The theme could not be uninstalled because it is the only theme left.</div>';
       
   393       }
       
   394       else
       
   395       {
       
   396         $q = 'DELETE FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\' LIMIT 1;';
       
   397         $s = $db->sql_query($q);
       
   398         if ( !$s )
       
   399         {
       
   400           die('Error deleting theme data: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   401         }
       
   402         else
       
   403         {
       
   404           echo('<div class="info-box">Theme uninstalled.</div>');
       
   405         }
       
   406       }
       
   407     }
       
   408   }
       
   409   elseif(isset($_POST['install'])) {
       
   410     $q = 'SELECT theme_id FROM '.table_prefix.'themes;';
       
   411     $s = $db->sql_query($q);
       
   412     if(!$s) die('Error getting theme count: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   413     $n = $db->numrows($s);
       
   414     $n++;
       
   415     $theme_id = $_POST['theme_id'];
       
   416     $theme = Array();
       
   417     include('./themes/'.$theme_id.'/theme.cfg');
       
   418     if ( !isset($theme['theme_id']) )
       
   419     {
       
   420       echo '<div class="error-box">Could not load theme.cfg (theme metadata file)</div>';
       
   421     }
       
   422     else
       
   423     {
       
   424       $default_style = false;
       
   425       if ( $dh = opendir('./themes/' . $theme_id . '/css') )
       
   426       {
       
   427         while ( $file = readdir($dh) )
       
   428         {
       
   429           if ( $file != '_printable.css' && preg_match('/\.css$/i', $file) )
       
   430           {
       
   431             $default_style = $file;
       
   432             break;
       
   433           }
       
   434         }
       
   435         closedir($dh);
       
   436       }
       
   437       else
       
   438       {
       
   439         die('The /css subdirectory could not be located in the theme\'s directory');
       
   440       }
       
   441       
       
   442       if ( $default_style )
       
   443       {
       
   444         $q = 'INSERT INTO '.table_prefix.'themes(theme_id,theme_name,theme_order,enabled,default_style) VALUES(\''.$db->escape($theme['theme_id']).'\', \''.$db->escape($theme['theme_name']).'\', '.$n.', 1, \'' . $db->escape($default_style) . '\')';
       
   445         $s = $db->sql_query($q);
       
   446         if(!$s) die('Error inserting theme data: '.$db->get_error().'<br /><u>SQL:</u><br />'.$q);
       
   447         else echo('<div class="info-box">Theme "'.$theme['theme_name'].'" installed.</div>');
       
   448       }
       
   449       else
       
   450       {
       
   451         echo '<div class="error-box">Could not determine the default style for the theme.</div>';
       
   452       }
       
   453     }
       
   454   }
       
   455   echo('
       
   456   <h3>Currently installed themes</h3>
       
   457     <form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">
       
   458     <p>
       
   459       <select name="theme_id">
       
   460         ');
       
   461         $q = 'SELECT theme_id,theme_name,enabled FROM '.table_prefix.'themes ORDER BY theme_order';
       
   462         $s = $db->sql_query($q);
       
   463         if(!$s) die('Error selecting theme data: '.$db->get_error().'<br /><u>Attempted SQL:</u><br />'.$q);
       
   464         while ( $r = $db->fetchrow_num($s) ) {
       
   465           if($r[2] < 1) $r[1] .= ' (disabled)';
       
   466           echo('<option value="'.$r[0].'">'.$r[1].'</option>');
       
   467         }
       
   468         $db->free_result();
       
   469         echo('
       
   470         </select> <input type="submit" name="disenable" value="Enable/Disable" /> <input type="submit" name="edit" value="Change settings" /> <input type="submit" name="up" value="Move up" /> <input type="submit" name="down" value="Move down" /> <input type="submit" name="uninstall" value="Uninstall" style="color: #DD3300; font-weight: bold;" />
       
   471       </p>
       
   472     </form>
       
   473     <h3>Install a new theme</h3>
       
   474   ');
       
   475     $theme = Array();
       
   476     $obb = '';
       
   477     for($i=0;$i<sizeof($l);$i++) {
       
   478       if(is_file('./themes/'.$l[$i].'/theme.cfg') && file_exists('./themes/'.$l[$i].'/theme.cfg')) {
       
   479         include('./themes/'.$l[$i].'/theme.cfg');
       
   480         $q = 'SELECT * FROM '.table_prefix.'themes WHERE theme_id=\''.$theme['theme_id'].'\'';
       
   481         $s = $db->sql_query($q);
       
   482         if(!$s) die('Error selecting list of currently installed themes: '.$db->get_error().'<br /><u>Attempted SQL:</u><br />'.$q);
       
   483         if($db->numrows($s) < 1) {
       
   484           $obb .= '<option value="'.$theme['theme_id'].'">'.$theme['theme_name'].'</option>';
       
   485         }
       
   486         $db->free_result();
       
   487       }
       
   488     }
       
   489     if($obb != '') {
       
   490       echo('<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post"><p>');
       
   491       echo('<select name="theme_id">');
       
   492       echo($obb);
       
   493       echo('</select>');
       
   494       echo('
       
   495       <input type="submit" name="install" value="Install this theme" />
       
   496       </p></form>');
       
   497     } else echo('<p>All themes are currently installed.</p>');
       
   498 }