echo "<p> </p></blockquote>"; } else { echo "<blockquote><p> </p>"; echo "$vbphrase[upgrade_wrong_version]"; echo "<p> </p></blockquote>"; print_upgrade_footer(); } } // ############################################################################# if ($vbulletin->GPC['step'] == 1) { require_once(DIR . '/includes/class_bitfield_builder.php'); vB_Bitfield_Builder::save($db); $upgrade->add_index( sprintf($upgrade_phrases['upgrade_300b3.php']['altering_x_table'], 'socialgroup', 1, 4), 'socialgroup', 'visible', 'visible' ); $upgrade->add_index( sprintf($upgrade_phrases['upgrade_300b3.php']['altering_x_table'], 'socialgroup', 2, 4), 'socialgroup', 'picturecount', 'picturecount' );
if (empty($_REQUEST['do'])) { $_REQUEST['do'] = 'modify'; } // ###################### Start add / edit moderator ####################### if ($_REQUEST['do'] == 'add' or $_REQUEST['do'] == 'edit' or $_REQUEST['do'] == 'editglobal') { require_once DIR . '/includes/class_bitfield_builder.php'; if (vB_Bitfield_Builder::build(false) !== false) { $myobj =& vB_Bitfield_Builder::init(); if (sizeof($myobj->data['misc']['moderatorpermissions']) != sizeof($vbulletin->bf_misc_moderatorpermissions) or sizeof($myobj->data['misc']['moderatorpermissions2']) != sizeof($vbulletin->bf_misc_moderatorpermissions2)) { $myobj->save($db); define('CP_REDIRECT', $vbulletin->scriptpath); print_stop_message('rebuilt_bitfields_successfully'); } } else { echo "<strong>error</strong>\n"; print_r(vB_Bitfield_Builder::fetch_errors()); } if ($_REQUEST['do'] == 'editglobal') { $moderator = $db->query_first("\n\t\t\tSELECT user.username, user.userid,\n\t\t\tmoderator.forumid, moderator.permissions, moderator.permissions2, moderator.moderatorid\n\t\t\tFROM " . TABLE_PREFIX . "user AS user\n\t\t\tLEFT JOIN " . TABLE_PREFIX . "moderator AS moderator ON (moderator.userid = user.userid AND moderator.forumid = -1)\n\t\t\tWHERE user.userid = " . $vbulletin->GPC['userid']); print_form_header('moderator', 'update'); construct_hidden_code('forumid', '-1'); construct_hidden_code('modusername', $moderator['username'], false); $username = $moderator['username']; log_admin_action('username = '******'username']); if (empty($moderator['moderatorid'])) { // this user doesn't have a record for super mod permissions, which is equivalent to having them all (except the email perms) $globalperms['permissions'] = array_sum($vbulletin->bf_misc_moderatorpermissions) - ($vbulletin->bf_misc_moderatorpermissions['newthreademail'] + $vbulletin->bf_misc_moderatorpermissions['newpostemail']); $globalperms['permissions2'] = array_sum($vbulletin->bf_misc_moderatorpermissions2); $moderator = convert_bits_to_array($globalperms['permissions'], $vbulletin->bf_misc_moderatorpermissions); $perms2 = convert_bits_to_array($globalperms['permissions2'], $vbulletin->bf_misc_moderatorpermissions2); $moderator['username'] = $username;
/** * Disable a product, not delete * */ public function disable($productid = null) { $productid = $productid ? $productid : $this->productinfo['productid']; $this->db->query_write("\n\t\t\tUPDATE " . TABLE_PREFIX . "product\n\t\t\tSET active = 0\n\t\t\tWHERE productid = '" . $this->db->escape_string($productid) . "'\n\t\t"); vBulletinHook::build_datastore($this->db); build_product_datastore(); // build bitfields to remove/add this products bitfields require_once DIR . '/includes/class_bitfield_builder.php'; vB_Bitfield_Builder::save($this->db); // Products can enable a cron entries, so we need to rebuild that as well require_once DIR . '/includes/functions_cron.php'; build_cron_next_run(); // Purge cache -- doesn't apply to pre-vB4 versions if (class_exists('vB_Cache')) { vB_Cache::instance()->purge('vb_types.types'); } // Reload blocks and block types -- doesn't apply to pre-vB4 versions if (class_exists('vB_BlockManager')) { $blockmanager = vB_BlockManager::create($this->registry); $blockmanager->reloadBlockTypes(); $blockmanager->getBlocks(true, true); } }
/** * Returns a multi-dimensional array of all defined bitfields, including <nocache> and disabled products * * $vbulletin->bf_ugp_forumpermissions['canview'] would be returned as $array['ugp']['forumpermissions']['canview'] * * @return array */ function return_data() { if (vB_Bitfield_Builder::build(true, true) === false) { return false; } $obj =& vB_Bitfield_Builder::init(); return $obj->data; }
function print_forum_permission_rows($customword, $forumpermission = array(), $extra = '') { global $vbphrase; print_label_row("<b>{$customword}</b>", ' <input type="button" class="button" value="' . $vbphrase['all_yes'] . '" onclick="' . iif($extra != '', 'if (js_set_custom()) { ') . ' js_check_all_option(this.form, 1);' . iif($extra != '', ' }') . '" class="button" /> <input type="button" class="button" value=" ' . $vbphrase['all_no'] . ' " onclick="' . iif($extra != '', 'if (js_set_custom()) { ') . ' js_check_all_option(this.form, 0);' . iif($extra != '', ' }') . '" class="button" /> <!--<input type="submit" class="button" value="Okay" class="button" />--> ', 'tcat', 'middle'); // Load permissions require_once DIR . '/includes/class_bitfield_builder.php'; $groupinfo = vB_Bitfield_Builder::fetch_permission_group('forumpermissions'); foreach ($groupinfo as $grouptitle => $group) { print_table_header($vbphrase["{$grouptitle}"]); foreach ($group as $permtitle => $permvalue) { print_yes_no_row($vbphrase["{$permvalue['phrase']}"], "forumpermission[{$permtitle}]", $forumpermission["{$permtitle}"], $extra); } //print_table_break(); //print_column_style_code(array('width: 70%', 'width: 30%')); } ($hook = vBulletinHook::fetch_hook('admin_fperms_form')) ? eval($hook) : false; }
} $vbulletin->input->clean_gpc('r', "num{$group}", vB_Cleaner::TYPE_UINT); for ($i = 0; $i < $vbulletin->GPC["num{$group}"]; $i++) { $vbulletin->GPC['navprefs'][] = $group . "_{$i}"; } } $vbulletin->GPC['navprefs'] = implode(',', $vbulletin->GPC['navprefs']); } else { $vbulletin->GPC['navprefs'] = ''; } $vbulletin->GPC['navprefs'] = preg_replace('#[^a-z0-9_,]#i', '', $vbulletin->GPC['navprefs']); $_REQUEST['do'] = 'savenavprefs'; } if ($_REQUEST['do'] == 'buildbitfields') { require_once DIR . '/includes/class_bitfield_builder.php'; vB_Bitfield_Builder::save(); build_channel_permissions(); print_stop_message2('rebuilt_bitfields_successfully', 'index'); } if ($_REQUEST['do'] == 'buildvideo' and (vB::getUserContext()->hasAdminPermission('canadminstyles') or vB::getUserContext()->hasAdminPermission('canadmintemplates'))) { require_once DIR . '/includes/functions_databuild.php'; build_bbcode_video(); print_cp_header(); vB_Library::instance('style')->buildAllStyles(); print_stop_message2('rebuilt_video_bbcodes_successfully', 'index'); } if ($_REQUEST['do'] == 'buildnavprefs') { $vbulletin->input->clean_array_gpc('r', array('prefs' => vB_Cleaner::TYPE_STR, 'dowhat' => vB_Cleaner::TYPE_STR, 'id' => vB_Cleaner::TYPE_INT)); $vbulletin->GPC['prefs'] = preg_replace('#[^a-z0-9_,]#i', '', $vbulletin->GPC['prefs']); $_tmp = preg_split('#,#', $vbulletin->GPC['prefs'], -1, PREG_SPLIT_NO_EMPTY); $_navprefs = array();
} $calendarpermission = convert_bits_to_array($getperms['calendarpermissions'], $vbulletin->bf_ugp_calendarpermissions); print_table_header(construct_phrase($vbphrase['edit_calendar_permissions_for_usergroup_x_in_calendar_y'], $usergroup['title'], $calendar['title'])); print_description_row(' <label for="uug_1"><input type="radio" name="useusergroup" value="1" id="uug_1" tabindex="1" onclick="this.form.reset(); this.checked=true;"' . iif(!$vbulletin->GPC['calendarpermissionid'], ' checked="checked"', '') . ' />' . $vbphrase['use_default_permissions'] . '</label> <br /> <label for="uug_0"><input type="radio" name="useusergroup" value="0" id="uug_0" tabindex="1"' . iif($vbulletin->GPC['calendarpermissionid'], ' checked="checked"', '') . ' />' . $vbphrase['use_custom_permissions'] . '</label> ', 0, 2, 'tfoot', '', 'mode'); print_table_break(); print_label_row('<b>' . $vbphrase['custom_calendar_permissions'] . '</b>', ' <input type="button" value="' . $vbphrase['all_yes'] . '" onclick="if (js_set_custom()) { js_check_all_option(this.form, 1); }" class="button" /> <input type="button" value=" ' . $vbphrase['all_no'] . ' " onclick="if (js_set_custom()) { js_check_all_option(this.form, 0); }" class="button" /> ', 'tcat', 'middle'); // Load permissions require_once DIR . '/includes/class_bitfield_builder.php'; $groupinfo = vB_Bitfield_Builder::fetch_permission_group('calendarpermissions'); foreach ($groupinfo as $grouptitle => $group) { print_table_header($vbphrase["{$grouptitle}"]); foreach ($group as $permtitle => $permvalue) { print_yes_no_row($vbphrase["{$permvalue['phrase']}"], "calendarpermission[{$permtitle}]", $calendarpermission["{$permtitle}"], 'js_set_custom();'); } } print_submit_row($vbphrase['save']); } // ###################### Start do update ####################### if ($_POST['do'] == 'doupdate') { $vbulletin->input->clean_array_gpc('p', array('calendarpermissionid' => TYPE_INT, 'calendarid' => TYPE_INT, 'useusergroup' => TYPE_INT, 'calendarpermission' => TYPE_ARRAY)); define('CP_REDIRECT', "calendarpermission.php?do=modify#calendar" . $vbulletin->GPC['calendarid']); if ($vbulletin->GPC['useusergroup']) { // use usergroup defaults. delete calendarpermission if it exists if ($vbulletin->GPC['calendarpermissionid']) {
/** * Fetch default usergroup data for adding or editing new usergroup * * @param int $usergroupid If present, the data will be copied from this usergroup * @return array Default usergroup data. It contains four sub-arrays: * 'usergroup' - Basic usergroup information * 'ugarr' - usergroups to be used for 'Create Forum Permissions Based off of Usergroup' * 'ug_bitfield' - Usergroup bitfield * 'groupinfo' - Usergroup permission information */ public function fetchDefaultData($usergroupid = 0) { $this->checkHasAdminPermission('canadminpermissions'); $bf_ugp = vB::getDatastore()->get_value('bf_ugp'); require_once DIR . '/includes/class_bitfield_builder.php'; $myobj =& vB_Bitfield_Builder::init(); if ($usergroupid) { $usergroup = vB::getDbAssertor()->getRow('usergroup', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_TABLE, vB_dB_Query::CONDITIONS_KEY => array('usergroupid' => $usergroupid))); $ug_bitfield = array(); foreach ($bf_ugp as $permissiongroup => $fields) { $ug_bitfield["{$permissiongroup}"] = convert_bits_to_array($usergroup["{$permissiongroup}"], $fields); } } else { $ug_bitfield = array('genericoptions' => array('showgroup' => 1, 'showeditedby' => 1, 'isnotbannedgroup' => 1), 'forumpermissions' => array('canview' => 1, 'canviewothers' => 1, 'cangetattachment' => 1, 'cansearch' => 1, 'canthreadrate' => 1, 'canpostattachment' => 1, 'canpostpoll' => 1, 'canvote' => 1, 'canviewthreads' => 1), 'forumpermissions2' => array('cangetimgattachment' => 1), 'wolpermissions' => array('canwhosonline' => 1), 'genericpermissions' => array('canviewmembers' => 1, 'canmodifyprofile' => 1, 'canseeprofilepic' => 1, 'canusesignature' => 1, 'cannegativerep' => 1, 'canuserep' => 1, 'cansearchft_nl' => 1)); // set default numeric permissions $usergroup = array('pmquota' => 0, 'pmsendmax' => 5, 'attachlimit' => 1000000, 'avatarmaxwidth' => 200, 'avatarmaxheight' => 200, 'avatarmaxsize' => 20000, 'profilepicmaxwidth' => 100, 'profilepicmaxheight' => 100, 'profilepicmaxsize' => 25000, 'sigmaxsizebbcode' => 7); } $permgroups = vB::getDbAssertor()->assertQuery('usergroup_fetchperms', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED)); $ugarr = array(); foreach ($permgroups as $group) { $ugarr["{$group['usergroupid']}"] = $group['title']; } foreach ((array) $myobj->data['ugp'] as $grouptitle => $perms) { if ($grouptitle == 'createpermissions') { continue; } foreach ($perms as $permtitle => $permvalue) { if (empty($permvalue['group'])) { continue; } $groupinfo["{$permvalue['group']}"]["{$permtitle}"] = array('phrase' => $permvalue['phrase'], 'value' => $permvalue['value'], 'parentgroup' => $grouptitle); if ($permvalue['intperm']) { $groupinfo["{$permvalue['group']}"]["{$permtitle}"]['intperm'] = true; } if (!empty($myobj->data['layout']["{$permvalue['group']}"]['ignoregroups'])) { $groupinfo["{$permvalue['group']}"]['ignoregroups'] = $myobj->data['layout']["{$permvalue['group']}"]['ignoregroups']; } if (!empty($permvalue['ignoregroups'])) { $groupinfo["{$permvalue['group']}"]["{$permtitle}"]['ignoregroups'] = $permvalue['ignoregroups']; } if (!empty($permvalue['options'])) { $groupinfo["{$permvalue['group']}"]["{$permtitle}"]['options'] = $permvalue['options']; } } } return array('usergroup' => $usergroup, 'ug_bitfield' => $ug_bitfield, 'ugarr' => $ugarr, 'groupinfo' => $groupinfo); }
/** * Fetches an array describing the bits in the requested bitfield * * @param string Represents the array key required... use x|y|z to fetch ['x']['y']['z'] * * @return array Reference to the requested array from includes/xml/bitfield_{product}.xml */ function &fetch_bitfield_definitions($string) { static $bitfields = null; if ($bitfields === null) { require_once DIR . '/includes/class_bitfield_builder.php'; $bitfields = vB_Bitfield_Builder::return_data(); } $keys = "['" . implode("']['", preg_split('#\\|#si', $string, -1, PREG_SPLIT_NO_EMPTY)) . "']"; eval('$return =& $bitfields' . $keys . ';'); return $return; }
} } else { if (VB_AREA == 'Install') { // load it up but don't actually call fetch, we need the ability to overwrite fields. $datastore_class = !empty($vbulletin->config['Datastore']['class']) ? $vbulletin->config['Datastore']['class'] : 'vB_Datastore'; if ($datastore_class != 'vB_Datastore') { require_once DIR . '/includes/class_datastore.php'; } $vbulletin->datastore = new $datastore_class($vbulletin, $db); } } // ## Load latest bitfields, overwrite datastore versions (if they exist) // ## (so latest upgrade script can access any new permissions) require_once DIR . '/includes/class_bitfield_builder.php'; if (vB_Bitfield_Builder::build_datastore() !== false) { $myobj =& vB_Bitfield_Builder::init(); require_once DIR . '/includes/functions.php'; require_once DIR . '/includes/functions_misc.php'; foreach (array_keys($myobj->datastore) as $group) { $vbulletin->{'bf_' . $group} =& $myobj->datastore["{$group}"]; foreach (array_keys($myobj->datastore["{$group}"]) as $subgroup) { $vbulletin->{'bf_' . $group . '_' . $subgroup} =& $myobj->datastore["{$group}"]["{$subgroup}"]; } } } else { trigger_error('Error Building Bitfields', E_USER_ERROR); } } // setup an empty hook class in case we run some of the main vB code require_once DIR . '/includes/class_hook.php'; $vbulletin->pluginlist = '';
// fetch the custom perms, row per type this time $customperms = array(); $customperms_data = $db->query_read("\n\t\t\tSELECT *\n\t\t\tFROM " . TABLE_PREFIX . "pt_projectpermission\n\t\t\tWHERE usergroupid = {$usergroup_info['usergroupid']}\n\t\t\t\tAND projectid = {$project['projectid']}\n\t\t"); while ($customperm = $db->fetch_array($customperms_data)) { $perms = $customperm; unset($perms['usergroupid'], $perms['projectid'], $perms['issuetypeid']); $customperms["{$customperm['issuetypeid']}"] = $perms; } } else { // editing global permissions print_table_header(construct_phrase($vbphrase['edit_permissions_for_x'], $usergroup_info['title']), sizeof($issuetype_options) + 1); $customperms = array(); } require_once DIR . '/includes/class_bitfield_builder.php'; vB_Bitfield_Builder::build(false); $builder =& vB_Bitfield_Builder::init(); $perms = array(); $has_custom = array(); if (!$project) { // these are the global-only (settable in one place) permissions for the project tools print_description_row($vbphrase['global_project_tools_permissions'], false, 4, 'thead'); foreach ($builder->data['ugp']['ptpermissions'] as $bitname => $permvalue) { $bit = $permvalue['value']; print_yes_no_row($vbphrase["{$permvalue['phrase']}"], "ugpermissions[{$bit}]", intval($usergroup_info['ptpermissions']) & intval($bit) ? 1 : 0); } print_description_row('<span class="smallfont"><a href="#" onclick="js_open_help(\'projectpermission\', \'edit\', \'about_reports\'); return false;">' . $vbphrase['what_are_reports'] . '</a></span>', false, 2, '', 'right'); print_table_break(); print_table_header(construct_phrase($vbphrase['project_tools_permissions_for_x'], $usergroup_info['title']), sizeof($issuetype_options) + 1); } else { // project specific -- let's check the general permissions for this group if (!(intval($usergroup_info['ptpermissions']) & $vbulletin->bf_ugp_ptpermissions['canviewprojecttools'])) {
/** * Step #7 - Default User Setup... * */ function step_7($data = null) { if ($data['response']) { array_map('trim', $data['htmldata']); $errors = array(); if (empty($data['htmldata']['username'])) { $errors['username'] = $this->phrase['install']['error_username']; } if (empty($data['htmldata']['email']) or !is_valid_email($data['htmldata']['email'])) { $errors['email'] = $this->phrase['install']['error_email']; } if (empty($data['htmldata']['password']) or empty($data['htmldata']['confirmpassword'])) { if (empty($data['htmldata']['password'])) { $errors['password'] = $this->phrase['install']['error_password']; } else { if (empty($data['htmldata']['confirmpassword'])) { $errors['confirmpassword'] = $this->phrase['install']['error_confirmpassword']; } } } else { if ($data['htmldata']['password'] != $data['htmldata']['confirmpassword']) { $errors['mismatch'] = $this->phrase['install']['error_password_not_match']; } else { if ($data['htmldata']['password'] == $data['htmldata']['username'] and !defined('ALLOW_SAME_USERNAME_PASSWORD')) { $errors['samepasswordasusername'] = $this->phrase['install']['error_same_password_as_username']; } } } // check if a user already exists. If so, DO NOT CREATE A NEW USER. $vbexists = $this->fetch_vbexists(); if (!$vbexists) { $errors[] = $this->phrase['install']['user_table_missing']; // we can't create a user without a user table. } else { // assuming if user table exists, userid will exist. If a user exists, DO NOT CREATE A NEW USER if ($this->db->query_first("SELECT userid FROM " . trim($this->registry->config['Database']['tableprefix']) . "user LIMIT 1")) { $errors[] = $this->phrase['install']['user_already_exists']; } } if (empty($errors)) { require_once DIR . '/includes/class_bitfield_builder.php'; vB_Bitfield_Builder::save($this->db); $admin_defaults = array('vbasset_enable', 'showsignatures', 'showavatars', 'showimages', 'adminemail', 'dstauto', 'receivepm', 'showusercss', 'receivefriendemailrequest', 'vm_enable'); $admin_useroption = 0; foreach ($admin_defaults as $bitfield) { $admin_useroption |= $this->registry->bf_misc_useroptions["{$bitfield}"]; } require_once DIR . '/includes/functions_user.php'; //for now we'll just include these to get the define for the salt length. Should investigate //using the DM to add the initial admin user, but there may be issues with doing that without //a proper user session (which we can't have until we require the user. require_once DIR . '/includes/class_dm.php'; require_once DIR . '/includes/class_dm_user.php'; $salt = fetch_user_salt(SALT_LENGTH); /*insert query*/ $this->db->query_write("\n\t\t\t\t\tINSERT INTO " . TABLE_PREFIX . "user\n\t\t\t\t\t\t(username, salt, password, email, usertitle, joindate, lastvisit, lastactivity, usergroupid, passworddate, options, showvbcode)\n\t\t\t\t\tVALUES (\n\t\t\t\t\t\t'" . $this->db->escape_string(htmlspecialchars_uni($data['htmldata']['username'])) . "',\n\t\t\t\t\t\t'" . $this->db->escape_string($salt) . "',\n\t\t\t\t\t\t'" . $this->db->escape_string(md5(md5($data['htmldata']['password']) . $salt)) . "',\n\t\t\t\t\t\t'" . $this->db->escape_string($data['htmldata']['email']) . "',\n\t\t\t\t\t\t'" . $this->db->escape_string($this->phrase['install']['usergroup_admin_usertitle']) . "',\n\t\t\t\t\t\t" . TIMENOW . ",\n\t\t\t\t\t\t" . TIMENOW . ",\n\t\t\t\t\t\t" . TIMENOW . ",\n\t\t\t\t\t\t6,\n\t\t\t\t\t\tFROM_UNIXTIME(" . TIMENOW . "),\n\t\t\t\t\t\t{$admin_useroption},\n\t\t\t\t\t\t2\n\t\t\t\t\t)\n\t\t\t\t"); $userid = $this->db->insert_id(); /*insert query*/ $this->db->query_write("\n\t\t\t\t\tINSERT INTO " . TABLE_PREFIX . "usertextfield\n\t\t\t\t\t\t(userid)\n\t\t\t\t\tVALUES\n\t\t\t\t\t\t({$userid})\n\t\t\t\t"); /*insert query*/ $this->db->query_write("\n\t\t\t\t\tINSERT INTO " . TABLE_PREFIX . "userfield\n\t\t\t\t\t\t(userid)\n\t\t\t\t\tVALUES\n\t\t\t\t\t\t({$userid})\n\t\t\t\t"); /*insert query*/ $this->db->query_write("INSERT INTO " . TABLE_PREFIX . "administrator\n\t\t\t\t\t(userid, adminpermissions)\n\t\t\t\tVALUES\n\t\t\t\t\t({$userid}, " . (array_sum($this->registry->bf_ugp_adminpermissions) - 3) . ")\n\t\t\t\t"); /*insert query*/ $this->db->query_write("INSERT INTO " . TABLE_PREFIX . "moderator\n\t\t\t\t\t(userid, forumid, permissions, permissions2)\n\t\t\t\tVALUES\n\t\t\t\t\t(\n\t\t\t\t\t\t{$userid},\n\t\t\t\t\t\t-1,\n\t\t\t\t\t\t" . (array_sum($this->registry->bf_misc_moderatorpermissions) - ($this->registry->bf_misc_moderatorpermissions['newthreademail'] + $this->registry->bf_misc_moderatorpermissions['newpostemail'])) . ",\n\t\t\t\t\t\t" . array_sum($this->registry->bf_misc_moderatorpermissions2) . "\n\t\t\t\t\t)\n\t\t\t\t"); build_image_cache('smilie'); build_image_cache('avatar'); build_image_cache('icon'); build_bbcode_cache(); require_once DIR . '/includes/functions_databuild.php'; build_user_statistics(); require_once DIR . '/includes/adminfunctions_forums.php'; build_forum_child_lists(); build_forum_permissions(); require_once DIR . '/includes/functions_cron.php'; build_cron_next_run(); require_once DIR . '/includes/adminfunctions_attachment.php'; build_attachment_permissions(); require_once DIR . '/includes/class_block.php'; $blockmanager = vB_BlockManager::create($this->registry); $blockmanager->reloadBlockTypes(); $this->show_message($this->phrase['install']['administrator_account_created']); return; } else { foreach ($errors as $key => $value) { $errors["{$key}"] = '<span class="usererror">' . $value . '</span>'; } } } else { $data['htmldata'] = array(); } $html = '<table cellspacing="0" cellpadding="4" border="0" align="center" width="100%" id="cpform_table" class="" style="border-collapse: separate;"> <tbody> <tr valign="top"> <td class="alt1">' . $this->phrase['install']['username'] . $errors['username'] . ' <span id="htmldata[username]_error" class="usererror hidden">' . $this->phrase['install']['field_required'] . '</span> </td> <td class="alt1"> <div id="ctrl_username"> <input type="text" tabindex="1" dir="ltr" size="35" value="' . htmlspecialchars_uni($data['htmldata']['username']) . '" id="it_username_1" name="htmldata[username]" class="bginput" vbrequire="1" /> </div> </td> </tr> <tr valign="top"> <td class="alt2">' . $this->phrase['install']['password'] . $errors['password'] . $errors['mismatch'] . $errors['samepasswordasusername'] . ' <span id="htmldata[password]_error" class="usererror hidden">' . $this->phrase['install']['field_required'] . '</span> </td> <td class="alt2"> <div id="ctrl_password"> <input type="password" tabindex="1" size="35" value="' . htmlspecialchars_uni($data['htmldata']['password']) . '" name="htmldata[password]" class="bginput" vbrequire="1" /> </div> </td> </tr> <tr valign="top"> <td class="alt1">' . $this->phrase['install']['confirm_password'] . $errors['confirmpassword'] . $errors['mismatch'] . ' <span id="htmldata[confirmpassword]_error" class="usererror hidden">' . $this->phrase['install']['field_required'] . '</span> </td> <td class="alt1"> <div id="ctrl_confirmpassword"> <input type="password" tabindex="1" size="35" value="' . htmlspecialchars_uni($data['htmldata']['confirmpassword']) . '" name="htmldata[confirmpassword]" class="bginput" vbrequire="1" /> </div> </td> </tr> <tr valign="top"> <td class="alt2">' . $this->phrase['install']['email_address'] . $errors['email'] . ' <span id="htmldata[email]_error" class="usererror hidden">' . $this->phrase['install']['field_required'] . '</span> </td> <td class="alt2"> <div id="ctrl_email"> <input type="text" tabindex="1" dir="ltr" size="35" value="' . htmlspecialchars_uni($data['htmldata']['email']) . '" id="it_email_2" name="htmldata[email]" class="bginput" vbrequire="1" /> </div> </td> </tr> </tbody></table>'; return array('html' => $html, 'width' => '640px', 'hidecancel' => true, 'title' => $this->phrase['install']['administrator_account_setup'], 'reset' => true); }
/** * Installs a product from the xml text * * This function depends on the vb class loader, which requires that the * framework init is called. * * @return bool True if the product requires a template merge, false otherwise */ function install_product($xml, $allow_overwrite) { global $vbphrase; global $vbulletin; global $db; require_once(DIR . '/includes/class_bitfield_builder.php'); require_once(DIR . '/includes/class_xml.php'); require_once(DIR . '/includes/class_block.php'); //share some code with the main xml style import require_once(DIR . '/includes/adminfunctions_template.php'); print_dots_start('<b>' . $vbphrase['importing_product'] . "</b>, $vbphrase[please_wait]", ':', 'dspan'); $xmlobj = new vB_XML_Parser($xml); if ($xmlobj->error_no == 1) { print_dots_stop(); throw new vB_Exception_AdminStopMessage('no_xml_and_no_path'); } if(!$arr = $xmlobj->parse()) { print_dots_stop(); throw new vB_Exception_AdminStopMessage( array('xml_error_x_at_line_y', $xmlobj->error_string(), $xmlobj->error_line())); } // ############## general product information $info = array( 'productid' => substr(preg_replace('#[^a-z0-9_]#', '', strtolower($arr['productid'])), 0, 25), 'title' => $arr['title'], 'description' => $arr['description'], 'version' => $arr['version'], 'active' => $arr['active'], 'url' => $arr['url'], 'versioncheckurl' => $arr['versioncheckurl'] ); if (!$info['productid']) { print_dots_stop(); if (!empty($arr['plugin'])) { throw new vB_Exception_AdminStopMessage('this_file_appears_to_be_a_plugin'); } else { throw new vB_Exception_AdminStopMessage('invalid_file_specified'); } } if (strtolower($info['productid']) == 'vbulletin') { print_dots_stop(); throw new vB_Exception_AdminStopMessage(array('product_x_installed_no_overwrite', 'vBulletin')); } // check for bitfield conflicts on install $bitfields = vB_Bitfield_Builder::return_data(); if (!$bitfields) { $bfobj =& vB_Bitfield_Builder::init(); if ($bfobj->errors) { print_dots_stop(); throw new vB_Exception_AdminStopMessage(array( 'bitfield_conflicts_x', '<li>' . implode('</li><li>', $bfobj->errors) . '</li>' )); } } // get system version info $system_versions = array( 'php' => PHP_VERSION, 'vbulletin' => $vbulletin->options['templateversion'], 'products' => fetch_product_list(true) ); $mysql_version = $db->query_first("SELECT VERSION() AS version"); $system_versions['mysql'] = $mysql_version['version']; // ############## import dependencies if (is_array($arr['dependencies']['dependency'])) { $dependencies =& $arr['dependencies']['dependency']; if (!isset($dependencies[0])) { $dependencies = array($dependencies); } $dependency_errors = array(); $ignore_dependency_errors = array(); // let's check the dependencies foreach ($dependencies AS $dependency) { // if we get an error, we haven't met this dependency // if we go through without a problem, we have automatically met // all dependencies for this "class" (mysql, php, vb, a specific product, etc) $this_dependency_met = true; // build a phrase for the version compats -- will look like (minver / maxver) if ($dependency['minversion']) { $compatible_phrase = construct_phrase( $vbphrase['compatible_starting_with_x'], htmlspecialchars_uni($dependency['minversion']) ); } else { $compatible_phrase = ''; } if ($dependency['maxversion']) { $incompatible_phrase = construct_phrase( $vbphrase['incompatible_with_x_and_greater'], htmlspecialchars_uni($dependency['maxversion']) ); } else { $incompatible_phrase = ''; } if ($compatible_phrase OR $incompatible_phrase) { $required_version_info = "($compatible_phrase"; if ($compatible_phrase AND $incompatible_phrase) { $required_version_info .= ' / '; } $required_version_info .= "$incompatible_phrase)"; } // grab the appropriate installed version string if ($dependency['dependencytype'] == 'product') { // group dependencies into types -- individual products get their own group $dependency_type_key = "product-$dependency[parentproductid]"; // undocumented feature -- you can put a producttitle attribute in a dependency so the id isn't displayed $parent_product_title = (!empty($dependency['producttitle']) ? $dependency['producttitle'] : $dependency['parentproductid']); $parent_product = $system_versions['products']["$dependency[parentproductid]"]; if (!$parent_product) { // required product is not installed $dependency_errors["$dependency_type_key"] = construct_phrase( $vbphrase['product_x_must_be_installed'], htmlspecialchars_uni($parent_product_title), $required_version_info ); continue; // can't do version checks if the product isn't installed } else if ($parent_product['active'] == 0) { // product is installed, but inactive $dependency_errors["{$dependency_type_key}-inactive"] = construct_phrase( $vbphrase['product_x_must_be_activated'], htmlspecialchars_uni($parent_product_title) ); $this_dependency_met = false; // allow version checks to continue } $sys_version_str = $parent_product['version']; $version_incompatible_phrase = 'product_incompatible_version_x_product_y'; } else { $dependency_type_key = $dependency['dependencytype']; $parent_product_title = ''; $sys_version_str = $system_versions["$dependency[dependencytype]"]; $version_incompatible_phrase = 'product_incompatible_version_x_' . $dependency['dependencytype']; } // if no version string, we are trying to do an unsupported dep check if ($sys_version_str == '') { continue; } $sys_version = fetch_version_array($sys_version_str); // error if installed version < minversion if ($dependency['minversion']) { $dep_version = fetch_version_array($dependency['minversion']); for ($i = 0; $i <= 5; $i++) { if ($sys_version["$i"] < $dep_version["$i"]) { // installed version is too old $dependency_errors["$dependency_type_key"] = construct_phrase( $vbphrase["$version_incompatible_phrase"], htmlspecialchars_uni($sys_version_str), $required_version_info, $parent_product_title ); $this_dependency_met = false; break; } else if ($sys_version["$i"] > $dep_version["$i"]) { break; } } } // error if installed version >= maxversion if ($dependency['maxversion']) { $dep_version = fetch_version_array($dependency['maxversion']); $all_equal = true; for ($i = 0; $i <= 5; $i++) { if ($sys_version["$i"] > $dep_version["$i"]) { // installed version is newer than the maxversion $dependency_errors["$dependency_type_key"] = construct_phrase( $vbphrase["$version_incompatible_phrase"], htmlspecialchars_uni($sys_version_str), $required_version_info, $parent_product_title ); $this_dependency_met = false; break; } else if ($sys_version["$i"] < $dep_version["$i"]) { // not every part is the same and since we've got less we can exit $all_equal = false; break; } else if ($sys_version["$i"] != $dep_version["$i"]) { // not every part is the same $all_equal = false; } } if ($all_equal == true) { // installed version is same as the max version, which is the first incompat version $dependency_errors["$dependency_type_key"] = construct_phrase( $vbphrase["$version_incompatible_phrase"], htmlspecialchars_uni($sys_version_str), $required_version_info, $parent_product_title ); $this_dependency_met = false; } } if ($this_dependency_met) { // we met 1 dependency for this type -- this emulates or'ing together groups $ignore_dependency_errors["$dependency_type_key"] = true; } } // for any group we met a dependency for, ignore any errors we might // have gotten for the group foreach ($ignore_dependency_errors AS $dependency_type_key => $devnull) { unset($dependency_errors["$dependency_type_key"]); } if ($dependency_errors) { $dependency_errors = array_unique($dependency_errors); $dependency_errors = '<ol><li>' . implode('</li><li>', $dependency_errors) . '</li></ol>'; print_dots_stop(); throw new vB_Exception_AdminStopMessage( array('dependencies_not_met_x', $dependency_errors)); } } // look to see if we already have this product installed if ($existingprod = $db->query_first(" SELECT * FROM " . TABLE_PREFIX . "product WHERE productid = '" . $db->escape_string($info['productid']) . "'" )) { if (!$allow_overwrite) { print_dots_stop(); throw new vB_Exception_AdminStopMessage( array('product_x_installed_no_overwrite', $info['title'])); } $active = $existingprod['active']; // not sure what we're deleting, so rebuild everything $rebuild = array( 'templates' => true, 'plugins' => true, 'phrases' => true, 'options' => true, 'cron' => true ); $installed_version = $existingprod['version']; } else { $active = ($info['active'] ? 1 : 0); $rebuild = array( 'templates' => false, 'plugins' => false, 'phrases' => false, 'options' => false, 'cron' => false ); $installed_version = null; } // ############## import install/uninstall code if (is_array($arr['codes']['code'])) { $codes =& $arr['codes']['code']; if (!isset($codes[0])) { $codes = array($codes); } // run each of the codes foreach ($codes AS $code) { // Run if: code version is * (meaning always run), no version // previously installed, or if the code is for a newer version // than is currently installed if ($code['version'] == '*' OR $installed_version === null OR is_newer_version($code['version'], $installed_version)) { eval($code['installcode']); } } // Clear routes from datastore build_datastore('routes', serialize(array()), 1); //assume that the product may have installed content types and purge the content type cache vB_Cache::instance()->purge('vb_types.types'); } // dependencies checked, install code run. Now clear out the old product info; // settings should be retained in memory already delete_product($info['productid'], false, true); if (is_array($codes)) { // we've now run all the codes, if execution is still going // then it's going to complete fully, so insert the codes foreach ($codes AS $code) { /* insert query */ $db->query_write(" INSERT INTO " . TABLE_PREFIX . "productcode (productid, version, installcode, uninstallcode) VALUES ('" . $db->escape_string($info['productid']) . "', '" . $db->escape_string($code['version']) . "', '" . $db->escape_string($code['installcode']) . "', '" . $db->escape_string($code['uninstallcode']) . "') "); } } if (is_array($dependencies)) { // dependencies met, codes run -- now we can insert the dependencies into the DB foreach ($dependencies AS $dependency) { /* insert query */ $db->query_write(" INSERT INTO " . TABLE_PREFIX . "productdependency (productid, dependencytype, parentproductid, minversion, maxversion) VALUES ('" . $db->escape_string($info['productid']) . "', '" . $db->escape_string($dependency['dependencytype']) . "', '" . $db->escape_string($dependency['parentproductid']) . "', '" . $db->escape_string($dependency['minversion']) . "', '" . $db->escape_string($dependency['maxversion']) . "') "); } } /* insert query */ $db->query_write(" INSERT INTO " . TABLE_PREFIX . "product (productid, title, description, version, active, url, versioncheckurl) VALUES ('" . $db->escape_string($info['productid']) . "', '" . $db->escape_string($info['title']) . "', '" . $db->escape_string($info['description']) . "', '" . $db->escape_string($info['version']) . "', " . intval($active) . ", '" . $db->escape_string($info['url']) . "', '" . $db->escape_string($info['versioncheckurl']) . "') "); // ############## import templates if (is_array($arr['templates']['template'])) { $querybits = array(); $querytemplates = 0; $templates =& $arr['templates']['template']; if (!isset($templates[0])) { $templates = array($templates); } foreach ($templates AS $template) { $title = $db->escape_string($template['name']); $template['template'] = $db->escape_string($template['value']); $template['username'] = $db->escape_string($template['username']); $template['templatetype'] = $db->escape_string($template['templatetype']); $template['date'] = intval($template['date']); if ($template['templatetype'] != 'template') { // template is a special template $querybits[] = "(-1, '$template[templatetype]', '$title', '$template[template]', '', $template[date], '$template[username]', '" . $db->escape_string($template['version']) . "', '" . $db->escape_string($info['productid']) . "')"; } else { // template is a standard template $querybits[] = "(-1, '$template[templatetype]', '$title', '" . $db->escape_string(compile_template($template['value'])) . "', '$template[template]', $template[date], '$template[username]', '" . $db->escape_string($template['version']) . "', '" . $db->escape_string($info['productid']) . "')"; } if (++$querytemplates % 20 == 0) { /*insert query*/ $db->query_write(" REPLACE INTO " . TABLE_PREFIX . "template (styleid, templatetype, title, template, template_un, dateline, username, version, product) VALUES " . implode(',', $querybits) . " "); $querybits = array(); } // Send some output to the browser inside this loop so certain hosts // don't artificially kill the script. See bug #34585 echo ' '; vbflush(); } // insert any remaining templates if (!empty($querybits)) { /*insert query*/ $db->query_write(" REPLACE INTO " . TABLE_PREFIX . "template (styleid, templatetype, title, template, template_un, dateline, username, version, product) VALUES " . implode(',', $querybits) . " "); } unset($querybits); $rebuild['templates'] = true; } // ############## import stylevars if (is_array($arr['stylevardfns']['stylevargroup'])) { xml_import_stylevar_definitions($arr['stylevardfns'], $info['productid']); } if (is_array($arr['stylevars']['stylevar'])) { xml_import_stylevars($arr['stylevars'], -1); } // ############## import hooks/plugins if (is_array($arr['plugins']['plugin'])) { $plugins =& $arr['plugins']['plugin']; if (!isset($plugins[0])) { $plugins = array($plugins); } foreach ($plugins AS $plugin) { $plugin['product'] = $info['productid']; unset($plugin['devkey']); $db->query_write(fetch_query_sql($plugin, 'plugin')); } $rebuild['plugins'] = true; } // ############## import phrases if (is_array($arr['phrases']['phrasetype'])) { require_once(DIR . '/includes/adminfunctions_language.php'); $master_phrasetypes = array(); $master_phrasefields = array(); foreach(fetch_phrasetypes_array(false) as $phrasetype) { $master_phrasefields["$phrasetype[fieldname]"] = true; } $phrasetypes =& $arr['phrases']['phrasetype']; if (!isset($phrasetypes[0])) { $phrasetypes = array($phrasetypes); } foreach ($phrasetypes AS $phrasetype) { if (empty($phrasetype['phrase'])) { continue; } if ($phrasetype['fieldname'] == '' OR !preg_match('#^[a-z0-9_]+$#i', $phrasetype['fieldname'])) // match a-z, A-Z, 0-9,_ only { continue; } $fieldname = $master_phrasefields["$phrasetype[fieldname]"]; if (!$fieldname) { $db->query_write(" INSERT IGNORE INTO " . TABLE_PREFIX . "phrasetype (fieldname, title, editrows, product) VALUES ('" . $db->escape_string($phrasetype['fieldname']) . "', '" . $db->escape_string($phrasetype['name']) . "', 3, '" . $db->escape_string($info['productid']) . "') "); // need to add the column to the language table as well require_once(DIR . '/includes/class_dbalter.php'); $db_alter = new vB_Database_Alter_MySQL($db); if ($db_alter->fetch_table_info('language')) { $db_alter->add_field(array( 'name' => "phrasegroup_$phrasetype[fieldname]", 'type' => 'mediumtext' )); } } $phrases =& $phrasetype['phrase']; if (!isset($phrases[0])) { $phrases = array($phrases); } $sql = array(); foreach ($phrases AS $phrase) { $sql[] = " (-1, '" . $db->escape_string($phrasetype['fieldname']) . "', '" . $db->escape_string($phrase['name']) . "', '" . $db->escape_string($phrase['value']) . "', '" . $db->escape_string($info['productid']) . "', '" . $db->escape_string($phrase['username']) . "', " . intval($phrase['date']) . ", '" . $db->escape_string($phrase['version']) . "') "; } /*insert query*/ $db->query_write(" REPLACE INTO " . TABLE_PREFIX . "phrase (languageid, fieldname, varname, text, product, username, dateline, version) VALUES " . implode(',', $sql) ); } $rebuild['phrases'] = true; } // ############## import settings if (is_array($arr['options']['settinggroup'])) { $settinggroups =& $arr['options']['settinggroup']; if (!isset($settinggroups[0])) { $settinggroups = array($settinggroups); } foreach ($settinggroups AS $group) { if (empty($group['setting'])) { continue; } // create the setting group if it doesn't already exist /*insert query*/ $db->query_write(" INSERT IGNORE INTO " . TABLE_PREFIX . "settinggroup (grouptitle, displayorder, volatile, product) VALUES ('" . $db->escape_string($group['name']) . "', " . intval($group['displayorder']) . ", 1, '" . $db->escape_string($info['productid']) . "') "); $settings =& $group['setting']; if (!isset($settings[0])) { $settings = array($settings); } $setting_bits = array(); foreach ($settings AS $setting) { if (isset($vbulletin->options["$setting[varname]"])) { $newvalue = $vbulletin->options["$setting[varname]"]; } else { $newvalue = $setting['defaultvalue']; } $setting_bits[] = "( '" . $db->escape_string($setting['varname']) . "', '" . $db->escape_string($group['name']) . "', '" . $db->escape_string(trim($newvalue)) . "', '" . $db->escape_string(trim($setting['defaultvalue'])) . "', '" . $db->escape_string(trim($setting['datatype'])) . "', '" . $db->escape_string($setting['optioncode']) . "', " . intval($setting['displayorder']) . ", " . intval($setting['advanced']) . ", 1, '" . $db->escape_string($setting['validationcode']) . "', " . intval($setting['blacklist']) . ", '" . $db->escape_string($info['productid']) . "'\n\t)"; } /*insert query*/ $db->query_write(" REPLACE INTO " . TABLE_PREFIX . "setting (varname, grouptitle, value, defaultvalue, datatype, optioncode, displayorder, advanced, volatile, validationcode, blacklist, product) VALUES " . implode(",\n\t", $setting_bits) ); } $rebuild['options'] = true; } // ############## import admin help if (is_array($arr['helptopics']['helpscript'])) { $help_scripts =& $arr['helptopics']['helpscript']; if (!isset($help_scripts[0])) { $help_scripts = array($help_scripts); } foreach ($help_scripts AS $help_script) { // Deal with single entry if (!is_array($help_script['helptopic'][0])) { $help_script['helptopic'] = array($help_script['helptopic']); } $help_sql = array(); foreach ($help_script['helptopic'] AS $topic) { $helpsql[] = " ('" . $db->escape_string($help_script['name']) . "', '" . $db->escape_string($topic['act']) . "', '" . $db->escape_string($topic['opt']) . "', " . intval($topic['disp']) . ", 1, '" . $db->escape_string($info['productid']) . "') "; } if (!empty($helpsql)) { /*insert query*/ $db->query_write(" REPLACE INTO " . TABLE_PREFIX . "adminhelp (script, action, optionname, displayorder, volatile, product) VALUES " . implode(",\n\t", $helpsql) ); } } } // ############## import cron if (is_array($arr['cronentries']['cron'])) { require_once(DIR . '/includes/functions_cron.php'); $cron_entries =& $arr['cronentries']['cron']; if (!isset($cron_entries[0])) { $cron_entries = array($cron_entries); } foreach ($cron_entries AS $cron) { $cron['varname'] = preg_replace('#[^a-z0-9_]#i', '', $cron['varname']); if (!$cron['varname']) { continue; } $cron['active'] = ($cron['active'] ? 1 : 0); $cron['loglevel'] = ($cron['loglevel'] ? 1 : 0); $scheduling = $cron['scheduling']; $scheduling['weekday'] = intval($scheduling['weekday']); $scheduling['day'] = intval($scheduling['day']); $scheduling['hour'] = intval($scheduling['hour']); $scheduling['minute'] = explode(',', preg_replace('#[^0-9,-]#i', '', $scheduling['minute'])); if (count($scheduling['minute']) == 0) { $scheduling['minute'] = array(0); } else { $scheduling['minute'] = array_map('intval', $scheduling['minute']); } /*insert query*/ $db->query_write(" REPLACE INTO " . TABLE_PREFIX . "cron (weekday, day, hour, minute, filename, loglevel, active, varname, volatile, product) VALUES ($scheduling[weekday], $scheduling[day], $scheduling[hour], '" . $db->escape_string(serialize($scheduling['minute'])) . "', '" . $db->escape_string($cron['filename']) . "', $cron[loglevel], $cron[active], '" . $db->escape_string($cron['varname']) . "', 1, '" . $db->escape_string($info['productid']) . "') "); $cronid = $db->insert_id(); // replace either inserts, or deletes+inserts if ($cronid) { build_cron_item($cronid); } $rebuild['cron'] = true; } } // ############## import faq if (is_array($arr['faqentries']['faq'])) { $faq_entries =& $arr['faqentries']['faq']; if (!isset($faq_entries[0])) { $faq_entries = array($faq_entries); } $sql = array(); foreach ($faq_entries AS $faq) { $sql[] = " ('" . $db->escape_string($faq['faqname']) . "', '" . $db->escape_string($faq['faqparent']) . "', " . intval($faq['displayorder']) . ", 1, '" . $db->escape_string($info['productid']) . "') "; } if ($sql) { /*insert query*/ $db->query_write(" REPLACE INTO " . TABLE_PREFIX . "faq (faqname, faqparent, displayorder, volatile, product) VALUES " . implode(',', $sql) . " "); } } // Check if the plugin system is disabled. If it is, enable it. if (!$vbulletin->options['enablehooks']) { $db->query_write(" UPDATE " . TABLE_PREFIX . "setting SET value = '1' WHERE varname = 'enablehooks' "); $rebuild['options'] = true; } // Now rebuild everything we need... if ($rebuild['plugins']) { vBulletinHook::build_datastore($db); if ($active) { $plugin_data = $db->query_read(" SELECT * FROM " . TABLE_PREFIX . "datastore WHERE title IN ('pluginlist', 'pluginlistadmin') "); while ($plugin_info = $db->fetch_array($plugin_data)) { if ($plugin_info['title'] == 'pluginlist') { $vbulletin->pluginlist = unserialize($plugin_info['data']); } else if ($plugin_info['title'] == 'pluginlistadmin') { $vbulletin->pluginlistadmin = unserialize($plugin_info['data']); } } // enable any hooks -- this is mainly necessary for importing templates (template_safe_functions hook) if (!defined('DISABLE_HOOKS')) { if (!empty($vbulletin->pluginlistadmin) AND is_array($vbulletin->pluginlistadmin)) { $vbulletin->pluginlist = array_merge($vbulletin->pluginlist, $vbulletin->pluginlistadmin); unset($vbulletin->pluginlistadmin); } vBulletinHook::set_pluginlist($vbulletin->pluginlist); } } } if ($rebuild['templates']) { build_all_styles(); } if ($rebuild['phrases']) { require_once(DIR . '/includes/adminfunctions_language.php'); build_language(); } if ($rebuild['options']) { build_options(); } if ($rebuild['cron']) { require_once(DIR . '/includes/functions_cron.php'); build_cron_next_run(); } build_product_datastore(); // build bitfields to remove/add this products bitfields vB_Bitfield_Builder::save($db); // reload block types $blockmanager = vB_BlockManager::create($vbulletin); $blockmanager->reloadBlockTypes(); print_dots_stop(); $info['need_merge'] = ($rebuild['templates'] AND $installed_version); return $info; }
/** * Things to do after each script is processed * */ protected function process_script_end() { build_bbcode_cache(); build_options(); require_once DIR . '/includes/functions_databuild.php'; build_bbcode_video(true); require_once DIR . '/includes/class_bitfield_builder.php'; vB_Bitfield_Builder::save($this->db); build_forum_permissions(); }
/** * Installs a product from the xml text * * This function depends on the vb class loader, which requires that the * framework init is called. * * @return bool True if the product requires a template merge, false otherwise */ function install_product($xml, $allow_overwrite = false, $verbose = true) { global $vbphrase; global $vbulletin; $assertor = vB::getDbAssertor(); require_once DIR . '/includes/class_bitfield_builder.php'; require_once DIR . '/includes/class_xml.php'; //share some code with the main xml style import require_once DIR . '/includes/adminfunctions_template.php'; if ($verbose) { print_dots_start('<b>' . $vbphrase['importing_product'] . "</b>, {$vbphrase['please_wait']}", ':', 'dspan'); } $xmlobj = new vB_XML_Parser($xml); if ($xmlobj->error_no() == 1) { if ($verbose) { print_dots_stop(); } throw new vB_Exception_AdminStopMessage('no_xml_and_no_path'); } if (!($arr = $xmlobj->parse())) { if ($verbose) { print_dots_stop(); } throw new vB_Exception_AdminStopMessage(array('xml_error_x_at_line_y', $xmlobj->error_string(), $xmlobj->error_line())); } // ############## general product information $info = array('productid' => substr(preg_replace('#[^a-z0-9_]#', '', strtolower($arr['productid'])), 0, 25), 'title' => $arr['title'], 'description' => $arr['description'], 'version' => $arr['version'], 'active' => $arr['active'], 'url' => $arr['url'], 'versioncheckurl' => $arr['versioncheckurl']); if (!$info['productid']) { if ($verbose) { print_dots_stop(); } throw new vB_Exception_AdminStopMessage('invalid_file_specified'); } if (strtolower($info['productid']) == 'vbulletin') { if ($verbose) { print_dots_stop(); } throw new vB_Exception_AdminStopMessage(array('product_x_installed_no_overwrite', 'vBulletin')); } // check for bitfield conflicts on install $bitfields = vB_Bitfield_Builder::return_data(); if (!$bitfields) { $bfobj =& vB_Bitfield_Builder::init(); if ($bfobj->errors) { if ($verbose) { print_dots_stop(); } throw new vB_Exception_AdminStopMessage(array('bitfield_conflicts_x', '<li>' . implode('</li><li>', $bfobj->errors) . '</li>')); } } // get system version info $system_versions = array('php' => PHP_VERSION, 'vbulletin' => $vbulletin->options['templateversion'], 'products' => fetch_product_list(true)); $mysql_version = $assertor->getRow('mysqlVersion'); $system_versions['mysql'] = $mysql_version['version']; // ############## import dependencies if (isset($arr['dependencies']['dependency']) and is_array($arr['dependencies']['dependency'])) { $dependencies =& $arr['dependencies']['dependency']; if (!isset($dependencies[0])) { $dependencies = array($dependencies); } $dependency_errors = array(); $ignore_dependency_errors = array(); // let's check the dependencies foreach ($dependencies as $dependency) { // if we get an error, we haven't met this dependency // if we go through without a problem, we have automatically met // all dependencies for this "class" (mysql, php, vb, a specific product, etc) $this_dependency_met = true; // build a phrase for the version compats -- will look like (minver / maxver) if ($dependency['minversion']) { $compatible_phrase = construct_phrase($vbphrase['compatible_starting_with_x'], htmlspecialchars_uni($dependency['minversion'])); } else { $compatible_phrase = ''; } if ($dependency['maxversion']) { $incompatible_phrase = construct_phrase($vbphrase['incompatible_with_x_and_greater'], htmlspecialchars_uni($dependency['maxversion'])); } else { $incompatible_phrase = ''; } if ($compatible_phrase or $incompatible_phrase) { $required_version_info = "({$compatible_phrase}"; if ($compatible_phrase and $incompatible_phrase) { $required_version_info .= ' / '; } $required_version_info .= "{$incompatible_phrase})"; } // grab the appropriate installed version string if ($dependency['dependencytype'] == 'product') { // group dependencies into types -- individual products get their own group $dependency_type_key = "product-{$dependency['parentproductid']}"; // undocumented feature -- you can put a producttitle attribute in a dependency so the id isn't displayed $parent_product_title = !empty($dependency['producttitle']) ? $dependency['producttitle'] : $dependency['parentproductid']; $parent_product = $system_versions['products']["{$dependency['parentproductid']}"]; if (!$parent_product) { // required product is not installed $dependency_errors["{$dependency_type_key}"] = construct_phrase($vbphrase['product_x_must_be_installed'], htmlspecialchars_uni($parent_product_title), $required_version_info); continue; // can't do version checks if the product isn't installed } else { if ($parent_product['active'] == 0) { // product is installed, but inactive $dependency_errors["{$dependency_type_key}-inactive"] = construct_phrase($vbphrase['product_x_must_be_activated'], htmlspecialchars_uni($parent_product_title)); $this_dependency_met = false; // allow version checks to continue } } $sys_version_str = $parent_product['version']; $version_incompatible_phrase = 'product_incompatible_version_x_product_y'; } else { $dependency_type_key = $dependency['dependencytype']; $parent_product_title = ''; $sys_version_str = $system_versions["{$dependency['dependencytype']}"]; $version_incompatible_phrase = 'product_incompatible_version_x_' . $dependency['dependencytype']; } // if no version string, we are trying to do an unsupported dep check if ($sys_version_str == '') { continue; } $sys_version = fetch_version_array($sys_version_str); // error if installed version < minversion if ($dependency['minversion']) { $dep_version = fetch_version_array($dependency['minversion']); for ($i = 0; $i <= 5; $i++) { if ($sys_version["{$i}"] < $dep_version["{$i}"]) { // installed version is too old $dependency_errors["{$dependency_type_key}"] = construct_phrase($vbphrase["{$version_incompatible_phrase}"], htmlspecialchars_uni($sys_version_str), $required_version_info, $parent_product_title); $this_dependency_met = false; break; } else { if ($sys_version["{$i}"] > $dep_version["{$i}"]) { break; } } } } // error if installed version >= maxversion if ($dependency['maxversion']) { $dep_version = fetch_version_array($dependency['maxversion']); $all_equal = true; for ($i = 0; $i <= 5; $i++) { if ($sys_version["{$i}"] > $dep_version["{$i}"]) { // installed version is newer than the maxversion $dependency_errors["{$dependency_type_key}"] = construct_phrase($vbphrase["{$version_incompatible_phrase}"], htmlspecialchars_uni($sys_version_str), $required_version_info, $parent_product_title); $this_dependency_met = false; break; } else { if ($sys_version["{$i}"] < $dep_version["{$i}"]) { // not every part is the same and since we've got less we can exit $all_equal = false; break; } else { if ($sys_version["{$i}"] != $dep_version["{$i}"]) { // not every part is the same $all_equal = false; } } } } if ($all_equal == true) { // installed version is same as the max version, which is the first incompat version $dependency_errors["{$dependency_type_key}"] = construct_phrase($vbphrase["{$version_incompatible_phrase}"], htmlspecialchars_uni($sys_version_str), $required_version_info, $parent_product_title); $this_dependency_met = false; } } if ($this_dependency_met) { // we met 1 dependency for this type -- this emulates or'ing together groups $ignore_dependency_errors["{$dependency_type_key}"] = true; } } // for any group we met a dependency for, ignore any errors we might // have gotten for the group foreach ($ignore_dependency_errors as $dependency_type_key => $devnull) { unset($dependency_errors["{$dependency_type_key}"]); } if ($dependency_errors) { $dependency_errors = array_unique($dependency_errors); $dependency_errors = '<ol><li>' . implode('</li><li>', $dependency_errors) . '</li></ol>'; if ($verbose) { print_dots_stop(); } throw new vB_Exception_AdminStopMessage(array('dependencies_not_met_x', $dependency_errors)); } } // look to see if we already have this product installed if ($existingprod = $assertor->getRow('product', array('productid' => $info['productid']))) { if (!$allow_overwrite) { if ($verbose) { print_dots_stop(); } throw new vB_Exception_AdminStopMessage(array('product_x_installed_no_overwrite', $info['title'])); } $active = $existingprod['active']; // not sure what we're deleting, so rebuild everything $rebuild = array('templates' => true, 'hooks' => true, 'phrases' => true, 'options' => true, 'cron' => true); $installed_version = $existingprod['version']; } else { $active = $info['active'] ? 1 : 0; $rebuild = array('templates' => false, 'hooks' => false, 'phrases' => false, 'options' => false, 'cron' => false); $installed_version = null; } // ############## import install/uninstall code if (isset($arr['codes']['code']) and is_array($arr['codes']['code'])) { $codes =& $arr['codes']['code']; if (!isset($codes[0])) { $codes = array($codes); } // run each of the codes foreach ($codes as $code) { // Run if: code version is * (meaning always run), no version // previously installed, or if the code is for a newer version // than is currently installed if ($code['version'] == '*' or $installed_version === null or is_newer_version($code['version'], $installed_version)) { eval($code['installcode']); } } // Clear routes from datastore build_datastore('routes', serialize(array()), 1); //assume that the product may have installed content types and purge the content type cache vB_Cache::instance()->purge('vb_types.types'); } // dependencies checked, install code run. Now clear out the old product info; // settings should be retained in memory already delete_product($info['productid'], false, true); if (is_array($codes)) { // we've now run all the codes, if execution is still going // then it's going to complete fully, so insert the codes $productCodes = array(); foreach ($codes as $code) { /* insert query */ $productCodes[] = array('productid' => $info['productid'], 'version' => $code['version'], 'installcode' => $code['installcode'], 'uninstallcode' => $code['uninstallcode']); } $assertor->insertMultiple('productcode', array('productid', 'version', 'installcode', 'uninstallcode'), $productCodes); } if (is_array($dependencies)) { // dependencies met, codes run -- now we can insert the dependencies into the DB $productDependencies = array(); foreach ($dependencies as $dependency) { /* insert query */ $productDependencies[] = array('productid' => $info['productid'], 'dependencytype' => $dependency['dependencytype'], 'parentproductid' => $dependency['parentproductid'], 'minversion' => $dependency['minversion'], 'maxversion' => $dependency['maxversion']); } $assertor->insertMultiple('productdependency', array('productid', 'dependencytype', 'parentproductid', 'minversion', 'maxversion'), $productDependencies); } /* insert query */ $assertor->insert('product', array('productid' => $info['productid'], 'title' => $info['title'], 'description' => $info['description'], 'version' => $info['version'], 'active' => intval($active), 'url' => $info['url'], 'versioncheckurl' => $info['versioncheckurl'])); // ############## import templates if (isset($arr['templates']['template']) and is_array($arr['templates']['template'])) { $querybits = array(); $querytemplates = 0; $templates =& $arr['templates']['template']; if (!isset($templates[0])) { $templates = array($templates); } foreach ($templates as $template) { $title = $template['name']; $template['template'] = $template['value']; $template['username'] = $template['username']; $template['templatetype'] = $template['templatetype']; $template['date'] = intval($template['date']); if ($template['templatetype'] != 'template') { // template is a special template $querybits[] = array('styleid' => -1, 'templatetype' => $template['templatetype'], 'title' => $title, 'template' => $template['template'], 'template_un' => '', 'dateline' => $template['date'], 'username' => $template['username'], 'version' => $template['version'], 'product' => $info['productid']); } else { // template is a standard template $querybits[] = array('styleid' => -1, 'templatetype' => $template['templatetype'], 'title' => $title, 'template' => compile_template($template['value']), 'template_un' => $template['template'], 'dateline' => $template['date'], 'username' => $template['username'], 'version' => $template['version'], 'product' => $info['productid']); } if (++$querytemplates % 20 == 0) { /*insert query*/ $assertor->assertQuery('replaceValues', array('values' => $querybits, 'table' => 'template')); $querybits = array(); } // Send some output to the browser inside this loop so certain hosts // don't artificially kill the script. See bug #34585 if (VB_AREA != 'Upgrade' and VB_AREA != 'Install') { echo ' '; vbflush(); } } // insert any remaining templates if (!empty($querybits)) { /*insert query*/ $assertor->assertQuery('replaceValues', array('values' => $querybits, 'table' => 'template')); } unset($querybits); $rebuild['templates'] = true; } // ############## import stylevars if (isset($arr['stylevardfns']['stylevargroup']) and is_array($arr['stylevardfns']['stylevargroup'])) { xml_import_stylevar_definitions($arr['stylevardfns'], $info['productid']); } if (!empty($arr['stylevars']) and is_array($arr['stylevars']) and is_array($arr['stylevars']['stylevar'])) { xml_import_stylevars($arr['stylevars'], -1); } // ############## import hooks if (isset($arr['hooks']['hook']) and is_array($arr['hooks']['hook'])) { $hooks =& $arr['hooks']['hook']; if (!isset($hooks[0])) { $hooks = array($hooks); } foreach ($hooks as $hook) { $hook['product'] = $info['productid']; $assertor->insert('hook', $hook); } $rebuild['hooks'] = true; } // ############## import phrases if (isset($arr['phrases']['phrasetype']) and is_array($arr['phrases']['phrasetype'])) { require_once DIR . '/includes/adminfunctions_language.php'; $master_phrasetypes = array(); $master_phrasefields = array(); foreach (vB_Api::instanceInternal('phrase')->fetch_phrasetypes(false) as $phrasetype) { $master_phrasefields["{$phrasetype['fieldname']}"] = true; } $phrasetypes =& $arr['phrases']['phrasetype']; if (!isset($phrasetypes[0])) { $phrasetypes = array($phrasetypes); } foreach ($phrasetypes as $phrasetype) { if (empty($phrasetype['phrase'])) { continue; } if ($phrasetype['fieldname'] == '' or !preg_match('#^[a-z0-9_]+$#i', $phrasetype['fieldname'])) { continue; } $fieldname = $master_phrasefields["{$phrasetype['fieldname']}"]; if (!$fieldname) { $assertor->assertQuery('installProductPhraseTypeInsert', array('fieldname' => $phrasetype['fieldname'], 'title' => $phrasetype['name'], 'editrows' => 3, 'product' => $info['productid'])); // need to add the column to the language table as well $assertor->assertQuery('addLanguageFromPackage', array('fieldname' => $phrasetype['fieldname'])); } $phrases =& $phrasetype['phrase']; if (!isset($phrases[0])) { $phrases = array($phrases); } $sql = array(); foreach ($phrases as $phrase) { $sql[] = array('languageid' => -1, 'fieldname' => $phrasetype['fieldname'], 'varname' => $phrase['name'], 'text' => $phrase['value'], 'product' => $info['productid'], 'username' => $phrase['username'], 'dateline' => $phrase['date'], 'version' => $phrase['version']); } /*insert query*/ $assertor->assertQuery('replaceValues', array('values' => $sql, 'table' => 'phrase')); } $rebuild['phrases'] = true; } // ############## import settings if (isset($arr['options']['settinggroup']) and is_array($arr['options']['settinggroup'])) { $settinggroups =& $arr['options']['settinggroup']; if (!isset($settinggroups[0])) { $settinggroups = array($settinggroups); } foreach ($settinggroups as $group) { if (empty($group['setting'])) { continue; } // create the setting group if it doesn't already exist $check = $assertor->assertQuery('settinggroup', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'grouptitle' => $group['name'])); if ($check->valid()) { $current = $check->current(); if ($group['adminperm'] != $current['adminperm'] or $group['displayorder'] != $current['displayorder']) { $assertor->assertQuery('settinggroup', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, 'grouptitle' => $group['name'], 'displayorder' => $group['displayorder'], 'adminperm' => $group['adminperm'])); } } else { /*insert query*/ $assertor->assertQuery('settinggroup', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERTIGNORE, 'grouptitle' => $group['name'], 'displayorder' => $group['displayorder'], 'volatile' => 1, 'product' => $info['productid'], 'adminperm' => $group['adminperm'])); } $settings =& $group['setting']; if (!isset($settings[0])) { $settings = array($settings); } $setting_bits = array(); foreach ($settings as $setting) { if (isset($vbulletin->options["{$setting['varname']}"])) { $newvalue = $vbulletin->options["{$setting['varname']}"]; } else { $newvalue = $setting['defaultvalue']; } $setting_bits[] = array('varname' => $setting['varname'], 'grouptitle' => $group['name'], 'value' => trim($newvalue), 'defaultvalue' => trim($setting['defaultvalue']), 'datatype' => trim($setting['datatype']), 'optioncode' => $setting['optioncode'], 'displayorder' => $setting['displayorder'], 'advanced' => intval($setting['advanced']), 'volatile' => 1, 'validationcode' => $setting['validationcode'], 'blacklist' => $setting['blacklist'], 'ispublic' => intval($setting['public']), 'product' => $info['productid'], 'adminperm' => empty($setting['adminperm']) ? '' : $setting['adminperm']); } /*insert query*/ $assertor->assertQuery('replaceValues', array('values' => $setting_bits, 'table' => 'setting')); } $rebuild['options'] = true; } // ############## import admin help if (isset($arr['helptopics']['helpscript']) and is_array($arr['helptopics']['helpscript'])) { $help_scripts =& $arr['helptopics']['helpscript']; if (!isset($help_scripts[0])) { $help_scripts = array($help_scripts); } foreach ($help_scripts as $help_script) { // Deal with single entry if (!is_array($help_script['helptopic'][0])) { $help_script['helptopic'] = array($help_script['helptopic']); } $help_sql = array(); foreach ($help_script['helptopic'] as $topic) { $helpsql[] = array('script' => $help_script['name'], 'action' => $topic['act'], 'optionname' => $topic['opt'], 'displayorder' => intval($topic['disp']), 'volatile' => 1, 'product' => $info['productid']); } if (!empty($helpsql)) { /*insert query*/ $assertor->assertQuery('replaceValues', array('values' => $helpsql, 'table' => 'adminhelp')); } } } // ############## import cron if (isset($arr['cronentries']['cron']) and is_array($arr['cronentries']['cron'])) { require_once DIR . '/includes/functions_cron.php'; $cron_entries =& $arr['cronentries']['cron']; if (!isset($cron_entries[0])) { $cron_entries = array($cron_entries); } foreach ($cron_entries as $cron) { $cron['varname'] = preg_replace('#[^a-z0-9_]#i', '', $cron['varname']); if (!$cron['varname']) { continue; } $cron['active'] = $cron['active'] ? 1 : 0; $cron['loglevel'] = $cron['loglevel'] ? 1 : 0; $scheduling = $cron['scheduling']; $scheduling['weekday'] = intval($scheduling['weekday']); $scheduling['day'] = intval($scheduling['day']); $scheduling['hour'] = intval($scheduling['hour']); $scheduling['minute'] = explode(',', preg_replace('#[^0-9,-]#i', '', $scheduling['minute'])); if (count($scheduling['minute']) == 0) { $scheduling['minute'] = array(0); } else { $scheduling['minute'] = array_map('intval', $scheduling['minute']); } /*insert query*/ $cronSql[] = array('weekday' => $scheduling['weekday'], 'day' => $scheduling['day'], 'hour' => $scheduling['hour'], 'minute' => serialize($scheduling['minute']), 'filename' => $cron['filename'], 'loglevel' => $cron['loglevel'], 'active' => $cron['active'], 'varname' => $cron['varname'], 'volatile' => 1, 'product' => $info['productid']); $cronid = $assertor->assertQuery('replaceValues', array('values' => $cronSql, 'table' => 'cron', 'returnId' => true)); if ($cronid) { build_cron_item($cronid); } $rebuild['cron'] = true; } } // ############## import faq if (isset($arr['faqentries']['faq']) and is_array($arr['faqentries']['faq'])) { $faq_entries =& $arr['faqentries']['faq']; if (!isset($faq_entries[0])) { $faq_entries = array($faq_entries); } $sql = array(); foreach ($faq_entries as $faq) { $sql[] = array('faqname' => $faq['faqname'], 'faqparent' => $faq['faqparent'], 'displayorder' => intval($faq['displayorder']), 'volatile' => 1, 'product' => $info['productid']); } if ($sql) { /*insert query*/ $assertor->assertQuery('replaceValues', array('values' => $sql, 'table' => 'faq')); } } // ############## import widgets if (isset($arr['widgets']['widget']) and is_array($arr['widgets']['widget'])) { $widgetImporter = new vB_Xml_Import_Widget($info['productid']); $widgetImporter->importFromParsedXML($arr['widgets']); } // ############## import pagetemplates if (isset($arr['pagetemplates']['pagetemplate']) and is_array($arr['pagetemplates']['pagetemplate'])) { $pageTemplateImporter = new vB_Xml_Import_PageTemplate($info['productid']); $pageTemplateImporter->importFromParsedXML($arr['pagetemplates']); } // ############## import page if (isset($arr['pages']['page']) and is_array($arr['pages']['page'])) { $pageImporter = new vB_Xml_Import_Page($info['productid']); $pageImporter->importFromParsedXML($arr['pages']); } // ############## import channels if (isset($arr['channels']['channel']) and is_array($arr['channels']['channel'])) { $channelImporter = new vB_Xml_Import_Channel($info['productid']); $channelImporter->importFromParsedXML($arr['channels']); } // ############## import routes if (isset($arr['routes']['route']) and is_array($arr['routes']['route'])) { $routeImporter = new vB_Xml_Import_Route($info['productid']); $routeImporter->importFromParsedXML($arr['routes']); } if (isset($routeImporter)) { // update pages and channels with new route ids if (isset($pageImporter)) { $pageImporter->updatePageRoutes(); } if (isset($channelImporter)) { $channelImporter->updateChannelRoutes(); } } // Check if the hook system is disabled. If it is, enable it. if (!$vbulletin->options['enablehooks']) { $assertor->update('setting', array('value' => 1), array('varname' => 'enablehooks')); $rebuild['options'] = true; } // Now rebuild everything we need... if ($rebuild['hooks']) { vB_Api::instanceInternal("Hook")->buildHookDatastore(); } if ($rebuild['templates']) { if ($error = build_all_styles(0, 0, '', false, $verbose)) { return $error; } } if ($rebuild['phrases']) { require_once DIR . '/includes/adminfunctions_language.php'; build_language(); } if ($rebuild['options']) { vB::getDatastore()->build_options(); } if ($rebuild['cron']) { require_once DIR . '/includes/functions_cron.php'; build_cron_next_run(); } build_product_datastore(); // build bitfields to remove/add this products bitfields vB_Bitfield_Builder::save(); if ($verbose) { print_dots_stop(); } $info['need_merge'] = ($rebuild['templates'] and $installed_version); return $info; }
/** * Builds the cache of project bitfields (for perms) into $vbulletin->pt_bitfields. * Accessed as [groupid][bitname] => value * * @return array Bitfield cache */ function build_project_bitfields() { global $vbulletin; require_once DIR . '/includes/class_bitfield_builder.php'; vB_Bitfield_Builder::build(false); $builder =& vB_Bitfield_Builder::init(); $bits = array(); if ($builder->data['pt_permissions']) { foreach ($builder->data['pt_permissions'] as $groupid => $permission_group) { foreach ($permission_group as $bitname => $permvalue) { $bits["{$groupid}"]["{$bitname}"] = intval(is_array($permvalue) ? $permvalue['value'] : $permvalue); } } } build_datastore('pt_bitfields', serialize($bits), 1); $vbulletin->pt_bitfields = $bits; return $bits; }