/** * Kill off unnecessary tags and return a clean array of XML data * * @param array Array of parsed XML data * @return array Cleaned array of XML data */ function kill_tags($array) { foreach ($array as $key => $val) { if ($key == "tag" || $key == "value") { unset($array[$key]); } else { if (is_array($val)) { // kill any nested tag or value indexes $array[$key] = kill_tags($val); // if the array no longer has any key/val sets // and therefore is at the deepest level, then // store the string value if (count($array[$key]) <= 0) { $array[$key] = $val['value']; } } } } return $array; }
/** * Import an entire theme (stylesheets, properties & templates) from an XML file. * * @param string The contents of the XML file * @param array Optional array of options or overrides * @return boolean True on success, false on failure */ function import_theme_xml($xml, $options = array()) { global $mybb, $db; require_once MYBB_ROOT . "inc/class_xml.php"; $parser = new XMLParser($xml); $tree = $parser->get_tree(); if (!is_array($tree) || !is_array($tree['theme'])) { return -1; } $theme = $tree['theme']; // Do we have MyBB 1.2 template's we're importing? $css_120 = ""; if (is_array($theme['cssbits'])) { $cssbits = kill_tags($theme['cssbits']); foreach ($cssbits as $name => $values) { $css_120 .= "{$name} {\n"; foreach ($values as $property => $value) { if (is_array($value)) { $property = str_replace('_', ':', $property); $css_120 .= "}\n{$name} {$property} {\n"; foreach ($value as $property2 => $value2) { $css_120 .= "\t{$property2}: {$value2}\n"; } } else { $css_120 .= "\t{$property}: {$value}\n"; } } $css_120 .= "}\n"; } } if (is_array($theme['themebits'])) { $themebits = kill_tags($theme['themebits']); $theme['properties']['tag'] = 'properties'; foreach ($themebits as $name => $value) { if ($name == "extracss") { $css_120 .= $value; continue; } $theme['properties'][$name] = $value; } } if ($css_120) { $css_120 = upgrade_css_120_to_140($css_120); $theme['stylesheets']['tag'] = 'stylesheets'; $theme['stylesheets']['stylesheet'][0]['tag'] = 'stylesheet'; $theme['stylesheets']['stylesheet'][0]['attributes'] = array('name' => 'global.css', 'version' => $mybb->version_code); $theme['stylesheets']['stylesheet'][0]['value'] = $css_120; unset($theme['cssbits']); unset($theme['themebits']); } if (is_array($theme['properties'])) { foreach ($theme['properties'] as $property => $value) { if ($property == "tag" || $property == "value") { continue; } $properties[$property] = $value['value']; } } if (empty($mybb->input['name'])) { $name = $theme['attributes']['name']; } else { $name = $mybb->input['name']; } $version = $theme['attributes']['version']; $query = $db->simple_select("themes", "tid", "name='" . $db->escape_string($name) . "'", array("limit" => 1)); $existingtheme = $db->fetch_array($query); if ($options['force_name_check'] && $existingtheme['tid']) { return -3; } else { if ($existingtheme['tid']) { $options['tid'] = $existingtheme['tid']; } } if ($mybb->version_code != $version && $options['version_compat'] != 1) { return -2; } // Do we have any templates to insert? if (!empty($theme['templates']['template']) && !$options['no_templates']) { if ($options['templateset']) { $sid = $options['templateset']; } else { $sid = $db->insert_query("templatesets", array('title' => $db->escape_string($name) . " Templates")); } $templates = $theme['templates']['template']; if (is_array($templates)) { // Theme only has one custom template if (array_key_exists("attributes", $templates)) { $templates = array($templates); } } $security_check = false; $templatecache = array(); foreach ($templates as $template) { if (check_template($template['value'])) { $security_check = true; break; } $templatecache[] = array("title" => $db->escape_string($template['attributes']['name']), "template" => $db->escape_string($template['value']), "sid" => $db->escape_string($sid), "version" => $db->escape_string($template['attributes']['version']), "dateline" => TIME_NOW); } if ($security_check == true) { return -4; } foreach ($templatecache as $template) { // PostgreSQL causes apache to stop sending content sometimes and // causes the page to stop loading during many queries all at one time if ($db->engine == "pgsql") { echo " "; flush(); } $db->insert_query("templates", $template); } $properties['templateset'] = $sid; } // Not overriding an existing theme if (!$options['tid']) { // Insert the theme $theme_id = build_new_theme($name, $properties, $options['parent']); } else { $db->delete_query("themestylesheets", "tid='{$options['tid']}'"); $db->update_query("themes", array("properties" => $db->escape_string(serialize($properties))), "tid='{$options['tid']}'"); $theme_id = $options['tid']; } // If we have any stylesheets, process them if (!empty($theme['stylesheets']['stylesheet']) && !$options['no_stylesheets']) { // Are we dealing with a single stylesheet? if (isset($theme['stylesheets']['stylesheet']['tag'])) { // Trick the system into thinking we have a good array =P $theme['stylesheets']['stylesheet'] = array($theme['stylesheets']['stylesheet']); } foreach ($theme['stylesheets']['stylesheet'] as $stylesheet) { if (substr($stylesheet['attributes']['name'], -4) != ".css") { continue; } if (!$stylesheet['attributes']['lastmodified']) { $stylesheet['attributes']['lastmodified'] = TIME_NOW; } $new_stylesheet = array("name" => $db->escape_string($stylesheet['attributes']['name']), "tid" => $theme_id, "attachedto" => $db->escape_string($stylesheet['attributes']['attachedto']), "stylesheet" => $db->escape_string($stylesheet['value']), "lastmodified" => intval($stylesheet['attributes']['lastmodified']), "cachefile" => $db->escape_string($stylesheet['attributes']['name'])); $sid = $db->insert_query("themestylesheets", $new_stylesheet); $css_url = "css.php?stylesheet={$sid}"; $cached = cache_stylesheet($theme_id, $stylesheet['attributes']['name'], $stylesheet['value']); if ($cached) { $css_url = $cached; } $attachedto = $stylesheet['attributes']['attachedto']; if (!$attachedto) { $attachedto = "global"; } // private.php?compose,folders|usercp.php,global|global $attachedto = explode("|", $attachedto); foreach ($attachedto as $attached_file) { $attached_actions = explode(",", $attached_file); $attached_file = array_shift($attached_actions); if (count($attached_actions) == 0) { $attached_actions = array("global"); } foreach ($attached_actions as $action) { $theme_stylesheets[$attached_file][$action][] = $css_url; } } } // Now we have our list of built stylesheets, save them $updated_theme = array("stylesheets" => $db->escape_string(serialize($theme_stylesheets))); $db->update_query("themes", $updated_theme, "tid='{$theme_id}'"); } update_theme_stylesheet_list($theme_id); // And done? return $theme_id; }