/** * Updates the list of themes in the database by examining the contents of the /themes folder. */ function ft_update_theme_list() { global $g_table_prefix, $g_root_dir, $LANG; $themes_folder = "{$g_root_dir}/themes"; // loop through all themes in this folder and if the theme contains the requisite files, add it to the database $theme_info = array(); $dh = opendir($themes_folder); // if we couldn't open the themes folder, it probably doesn't exist if (!$dh) { return array(false, $message); } // get the existing themes $current_themes = ft_get_themes(); // empty the themes table mysql_query("TRUNCATE {$g_table_prefix}themes"); while (($folder = readdir($dh)) !== false) { if (is_dir("{$themes_folder}/{$folder}") && $folder != "." && $folder != "..") { $summary_file = "{$themes_folder}/{$folder}/about/theme.php"; $thumbnail = "{$themes_folder}/{$folder}/about/thumbnail.gif"; if (!is_file($summary_file) || !is_file($thumbnail)) { continue; } $info = _ft_get_theme_info_file_contents($summary_file); $info = ft_sanitize($info); // if the theme name is not defined, skip it if (empty($info["theme_name"])) { continue; } $theme_name = $info["theme_name"]; $theme_author = $info["theme_author"]; $theme_author_email = $info["theme_author_email"]; $theme_link = $info["theme_link"]; $theme_description = $info["theme_description"]; $theme_version = $info["theme_version"]; $theme_uses_swatches = $info["theme_uses_swatches"]; $swatches = ""; if ($theme_uses_swatches == "yes") { $swatch_info = array(); while (list($key, $value) = each($info["theme_swatches"])) { $swatch_info[] = "{$key},{$value}"; } $swatches = ft_sanitize(implode("|", $swatch_info)); } // try and set the cache folder as writable if (!is_writable("{$themes_folder}/{$folder}/cache/")) { @chmod("{$themes_folder}/{$folder}/cache/", 0777); } $cache_folder_writable = is_writable("{$themes_folder}/{$folder}/cache/") ? "yes" : "no"; mysql_query("\n INSERT INTO {$g_table_prefix}themes (theme_folder, theme_name, uses_swatches, swatches,\n author, theme_link, description, is_enabled, theme_version)\n VALUES ('{$folder}', '{$theme_name}', '{$theme_uses_swatches}', '{$swatches}', '{$theme_author}',\n '{$theme_link}', '{$theme_description}', '{$cache_folder_writable}', '{$theme_version}')\n "); } } closedir($dh); $success = true; $message = $LANG["notify_theme_list_updated"]; extract(ft_process_hook_calls("end", array(), array("success", "message")), EXTR_OVERWRITE); return array($success, $message); }
function smarty_function_themes_dropdown($params, &$smarty) { global $LANG; if (empty($params["name_id"])) { $smarty->trigger_error("assign: missing 'name_id' parameter. This is used to give the select field a name and id value."); return; } $default_value = isset($params["default"]) ? $params["default"] : ""; $default_swatch = isset($params["default_swatch"]) ? $params["default_swatch"] : ""; $onchange = isset($params["onchange"]) ? $params["onchange"] : ""; // we always give theme dropdowns a special "ft_themes_dropdown" class. This is used to dynamically // add the event handlers to hide/show the appropriate swatch dropdown $attributes = array("id" => $params["name_id"], "name" => $params["name_id"], "class" => "ft_themes_dropdown", "onchange" => $onchange); $attribute_str = ""; while (list($key, $value) = each($attributes)) { if (!empty($value)) { $attribute_str .= " {$key}=\"{$value}\""; } } $themes = ft_get_themes(); $html = "<select {$attribute_str}>\n <option value=\"\">{$LANG["phrase_please_select"]}</option>"; $swatch_info = array(); foreach ($themes as $theme) { if ($theme["is_enabled"] == "no") { continue; } $selected = $theme["theme_folder"] == $default_value ? "selected" : ""; $html .= "<option value=\"{$theme["theme_folder"]}\" {$selected}>{$theme["theme_name"]}</option>"; if ($theme["uses_swatches"] == "yes") { $swatch_info[$theme["theme_folder"]] = $theme["swatches"]; } } $html .= "</select>"; // now generate swatch dropdowns for all themes that have them. This is by far the simplest solution, // since there will always be very few themes and even fewer that have while (list($theme_folder, $swatches) = each($swatch_info)) { $classes = array("{$params["name_id"]}_swatches"); if ($theme_folder != $default_value) { $classes[] = "hidden"; } $class_str = implode(" ", $classes); $html .= "<select name=\"{$theme_folder}_{$params["name_id"]}_swatches\" id=\"{$theme_folder}_{$params["name_id"]}_swatches\" class=\"{$class_str}\">" . "<option value=\"\">{$LANG["phrase_select_swatch"]}</option>"; $pairs = explode("|", $swatches); foreach ($pairs as $pair) { list($swatch, $swatch_label) = explode(",", $pair); $selected = ""; if ($theme_folder == $default_value && $default_swatch == $swatch) { $selected = "selected"; } $swatch_label = ft_eval_smarty_string($swatch_label); $html .= "<option value=\"{$swatch}\" {$selected}>{$swatch_label}</option>"; } $html .= "</select>"; } return $html; }
ft_check_permission("admin"); $request = array_merge($_POST, $_GET); // provides means to manually override admin theme in case of disaster if (isset($request["theme_override"])) { list($g_success, $g_message) = ft_reset_admin_theme($request["theme_override"]); } if (isset($request["update"])) { list($g_success, $g_message) = ft_update_theme_settings($_POST); } if (isset($_POST["refresh_theme_list"])) { list($g_success, $g_message) = ft_update_theme_list(); } if (isset($_GET["mass_assign"])) { list($g_success, $g_message) = ft_update_client_themes($_GET["accounts"], $_GET["theme_id"]); } $themes = ft_get_themes(); // check permissions on all the themes $updated_themes = array(); foreach ($themes as $theme_info) { $cache_folder = "{$g_root_dir}/themes/{$theme_info["theme_folder"]}/cache"; $theme_info["cache_folder_writable"] = is_writable($cache_folder); // if this theme uses swatches, generate a list if ($theme_info["uses_swatches"] == "yes") { $theme_info["available_swatches"] = ft_get_theme_swatch_list($theme_info["swatches"]); } $updated_themes[] = $theme_info; } // compile the header information $page_vars = array(); $page_vars["page"] = "themes"; $page_vars["page_url"] = ft_get_page_url("settings_themes");
/** * Tests: theme, menu_id. */ function sc_orphan_test__accounts($remove_orphans) { global $g_table_prefix, $g_current_version, $g_cache; $response = array("test_descriptions" => "Checks theme associated with accounts is a valid, enabled theme, and checks the menu ID of accounts exists.", "problems" => array(), "clean_up_problems" => array()); $query = mysql_query("\n SELECT account_id, account_type, theme, menu_id\n FROM {$g_table_prefix}accounts\n "); $valid_menu_ids = sc_get_menu_ids(); $first_client_menu_id = ""; if ($remove_orphans) { $menu_query = mysql_query("SELECT menu_id FROM {$g_table_prefix}menus WHERE menu_type = 'client' LIMIT 1"); $info = mysql_fetch_assoc($menu_query); if (!empty($info["menu_id"])) { $first_client_menu_id = $info["menu_id"]; } } // get a list of valid theme folders $themes = ft_get_themes(true); $valid_theme_folders = array(); foreach ($themes as $theme_info) { $valid_theme_folders[] = $theme_info["theme_folder"]; } $num_tests = 0; while ($row = mysql_fetch_assoc($query)) { if (!in_array($row["menu_id"], $valid_menu_ids)) { $response["problems"][] = "Invalid menu ID: {$row["menu_id"]}"; // clean-up code if ($remove_orphans) { $new_menu_id = 1; if ($row["account_type"] == "client") { $new_menu_id = $first_client_menu_id; } if (empty($new_menu_id)) { $response["clean_up_problems"][] = "There's no client menu. Please create one, then re-run the test to fix all dud references."; } else { @mysql_query("\n UPDATE {$g_table_prefix}accounts\n SET menu_id = {$new_menu_id}\n WHERE account_id = {$row["account_id"]}\n "); } } } $num_tests++; if (!in_array($row["theme"], $valid_theme_folders)) { $response["problems"][] = "Invalid theme: {$row["theme"]}"; // clean-up code if ($remove_orphans) { @mysql_query("\n UPDATE {$g_table_prefix}accounts\n SET theme = 'default',\n swatch = 'green'\n WHERE account_id = {$row["account_id"]}\n "); } } $num_tests++; } $response["num_tests"] = $num_tests; $response["num_orphans"] = count($response["problems"]); return $response; }
/** * Called by the administrator from the Themes settings page. It updates the list of enabled * themes, and which theme is assigned to the administrator and (default) client accounts. Note: * it doesn't disable any themes that are already assigned to a user account. If that happens, * it returns a message listing the accounts (each clickable) and an option to bulk assign them * to a different theme. * * @param array $infohash this parameter should be a hash (e.g. $_POST or $_GET) containing the * various fields from the main settings admin page. * @return array Returns array with indexes:<br/> * [0]: true/false (success / failure)<br/> * [1]: message string<br/> */ function ft_update_theme_settings($infohash) { global $g_table_prefix, $g_root_url, $g_root_dir, $LANG; // lots to validate! First, check the default admin & client themes have been entered $rules = array(); $rules[] = "required,admin_theme,{$LANG["validation_no_admin_theme"]}"; $rules[] = "required,default_client_theme,{$LANG["validation_no_default_client_theme"]}"; $errors = validate_fields($infohash, $rules); if (!isset($infohash["is_enabled"])) { $errors[] = $LANG["validation_no_enabled_themes"]; } if (!empty($errors)) { $success = false; array_walk($errors, create_function('&$el', '$el = "• " . $el;')); $message = join("<br />", $errors); return array($success, $message); } $enabled_themes = $infohash["is_enabled"]; // next, check that both the admin and default client themes are enabled $admin_theme = $infohash["admin_theme"]; $default_client_theme = $infohash["default_client_theme"]; if (!in_array($admin_theme, $enabled_themes) || !in_array($default_client_theme, $enabled_themes)) { return array(false, $LANG["validation_default_admin_and_client_themes_not_enabled"]); } // lastly, if there are already client accounts assigned to disabled themes, we need to sort it out. // We handle it the same way as deleting the client menus: if anyone is assigned to this theme, // we generate a list of their names, each a link to their account page (in a _blank link). We // then inform the user of what's going on, and underneath the name list, give them the option of // assigning ALL affected accounts to another (enabled) theme. $theme_clauses = array(); foreach ($enabled_themes as $theme) { $theme_clauses[] = "theme != '{$theme}'"; } $theme_clause = join(" AND ", $theme_clauses); $query = mysql_query("\n SELECT account_id, first_name, last_name\n FROM {$g_table_prefix}accounts\n WHERE {$theme_clause}\n "); $client_info = array(); while ($row = mysql_fetch_assoc($query)) { $client_info[] = $row; } if (!empty($client_info)) { $message = $LANG["notify_disabled_theme_already_assigned"]; $placeholder_str = $LANG["phrase_assign_all_listed_client_accounts_to_theme"]; $themes = ft_get_themes(true); $dd = "<select id=\"mass_update_client_theme\">"; foreach ($themes as $theme) { $dd .= "<option value=\"{$theme["theme_id"]}\">{$theme["theme_name"]}</option>"; } $dd .= "</select>"; // a bit bad (hardcoded HTML!), but organize the account list in 3 columns $client_links_table = "<table cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">\n<tr>"; $num_affected_clients = count($client_info); for ($i = 0; $i < $num_affected_clients; $i++) { $account_info = $client_info[$i]; $client_id = $account_info["account_id"]; $first_name = $account_info["first_name"]; $last_name = $account_info["last_name"]; $client_ids[] = $client_id; if ($i != 0 && $i % 3 == 0) { $client_links_table .= "</tr>\n<tr>"; } $client_links_table .= "<td width=\"33%\">• <a href=\"{$g_root_url}/admin/clients/edit.php?page=settings&client_id={$client_id}\" target=\"_blank\">{$first_name} {$last_name}</a></td>\n"; } $client_id_str = join(",", $client_ids); // close the table if ($num_affected_clients % 3 == 1) { $client_links_table .= "<td colspan=\"2\" width=\"66%\"> </td>"; } else { if ($num_affected_clients % 3 == 2) { $client_links_table .= "<td width=\"33%\"> </td>"; } } $client_links_table .= "</tr></table>"; $submit_button = "<input type=\"button\" value=\"{$LANG["phrase_update_accounts"]}\" onclick=\"window.location='index.php?page=themes&mass_assign=1&accounts={$client_id_str}&theme_id=' + \$('#mass_update_client_theme').val()\" />"; $placeholders = array("theme_dropdown" => $dd, "submit_button" => $submit_button); $mass_assign_html = "<div class=\"margin_top_large margin_bottom_large\">" . ft_eval_smarty_string($placeholder_str, $placeholders) . "</div>"; $html = $message . $mass_assign_html . $client_links_table; return array(false, $html); } // hoorah! Validation complete, let's update the bloomin' database at last // update the admin settings $admin_id = $_SESSION["ft"]["account"]["account_id"]; $admin_swatch = ""; if (isset($infohash["{$admin_theme}_admin_theme_swatches"])) { $admin_swatch = $infohash["{$admin_theme}_admin_theme_swatches"]; } mysql_query("\n UPDATE {$g_table_prefix}accounts\n SET theme = '{$admin_theme}',\n swatch = '{$admin_swatch}'\n WHERE account_id = {$admin_id}\n "); $_SESSION["ft"]["account"]["theme"] = $admin_theme; $_SESSION["ft"]["account"]["swatch"] = $admin_swatch; $default_client_swatch = ""; if (isset($infohash["{$default_client_theme}_default_client_theme_swatches"])) { $default_client_swatch = $infohash["{$default_client_theme}_default_client_theme_swatches"]; } // update the default client theme & swatch $new_settings = array("default_theme" => $default_client_theme, "default_client_swatch" => $default_client_swatch); ft_set_settings($new_settings); // finally, update the enabled themes list. Only set the theme as enabled if the // cache folder is writable mysql_query("UPDATE {$g_table_prefix}themes SET is_enabled = 'no'"); foreach ($enabled_themes as $theme) { $cache_folder = "{$g_root_dir}/themes/{$theme}/cache"; // try and set the cache folder as writable if (!is_writable($cache_folder)) { @chmod($cache_folder, 0777); } if (!is_writable($cache_folder)) { continue; } mysql_query("\n UPDATE {$g_table_prefix}themes\n SET is_enabled = 'yes'\n WHERE theme_folder = '{$theme}'\n "); } // reset the settings in sessions $_SESSION["ft"]["settings"] = ft_get_settings(); $success = true; $message = $LANG["notify_themes_settings_updated"]; extract(ft_process_hook_calls("end", compact("infohash"), array("success", "message")), EXTR_OVERWRITE); return array($success, $message); }
/** * This was added in 2.1.0. and replaces ft_build_and_cache_upgrade_info() which really wasn't necessary. * It returns a hash of information to pass in a hidden form when the user clicks "Update". */ function ft_get_formtools_installed_components() { global $g_current_version, $g_release_type, $g_release_date; $settings = ft_get_settings(); // a hash storing the installed component info $components = array(); // get the main build version $program_version = $g_current_version; $release_date = $g_release_date; $release_type = $g_release_type; $version = $program_version; if ($release_type == "alpha") { $version = "{$program_version}-alpha-{$release_date}"; } else { if ($release_type == "beta") { $version = "{$program_version}-beta-{$release_date}"; } } $components["m"] = $version; $components["rt"] = $release_type; $components["rd"] = $release_date; $components["api"] = $settings["api_version"]; // not sure about this, but I've added it for backward compatibility, just in case... if ($release_type == "beta") { $components["beta"] = "yes"; $components["bv"] = $version; } // get the theme info $themes = ft_get_themes(); $count = 1; foreach ($themes as $theme_info) { $components["t{$count}"] = $theme_info["theme_folder"]; $components["tv{$count}"] = $theme_info["theme_version"]; $count++; } // get the module info $modules = ft_get_modules(); $count = 1; foreach ($modules as $module_info) { $components["m{$count}"] = $module_info["module_folder"]; $components["mv{$count}"] = $module_info["version"]; $count++; } return $components; }