Browse Source

Moving code to Subs-Themes
Still needs to be rewritten...

Signed-off-by: Suki <[email protected]>

Suki 11 years ago
parent
commit
50749250df
2 changed files with 249 additions and 15 deletions
  1. 208 0
      Sources/Subs-Themes.php
  2. 41 15
      Sources/Themes.php

+ 208 - 0
Sources/Subs-Themes.php

@@ -56,4 +56,212 @@ function get_single_theme($id)
 	return $single;
 }
 
+function theme_install()
+{
+	// One last check.
+	if ($theme_dir != '' && basename($theme_dir) != 'Themes')
+		return false;
+
+	// Defaults.
+	$context['to_install'] = array(
+		'theme_url' => $boardurl . '/Themes/' . basename($theme_dir),
+		'images_url' => isset($images_url) ? $images_url : $boardurl . '/Themes/' . basename($theme_dir) . '/images',
+		'theme_dir' => $theme_dir,
+		'name' => $theme_name
+	);
+
+	// Perhaps they are trying to install a mod, lets tell them nicely this is the wrong function.
+	if (file_exists($theme_dir . '/package-info.xml'))
+	{
+		$txt['package_get_error_is_mod'] = str_replace('{MANAGEMODURL}', $scripturl . '?action=admin;area=packages;' . $context['session_var'] . '=' . $context['session_id'], $txt['package_get_error_is_mod']);
+		fatal_lang_error('package_theme_upload_error_broken', false, $txt['package_get_error_is_mod']);
+	}
+
+	// Get the theme info.
+	elseif (file_exists($theme_dir . '/theme_info.xml'))
+	{
+		$theme_info = file_get_contents($theme_dir . '/theme_info.xml');
+
+		// Parse theme-info.xml into an xmlArray.
+		require_once($sourcedir . '/Class-Package.php');
+		$theme_info_xml = new xmlArray($theme_info);
+
+		// Error message, there isn't any valid info.
+		if (!$theme_info_xml->exists('theme-info[0]'))
+			fatal_lang_error('package_get_error_packageinfo_corrupt', false);
+
+		// Check for compatibility with 2.1 or greater.
+		if (!$theme_info_xml->exists('theme-info/install'))
+			fatal_lang_error('package_get_error_theme_not_compatible', false, $forum_version);
+
+		// So, we have an install tag which is cool and stuff but we also need to check it and match your current SMF version...
+		$the_version = strtr($forum_version, array('SMF ' => ''));
+		$install_versions = $theme_info_xml->path('theme-info/install/@for');
+
+		// The theme isn't compatible with the current SMF version.
+		if (!$install_versions || !matchPackageVersion($the_version, $install_versions))
+			fatal_lang_error('package_get_error_theme_not_compatible', false, $forum_version);
+
+		$theme_info_xml = $theme_info_xml->path('theme-info[0]');
+		$theme_info_xml = $theme_info_xml->to_array();
+
+		$xml_elements = array(
+			'name' => 'name',
+			'theme_layers' => 'layers',
+			'theme_templates' => 'templates',
+			'based_on' => 'based-on',
+			'version' => 'version',
+		);
+
+		// Assign the values to be stored.
+		foreach ($xml_elements as $var => $name)
+			if (!empty($theme_info_xml[$name]))
+				$context['to_install'][$var] = $theme_info_xml[$name];
+
+		// OK, is this a newer version of an already installed theme?
+		if (!empty($context['to_install']['version']))
+		{
+			$to_update = array();
+			$request = $smcFunc['db_query']('', '
+				SELECT th.value AS name, th.id_theme, th2.value AS version
+				FROM {db_prefix}themes AS th
+					INNER JOIN {db_prefix}themes AS th2 ON (th2.id_theme = th.id_theme
+						AND th2.id_member = {int:no_member}
+						AND th2.variable = {string:version})
+				WHERE th.id_member = {int:no_member}
+					AND th.variable = {string:name}
+					AND th.value LIKE {string:name_value}
+				LIMIT 1',
+				array(
+					'no_member' => 0,
+					'name' => 'name',
+					'version' => 'version',
+					'name_value' => '%'. $context['to_install']['name'] .'%',
+				)
+			);
+			$to_update = $smcFunc['db_fetch_assoc']($request);
+			$smcFunc['db_free_result']($request);
+
+			// Got something, lets figure it out what to do next.
+			if (!empty($to_update) && !empty($to_update['version']))
+				switch (compareVersions($context['to_install']['version'], $to_update['version']))
+				{
+					case 0: // This is exactly the same theme.
+					case -1: // The one being installed is older than the one already installed.
+					default: // Any other possible result.
+						fatal_lang_error('package_get_error_theme_no_new_version', false, array($context['to_install']['version'], $to_update['version']));
+						break;
+					case 1: // Got a newer version, update the old entry.
+						$smcFunc['db_query']('', '
+							UPDATE {db_prefix}themes
+							SET value = {string:new_value}
+							WHERE variable = {string:version}
+								AND id_theme = {int:id_theme}',
+							array(
+								'new_value' => $context['to_install']['version'],
+								'version' => 'version',
+								'id_theme' => $to_update['id_theme'],
+							)
+						);
+
+						// Do a redirect and set a nice updated message.
+						redirectexit('action=admin;area=theme;sa=install;theme_id=' . $to_update['id_theme'] . ';updated;' . $context['session_var'] . '=' . $context['session_id']);
+						break;
+				}
+		}
+
+		if (!empty($theme_info_xml['images']))
+		{
+			$context['to_install']['images_url'] = $context['to_install']['theme_url'] . '/' . $theme_info_xml['images'];
+			$explicit_images = true;
+		}
+
+		if (!empty($theme_info_xml['extra']))
+			$context['to_install'] += unserialize($theme_info_xml['extra']);
+	}
+
+	if (isset($context['to_install']['based_on']))
+	{
+		// No need for elaborated stuff when the theme is based on the default one.
+		if ($context['to_install']['based_on'] == 'default')
+		{
+			$context['to_install']['theme_url'] = $settings['default_theme_url'];
+			$context['to_install']['images_url'] = $settings['default_images_url'];
+		}
+
+		// Custom theme based on another custom theme, lets get some info.
+		elseif ($context['to_install']['based_on'] != '')
+		{
+			$context['to_install']['based_on'] = preg_replace('~[^A-Za-z0-9\-_ ]~', '', $context['to_install']['based_on']);
+
+			$request = $smcFunc['db_query']('', '
+				SELECT th.value AS base_theme_dir, th2.value AS base_theme_url' . (!empty($explicit_images) ? '' : ', th3.value AS images_url') . '
+				FROM {db_prefix}themes AS th
+					INNER JOIN {db_prefix}themes AS th2 ON (th2.id_theme = th.id_theme
+						AND th2.id_member = {int:no_member}
+						AND th2.variable = {string:theme_url})' . (!empty($explicit_images) ? '' : '
+					INNER JOIN {db_prefix}themes AS th3 ON (th3.id_theme = th.id_theme
+						AND th3.id_member = {int:no_member}
+						AND th3.variable = {string:images_url})') . '
+				WHERE th.id_member = {int:no_member}
+					AND (th.value LIKE {string:based_on} OR th.value LIKE {string:based_on_path})
+					AND th.variable = {string:theme_dir}
+				LIMIT 1',
+				array(
+					'no_member' => 0,
+					'theme_url' => 'theme_url',
+					'images_url' => 'images_url',
+					'theme_dir' => 'theme_dir',
+					'based_on' => '%/' . $context['to_install']['based_on'],
+					'based_on_path' => '%' . "\\" . $context['to_install']['based_on'],
+				)
+			);
+			$temp = $smcFunc['db_fetch_assoc']($request);
+			$smcFunc['db_free_result']($request);
+
+			// Found the based on theme info, add it to the current one being installed.
+			if (is_array($temp))
+			{
+				$context['to_install'] = $temp + $context['to_install'];
+
+				if (empty($explicit_images) && !empty($context['to_install']['base_theme_url']))
+					$context['to_install']['theme_url'] = $context['to_install']['base_theme_url'];
+			}
+
+			// Nope, sorry, couldn't find any theme already installed.
+			else
+				fatal_lang_error('package_get_error_theme_no_based_on_found', false, $context['to_install']['based_on']);
+		}
+
+		unset($context['to_install']['based_on']);
+	}
+
+	// Find the newest id_theme.
+	$result = $smcFunc['db_query']('', '
+		SELECT MAX(id_theme)
+		FROM {db_prefix}themes',
+		array(
+		)
+	);
+	list ($id_theme) = $smcFunc['db_fetch_row']($result);
+	$smcFunc['db_free_result']($result);
+
+	// This will be theme number...
+	$id_theme++;
+
+	$inserts = array();
+	foreach ($context['to_install'] as $var => $val)
+		$inserts[] = array($id_theme, $var, $val);
+
+	if (!empty($inserts))
+		$smcFunc['db_insert']('insert',
+			'{db_prefix}themes',
+			array('id_theme' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'),
+			$inserts,
+			array('id_theme', 'variable')
+		);
+
+	updateSettings(array('knownThemes' => strtr($modSettings['knownThemes'] . ',' . $id_theme, array(',,' => ','))));
+}
+
 ?>

+ 41 - 15
Sources/Themes.php

@@ -1272,7 +1272,8 @@ function PickTheme()
  */
 function ThemeInstall()
 {
-	global $sourcedir, $txt, $context;
+	global $sourcedir, $txt, $context, $boarddir, $boardurl;
+	global $themedir, $themeurl;
 
 	checkSession('request');
 	isAllowedTo('admin_forum');
@@ -1291,6 +1292,10 @@ function ThemeInstall()
 	// Is there a function to call?
 	if (isset($_GET['do']) && empty($_GET['do']) && isset($subActions[$_GET['do']]))
 	{
+		// Hopefully the themes directory is writable, or we might have a problem.
+		if (!is_writable($themedir))
+			fatal_lang_error('theme_install_write_error', 'critical');
+
 		// Call the function and handle the result.
 		$result = $subActions[$_GET['do']]();
 
@@ -1299,18 +1304,15 @@ function ThemeInstall()
 		$context['installed_theme'] = false;
 		$context['sub_template'] = 'installed';
 
+		// Make it easier to change the path and url.
+		$themedir = $boarddir . '/Themes';
+		$themeurl = $boardurl . '/Themes';
+
 		// Everything went better than expected!
-		if (!empty($result) && !empty($result['id']))
+		if (!empty($result) && true == $result)
 		{
 			$context['page_title'] = $txt['theme_installed'];
-			$context['installed_theme'] = get_single_theme($_GET['theme_id']);
-		}
-
-		// Nope, there was an error, show it along with some info about it.
-		elseif (!empty($result) && !empty($result['message']))
-		{
-			$context['error_message'] = $result['message'];
-			$context['page_title'] = $txt['theme_install_error_title'];
+			$context['installed_theme'] = get_single_theme($result);
 		}
 	}
 
@@ -1321,16 +1323,40 @@ function ThemeInstall()
 
 function InstallFile()
 {
-	global $txt;
+	global $themedir, $themeurl, $context;
 
 	$result = array();
 
-	// Such pessimist, looking for errors first, nah, just cautious :P
-	if (!isset($_FILES) || (empty($_FILES['theme_gz']) || !empty($_REQUEST['theme_gz']))
+	// This happens when the admin session is gone and the user has to login again.
+	if (!isset($_FILES) || !isset($_FILES['theme_gz']) || empty($_FILES['theme_gz']))
+		redirectexit('action=admin;area=theme;sa=admin;' . $context['session_var'] . '=' . $context['session_id']);
 
-	// Another error check layer.
+	// Another error check layer, something went wrong with the upload.
 	if (isset($_FILES['theme_gz']['error']) && $_FILES['theme_gz']['error'] != 0)
-		$result['message'] =  $txt['theme_install_error_file_'. $_FILES['theme_gz']['error']];
+		fatal_lang_error('theme_install_error_file_'. $_FILES['theme_gz']['error'], false);
+
+	// Get the theme's name.
+	$theme_name = strtok(basename($_FILES['theme_gz']['name']);
+	$theme_name = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), $theme_name);
+
+	// Start setting some vars.
+	$context['to_install'] = array(
+		'name' => $theme_name,
+		'dir' => $themedir . '/' . $theme_name,
+	);
+
+	// Extract the file on the proper themes dir.
+	$extracted = read_tgz_file($_FILES['theme_gz']['tmp_name'], $context['to_install']['dir'], false, true);
+
+	// Read its info form the XML file.
+
+	// Install the theme.
+
+	// return the ID.
+}
+
+function InstallDir()
+{
 
 }