/**
 * 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;
}
Пример #2
0
/**
 * 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;
}