plugins/admin/ThemeManager.php
changeset 1227 bdac73ed481e
parent 1081 745200a9cc2a
child 1262 8ebaa6c49745
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
    11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    12  */
    12  */
    13 
    13 
    14 function page_Admin_ThemeManager($force_no_json = false)
    14 function page_Admin_ThemeManager($force_no_json = false)
    15 {
    15 {
    16   global $db, $session, $paths, $template, $plugins; // Common objects
    16 	global $db, $session, $paths, $template, $plugins; // Common objects
    17   global $lang;
    17 	global $lang;
    18   global $cache;
    18 	global $cache;
    19   
    19 	
    20   if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
    20 	if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
    21   {
    21 	{
    22     $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
    22 		$login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
    23     echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
    23 		echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
    24     echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
    24 		echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
    25     return;
    25 		return;
    26   }
    26 	}
    27   
    27 	
    28   $system_themes =& $template->system_themes;
    28 	$system_themes =& $template->system_themes;
    29   
    29 	
    30   // Obtain the list of themes (both available and already installed) and the styles available for each
    30 	// Obtain the list of themes (both available and already installed) and the styles available for each
    31   $dh = @opendir(ENANO_ROOT . '/themes');
    31 	$dh = @opendir(ENANO_ROOT . '/themes');
    32   if ( !$dh )
    32 	if ( !$dh )
    33     die('Couldn\'t open themes directory');
    33 		die('Couldn\'t open themes directory');
    34   $themes = array();
    34 	$themes = array();
    35   while ( $dr = @readdir($dh) )
    35 	while ( $dr = @readdir($dh) )
    36   {
    36 	{
    37     if ( $dr == '.' || $dr == '..' )
    37 		if ( $dr == '.' || $dr == '..' )
    38       continue;
    38 			continue;
    39     if ( !is_dir(ENANO_ROOT . "/themes/$dr") )
    39 		if ( !is_dir(ENANO_ROOT . "/themes/$dr") )
    40       continue;
    40 			continue;
    41     if ( !file_exists(ENANO_ROOT . "/themes/$dr/theme.cfg") || !is_dir(ENANO_ROOT . "/themes/$dr/css") )
    41 		if ( !file_exists(ENANO_ROOT . "/themes/$dr/theme.cfg") || !is_dir(ENANO_ROOT . "/themes/$dr/css") )
    42       continue;
    42 			continue;
    43     $cdh = @opendir(ENANO_ROOT . "/themes/$dr/css");
    43 		$cdh = @opendir(ENANO_ROOT . "/themes/$dr/css");
    44     if ( !$cdh )
    44 		if ( !$cdh )
    45       continue;
    45 			continue;
    46     
    46 		
    47     require(ENANO_ROOT . "/themes/$dr/theme.cfg");
    47 		require(ENANO_ROOT . "/themes/$dr/theme.cfg");
    48     global $theme;
    48 		global $theme;
    49     
    49 		
    50     $themes[$dr] = array(
    50 		$themes[$dr] = array(
    51         'css' => array(),
    51 				'css' => array(),
    52         'theme_name' => $theme['theme_name']
    52 				'theme_name' => $theme['theme_name']
    53       );
    53 			);
    54     while ( $cdr = @readdir($cdh) )
    54 		while ( $cdr = @readdir($cdh) )
    55     {
    55 		{
    56       if ( $cdr == '.' || $cdr == '..' )
    56 			if ( $cdr == '.' || $cdr == '..' )
    57         continue;
    57 				continue;
    58       if ( preg_match('/\.css$/i', $cdr) )
    58 			if ( preg_match('/\.css$/i', $cdr) )
    59         $themes[$dr]['css'][] = substr($cdr, 0, -4);
    59 				$themes[$dr]['css'][] = substr($cdr, 0, -4);
    60     }
    60 		}
    61   }
    61 	}
    62   
    62 	
    63   // Decide which themes are not installed
    63 	// Decide which themes are not installed
    64   $installable = array_flip(array_keys($themes));
    64 	$installable = array_flip(array_keys($themes));
    65   // FIXME: sanitize directory names or check with preg_match()
    65 	// FIXME: sanitize directory names or check with preg_match()
    66   $where_clause = 'theme_id = \'' . implode('\' OR theme_id = \'', array_flip($installable)) . '\'';
    66 	$where_clause = 'theme_id = \'' . implode('\' OR theme_id = \'', array_flip($installable)) . '\'';
    67   $q = $db->sql_query('SELECT theme_id, theme_name, enabled FROM ' . table_prefix . "themes WHERE $where_clause;");
    67 	$q = $db->sql_query('SELECT theme_id, theme_name, enabled FROM ' . table_prefix . "themes WHERE $where_clause;");
    68   if ( !$q )
    68 	if ( !$q )
    69     $db->_die();
    69 		$db->_die();
    70   
    70 	
    71   while ( $row = $db->fetchrow() )
    71 	while ( $row = $db->fetchrow() )
    72   {
    72 	{
    73     $tid =& $row['theme_id'];
    73 		$tid =& $row['theme_id'];
    74     unset($installable[$tid]);
    74 		unset($installable[$tid]);
    75     $themes[$tid]['theme_name'] = $row['theme_name'];
    75 		$themes[$tid]['theme_name'] = $row['theme_name'];
    76     $themes[$tid]['enabled'] = ( $row['enabled'] == 1 );
    76 		$themes[$tid]['enabled'] = ( $row['enabled'] == 1 );
    77   }
    77 	}
    78   
    78 	
    79   foreach ( $system_themes as $st )
    79 	foreach ( $system_themes as $st )
    80   {
    80 	{
    81     unset($installable[$st]);
    81 		unset($installable[$st]);
    82   }
    82 	}
    83   
    83 	
    84   $installable = array_flip($installable);
    84 	$installable = array_flip($installable);
    85   
    85 	
    86   // AJAX code
    86 	// AJAX code
    87   if ( $paths->getParam(0) === 'action.json' && !$force_no_json )
    87 	if ( $paths->getParam(0) === 'action.json' && !$force_no_json )
    88   {
    88 	{
    89     return ajaxServlet_Admin_ThemeManager($themes);
    89 		return ajaxServlet_Admin_ThemeManager($themes);
    90   }
    90 	}
    91   
    91 	
    92   // List installed themes
    92 	// List installed themes
    93   ?>
    93 	?>
    94   <div style="float: right;">
    94 	<div style="float: right;">
    95     <a href="#" id="systheme_toggler" onclick="ajaxToggleSystemThemes(); return false;"><?php echo $lang->get('acptm_btn_system_themes_show'); ?></a>
    95 		<a href="#" id="systheme_toggler" onclick="ajaxToggleSystemThemes(); return false;"><?php echo $lang->get('acptm_btn_system_themes_show'); ?></a>
    96   </div>
    96 	</div>
    97   <?php
    97 	<?php
    98   echo '<h3>' . $lang->get('acptm_heading_edit_themes') . '</h3>';
    98 	echo '<h3>' . $lang->get('acptm_heading_edit_themes') . '</h3>';
    99   echo '<div id="theme_list_edit">';
    99 	echo '<div id="theme_list_edit">';
   100   foreach ( $themes as $theme_id => $theme_data )
   100 	foreach ( $themes as $theme_id => $theme_data )
   101   {
   101 	{
   102     if ( in_array($theme_id, $installable) )
   102 		if ( in_array($theme_id, $installable) )
   103       continue;
   103 			continue;
   104     if ( file_exists(ENANO_ROOT . "/themes/$theme_id/preview.png") )
   104 		if ( file_exists(ENANO_ROOT . "/themes/$theme_id/preview.png") )
   105     {
   105 		{
   106       $preview_path = scriptPath . "/themes/$theme_id/preview.png";
   106 			$preview_path = scriptPath . "/themes/$theme_id/preview.png";
   107     }
   107 		}
   108     else
   108 		else
   109     {
   109 		{
   110       $preview_path = scriptPath . "/images/themepreview.png";
   110 			$preview_path = scriptPath . "/images/themepreview.png";
   111     }
   111 		}
   112     $d = ( @$theme_data['enabled'] ) ? '' : ' themebutton_theme_disabled';
   112 		$d = ( @$theme_data['enabled'] ) ? '' : ' themebutton_theme_disabled';
   113     $st = ( in_array($theme_id, $system_themes) ) ? ' themebutton_theme_system' : '';
   113 		$st = ( in_array($theme_id, $system_themes) ) ? ' themebutton_theme_system' : '';
   114     echo '<div class="themebutton' . $st . '' . $d . '" id="themebtn_edit_' . $theme_id . '" style="background-image: url(' . $preview_path . ');">';
   114 		echo '<div class="themebutton' . $st . '' . $d . '" id="themebtn_edit_' . $theme_id . '" style="background-image: url(' . $preview_path . ');">';
   115     if ( in_array($theme_id, $system_themes) )
   115 		if ( in_array($theme_id, $system_themes) )
   116     {
   116 		{
   117       echo   '<a class="tb-inner" href="#" onclick="return false;">
   117 			echo   '<a class="tb-inner" href="#" onclick="return false;">
   118                 ' . $lang->get('acptm_btn_theme_system') . '
   118 								' . $lang->get('acptm_btn_theme_system') . '
   119                 <span class="themename">' . htmlspecialchars($theme_data['theme_name']) . '</span>
   119 								<span class="themename">' . htmlspecialchars($theme_data['theme_name']) . '</span>
   120               </a>';
   120 							</a>';
   121     }
   121 		}
   122     else
   122 		else
   123     {
   123 		{
   124       echo   '<a class="tb-inner" href="#" onclick="ajaxEditTheme(\'' . $theme_id . '\'); return false;">
   124 			echo   '<a class="tb-inner" href="#" onclick="ajaxEditTheme(\'' . $theme_id . '\'); return false;">
   125                 ' . $lang->get('acptm_btn_theme_edit') . '
   125 								' . $lang->get('acptm_btn_theme_edit') . '
   126                 <span class="themename">' . htmlspecialchars($theme_data['theme_name']) . '</span>
   126 								<span class="themename">' . htmlspecialchars($theme_data['theme_name']) . '</span>
   127               </a>';
   127 							</a>';
   128     }
   128 		}
   129     echo '</div>';
   129 		echo '</div>';
   130   }
   130 	}
   131   echo '</div>';
   131 	echo '</div>';
   132   echo '<span class="menuclear"></span>';
   132 	echo '<span class="menuclear"></span>';
   133   
   133 	
   134   if ( count($installable) > 0 )
   134 	if ( count($installable) > 0 )
   135   {
   135 	{
   136     echo '<h3>' . $lang->get('acptm_heading_install_themes') . '</h3>';
   136 		echo '<h3>' . $lang->get('acptm_heading_install_themes') . '</h3>';
   137   
   137 	
   138     echo '<div id="theme_list_install">';
   138 		echo '<div id="theme_list_install">';
   139     foreach ( $installable as $i => $theme_id )
   139 		foreach ( $installable as $i => $theme_id )
   140     {
   140 		{
   141       if ( file_exists(ENANO_ROOT . "/themes/$theme_id/preview.png") )
   141 			if ( file_exists(ENANO_ROOT . "/themes/$theme_id/preview.png") )
   142       {
   142 			{
   143         $preview_path = scriptPath . "/themes/$theme_id/preview.png";
   143 				$preview_path = scriptPath . "/themes/$theme_id/preview.png";
   144       }
   144 			}
   145       else
   145 			else
   146       {
   146 			{
   147         $preview_path = scriptPath . "/images/themepreview.png";
   147 				$preview_path = scriptPath . "/images/themepreview.png";
   148       }
   148 			}
   149       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 '<div class="themebutton" id="themebtn_install_' . $theme_id . '" enano:themename="' . htmlspecialchars($themes[$theme_id]['theme_name']) . '" style="background-image: url(' . $preview_path . ');">';
   150       echo   '<a class="tb-inner" href="#" onclick="ajaxInstallTheme(\'' . $theme_id . '\'); return false;">
   150 			echo   '<a class="tb-inner" href="#" onclick="ajaxInstallTheme(\'' . $theme_id . '\'); return false;">
   151                 ' . $lang->get('acptm_btn_theme_install') . '
   151 								' . $lang->get('acptm_btn_theme_install') . '
   152                 <span class="themename">' . htmlspecialchars($themes[$theme_id]['theme_name']) . '</span>
   152 								<span class="themename">' . htmlspecialchars($themes[$theme_id]['theme_name']) . '</span>
   153               </a>';
   153 							</a>';
   154       echo '</div>';
   154 			echo '</div>';
   155     }
   155 		}
   156     echo '</div>';
   156 		echo '</div>';
   157     echo '<span class="menuclear"></span>';
   157 		echo '<span class="menuclear"></span>';
   158   }
   158 	}
   159 }
   159 }
   160 
   160 
   161 function ajaxServlet_Admin_ThemeManager(&$themes)
   161 function ajaxServlet_Admin_ThemeManager(&$themes)
   162 {
   162 {
   163   global $db, $session, $paths, $template, $plugins; // Common objects
   163 	global $db, $session, $paths, $template, $plugins; // Common objects
   164   global $lang;
   164 	global $lang;
   165   global $cache;
   165 	global $cache;
   166   
   166 	
   167   if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
   167 	if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
   168   {
   168 	{
   169     $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
   169 		$login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
   170     echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
   170 		echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
   171     echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
   171 		echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
   172     return;
   172 		return;
   173   }
   173 	}
   174   
   174 	
   175   if ( !isset($_POST['r']) )
   175 	if ( !isset($_POST['r']) )
   176     return false;
   176 		return false;
   177   
   177 	
   178   try
   178 	try
   179   {
   179 	{
   180     $request = enano_json_decode($_POST['r']);
   180 		$request = enano_json_decode($_POST['r']);
   181   }
   181 	}
   182   catch ( Exception $e )
   182 	catch ( Exception $e )
   183   {
   183 	{
   184     die('Exception in JSON parser, probably invalid input.');
   184 		die('Exception in JSON parser, probably invalid input.');
   185   }
   185 	}
   186   
   186 	
   187   if ( !isset($request['mode']) )
   187 	if ( !isset($request['mode']) )
   188   {
   188 	{
   189     die('No mode specified in JSON request.');
   189 		die('No mode specified in JSON request.');
   190   }
   190 	}
   191   
   191 	
   192   switch ( $request['mode'] )
   192 	switch ( $request['mode'] )
   193   {
   193 	{
   194     case 'fetch_theme':
   194 		case 'fetch_theme':
   195       $theme_id = $db->escape($request['theme_id']);
   195 			$theme_id = $db->escape($request['theme_id']);
   196       if ( empty($theme_id) )
   196 			if ( empty($theme_id) )
   197         die('Invalid theme_id');
   197 				die('Invalid theme_id');
   198       
   198 			
   199       $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';");
   199 			$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';");
   200       if ( !$q )
   200 			if ( !$q )
   201         $db->die_json();
   201 				$db->die_json();
   202       
   202 			
   203       if ( $db->numrows() < 1 )
   203 			if ( $db->numrows() < 1 )
   204         die('BUG: no theme with that theme_id installed.');
   204 				die('BUG: no theme with that theme_id installed.');
   205       
   205 			
   206       $row = $db->fetchrow();
   206 			$row = $db->fetchrow();
   207       $row['enabled'] = ( $row['enabled'] == 1 );
   207 			$row['enabled'] = ( $row['enabled'] == 1 );
   208       $row['css'] = @$themes[$theme_id]['css'];
   208 			$row['css'] = @$themes[$theme_id]['css'];
   209       $row['default_style'] = preg_replace('/\.css$/', '', $row['default_style']);
   209 			$row['default_style'] = preg_replace('/\.css$/', '', $row['default_style']);
   210       $row['is_default'] = ( getConfig('theme_default') === $theme_id );
   210 			$row['is_default'] = ( getConfig('theme_default') === $theme_id );
   211       $row['group_list'] = ( empty($row['group_list']) ) ? array() : enano_json_decode($row['group_list']);
   211 			$row['group_list'] = ( empty($row['group_list']) ) ? array() : enano_json_decode($row['group_list']);
   212       
   212 			
   213       // Build a list of group names
   213 			// Build a list of group names
   214       $row['group_names'] = array();
   214 			$row['group_names'] = array();
   215       $q = $db->sql_query('SELECT group_id, group_name FROM ' . table_prefix . 'groups;');
   215 			$q = $db->sql_query('SELECT group_id, group_name FROM ' . table_prefix . 'groups;');
   216       if ( !$q )
   216 			if ( !$q )
   217         $db->die_json();
   217 				$db->die_json();
   218       while ( $gr = $db->fetchrow() )
   218 			while ( $gr = $db->fetchrow() )
   219       {
   219 			{
   220         $row['group_names'][ intval($gr['group_id']) ] = $gr['group_name'];
   220 				$row['group_names'][ intval($gr['group_id']) ] = $gr['group_name'];
   221       }
   221 			}
   222       $db->free_result();
   222 			$db->free_result();
   223       
   223 			
   224       // Build a list of usernames
   224 			// Build a list of usernames
   225       $row['usernames'] = array();
   225 			$row['usernames'] = array();
   226       foreach ( $row['group_list'] as $el )
   226 			foreach ( $row['group_list'] as $el )
   227       {
   227 			{
   228         if ( !preg_match('/^u:([0-9]+)$/', $el, $match) )
   228 				if ( !preg_match('/^u:([0-9]+)$/', $el, $match) )
   229           continue;
   229 					continue;
   230         $uid =& $match[1];
   230 				$uid =& $match[1];
   231         $q = $db->sql_query('SELECT username FROM ' . table_prefix . "users WHERE user_id = $uid;");
   231 				$q = $db->sql_query('SELECT username FROM ' . table_prefix . "users WHERE user_id = $uid;");
   232         if ( !$q )
   232 				if ( !$q )
   233           $db->die_json();
   233 					$db->die_json();
   234         if ( $db->numrows() < 1 )
   234 				if ( $db->numrows() < 1 )
   235         {
   235 				{
   236           $db->free_result();
   236 					$db->free_result();
   237           continue;
   237 					continue;
   238         }
   238 				}
   239         list($username) = $db->fetchrow_num();
   239 				list($username) = $db->fetchrow_num();
   240         $row['usernames'][$uid] = $username;
   240 				$row['usernames'][$uid] = $username;
   241         $db->free_result();
   241 				$db->free_result();
   242       }
   242 			}
   243       
   243 			
   244       echo enano_json_encode($row);
   244 			echo enano_json_encode($row);
   245       break;
   245 			break;
   246     case 'uid_lookup':
   246 		case 'uid_lookup':
   247       $username = @$request['username'];
   247 			$username = @$request['username'];
   248       if ( empty($username) )
   248 			if ( empty($username) )
   249       {
   249 			{
   250         die(enano_json_encode(array(
   250 				die(enano_json_encode(array(
   251             'mode' => 'error',
   251 						'mode' => 'error',
   252             'error' => $lang->get('acptm_err_invalid_username')
   252 						'error' => $lang->get('acptm_err_invalid_username')
   253           )));
   253 					)));
   254       }
   254 			}
   255       $username = $db->escape(strtolower($username));
   255 			$username = $db->escape(strtolower($username));
   256       $q = $db->sql_query('SELECT user_id, username FROM ' . table_prefix . "users WHERE " . ENANO_SQLFUNC_LOWERCASE . "(username) = '$username';");
   256 			$q = $db->sql_query('SELECT user_id, username FROM ' . table_prefix . "users WHERE " . ENANO_SQLFUNC_LOWERCASE . "(username) = '$username';");
   257       if ( !$q )
   257 			if ( !$q )
   258         $db->die_json();
   258 				$db->die_json();
   259       
   259 			
   260       if ( $db->numrows() < 1 )
   260 			if ( $db->numrows() < 1 )
   261       {
   261 			{
   262         die(enano_json_encode(array(
   262 				die(enano_json_encode(array(
   263             'mode' => 'error',
   263 						'mode' => 'error',
   264             'error' => $lang->get('acptm_err_username_not_found')
   264 						'error' => $lang->get('acptm_err_username_not_found')
   265           )));
   265 					)));
   266       }
   266 			}
   267       
   267 			
   268       list($uid, $username_real) = $db->fetchrow_num();
   268 			list($uid, $username_real) = $db->fetchrow_num();
   269       $db->free_result();
   269 			$db->free_result();
   270       
   270 			
   271       echo enano_json_encode(array(
   271 			echo enano_json_encode(array(
   272           'uid' => $uid,
   272 					'uid' => $uid,
   273           'username' => $username_real
   273 					'username' => $username_real
   274         ));
   274 				));
   275       break;
   275 			break;
   276     case 'save_theme':
   276 		case 'save_theme':
   277       if ( !isset($request['theme_data']) )
   277 			if ( !isset($request['theme_data']) )
   278       {
   278 			{
   279         die(enano_json_encode(array(
   279 				die(enano_json_encode(array(
   280             'mode' => 'error',
   280 						'mode' => 'error',
   281             'error' => 'No theme data in request'
   281 						'error' => 'No theme data in request'
   282           )));
   282 					)));
   283       }
   283 			}
   284       $theme_data =& $request['theme_data'];
   284 			$theme_data =& $request['theme_data'];
   285       // Perform integrity check on theme data
   285 			// Perform integrity check on theme data
   286       $chk_theme_exists = isset($themes[@$theme_data['theme_id']]);
   286 			$chk_theme_exists = isset($themes[@$theme_data['theme_id']]);
   287       $theme_data['theme_name'] = trim(@$theme_data['theme_name']);
   287 			$theme_data['theme_name'] = trim(@$theme_data['theme_name']);
   288       $chk_name_good = !empty($theme_data['theme_name']);
   288 			$chk_name_good = !empty($theme_data['theme_name']);
   289       $chk_policy_good = in_array(@$theme_data['group_policy'], array('allow_all', 'whitelist', 'blacklist'));
   289 			$chk_policy_good = in_array(@$theme_data['group_policy'], array('allow_all', 'whitelist', 'blacklist'));
   290       $chk_grouplist_good = true;
   290 			$chk_grouplist_good = true;
   291       foreach ( $theme_data['group_list'] as $acl_entry )
   291 			foreach ( $theme_data['group_list'] as $acl_entry )
   292       {
   292 			{
   293         if ( !preg_match('/^(u|g):[0-9]+$/', $acl_entry) )
   293 				if ( !preg_match('/^(u|g):[0-9]+$/', $acl_entry) )
   294         {
   294 				{
   295           $chk_grouplist_good = false;
   295 					$chk_grouplist_good = false;
   296           break;
   296 					break;
   297         }
   297 				}
   298       }
   298 			}
   299       $chk_style_good = @in_array(@$theme_data['default_style'], @$themes[@$theme_data['theme_id']]['css']);
   299 			$chk_style_good = @in_array(@$theme_data['default_style'], @$themes[@$theme_data['theme_id']]['css']);
   300       if ( !$chk_theme_exists || !$chk_name_good || !$chk_policy_good || !$chk_grouplist_good || !$chk_style_good )
   300 			if ( !$chk_theme_exists || !$chk_name_good || !$chk_policy_good || !$chk_grouplist_good || !$chk_style_good )
   301       {
   301 			{
   302         die(enano_json_encode(array(
   302 				die(enano_json_encode(array(
   303             'mode' => 'error',
   303 						'mode' => 'error',
   304             'error' => $lang->get('acptm_err_save_validation_failed')
   304 						'error' => $lang->get('acptm_err_save_validation_failed')
   305           )));
   305 					)));
   306       }
   306 			}
   307       
   307 			
   308       $enable = ( $theme_data['enabled'] ) ? '1' : '0';
   308 			$enable = ( $theme_data['enabled'] ) ? '1' : '0';
   309       $theme_default = getConfig('theme_default');
   309 			$theme_default = getConfig('theme_default');
   310       $warn_default = ( $theme_default === $theme_data['theme_id'] || $theme_data['make_default'] ) ?
   310 			$warn_default = ( $theme_default === $theme_data['theme_id'] || $theme_data['make_default'] ) ?
   311                         ' ' . $lang->get('acptm_warn_access_with_default') . ' ' :
   311 												' ' . $lang->get('acptm_warn_access_with_default') . ' ' :
   312                         ' ';
   312 												' ';
   313       if ( $enable == 0 && ( $theme_default === $theme_data['theme_id'] || $theme_data['make_default'] ) )
   313 			if ( $enable == 0 && ( $theme_default === $theme_data['theme_id'] || $theme_data['make_default'] ) )
   314       {
   314 			{
   315         $enable = '1';
   315 				$enable = '1';
   316         $warn_default .= '<b>' . $lang->get('acptm_warn_cant_disable_default') . '</b>';
   316 				$warn_default .= '<b>' . $lang->get('acptm_warn_cant_disable_default') . '</b>';
   317       }
   317 			}
   318       
   318 			
   319       // We're good. Update the theme...
   319 			// We're good. Update the theme...
   320       $q = $db->sql_query('UPDATE ' . table_prefix . 'themes SET
   320 			$q = $db->sql_query('UPDATE ' . table_prefix . 'themes SET
   321                                theme_name = \'' . $db->escape($theme_data['theme_name']) . '\',
   321  															theme_name = \'' . $db->escape($theme_data['theme_name']) . '\',
   322                                default_style = \'' . $db->escape($theme_data['default_style']) . '\',
   322  															default_style = \'' . $db->escape($theme_data['default_style']) . '\',
   323                                group_list = \'' . $db->escape(enano_json_encode($theme_data['group_list'])) . '\',
   323  															group_list = \'' . $db->escape(enano_json_encode($theme_data['group_list'])) . '\',
   324                                group_policy = \'' . $db->escape($theme_data['group_policy']) . '\',
   324  															group_policy = \'' . $db->escape($theme_data['group_policy']) . '\',
   325                                enabled = ' . $enable . '
   325  															enabled = ' . $enable . '
   326                              WHERE theme_id = \'' . $db->escape($theme_data['theme_id']) . '\';');
   326  														WHERE theme_id = \'' . $db->escape($theme_data['theme_id']) . '\';');
   327       if ( !$q )
   327 			if ( !$q )
   328         $db->die_json();
   328 				$db->die_json();
   329       
   329 			
   330       if ( $theme_data['make_default'] )
   330 			if ( $theme_data['make_default'] )
   331       {
   331 			{
   332         setConfig('theme_default', $theme_data['theme_id']);
   332 				setConfig('theme_default', $theme_data['theme_id']);
   333       }
   333 			}
   334       
   334 			
   335       $cache->purge('themes');
   335 			$cache->purge('themes');
   336       
   336 			
   337       echo '<div class="info-box"><b>' . $lang->get('acptm_msg_save_success') . '</b>' . $warn_default . '</div>';
   337 			echo '<div class="info-box"><b>' . $lang->get('acptm_msg_save_success') . '</b>' . $warn_default . '</div>';
   338       
   338 			
   339       page_Admin_ThemeManager(true);
   339 			page_Admin_ThemeManager(true);
   340       break;
   340 			break;
   341     case 'install':
   341 		case 'install':
   342       $theme_id =& $request['theme_id'];
   342 			$theme_id =& $request['theme_id'];
   343       if ( !isset($themes[$theme_id]) )
   343 			if ( !isset($themes[$theme_id]) )
   344       {
   344 			{
   345         die(enano_json_encode(array(
   345 				die(enano_json_encode(array(
   346             'mode' => 'error',
   346 						'mode' => 'error',
   347             'error' => 'Theme was deleted from themes/ directory or couldn\'t read theme metadata from filesystem'
   347 						'error' => 'Theme was deleted from themes/ directory or couldn\'t read theme metadata from filesystem'
   348           )));
   348 					)));
   349       }
   349 			}
   350       if ( !isset($themes[$theme_id]['css'][0]) )
   350 			if ( !isset($themes[$theme_id]['css'][0]) )
   351       {
   351 			{
   352         die(enano_json_encode(array(
   352 				die(enano_json_encode(array(
   353             'mode' => 'error',
   353 						'mode' => 'error',
   354             'error' => 'Theme doesn\'t have any files in css/, thus it can\'t be installed. (translators: l10n?)'
   354 						'error' => 'Theme doesn\'t have any files in css/, thus it can\'t be installed. (translators: l10n?)'
   355           )));
   355 					)));
   356       }
   356 			}
   357       // build dataset
   357 			// build dataset
   358       $theme_name = $db->escape($themes[$theme_id]['theme_name']);
   358 			$theme_name = $db->escape($themes[$theme_id]['theme_name']);
   359       $default_style = $db->escape($themes[$theme_id]['css'][0]);
   359 			$default_style = $db->escape($themes[$theme_id]['css'][0]);
   360       $theme_id = $db->escape($theme_id);
   360 			$theme_id = $db->escape($theme_id);
   361       
   361 			
   362       // insert it
   362 			// insert it
   363       $q = $db->sql_query('INSERT INTO ' . table_prefix . "themes(theme_id, theme_name, default_style, enabled, group_list, group_policy)\n"
   363 			$q = $db->sql_query('INSERT INTO ' . table_prefix . "themes(theme_id, theme_name, default_style, enabled, group_list, group_policy)\n"
   364                         . "  VALUES( '$theme_id', '$theme_name', '$default_style', 1, '[]', 'allow_all' );");
   364 												. "  VALUES( '$theme_id', '$theme_name', '$default_style', 1, '[]', 'allow_all' );");
   365       if ( !$q )
   365 			if ( !$q )
   366         $db->die_json();
   366 				$db->die_json();
   367       
   367 			
   368       $cache->purge('themes');
   368 			$cache->purge('themes');
   369       
   369 			
   370       // The response isn't processed unless it's in JSON.
   370 			// The response isn't processed unless it's in JSON.
   371       echo 'Roger that, over and out.';
   371 			echo 'Roger that, over and out.';
   372       
   372 			
   373       break;
   373 			break;
   374     case 'uninstall':
   374 		case 'uninstall':
   375       $theme_id =& $request['theme_id'];
   375 			$theme_id =& $request['theme_id'];
   376       $theme_default = getConfig('theme_default');
   376 			$theme_default = getConfig('theme_default');
   377       
   377 			
   378       // Validation
   378 			// Validation
   379       if ( !isset($themes[$theme_id]) )
   379 			if ( !isset($themes[$theme_id]) )
   380       {
   380 			{
   381         die(enano_json_encode(array(
   381 				die(enano_json_encode(array(
   382             'mode' => 'error',
   382 						'mode' => 'error',
   383             'error' => 'Theme was deleted from themes/ directory or couldn\'t read theme metadata from filesystem'
   383 						'error' => 'Theme was deleted from themes/ directory or couldn\'t read theme metadata from filesystem'
   384           )));
   384 					)));
   385       }
   385 			}
   386       
   386 			
   387       if ( $theme_id == $theme_default )
   387 			if ( $theme_id == $theme_default )
   388       {
   388 			{
   389         die(enano_json_encode(array(
   389 				die(enano_json_encode(array(
   390             'mode' => 'error',
   390 						'mode' => 'error',
   391             'error' => $lang->get('acptm_err_uninstalling_default')
   391 						'error' => $lang->get('acptm_err_uninstalling_default')
   392           )));
   392 					)));
   393       }
   393 			}
   394       
   394 			
   395       if ( $theme_id == 'oxygen' )
   395 			if ( $theme_id == 'oxygen' )
   396       {
   396 			{
   397         die(enano_json_encode(array(
   397 				die(enano_json_encode(array(
   398             'mode' => 'error',
   398 						'mode' => 'error',
   399             'error' => $lang->get('acptm_err_uninstalling_oxygen')
   399 						'error' => $lang->get('acptm_err_uninstalling_oxygen')
   400           )));
   400 					)));
   401       }
   401 			}
   402       
   402 			
   403       $theme_id = $db->escape($theme_id);
   403 			$theme_id = $db->escape($theme_id);
   404       
   404 			
   405       $q = $db->sql_query('DELETE FROM ' . table_prefix . "themes WHERE theme_id = '$theme_id';");
   405 			$q = $db->sql_query('DELETE FROM ' . table_prefix . "themes WHERE theme_id = '$theme_id';");
   406       if ( !$q )
   406 			if ( !$q )
   407         $db->die_json();
   407 				$db->die_json();
   408       
   408 			
   409       $cache->purge('themes');
   409 			$cache->purge('themes');
   410       
   410 			
   411       // Change all the users that were on that theme to the default
   411 			// Change all the users that were on that theme to the default
   412       $default_style = $template->named_theme_list[$theme_default]['default_style'];
   412 			$default_style = $template->named_theme_list[$theme_default]['default_style'];
   413       $default_style = preg_replace('/\.css$/', '', $default_style);
   413 			$default_style = preg_replace('/\.css$/', '', $default_style);
   414       
   414 			
   415       $theme_default = $db->escape($theme_default);
   415 			$theme_default = $db->escape($theme_default);
   416       $default_style = $db->escape($default_style);
   416 			$default_style = $db->escape($default_style);
   417       
   417 			
   418       $q = $db->sql_query('UPDATE ' . table_prefix . "users SET theme = '$theme_default', style = '$default_style' WHERE theme = '$theme_id';");
   418 			$q = $db->sql_query('UPDATE ' . table_prefix . "users SET theme = '$theme_default', style = '$default_style' WHERE theme = '$theme_id';");
   419       if ( !$q )
   419 			if ( !$q )
   420         $db->die_json();
   420 				$db->die_json();
   421       
   421 			
   422       echo '<div class="info-box">' . $lang->get('acptm_msg_uninstall_success') . '</div>';
   422 			echo '<div class="info-box">' . $lang->get('acptm_msg_uninstall_success') . '</div>';
   423       
   423 			
   424       page_Admin_ThemeManager(true);
   424 			page_Admin_ThemeManager(true);
   425       break;
   425 			break;
   426   }
   426 	}
   427 }
   427 }
   428 
   428