/**
* Reads XML style file and imports data from it into the database
*
* @param	string	XML data
* @param	integer	Style ID
* @param	integer	Parent style ID
* @param	string	New style title
* @param	boolean	Allow vBulletin version mismatch
* @param	integer	Display order for new style
* @param	boolean	Allow user selection of new style
* @param  int|null Starting template group index for this run of importing templates (0 based).
*		Null means all templates (single run)
* @paream int|null
*
* @return	array	Array of information about the imported style
*/
function xml_import_style(
	$xml = false,
	$styleid = -1,
	$parentid = -1,
	$title = '',
	$anyversion = false,
	$displayorder = 1,
	$userselect = true,
	$startat = null,
	$perpage = null
)
{
	// $GLOBALS['path'] needs to be passed into this function or reference $vbulletin->GPC['path']

	global $vbulletin, $vbphrase;

	print_dots_start('<b>' . $vbphrase['importing_style'] . "</b>, $vbphrase[please_wait]", ':', 'dspan');

	require_once(DIR . '/includes/class_xml.php');

	//where is this used?  I hate having this random global value in the middle of this function
	$xmlobj = new vB_XML_Parser($xml, $vbulletin->GPC['path']);
	if ($xmlobj->error_no == 1)
	{
			print_dots_stop();
			print_stop_message('no_xml_and_no_path');
	}
	else if ($xmlobj->error_no == 2)
	{
			print_dots_stop();
			print_stop_message('please_ensure_x_file_is_located_at_y', 'vbulletin-style.xml', $vbulletin->GPC['path']);
	}

	if(!$parsed_xml = $xmlobj->parse())
	{
		print_dots_stop();
		print_stop_message('xml_error_x_at_line_y', $xmlobj->error_string(), $xmlobj->error_line());
	}

	$version = $parsed_xml['vbversion'];
	$master = ($parsed_xml['type'] == 'master' ? 1 : 0);
	$title = (empty($title) ? $parsed_xml['name'] : $title);
	$product = (empty($parsed_xml['product']) ? 'vbulletin' : $parsed_xml['product']);


	$one_pass = (is_null($startat) AND is_null($perpage));
	if (!$one_pass AND (!is_numeric($startat) OR !is_numeric($perpage) OR $perpage <= 0 OR $startat < 0))
	{
			print_dots_stop();
			print_stop_message('');
	}

	if ($one_pass OR ($startat == 0))
	{
		// version check
		$full_product_info = fetch_product_list(true);
		$product_info = $full_product_info["$product"];

		if ($version != $product_info['version'] AND !$anyversion AND !$master)
		{
			print_dots_stop();
			print_stop_message('upload_file_created_with_different_version', $product_info['version'], $version);
		}

		//Initialize the style -- either init the master, create a new style, or verify the style to overwrite.
		if ($master)
		{
			$import_data = @unserialize(fetch_adminutil_text('master_style_import'));
			if (!empty($import_data) AND (TIMENOW - $import_data['last_import']) <= 30)
			{
				print_dots_stop();
				print_stop_message('must_wait_x_seconds_master_style_import', vb_number_format($import_data['last_import'] + 30 - TIMENOW));
			}

			// overwrite master style
			echo "<h3>$vbphrase[master_style]</h3>\n<p>$vbphrase[please_wait]</p>";
			vbflush();

			$vbulletin->db->query_write("
				DELETE FROM " . TABLE_PREFIX . "template
				WHERE styleid = -10 AND (product = '" . $vbulletin->db->escape_string($product) . "'" .
					iif($product == 'vbulletin', " OR product = ''") . ")"
			);

			$vbulletin->db->query_write("
				UPDATE " . TABLE_PREFIX . "template
				SET styleid = -10 WHERE styleid = -1 AND (product = '" . $vbulletin->db->escape_string($product) . "'" .
					iif($product == 'vbulletin', " OR product = ''") . ")
			");
			$styleid = -1;
		}
		else
		{
			if ($styleid == -1)
			{
				// creating a new style
				$test = $vbulletin->db->query_first("
					SELECT styleid FROM " . TABLE_PREFIX . "style
					WHERE title = '" . $vbulletin->db->escape_string($title) . "'"
				);

				if ($test)
				{
					print_dots_stop();
					print_stop_message('style_already_exists', $title);
				}
				else
				{
					echo "<h3><b>" . construct_phrase($vbphrase['creating_a_new_style_called_x'], $title) . "</b></h3>\n<p>$vbphrase[please_wait]</p>";
					vbflush();
					/*insert query*/
					$styleresult = $vbulletin->db->query_write("
						INSERT INTO " . TABLE_PREFIX . "style
						(title, parentid, displayorder, userselect)
						VALUES
						('" . $vbulletin->db->escape_string($title) . "', $parentid, $displayorder, " . ($userselect ? 1 : 0) . ")
					");
					$styleid = $vbulletin->db->insert_id($styleresult);
				}
			}
			else
			{
				// overwriting an existing style
				if ($getstyle = $vbulletin->db->query_first("SELECT title FROM " . TABLE_PREFIX . "style WHERE styleid = $styleid"))
				{
					echo "<h3><b>" . construct_phrase($vbphrase['overwriting_style_x'], $getstyle['title']) . "</b></h3>\n<p>$vbphrase[please_wait]</p>";
					vbflush();
				}
				else
				{
					print_dots_stop();
					print_stop_message('cant_overwrite_non_existent_style');
				}
			}
		}
	}

	//load the templates
	if ($arr = $parsed_xml['templategroup'])
	{
		if (empty($arr[0]))
		{
			$arr = array($arr);
		}

		$templates_done = (is_numeric($startat) AND (count($arr) < $startat));
		if ($one_pass OR !$templates_done)
		{
			if (!$one_pass)
			{
				$arr = array_slice($arr, $startat, $perpage);
			}
			xml_import_template_groups($styleid, $product, $arr, !$one_pass);
		}
	}
	else
	{
		$templates_done = true;
	}

	//note that templates may actually be done at this point, but templates_done is
	//only true if templates were completed in a prior step. If we are doing a multi-pass
	//process, we don't want to install stylevars in the same pass.  We aren't really done
	//until we hit a pass where the templates are done before processing.
	$done = ($one_pass OR $templates_done);
	if ($done)
	{
		//load stylevars and definitions
		// re-import any stylevar definitions
		if ($master AND !empty($parsed_xml['stylevardfns']['stylevargroup']))
		{
			xml_import_stylevar_definitions($parsed_xml['stylevardfns'], 'vbulletin');
		}

		//if the tag is present but empty we'll end up with a string with whitespace which
		//is a non "empty" value.
		if (!empty($parsed_xml['stylevars']) AND is_array($parsed_xml['stylevars']))
		{
			xml_import_stylevars($parsed_xml['stylevars'], $styleid);
		}

		if ($master)
		{
			xml_import_restore_adsense_templates();
			build_adminutil_text('master_style_import', serialize(array('last_import' => TIMENOW)));
		}

		print_dots_stop();
	}

	return array(
		'version' => $version,
		'master'  => $master,
		'title'   => $title,
		'product' => $product,
		'done'    => $done
	);
}
Example #2
0
                    $userdm =& datamanager_init('User', $vbulletin, ERRTYPE_SILENT);
                    $userdm->set_existing($user);
                    $userdm->delete();
                    unset($userdm);
                }
            }
            // else, do nothing
        }
        define('CP_REDIRECT', 'index.php?do=home');
        print_stop_message('user_accounts_validated');
    }
}
// ############################# do prune users (step 2) #########################
if ($_REQUEST['do'] == 'prune_updateposts') {
    $vbulletin->input->clean_array_gpc('r', array('startat' => TYPE_INT));
    $userids = fetch_adminutil_text('ids');
    if (!$userids) {
        $userids = '0';
    }
    $users = $db->query_read("\n\t\tSELECT userid, username\n\t\tFROM " . TABLE_PREFIX . "user\n\t\tWHERE userid IN ({$userids})\n\t\tLIMIT " . $vbulletin->GPC['startat'] . ", 50\n\t");
    if ($db->num_rows($users)) {
        while ($user = $db->fetch_array($users)) {
            echo '<p>' . construct_phrase($vbphrase['updating_threads_posts_for_x'], $user['username']) . "\n";
            vbflush();
            $db->query_write("\n\t\t\t\tUPDATE " . TABLE_PREFIX . "thread SET\n\t\t\t\t\tpostuserid = 0,\n\t\t\t\t\tpostusername = '******'username']) . "'\n\t\t\t\tWHERE postuserid = {$user['userid']}\n\t\t\t");
            $db->query_write("\n\t\t\t\tUPDATE " . TABLE_PREFIX . "post SET\n\t\t\t\t\tuserid = 0,\n\t\t\t\t\tusername = '******'username']) . "'\n\t\t\t\tWHERE userid = {$user['userid']}\n\t\t\t");
            echo '<b>' . $vbphrase['done'] . "</b></p>\n";
            vbflush();
        }
        $vbulletin->GPC['startat'] += 50;
        print_cp_redirect("user.php?" . $vbulletin->session->vars['sessionurl'] . "do=prune_updateposts&startat=" . $vbulletin->GPC['startat'], 0);
Example #3
0
 /**
  * Do prune/move users (step 2). Userids to be updated are stored in adminutil table.
  *
  * @param integer $startat Start at index.
  * @return integer |bool Next startat value. True means all users have been updated.
  */
 public function pruneUpdateposts($startat)
 {
     $this->checkHasAdminPermission('canadminusers');
     require_once DIR . '/includes/adminfunctions.php';
     $userids = fetch_adminutil_text('ids');
     if (!$userids) {
         $userids = '0';
     }
     $users = vB::getDbAssertor()->getRows('user_fetch', array('userids' => $userids, vB_dB_Query::PARAM_LIMITSTART => intval($startat)));
     if ($users) {
         foreach ($users as $user) {
             vB::getDbAssertor()->assertQuery('user_updatethread', array('username' => $user['username'], 'userid' => $user['userid']));
             vB::getDbAssertor()->assertQuery('user_updatepost', array('username' => $user['username'], 'userid' => $user['userid']));
         }
         return $startat + 50;
     } else {
         vB::getDbAssertor()->assertQuery('user_deleteusertextfield', array('userids' => $userids));
         vB::getDbAssertor()->assertQuery('user_deleteuserfield', array('userids' => $userids));
         vB::getDbAssertor()->assertQuery('user_deleteuser', array('userids' => $userids));
         require_once DIR . '/includes/functions_databuild.php';
         build_user_statistics();
         return true;
     }
 }
Example #4
0
	else
	{
		define('CP_REDIRECT', 'misc.php');
		print_stop_message('rebuilt_statistics_successfully');
	}
}

// ###################### Start remove dupe threads #######################
if ($_REQUEST['do'] == 'removeorphanthreads')
{
	if (empty($vbulletin->GPC['perpage']))
	{
		$vbulletin->GPC['perpage'] = 50;
	}

	$result = fetch_adminutil_text('orphanthread');

	if ($result == 'done')
	{
		build_adminutil_text('orphanthread');
		define('CP_REDIRECT', 'misc.php');
		print_stop_message('deleted_orphan_threads_successfully');
	}
	else if ($result != '')
	{
		$threadarray = unserialize($result);
	}
	else
	{
		$threadarray = array();
		// Fetch IDS
Example #5
0
        if ($userexist['userid']) {
            $idarray['userid'] = $userexist['userid'];
            $name = $vbulletin->GPC['username'];
        } else {
            $name = $vbphrase['all_users'];
        }
        print_description_row(construct_phrase($vbphrase['x_subscriptions_matches_found'], vb_number_format($sub['threads'])) . '<br /><br />' . $vbphrase['are_you_sure_you_want_to_delete_these_subscriptions']);
        print_submit_row($vbphrase['yes'], 0, 2, $vbphrase['no']);
        build_adminutil_text('subscribe', serialize($idarray));
    } else {
        print_stop_message('no_threads_matched_your_query');
    }
}
// ############### do unsubscribe threads ####################
if ($_POST['do'] == 'killsubscription') {
    $idarray = unserialize(fetch_adminutil_text('subscribe'));
    $threadids = trim($idarray['threadids']);
    $db->query_write("\n\t\tDELETE FROM " . TABLE_PREFIX . "subscribethread\n\t\tWHERE threadid IN ({$threadids}) AND\n\t\t\temailupdate <> 0\n\t\t" . iif($idarray['userid'], " AND userid = {$idarray['userid']}") . "\n\t");
    define('CP_REDIRECT', 'thread.php?do=unsubscribe');
    print_stop_message('deleted_subscriptions_successfully');
}
// ############### unsubscribe threads ####################
if ($_REQUEST['do'] == 'unsubscribe') {
    print_form_header('thread', 'dospecificunsubscribe');
    print_table_header($vbphrase['unsubsribe_all_users_from_specific_threads']);
    print_textarea_row($vbphrase['enter_the_threadids_of_the_threads'], 'ids');
    print_submit_row($vbphrase['go']);
    print_form_header('thread', 'domassunsubscribe');
    print_table_header($vbphrase['unsubsribe_all_threads_from_specific_users']);
    print_input_row($vbphrase['username_leave_blank_to_remove_all'], 'username');
    print_input_row($vbphrase['find_all_threads_older_than_days'], 'daysprune', 30);
/**
* Reads XML style file and imports data from it into the database
*
* @param	string	XML data
* @param	integer	Style ID
* @param	integer	Parent style ID
* @param	string	New style title
* @param	boolean	Allow vBulletin version mismatch
* @param	integer	Display order for new style
* @param	boolean	Allow user selection of new style
* @param	int|null Starting template group index for this run of importing templates (0 based). Null means all templates (single run)
* @param	int|null
* @param	int 0 = normal import, 1 = style generator
* @param	string Import Filename
*
* @return	array	Array of information about the imported style
*/
function xml_import_style($xml = false, $styleid = -1, $parentid = -1, $title = '', $anyversion = false, $displayorder = 1, $userselect = true, $startat = null, $perpage = null, $importtype = 0, $filename = 'vbulletin-style.xml')
{
    // $GLOBALS['path'] needs to be passed into this function or reference $vbulletin->GPC['path']
    global $vbulletin, $vbphrase;
    print_dots_start('<b>' . $vbphrase['importing_style'] . "</b>, {$vbphrase['please_wait']}", ':', 'dspan');
    require_once DIR . '/includes/class_xml.php';
    //where is this used?  I hate having this random global value in the middle of this function
    $xmlobj = new vB_XML_Parser($xml, $vbulletin->GPC['path']);
    if ($xmlobj->error_no == 1) {
        print_dots_stop();
        print_stop_message('no_xml_and_no_path');
    } else {
        if ($xmlobj->error_no == 2) {
            print_dots_stop();
            print_stop_message('please_ensure_x_file_is_located_at_y', $filename, $vbulletin->GPC['path']);
        }
    }
    if (!($parsed_xml = $xmlobj->parse())) {
        print_dots_stop();
        print_stop_message('xml_error_x_at_line_y', $xmlobj->error_string(), $xmlobj->error_line());
    }
    if (!$styleid) {
        if ($parentid == -1 or $parentid == -2) {
            $styleid = $parentid;
        } else {
            $style = $vbulletin->db->query_first("\n\t\t\t\tSELECT IF(type = 'standard', -1, -2) AS mastertype\n\t\t\t\tFROM " . TABLE_PREFIX . "style\n\t\t\t\tWHERE styleid = {$parentid}\n\t\t\t");
            $styleid = $style['mastertype'];
        }
    }
    $version = $parsed_xml['vbversion'];
    $master = $parsed_xml['type'] == 'master' ? true : false;
    $mobilemaster = $parsed_xml['type'] == 'mobilemaster' ? true : false;
    $title = empty($title) ? $parsed_xml['name'] : $title;
    $product = empty($parsed_xml['product']) ? 'vbulletin' : $parsed_xml['product'];
    $one_pass = (is_null($startat) and is_null($perpage));
    if (!$one_pass and (!is_numeric($startat) or !is_numeric($perpage) or $perpage <= 0 or $startat < 0)) {
        print_dots_stop();
        print_stop_message('');
    }
    if ($one_pass or $startat == 0) {
        // version check
        $full_product_info = fetch_product_list(true);
        $product_info = $full_product_info["{$product}"];
        if ($version != $product_info['version'] and !$anyversion and !$master and !$mobilemaster) {
            print_dots_stop();
            print_stop_message('upload_file_created_with_different_version', $product_info['version'], $version);
        }
        //Initialize the style -- either init the master, create a new style, or verify the style to overwrite.
        if ($master or $mobilemaster) {
            $styleid = $master ? -1 : -2;
            $specialstyleid = $master ? -10 : -20;
            $import_data = @unserialize(fetch_adminutil_text("master_style_import_{$product}_{$specialstyleid}"));
            if (!empty($import_data) and TIMENOW - $import_data['last_import'] <= 30) {
                print_dots_stop();
                if ($master) {
                    print_stop_message('must_wait_x_seconds_master_style_import', vb_number_format($import_data['last_import'] + 30 - TIMENOW));
                } else {
                    print_stop_message('must_wait_x_seconds_mobile_master_style_import', vb_number_format($import_data['last_import'] + 30 - TIMENOW));
                }
            }
            $stylename = $master ? $vbphrase['master_style'] : $vbphrase['mobile_master_style'];
            // overwrite master style
            if (VB_AREA != 'Upgrade' and VB_AREA != 'Install') {
                echo "<h3>{$stylename}</h3>\n<p>{$vbphrase['please_wait']}</p>";
                vbflush();
            }
            $vbulletin->db->query_write("\n\t\t\t\tDELETE FROM " . TABLE_PREFIX . "template\n\t\t\t\tWHERE styleid = {$specialstyleid} AND (product = '" . $vbulletin->db->escape_string($product) . "'" . ($product == 'vbulletin' ? " OR product = ''" : "") . ")");
            $vbulletin->db->query_write("\n\t\t\t\tUPDATE " . TABLE_PREFIX . "template\n\t\t\t\tSET styleid = {$specialstyleid} WHERE styleid = {$styleid} AND (product = '" . $vbulletin->db->escape_string($product) . "'" . ($product == 'vbulletin' ? " OR product = ''" : "") . ")");
        } else {
            if ($styleid == -1 or $styleid == -2) {
                $type = $styleid == -1 ? 'standard' : 'mobile';
                // creating a new style
                $test = $vbulletin->db->query_first("\n\t\t\t\t\tSELECT styleid FROM " . TABLE_PREFIX . "style\n\t\t\t\t\tWHERE\n\t\t\t\t\t\ttitle = '" . $vbulletin->db->escape_string($title) . "'\n\t\t\t\t\t\t\tAND\n\t\t\t\t\t\ttype = '{$type}'\n\t\t\t\t");
                if ($test) {
                    print_dots_stop();
                    print_stop_message('style_already_exists', $title);
                } else {
                    echo "<h3><b>" . construct_phrase($vbphrase['creating_a_new_style_called_x'], $title) . "</b></h3>\n<p>{$vbphrase['please_wait']}</p>";
                    vbflush();
                    /*insert query*/
                    $styleresult = $vbulletin->db->query_write("\n\t\t\t\t\t\tINSERT INTO " . TABLE_PREFIX . "style\n\t\t\t\t\t\t(title, parentid, displayorder, userselect, type)\n\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t('" . $vbulletin->db->escape_string($title) . "', {$parentid}, {$displayorder}, " . ($userselect ? 1 : 0) . ", '{$type}')\n\t\t\t\t\t");
                    $styleid = $vbulletin->db->insert_id($styleresult);
                }
            } else {
                // overwriting an existing style
                if ($getstyle = $vbulletin->db->query_first("SELECT title FROM " . TABLE_PREFIX . "style WHERE styleid = {$styleid}")) {
                    if (VB_AREA != 'Upgrade' and VB_AREA != 'Install') {
                        echo "<h3><b>" . construct_phrase($vbphrase['overwriting_style_x'], $getstyle['title']) . "</b></h3>\n<p>{$vbphrase['please_wait']}</p>";
                        vbflush();
                    }
                } else {
                    print_dots_stop();
                    print_stop_message('cant_overwrite_non_existent_style');
                }
            }
        }
    } else {
        //We should never get styleid = -1 unless $master is true;
        if ($styleid == -1 and !$master or $styleid == -2 and !$mobilemaster) {
            $type = $styleid == -1 ? 'standard' : 'mobile';
            $stylerec = $vbulletin->db->query_first("\n\t\t\t\tSELECT styleid\n\t\t\t\tFROM " . TABLE_PREFIX . "style\n\t\t\t\tWHERE\n\t\t\t\t\ttitle = '" . $vbulletin->db->escape_string($title) . "'\n\t\t\t\t\t\tAND\n\t\t\t\t\ttype = '{$type}'\n\t\t\t");
            if ($stylerec and intval($stylerec['styleid'])) {
                $styleid = $stylerec['styleid'];
            } else {
                print_dots_stop();
                print_stop_message('incorrect_style_setting', $title);
            }
        }
    }
    $outputtext = '';
    //load the templates
    if ($arr = $parsed_xml['templategroup']) {
        if (empty($arr[0])) {
            $arr = array($arr);
        }
        $templates_done = (is_numeric($startat) and count($arr) <= $startat);
        if ($one_pass or !$templates_done) {
            if (!$one_pass) {
                $arr = array_slice($arr, $startat, $perpage);
            }
            $outputtext = xml_import_template_groups($styleid, $product, $arr, !$one_pass);
        }
    } else {
        $templates_done = true;
    }
    //note that templates may actually be done at this point, but templates_done is
    //only true if templates were completed in a prior step. If we are doing a multi-pass
    //process, we don't want to install stylevars in the same pass.  We aren't really done
    //until we hit a pass where the templates are done before processing.
    $done = ($one_pass or $templates_done);
    if ($done) {
        //load stylevars and definitions
        // re-import any stylevar definitions
        if (($master or $mobilemaster) and is_array($parsed_xml['stylevardfns']) and !empty($parsed_xml['stylevardfns']['stylevargroup'])) {
            xml_import_stylevar_definitions($parsed_xml['stylevardfns'], 'vbulletin', $master ? -1 : -2);
        }
        //if the tag is present but empty we'll end up with a string with whitespace which
        //is a non "empty" value.
        if (!empty($parsed_xml['stylevars']) and is_array($parsed_xml['stylevars'])) {
            xml_import_stylevars($parsed_xml['stylevars'], $styleid, $importtype);
        }
        if ($master or $mobilemaster) {
            xml_import_restore_ad_templates($styleid);
            $specialstyleid = $master ? -10 : -20;
            build_adminutil_text("master_style_import_{$product}_{$specialstyleid}", serialize(array('last_import' => TIMENOW)));
        }
        print_dots_stop();
    }
    return array('version' => $version, 'master' => $master, 'mobilemaster' => $mobilemaster, 'title' => $title, 'product' => $product, 'done' => $done, 'overwritestyleid' => $styleid, 'output' => $outputtext);
}
/**
* Reads XML style file and imports data from it into the database
*
* @param	string	$xml		XML data
* @param	integer	$styleid	Style ID
* @param	integer	$parentid	Parent style ID
* @param	string	$title		New style title
* @param	boolean	$anyversion	Allow vBulletin version mismatch
* @param	integer	$displayorder	Display order for new style
* @param	boolean	$userselct	Allow user selection of new style
* @param  	int|null	$startat	Starting template group index for this run of importing templates (0 based). Null means all templates (single run)
* @param  	int|null	$perpage	Number of templates to import at a time
* @param	boolean	$scilent		Run silently (do not echo)
* @param	array|boolean	$parsed_xml	Parsed array of XML data. If provided the function will ignore $xml and use the provided, already parsed data.
*
* @return	array	Array of information about the imported style
*/
function xml_import_style($xml = false, $styleid = -1, $parentid = -1, $title = '', $anyversion = false, $displayorder = 1, $userselect = true, $startat = null, $perpage = null, $scilent = false, $parsed_xml = false)
{
    // $GLOBALS['path'] needs to be passed into this function or reference $vbulletin->GPC['path']
    //checking the root node name
    if (!empty($xml)) {
        $r = new XMLReader();
        if ($r->xml($xml)) {
            if ($r->read()) {
                $node_name = $r->name;
                if ($node_name != 'style') {
                    print_stop_message2('file_uploaded_not_in_right_format_error');
                }
            } else {
                //can not read the document
                print_stop_message2('file_uploaded_unreadable');
            }
        } else {
            //can not open the xml
            print_stop_message2('file_uploaded_unreadable');
        }
    }
    global $vbulletin;
    if (!$scilent) {
        $vbphrase = vB_Api::instanceInternal('phrase')->fetch(array('importing_style', 'please_wait', 'creating_a_new_style_called_x'));
        print_dots_start('<b>' . $vbphrase['importing_style'] . "</b>, {$vbphrase['please_wait']}", ':', 'dspan');
    }
    require_once DIR . '/includes/class_xml.php';
    if (empty($parsed_xml)) {
        //where is this used?  I hate having this random global value in the middle of this function
        $xmlobj = new vB_XML_Parser($xml, $vbulletin->GPC['path']);
        if ($xmlobj->error_no() == 1) {
            if ($scilent) {
                throw new vB_Exception_AdminStopMessage('no_xml_and_no_path');
            }
            print_dots_stop();
            print_stop_message2('no_xml_and_no_path');
        } else {
            if ($xmlobj->error_no() == 2) {
                if ($scilent) {
                    throw new vB_Exception_AdminStopMessage(array('please_ensure_x_file_is_located_at_y', 'vbulletin-style.xml', $vbulletin->GPC['path']));
                }
                print_dots_stop();
                print_stop_message2(array('please_ensure_x_file_is_located_at_y', 'vbulletin-style.xml', $vbulletin->GPC['path']));
            }
        }
        if (!($parsed_xml = $xmlobj->parse())) {
            if ($scilent) {
                throw new vB_Exception_AdminStopMessage(array('xml_error_x_at_line_y', $xmlobj->error_string(), $xmlobj->error_line()));
            }
            print_dots_stop();
            print_stop_message2(array('xml_error_x_at_line_y', $xmlobj->error_string(), $xmlobj->error_line()));
        }
    }
    $version = $parsed_xml['vbversion'];
    $master = $parsed_xml['type'] == 'master' ? 1 : 0;
    $title = empty($title) ? $parsed_xml['name'] : $title;
    $product = empty($parsed_xml['product']) ? 'vbulletin' : $parsed_xml['product'];
    $one_pass = (is_null($startat) and is_null($perpage));
    if (!$one_pass and (!is_numeric($startat) or !is_numeric($perpage) or $perpage <= 0 or $startat < 0)) {
        if ($scilent) {
            throw new vB_Exception_AdminStopMessage('');
        }
        print_dots_stop();
        print_stop_message2('');
    }
    $outputtext = '';
    if ($one_pass or $startat == 0) {
        require_once DIR . '/includes/adminfunctions.php';
        // version check
        $full_product_info = fetch_product_list(true);
        $product_info = $full_product_info["{$product}"];
        if ($version != $product_info['version'] and !$anyversion and !$master) {
            if ($scilent) {
                throw new vB_Exception_AdminStopMessage(array('upload_file_created_with_different_version', $product_info['version'], $version));
            }
            print_dots_stop();
            print_stop_message2(array('upload_file_created_with_different_version', $product_info['version'], $version));
        }
        //Initialize the style -- either init the master, create a new style, or verify the style to overwrite.
        if ($master) {
            $import_data = @unserialize(fetch_adminutil_text('master_style_import'));
            if (!empty($import_data) and TIMENOW - $import_data['last_import'] <= 30) {
                if ($scilent) {
                    throw new vB_Exception_AdminStopMessage(array('must_wait_x_seconds_master_style_import', vb_number_format($import_data['last_import'] + 30 - TIMENOW)));
                }
                print_dots_stop();
                print_stop_message2(array('must_wait_x_seconds_master_style_import', vb_number_format($import_data['last_import'] + 30 - TIMENOW)));
            }
            // overwrite master style
            //			if  ($printInfo AND (VB_AREA != 'Upgrade' AND VB_AREA != 'Install'))
            //			{
            //				echo "<h3>$vbphrase[master_style]</h3>\n<p>$vbphrase[please_wait]</p>";
            //				vbflush();
            //			}
            $products = array($product);
            if ($product == 'vbulletin') {
                $products[] = '';
            }
            vB::getDbAssertor()->assertQuery('vBForum:deleteProductTemplates', array('products' => $products));
            vB::getDbAssertor()->assertQuery('vBForum:updateProductTemplates', array('products' => $products));
            $styleid = -1;
        } else {
            if ($styleid == -1) {
                // creating a new style
                if (vB::getDbAssertor()->getRow('style', array('title' => $title))) {
                    if ($scilent) {
                        throw new vB_Exception_AdminStopMessage(array('style_already_exists', $title));
                    }
                    print_dots_stop();
                    print_stop_message2(array('style_already_exists', $title));
                } else {
                    if (!$scilent) {
                        if (VB_AREA != 'Upgrade' or VB_AREA != 'Install') {
                            $outputtext = construct_phrase($vbphrase['creating_a_new_style_called_x'], $title) . "<br>\n";
                        } else {
                            // this isn't compatible with the ajax installer
                            echo "<h3><b>" . construct_phrase($vbphrase['creating_a_new_style_called_x'], $title) . "</b></h3>\n<p>{$vbphrase['please_wait']}</p>";
                            vbflush();
                        }
                    }
                    /*insert query*/
                    $styleid = vB::getDbAssertor()->insert('style', array('title' => $title, 'parentid' => $parentid, 'displayorder' => $displayorder, 'userselect' => $userselect ? 1 : 0));
                    if (is_array($styleid)) {
                        $styleid = array_pop($styleid);
                    }
                }
            } else {
                // overwriting an existing style
                if (vB::getDbAssertor()->getRow('style', array('styleid' => $styleid))) {
                    //					if  ($printInfo AND (VB_AREA != 'Upgrade' AND VB_AREA != 'Install'))
                    //					{
                    //						echo "<h3><b>" . construct_phrase($vbphrase['overwriting_style_x'], $getstyle['title']) . "</b></h3>\n<p>$vbphrase[please_wait]</p>";
                    //						vbflush();
                    //					}
                } else {
                    if ($scilent) {
                        throw new vB_Exception_AdminStopMessage('cant_overwrite_non_existent_style');
                    }
                    print_dots_stop();
                    print_stop_message2('cant_overwrite_non_existent_style');
                }
            }
        }
    } else {
        //We should never get styleid = -1 unless $master is true;
        if ($styleid == -1 and !$master) {
            $stylerec = vB::getDbAssertor()->getRow('style', array('title' => $title));
            if ($stylerec and intval($stylerec['styleid'])) {
                $styleid = $stylerec['styleid'];
            } else {
                if ($scilent) {
                    throw new vB_Exception_AdminStopMessage(array('incorrect_style_setting', $title));
                }
                print_dots_stop();
                print_stop_message2(array('incorrect_style_setting', $title));
            }
        }
    }
    //load the templates
    if ($arr = $parsed_xml['templategroup']) {
        if (empty($arr[0])) {
            $arr = array($arr);
        }
        $templates_done = (is_numeric($startat) and count($arr) <= $startat);
        if ($one_pass or !$templates_done) {
            if (!$one_pass) {
                $arr = array_slice($arr, $startat, $perpage);
            }
            $outputtext .= xml_import_template_groups($styleid, $product, $arr, !$one_pass);
        }
    } else {
        $templates_done = true;
    }
    //note that templates may actually be done at this point, but templates_done is
    //only true if templates were completed in a prior step. If we are doing a multi-pass
    //process, we don't want to install stylevars in the same pass.  We aren't really done
    //until we hit a pass where the templates are done before processing.
    $done = ($one_pass or $templates_done);
    if ($done) {
        //load stylevars and definitions
        // re-import any stylevar definitions
        if ($master and !empty($parsed_xml['stylevardfns']['stylevargroup'])) {
            xml_import_stylevar_definitions($parsed_xml['stylevardfns'], 'vbulletin');
        }
        //if the tag is present but empty we'll end up with a string with whitespace which
        //is a non "empty" value.
        if (!empty($parsed_xml['stylevars']) and is_array($parsed_xml['stylevars'])) {
            xml_import_stylevars($parsed_xml['stylevars'], $styleid);
        }
        if ($master) {
            xml_import_restore_ad_templates();
            build_adminutil_text('master_style_import', serialize(array('last_import' => TIMENOW)));
        }
        if (!$scilent) {
            print_dots_stop();
        }
    }
    $fastDs = vB_FastDS::instance();
    //We want to force a fastDS rebuild, but we can't just call rebuild. There may be dual web servers,
    // and calling rebuild only rebuilds one of them.
    $options = vB::getDatastore()->getValue('miscoptions');
    $options['tmtdate'] = vB::getRequest()->getTimeNow();
    vB::getDatastore()->build('miscoptions', serialize($options), 1);
    return array('version' => $version, 'master' => $master, 'title' => $title, 'product' => $product, 'done' => $done, 'overwritestyleid' => $styleid, 'output' => $outputtext);
}