/** * Create an article category channel. This function works basically like the blog library's version * * @param array $input data array, should have standard channel data like title, parentid, * @param int $channelid parentid that the new channel should fall under. * @param int $channelConvTemplateid "Conversation" level pagetemplate to use. Typically vB_Page::getArticleConversPageTemplate() * @param int $channelPgTemplateId "Channel" level pagetemplate to use. Typically vB_Page::getArticleChannelPageTemplate() * @param int $ownerSystemGroupId * * @return int The nodeid of the new blog channel */ public function createChannel($input, $channelid, $channelConvTemplateid, $channelPgTemplateId, $ownerSystemGroupId) { if (!isset($input['parentid']) or intval($input['parentid']) < 1) { $input['parentid'] = $channelid; } $input['inlist'] = 1; // we don't want it to be shown in channel list, but we want to move them $input['protected'] = 0; if (empty($input['userid'])) { $input['userid'] = vB::getCurrentSession()->get('userid'); } if (!isset($input['publishdate'])) { $input['publishdate'] = vB::getRequest()->getTimeNow(); } $input['templates']['vB5_Route_Channel'] = $channelPgTemplateId; $input['templates']['vB5_Route_Article'] = $channelConvTemplateid; $input['childroute'] = 'vB5_Route_Article'; // add channel node $channelLib = vB_Library::instance('content_channel'); $input['page_parentid'] = 0; $result = $channelLib->add($input, array('skipNotifications' => true, 'skipFloodCheck' => true, 'skipDupCheck' => true)); //Make the current user the channel owner. $userApi = vB_Api::instanceInternal('user'); $usergroup = vB::getDbAssertor()->getRow('usergroup', array('systemgroupid' => $ownerSystemGroupId)); vB_Cache::allCacheEvent(array('nodeChg_' . $this->articleHomeChannel, "nodeChg_{$channelid}")); vB::getUserContext()->rebuildGroupAccess(); vB_Channel::rebuildChannelTypes(); // clear follow cache vB_Api::instanceInternal('follow')->clearFollowCache(array($input['userid'])); return $result['nodeid']; }
/** * Create a blog channel. * * @param array $input * @param int $channelid * @param int $channelConvTemplateid * @param int $channelPgTemplateId * @param int $ownerSystemGroupId * * @return int The nodeid of the new blog channel */ public function createChannel($input, $channelid, $channelConvTemplateid, $channelPgTemplateId, $ownerSystemGroupId) { $input['parentid'] = $channelid; $input['inlist'] = 1; // we don't want it to be shown in channel list, but we want to move them $input['protected'] = 0; if (empty($input['userid'])) { $input['userid'] = vB::getCurrentSession()->get('userid'); } if (!isset($input['publishdate'])) { $input['publishdate'] = vB::getRequest()->getTimeNow(); } $input['templates']['vB5_Route_Channel'] = $channelPgTemplateId; $input['templates']['vB5_Route_Conversation'] = $channelConvTemplateid; // add channel node $channelLib = vB_Library::instance('content_channel'); $input['page_parentid'] = 0; $result = $channelLib->add($input, array('skipFloodCheck' => true, 'skipDupCheck' => true)); //Make the current user the channel owner. $userApi = vB_Api::instanceInternal('user'); $usergroup = vB::getDbAssertor()->getRow('usergroup', array('systemgroupid' => $ownerSystemGroupId)); if (empty($usergroup) or !empty($usergroup['errors'])) { //This should never happen. It would mean an invalid parameter was passed throw new vB_Exception_Api('invalid_request'); } vB_User::setGroupInTopic($input['userid'], $result['nodeid'], $usergroup['usergroupid']); vB_Cache::allCacheEvent(array('nodeChg_' . $this->blogChannel, "nodeChg_{$channelid}")); vB::getUserContext()->rebuildGroupAccess(); vB_Channel::rebuildChannelTypes(); // clear follow cache vB_Api::instanceInternal('follow')->clearFollowCache(array($input['userid'])); return $result['nodeid']; }
/** * Inserts the message into the queue instead of sending it. * * @return string True on success, false on failure */ protected function execSend() { if (!$this->toemail) { return false; } $data = array('dateline' => vB::getRequest()->getTimeNow(), 'toemail' => $this->toemail, 'fromemail' => $this->fromemail, 'subject' => $this->subject, 'message' => $this->message, 'header' => $this->headers); if ($this->bulk) { $this->mailsql[] = $data; $this->mailcounter++; // current insert exceeds half megabyte, insert it and start over if ($this->arraySize($this->mailsql) > 524288) { $this->setBulk(false); $this->setBulk(true); } } else { /*insert query*/ vB::getDbAssertor()->insert('mailqueue', $data); vB::getDbAssertor()->assertQuery('mailqueue_updatecount', array('counter' => 1)); // if we're using a alternate datastore, we need to give it an integer value // this may not be atomic $mailqueue_db = vB::getDbAssertor()->getRow('datastore', array('title' => 'mailqueue')); vB::getDatastore()->build('mailqueue', intval($mailqueue_db['data'])); } return true; }
function do_mark_read() { $vbulletin = vB::get_registry(); $userinfo = vB_Api::instance('user')->fetchUserInfo(); $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('forumid' => vB_Cleaner::TYPE_INT)); $forumid = $cleaned['forumid']; if ($forumid == 0) { return json_error(ERR_INVALID_FORUM); } $foruminfo = vB_Api::instance('node')->getFullContentforNodes(array($forumid)); if (empty($foruminfo) or $foruminfo[0]['contenttypeclass'] != 'Channel') { return json_error(ERR_INVALID_FORUM); } if (!$userinfo['userid']) { return json_error(ERR_INVALID_LOGGEDIN, RV_NOT_LOGGED_IN); } $forums_marked = vB_Api::instance('node')->markChannelsRead($forumid > 0 ? $forumid : 0); $tableinfo = $vbulletin->db->query_first("\n\t\tSHOW TABLES LIKE '" . TABLE_PREFIX . "forumrunner_push_data'\n\t\t"); if ($tableinfo) { if ($forumid > 0) { $vbulletin->db->query_write("\n\t\t\t\tUPDATE " . TABLE_PREFIX . "forumrunner_push_data AS forumrunner_push_data\n\t\t\t\tLEFT JOIN " . TABLE_PREFIX . "node AS thread\n\t\t\t\tON thread.nodeid = forumrunner_push_data.vb_threadid\n\t\t\t\tSET forumrunner_push_data.vb_subsent = 0, forumrunner_push_data.vb_threadread = " . vB::getRequest()->getTimeNow() . "\n\t\t\t\tWHERE forumrunner_push_data.vb_userid = {$userinfo['userid']} AND thread.parentid IN (" . join(',', $forums_marked) . ")\n\t\t\t\t"); } else { $vbulletin->db->query_write("\n\t\t\t\tUPDATE " . TABLE_PREFIX . "forumrunner_push_data\n\t\t\t\tSET vb_subsent = 0, vb_threadread = " . vB::getRequest()->getTimeNow() . "\n\t\t\t\tWHERE vb_userid = {$userinfo['userid']} AND vb_threadid > 0\n\t\t\t\t"); } } return true; }
/** * starts a new lightweight (no shutdown) session * * @param string session hash * * @return mixed array of permissions, */ public static function startSessionLight($sessionHash = false, $cphash = false, $languageid = 0, $checkTimeout = false) { if (!empty($sessionHash)) { if ($checkTimeout) { $timenow = vB::getRequest()->getTimeNow(); $timeout = vB::getDatastore()->getOption('cookietimeout'); if ($timenow > $timeout) { $cutoff = $timenow - $timeout; } else { $cutoff = 0; } $sessionInfo = vB::getDbAssertor()->getRow('session', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'sessionhash', 'value' => $sessionHash, 'operator' => vB_dB_Query::OPERATOR_EQ), array('field' => 'lastactivity', 'value' => $cutoff, 'operator' => vB_dB_Query::OPERATOR_GT)))); } else { $sessionInfo = vB::getDbAssertor()->getRow('session', array('sessionhash' => $sessionHash)); } if (!empty($sessionInfo) and empty($sessionInfo['errors'])) { $session = vB_Session_Web::getSession($sessionInfo['userid'], $sessionHash); if (!empty($cphash)) { $session->setCpsessionHash($cphash); } } } if (empty($session)) { //constructor is now private $session = vB_Session_Web::getSession(0, ''); } $session->set('languageid', $languageid); vB::skipShutdown(true); vB::setCurrentSession($session); return $session; }
public function __call($method, $arguments) { try { $logger = vB::getLogger('api.' . $this->controller . '.' . $method); //check so that we don't var_export large variables when we don't have to if ($logger->isInfoEnabled()) { if (!($ip = vB::getRequest()->getAltIp())) { $ip = vB::getRequest()->getIpAddress(); } $message = str_repeat('=', 80) . "\ncalled {$method} on {$this->controller} from ip {$ip} \n\$arguments = " . var_export($arguments, true) . "\n" . str_repeat('=', 80) . "\n"; $logger->info($message); $logger->info("time: " . microtime(true)); } if ($logger->isTraceEnabled()) { $message = str_repeat('=', 80) . "\n " . $this->getTrace() . str_repeat('=', 80) . "\n"; $logger->trace($message); } $c = $this->api; // This is a hack to prevent method parameter reference error. See VBV-5546 $hackedarguments = array(); foreach ($arguments as $k => &$arg) { $hackedarguments[$k] =& $arg; } $return = call_user_func_array(array(&$c, $method), $hackedarguments); //check so that we don't var_export large variables when we don't have to if ($logger->isDebugEnabled()) { $message = str_repeat('=', 80) . "\ncalled {$method} on {$this->controller}\n\$return = " . var_export($return, true) . "\n" . str_repeat('=', 80) . "\n"; $logger->debug($message); } return $return; } catch (vB_Exception_Api $e) { $errors = $e->get_errors(); $config = vB::getConfig(); if (!empty($config['Misc']['debug'])) { $trace = '## ' . $e->getFile() . '(' . $e->getLine() . ") Exception Thrown \n" . $e->getTraceAsString(); $errors[] = array("exception_trace", $trace); } return array('errors' => $errors); } catch (vB_Exception_Database $e) { $config = vB::getConfig(); if (!empty($config['Misc']['debug']) or vB::getUserContext()->hasAdminPermission('cancontrolpanel')) { $errors = array('Error ' . $e->getMessage()); $trace = '## ' . $e->getFile() . '(' . $e->getLine() . ") Exception Thrown \n" . $e->getTraceAsString(); $errors[] = array("exception_trace", $trace); return array('errors' => $errors); } else { // This text is purposely hard-coded since we don't have // access to the database to get a phrase return array('errors' => array(array('There has been a database error, and the current page cannot be displayed. Site staff have been notified.'))); } } catch (Exception $e) { $errors = array(array('unexpected_error', $e->getMessage())); $config = vB::getConfig(); if (!empty($config['Misc']['debug'])) { $trace = '## ' . $e->getFile() . '(' . $e->getLine() . ") Exception Thrown \n" . $e->getTraceAsString(); $errors[] = array("exception_trace", $trace); } return array('errors' => $errors); } }
/** * Saves the stylevars specified in the array as default style for the whole site * * @param array $stylevars - associative array */ function save_default($stylevars) { $result = array(); if (!$this->canSaveDefault()) { $result['error'][] = 'no_permission_styles'; } if (!$this->hasPermissions()) { $result['error'][] = 'no_permission'; } if (!isset($result['error'])) { $values = array(); $now = vB::getRequest()->getTimeNow(); $styleid = vB::getDatastore()->getOption('styleid'); foreach ($stylevars as $stylevarname => $stylevarvalue) { $values[] = array('stylevarid' => $stylevarname, 'styleid' => $styleid, 'value' => serialize($stylevarvalue), 'dateline' => $now); } vB::getDbAssertor()->assertQuery('replaceValues', array('table' => 'stylevar', 'values' => $values)); $style_lib = vB_Library::instance('Style'); $style_lib->buildStyleDatastore(); require_once DIR . '/includes/adminfunctions_template.php'; $style_lib->buildStyle($styleid, '', array('docss' => 1, 'dostylevars' => 1), true); } vB_Library::instance('Style')->setCssDate(); return $result; }
/** * Fetches announcements by channel ID * * @param int $channelid (optional) Channel ID * @param int $announcementid (optional) Announcement ID * * @throws vB_Exception_Api no_permission if the user doesn't have permission to view the announcements * * @return array Announcements, each element is an array containing all the fields * in the announcement table and username, avatarurl, and the individual * options from the announcementoptions bitfield-- dohtml, donl2br, * dobbcode, dobbimagecode, dosmilies. */ public function fetch($channelid = 0, $announcementid = 0) { $usercontext = vB::getUserContext(); $userapi = vB_Api::instanceInternal('user'); $channelapi = vB_Api::instanceInternal('content_channel'); $parentids = array(); // Check channel permission if ($channelid) { // This is to verify $channelid $channelapi->fetchChannelById($channelid); if (!$usercontext->getChannelPermission('forumpermissions', 'canview', $channelid)) { throw new vB_Exception_Api('no_permission'); } $parents = vB_Library::instance('node')->getParents($channelid); foreach ($parents as $parent) { if ($parent['nodeid'] != 1) { $parentids[] = $parent['nodeid']; } } } $data = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'startdate', 'value' => vB::getRequest()->getTimeNow(), 'operator' => vB_dB_Query::OPERATOR_LTE), array('field' => 'enddate', 'value' => vB::getRequest()->getTimeNow(), 'operator' => vB_dB_Query::OPERATOR_GTE))); if ($parentids) { $parentids[] = -1; // We should always include -1 for global announcements $data[vB_dB_Query::CONDITIONS_KEY][] = array('field' => 'nodeid', 'value' => $parentids); } elseif ($channelid) { $channelid = array($channelid, -1); // We should always include -1 for global announcements $data[vB_dB_Query::CONDITIONS_KEY][] = array('field' => 'nodeid', 'value' => $channelid); } else { $data[vB_dB_Query::CONDITIONS_KEY][] = array('field' => 'nodeid', 'value' => '-1'); } $announcements = $this->assertor->getRows('vBForum:announcement', $data, array('field' => array('startdate', 'announcementid'), 'direction' => array(vB_dB_Query::SORT_DESC, vB_dB_Query::SORT_DESC))); if (!$announcements) { return array(); } else { $results = array(); $bf_misc_announcementoptions = vB::getDatastore()->getValue('bf_misc_announcementoptions'); foreach ($announcements as $k => $post) { $userinfo = $userapi->fetchUserinfo($post['userid'], array(vB_Api_User::USERINFO_AVATAR, vB_Api_User::USERINFO_SIGNPIC)); $announcements[$k]['username'] = $userinfo['username']; $announcements[$k]['avatarurl'] = $userapi->fetchAvatar($post['userid']); $announcements[$k]['dohtml'] = $post['announcementoptions'] & $bf_misc_announcementoptions['allowhtml']; if ($announcements[$k]['dohtml']) { $announcements[$k]['donl2br'] = false; } else { $announcements[$k]['donl2br'] = true; } $announcements[$k]['dobbcode'] = $post['announcementoptions'] & $bf_misc_announcementoptions['allowbbcode']; $announcements[$k]['dobbimagecode'] = $post['announcementoptions'] & $bf_misc_announcementoptions['allowbbcode']; $announcements[$k]['dosmilies'] = $post['announcementoptions'] & $bf_misc_announcementoptions['allowsmilies']; if ($announcements[$k]['dobbcode'] and $post['announcementoptions'] & $bf_misc_announcementoptions['parseurl']) { require_once DIR . '/includes/functions_newpost.php'; $announcements[$k]['pagetext'] = convert_url_to_bbcode($post['pagetext']); } } return $announcements; } }
/** * Returns an array of request information * * @return array The request info */ public function getRequestInfo() { $request = vB::getRequest(); $items = array('sessionClass' => 'getSessionClass', 'timeNow' => 'getTimeNow', 'ipAddress' => 'getIpAddress', 'altIp' => 'getAltIp', 'sessionHost' => 'getSessionHost', 'userAgent' => 'getUserAgent', 'useEarlyFlush' => 'getUseEarlyFlush', 'cachePageForGuestTime' => 'getCachePageForGuestTime', 'referrer' => 'getReferrer', 'vBHttpHost' => 'getVbHttpHost', 'vBUrlScheme' => 'getVbUrlScheme', 'vBUrlPath' => 'getVbUrlPath', 'vBUrlQuery' => 'getVbUrlQuery', 'vBUrlQueryRaw' => 'getVbUrlQueryRaw', 'vBUrlClean' => 'getVbUrlClean', 'vBUrlWebroot' => 'getVbUrlWebroot', 'scriptPath' => 'getScriptPath'); $values = array(); foreach ($items as $varName => $methodName) { $values[$varName] = $request->{$methodName}(); } return $values; }
/** * Vote a node * * @param int $nodeid Node ID. * @return array New Node info. * @see vB_Api_Node::getNode() * @throws vB_Exception_Api */ public function vote($nodeid) { $node = vB_Api::instanceInternal('node')->getNodeFullContent($nodeid); $node = $node[$nodeid]; $this->checkCanUseRep($node); $loginuser =& vB::getCurrentSession()->fetch_userinfo(); if ($node['userid'] == $loginuser['userid']) { // Can't vote own node throw new vB_Exception_Api('reputationownpost'); } $score = $this->fetchReppower($loginuser['userid']); // Check if the user has already reputation this node $check = $this->assertor->getRow('vBForum:reputation', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'nodeid' => $node['nodeid'], 'whoadded' => $loginuser['userid'])); if (!empty($check)) { throw new vB_Exception_Api('reputationsamepost'); } $userinfo = vB_Api::instanceInternal('user')->fetchUserinfo($node['userid']); if (!$userinfo['userid']) { throw new vB_Exception_Api('invalidid', 'User'); } $usergroupcache = vB::getDatastore()->getValue('usergroupcache'); $bf_ugp_genericoptions = vB::getDatastore()->getValue('bf_ugp_genericoptions'); if (!($usergroupcache["{$userinfo['usergroupid']}"]['genericoptions'] & $bf_ugp_genericoptions['isnotbannedgroup'])) { throw new vB_Exception_Api('reputationbanned'); } $usercontext =& vB::getUserContext($loginuser['userid']); $vboptions = vB::getDatastore()->getValue('options'); $userinfo['reputation'] += $score; // Determine this user's reputationlevelid. $reputationlevelid = $this->assertor->getField('vBForum:reputation_userreputationlevel', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'reputation' => $userinfo['reputation'])); // init user data manager $userdata = new vB_Datamanager_User(NULL, vB_DataManager_Constants::ERRTYPE_STANDARD); $userdata->set_existing($userinfo); $userdata->set('reputation', $userinfo['reputation']); $userdata->set('reputationlevelid', intval($reputationlevelid)); $userdata->pre_save(); /*insert query*/ $this->assertor->assertQuery('vBForum:reputation', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERTIGNORE, 'nodeid' => $node['nodeid'], 'reputation' => $score, 'userid' => $userinfo['userid'], 'whoadded' => $loginuser['userid'], 'dateline' => vB::getRequest()->getTimeNow())); if ($this->assertor->affected_rows() == 0) { // attempt Zat a flood! throw new vB_Exception_Api('reputationsamepost'); } $userdata->save(); $condition = array('nodeid' => $nodeid); $this->assertor->assertQuery('vBForum:updateNodeVotes', $condition); // Send notification $recipients = array($node['userid']); $contextData = array('sentbynodeid' => $nodeid, 'sender' => vB::getUserContext()->fetchUserId()); vB_Library::instance('notification')->triggerNotificationEvent('node-reputation-vote', $contextData, $recipients); vB_Library::instance('notification')->insertNotificationsToDB(); // Expire node cache so this like displays correctly vB_Cache::instance()->allCacheEvent('nodeChg_' . $nodeid); $votesCount = $this->assertor->getField('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('votes'), vB_dB_Query::CONDITIONS_KEY => $condition)); return array('nodeid' => $nodeid, 'votes' => $votesCount); }
/** * Deletes all expired redirects * */ public function deleteExpiredRedirects() { $timenow = vB::getRequest()->getTimeNow(); $contenttypeid = vB_Types::instance()->getContentTypeId($this->contenttype); $assertor = vB::getDbAssertor(); $expiredRedirects = $assertor->getRows('vBForum:node', array(vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'contenttypeid', 'value' => $contenttypeid, vB_Db_Query::OPERATOR_KEY => vB_Db_Query::OPERATOR_EQ), array('field' => 'unpublishdate', 'value' => $timenow, vB_Db_Query::OPERATOR_KEY => vB_Db_Query::OPERATOR_LTE)))); $redirectids = array(); foreach ($expiredRedirects as $redirect) { $redirectids[] = $redirect['nodeid']; } $assertor->delete('vBForum:redirect', array(array('field' => 'nodeid', 'value' => $redirectids, vB_Db_Query::OPERATOR_KEY => vB_Db_Query::OPERATOR_EQ))); $assertor->delete('vBForum:node', array(array('field' => 'nodeid', 'value' => $redirectids, vB_Db_Query::OPERATOR_KEY => vB_Db_Query::OPERATOR_EQ))); }
public function sendemail($postid, $reason) { $cleaner = vB::getCleaner(); $postid = $cleaner->clean($postid, vB_Cleaner::TYPE_UINT); $reason = $cleaner->clean($reason, vB_Cleaner::TYPE_STR); if (empty($postid)) { return array('response' => array('errormessage' => array('invalidid'))); } if (empty($reason)) { return array('response' => array('errormessage' => array('invalidid'))); } $userinfo = vB_Api::instance('user')->fetchUserinfo(); $data = array('reportnodeid' => $postid, 'rawtext' => $reason, 'created' => vB::getRequest()->getTimeNow(), 'userid' => $userinfo['userid'], 'authorname' => $userinfo['username']); $result = vB_Api::instance('content_report')->add($data, array('wysiwyg' => false)); if ($result === null || isset($result['errors'])) { return vB_Library::instance('vb4_functions')->getErrorResponse($result); } return array('response' => array('errormessage' => array('redirect_reportthanks'))); }
/** * Constructor protected to enforce singleton use. * @see instance() */ protected function __construct($cachetype) { parent::__construct($cachetype); $this->memcached = vB_Memcache::instance(); $check = $this->memcached->connect(); if ($check === 3) { trigger_error('Unable to connect to memcache server', E_USER_ERROR); } $this->expiration = 48 * 60 * 60; // two days $this->timeNow = vB::getRequest()->getTimeNow(); //get the memcache prefix. $config = vB::getConfig(); if (empty($config['Cache']['memcacheprefix'])) { $this->prefix = $config['Database']['tableprefix']; } else { $this->prefix = $config['Cache']['memcacheprefix']; } }
public function newthread($forumid) { $cleaner = vB::getCleaner(); $forumid = $cleaner->clean($forumid, vB_Cleaner::TYPE_UINT); $forum = vB_Api::instance('node')->getFullContentforNodes(array($forumid)); if (empty($forum)) { return array("response" => array("errormessage" => array("invalidid"))); } $forum = $forum[0]; $foruminfo = vB_Library::instance('vb4_functions')->parseForumInfo($forum); $prefixes = vB_Library::instance('vb4_functions')->getPrefixes($forumid); $options = vB::getDatastore()->getValue('options'); $postattachment = $forum['content']['createpermissions']['vbforum_attach']; $postattachment = empty($postattachment) ? 0 : intval($postattachment); $usercontext = vB::getUserContext($this->currentUserId); $maxtags = $usercontext->getChannelLimits($forumid, 'maxstartertags'); $out = array('show' => array('tag_option' => 1), 'vboptions' => array('postminchars' => $options['postminchars'], 'titlemaxchars' => $options['titlemaxchars'], 'maxtags' => $maxtags), 'response' => array('forumrules' => array('can' => array('postattachment' => $postattachment)), 'prefix_options' => $prefixes, 'foruminfo' => $foruminfo, 'poststarttime' => vB::getRequest()->getTimeNow(), 'posthash' => vB_Library::instance('vb4_posthash')->getNewPosthash())); return $out; }
public function postreply($threadid, $message, $posthash = null, $subject = null) { $cleaner = vB::getCleaner(); $threadid = $cleaner->clean($threadid, vB_Cleaner::TYPE_UINT); $message = $cleaner->clean($message, vB_Cleaner::TYPE_STR); $subject = $cleaner->clean($subject, vB_Cleaner::TYPE_STR); $posthash = $cleaner->clean($posthash, vB_Cleaner::TYPE_STR); if (empty($threadid) || empty($message)) { return array("response" => array("errormessage" => array("invalidid"))); } $hv = vB_Library::instance('vb4_functions')->getHVToken(); $data = array('parentid' => $threadid, 'title' => !empty($subject) ? $subject : '(Untitled)', 'rawtext' => $message, 'created' => vB::getRequest()->getTimeNow(), 'hvinput' => $hv); $result = vB_Api::instance('content_text')->add($data, array('nl2br' => true, 'wysiwyg' => false)); if (empty($result) || !empty($result['errors'])) { return vB_Library::instance('vb4_functions')->getErrorResponse($result); } vB_Library::instance('vb4_posthash')->appendAttachments($result, $posthash); return array('response' => array('errormessage' => 'redirect_postthanks', 'show' => array('threadid' => $result, 'postid' => $result))); }
/** * Returns an array of bbcode parsing information. {@see vB_Api_Bbcode::fetchTagList} * * @see vB_Api_Bbcode::fetchTagList * @see vB_Api_Bbcode::fetchCustomTags() * @return array Bbcode parsing information. Format: * <pre>array( * defaultTags => array {@see vB_Api_Bbcode::fetchTagList} * customTags => array @see vB_Api_Bbcode::fetchCustomTags * defaultOptions => array {@see vB_Api_Bbcode::fetchBbcodeOptions()} * )</pre> */ public function initInfo() { $response['defaultTags'] = $this->fetchTagList(); $response['customTags'] = $this->fetchCustomTags(); $response['defaultOptions'] = $this->fetchBbcodeOptions(); $response['censorship'] = $this->fetchCensorshipInfo(); $response['smilies'] = $this->fetchSmilies(); $response['sessionUrl'] = vB::getCurrentSession()->get('sessionurl'); $response['vBHttpHost'] = vB::getRequest()->getVbHttpHost(); $options = vB::getDatastore()->get_value('options'); $response['blankAsciiStrip'] = $options['blankasciistrip']; $response['wordWrap'] = $options['wordwrap']; $response['codeMaxLines'] = $options['codemaxlines']; $response['bbUrl'] = $options['bburl']; $response['viewAttachedImages'] = $options['viewattachedimages']; $response['urlNoFollow'] = $options['url_nofollow']; $response['urlNoFollowWhiteList'] = $options['url_nofollow_whitelist']; $response['useFileAvatar'] = $options['usefileavatar']; $response['sigpicUrl'] = $options['sigpicurl']; return $response; }
/** * Stores a cache of various data for ACP Home Quick Stats into the datastore. */ function build_acpstats_datastore() { global $vbulletin; $assertor = vB::getDbAssertor(); $starttime = mktime(0, 0, 0, date('m'), date('d'), date('Y')); $mysqlversion = $assertor->getRow('mysqlVersion'); $data = $assertor->getRow('vBForum:getFiledataFilesizeSum'); $vbulletin->acpstats['attachsize'] = $data['size']; $data = $assertor->getRow('getCustomAvatarFilesizeSum'); $vbulletin->acpstats['avatarsize'] = $data['size']; $data = $assertor->getRow('vBForum:getCustomProfilePicFilesizeSum'); $vbulletin->acpstats['profilepicsize'] = $data['size']; $data = $assertor->getRow('user', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_COUNT, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'joindate', 'value' => $starttime, vB_dB_Query::OPERATOR_KEY => vB_dB_Query::OPERATOR_GTE)))); $vbulletin->acpstats['newusers'] = $data['count']; $data = $assertor->getRow('user', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_COUNT, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'lastactivity', 'value' => $starttime, vB_dB_Query::OPERATOR_KEY => vB_dB_Query::OPERATOR_GTE)))); $vbulletin->acpstats['userstoday'] = $data['count']; $data = $assertor->getRow('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_COUNT, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'created', 'value' => $starttime, vB_dB_Query::OPERATOR_KEY => vB_dB_Query::OPERATOR_GTE)))); $vbulletin->acpstats['newposts'] = $data['count']; $vbulletin->acpstats['indexsize'] = 0; $vbulletin->acpstats['datasize'] = 0; try { $tables = $assertor->getRows('getTableStatus', array()); } catch (Exception $ex) { $tables = array(); } if ($tables and !isset($table['errors'])) { foreach ($tables as $table) { $vbulletin->acpstats['datasize'] += $table['Data_length']; $vbulletin->acpstats['indexsize'] += $table['Index_length']; } } if (!$vbulletin->acpstats['indexsize']) { $vbulletin->acpstats['indexsize'] = -1; } if (!$vbulletin->acpstats['datasize']) { $vbulletin->acpstats['datasize'] = -1; } $vbulletin->acpstats['lastupdate'] = vB::getRequest()->getTimeNow(); build_datastore('acpstats', serialize($vbulletin->acpstats), 1); }
function do_post_reply() { $userinfo = vB_Api::instance('user')->fetchUserInfo(); if ($userinfo['userid'] < 1) { return json_error(ERR_NO_PERMISSION); } $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('postid' => vB_Cleaner::TYPE_UINT, 'threadid' => vB_Cleaner::TYPE_UINT, 'message' => vB_Cleaner::TYPE_STR, 'sig' => vB_Cleaner::TYPE_STR, 'poststarttime' => vB_Cleaner::TYPE_UINT)); if (empty($cleaned['message'])) { return json_error(ERR_NO_PERMISSION); } if (empty($cleaned['threadid'])) { if (!empty($cleaned['postid'])) { $post = vB_Api::instance('node')->getNode($cleaned['postid']); if (empty($post['errors'])) { $cleaned['threadid'] = $post['starter']; } else { return json_error(ERR_NO_PERMISSION); } } } if (!empty($cleaned['sig'])) { $cleaned['message'] = $cleaned['message'] . "\n\n" . $cleaned['sig']; } $result = vB_Api::instance('content_text')->add(array('parentid' => $cleaned['threadid'], 'title' => '(Untitled)', 'rawtext' => $cleaned['message'], 'created' => vB::getRequest()->getTimeNow(), 'hvinput' => fr_get_hvtoken())); if (empty($result) || !empty($result['errors'])) { return json_error(ERR_INVALID_THREAD); } if (!fr_do_attachment($result, $cleaned['poststarttime'])) { return json_error(ERR_CANT_ATTACH); } $result = vB_Api::instance('content_text')->update($result, array('rawtext' => fr_process_message($cleaned['message']))); if (empty($result) || !empty($result['errors'])) { return json_error(ERR_INVALID_THREAD); } return true; }
/** * Generates HTML for the subscription form page * * @param string Hash used to indicate the transaction within vBulletin * @param string The cost of this payment * @param string The currency of this payment * @param array Information regarding the subscription that is being purchased * @param array Information about the user who is purchasing this subscription * @param array Array containing specific data about the cost and time for the specific subscription period * * @return array Compiled form information */ function generate_form_html($hash, $cost, $currency, $subinfo, $userinfo, $timeinfo) { global $vbphrase, $vbulletin, $show; $item = $hash; $currency = strtoupper($currency); $timenow = vB::getRequest()->getTimeNow(); $sequence = vbrand(1, 1000); $fingerprint = $this->hmac($this->settings['txnkey'], $this->settings['authorize_loginid'] . '^' . $sequence . '^' . $timenow . '^' . $cost . '^' . $currency); $form['action'] = $this->form_target; $form['method'] = 'post'; // load settings into array so the template system can access them $settings =& $this->settings; $templater = new vB5_Template('subscription_payment_authorizenet'); $templater->register('cost', $cost); $templater->register('currency', $currency); $templater->register('fingerprint', $fingerprint); $templater->register('item', $item); $templater->register('sequence', $sequence); $templater->register('settings', $settings); $templater->register('timenow', $timenow); $templater->register('userinfo', $userinfo); $form['hiddenfields'] .= $templater->render(); return $form; }
protected function clearOneCache($fileName = false, $cacheid = false, $only_expired = true) { if (!empty($fileName)) { if (!file_exists($fileName)) { return false; } $fileInfo = pathinfo($fileName); //This only makes sense for .dat files if ($fileInfo['extension'] != 'dat') { return false; } $cacheid = $fileInfo['basename']; $baseName = $fileInfo['dirname'] . '/' . $cacheid; } else { if (!empty($cacheid)) { $baseName = $this->getPath($fileName); $fileName = $baseName . '.dat'; } else { return false; } } $fhandle = fopen($fileName, 'r'); if (!$fhandle) { return false; } //First we have a six-character space padded size. That's the space taken by the serialized array. $size = intval(fread($fhandle, 6)); //next is a serialized array, with values 'expires', 'events', 'serialized', 'created', 'size' $summary = unserialize(fread($fhandle, $size)); fclose($fhandle); if ($only_expired and $summary['expires'] >= vB::getRequest()->getTimeNow()) { return true; } //we delete the file first, then the del file, then the events. if (file_exists($fileName)) { unlink($fileName); } if (file_exists($baseName . '.del')) { unlink($baseName . '.del'); } if (!empty($summary['events'])) { if (!is_array($summary['events'])) { $summary['events'] = array($summary['events']); } foreach ($summary['events'] as $event) { $eventFile = $this->getPath($event) . '.ev'; if (!$eventFile) { continue; } if (file_exists($eventFile)) { unlink($eventFile); } } } }
public function cropImg($imgInfo, $maxwidth = 100, $maxheight = 100, $forceResize = false) { $thumbnail = array('filedata' => '', 'filesize' => 0, 'dateline' => 0, 'imageerror' => ''); $filename = $imgInfo['filename']; $imgInfo['extension'] = strtoupper($imgInfo['extension']); if ($imgInfo['extension'] == 'JPG') { $imgInfo['extension'] = 'JPEG'; } if ($validfile = $this->isValidThumbnailExtension($imgInfo['extension'])) { $thumbnail['source_width'] = $new_width = $width = $imgInfo['width']; $thumbnail['source_height'] = $new_height = $height = $imgInfo['height']; if ($forceResize or $width >= $maxwidth or $height >= $maxheight) { $memoryok = true; $checkmem = false; if (function_exists('memory_get_usage') and $memory_limit = @ini_get('memory_limit') and $memory_limit != -1) { $memorylimit = vb_number_format($memory_limit, 0, false, null, ''); $memoryusage = memory_get_usage(); $freemem = $memorylimit - $memoryusage; $checkmem = true; $tmemory = $width * $height * ($imgInfo['extension'] == 'JPEG' ? 5 : 2) + 7372.8 + sqrt(sqrt($width * $height)); $tmemory += 166000; // fudge factor, object overhead, etc if ($freemem > 0 and $tmemory > $freemem and $tmemory <= $memorylimit * 3) { // attempt to increase memory within reason, no more than triple if (($current_memory_limit = vB_Utilities::ini_size_to_bytes(@ini_get('memory_limit'))) < $memorylimit + $tmemory and $current_memory_limit > 0) { @ini_set('memory_limit', $memorylimit + $tmemory); } $memory_limit = @ini_get('memory_limit'); $memorylimit = vb_number_format($memory_limit, 0, false, null, ''); $memoryusage = memory_get_usage(); $freemem = $memorylimit - $memoryusage; } } $fh = fopen($filename, 'w'); fwrite($fh, $imgInfo['filedata']); fclose($fh); switch ($imgInfo['extension']) { case 'GIF': if (function_exists('imagecreatefromgif')) { if ($checkmem) { if ($freemem > 0 and $tmemory > $freemem) { throw new vB_Exception_Api('thumbnail_notenoughmemory'); } } if ($memoryok and !($image = @imagecreatefromgif($filename))) { throw new vB_Exception_Api('thumbnail_nocreateimage_gif'); } } else { throw new vB_Exception_Api('thumbnail_nosupport'); } break; case 'JPEG': if (function_exists('imagecreatefromjpeg')) { if ($checkmem) { if ($freemem > 0 and $tmemory > $freemem) { throw new vB_Exception_Api('thumbnail_notenoughmemory'); } } if ($memoryok and !($image = @imagecreatefromjpeg($filename))) { throw new vB_Exception_Api('thumbnail_nocreateimage_jpeg'); } } else { throw new vB_Exception_Api('thumbnail_nosupport'); } break; case 'PNG': if (function_exists('imagecreatefrompng')) { if ($checkmem) { if ($freemem > 0 and $tmemory > $freemem) { throw new vB_Exception_Api('thumbnail_notenoughmemory'); } } if ($memoryok and !($image = @imagecreatefrompng($filename))) { throw new vB_Exception_Api('thumbnail_nocreateimage_png'); } } else { throw new vB_Exception_Api('thumbnail_nosupport'); } break; } if ($image) { $xratio = $maxwidth == 0 ? 1 : $width / $maxwidth; $yratio = $maxheight == 0 ? 1 : $height / $maxheight; if ($xratio > $yratio) { $new_width = round($width / $xratio); $new_height = round($height / $xratio); } else { $new_width = round($width / $yratio); $new_height = round($height / $yratio); } } if (!($finalimage = @imagecreatetruecolor($new_width, $new_height))) { imagedestroy($image); throw new vB_Exception_Api('thumbnail_nocreateimage_truecolor'); } $bgcolor = imagecolorallocate($finalimage, 255, 255, 255); imagefill($finalimage, 0, 0, $bgcolor); imagecopyresampled($finalimage, $image, 0, 0, $imgInfo['x1'], $imgInfo['y1'], $new_width, $new_height, $imgInfo['width'], $imgInfo['height']); imagedestroy($image); if ($imgInfo['extension'] != 'GIF') { $this->unsharpmask($finalimage); } ob_start(); $new_extension = $this->printImage($finalimage, $imgInfo['extension'], false, 75); $thumbnail['filedata'] = ob_get_contents(); ob_end_clean(); $thumbnail['width'] = $new_width; $thumbnail['height'] = $new_height; $extension = $imgInfo['extension']; if ($new_extension != $extension) { $thumbnail['filename'] = preg_replace('#' . preg_quote($extension, '#') . '$#', $new_extension, $filename); } } else { // image is a thumbnail size already if ($imgInfo['width'] > 0 and $imgInfo['height'] > 0) { $thumbnail['filedata'] = @file_get_contents($filename); $thumbnail['width'] = $imgInfo['width']; $thumbnail['height'] = $imgInfo['height']; } else { throw new vB_Exception_Api('thumbnail_nogetimagesize'); } } } else { if (!$validfile) { throw new vB_Exception_Api('thumbnail_nosupport'); } } if (!empty($thumbnail['filedata'])) { $thumbnail['filesize'] = strlen($thumbnail['filedata']); $thumbnail['dateline'] = vB::getRequest()->getTimeNow(); } @unlink($filename); return $thumbnail; }
/** * Fetches the 'url' variable - usually the URL of the previous page in the history * * @return string */ function fetch_url() { $scriptpath = vB::getRequest()->getScriptPath(); //note regarding the default url if not set or inappropriate. //started out as index.php then moved to options['forumhome'] . '.php' when that option was added. //now we've changed to to the forumhome url since there is now quite a bit of logic around that. //Its not clear, however, with the expansion of vb if that's the most appropriate generic landing //place (perhaps it *should* be index.php). //In any case there are several places in the code that check for the default page url and change it //to something more appropriate. If the default url changes, so do those checks. //The solution is, most likely, to make some note when vbulletin->url is the default so it can be overridden //without worrying about what the exact text is. if (empty($_REQUEST['url'])) { $url = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; } else { $temp_url = $_REQUEST['url']; if (!empty($_SERVER['HTTP_REFERER']) and $temp_url == $_SERVER['HTTP_REFERER']) { //$url = 'index.php'; $url = vB5_Route::buildUrl('home|fullurl'); } else { $url = $temp_url; } } if ($url == $scriptpath or empty($url)) { //$url = 'index.php'; $url = vB5_Route::buildUrl('home|fullurl'); } $url = $this->registry->cleaner->xssClean($url); return $url; }
public function checkRegistration($username = '', $ipaddress = '', $email = '') { $query = array('f=json', 'unix=1'); if ($username and $this->options['vb_antispam_sfs_username']) { $query['username'] = '******' . urlencode($username); } if ($ipaddress and $this->options['vb_antispam_sfs_ip']) { $query['ip'] = 'ip=' . urlencode($ipaddress); } if ($email and $this->options['vb_antispam_sfs_email']) { $query['email'] = 'email=' . urlencode($email); } if (count($query) == 2) { // No options are enabled so fall out of here return true; } $url = 'http://' . $this->hostUrl . '/api?' . implode('&', $query); $result = @json_decode($this->_submit($url), true); if (!$result or !isset($result['success'])) { return $this->options['vb_antispam_sfs_unavailable']; } $spammer = false; $maxconfidence = 0; if ($username and $this->options['vb_antispam_sfs_username'] and isset($result['username']['appears']) and $result['username']['appears'] > 0) { $spammer = true; $minDaysPast = floor((vB::getRequest()->getTimeNow() - $result['username']['lastseen']) / 86400); $maxConfidence = $result['username']['confidence']; } if ($ipaddress and $this->options['vb_antispam_sfs_ip'] and isset($result['ip']['appears']) and $result['ip']['appears'] > 0) { $allow = false; if ($whitelist = trim($this->options['vb_antispam_sfs_iplist'])) { $addresses = preg_split('#\\s+#', $whitelist, -1, PREG_SPLIT_NO_EMPTY); foreach ($addresses as $allowed_ip) { if (strpos($allowed_ip, '*') === false and $allowed_ip[strlen($allowed_ip) - 1] != '.' and substr_count($allowed_ip, '.') < 4) { $allowed_ip .= '.'; } $allowed_ip_regex = str_replace('\\*', '(.*)', preg_quote($allowed_ip, '#')); if (preg_match('#^' . $allowed_ip_regex . '#U', $ipaddress)) { $allow = true; } } } if (!$allow) { $spammer = true; $daysPast = floor((vB::getRequest()->getTimeNow() - $result['ip']['lastseen']) / 86400); $minDaysPast = isset($minDaysPast) ? min($minDaysPast, $daysPast) : $daysPast; $maxConfidence = isset($maxConfidence) ? max($maxConfidence, $result['ip']['confidence']) : $result['ip']['confidence']; } } if ($email and $this->options['vb_antispam_sfs_email'] and isset($result['email']['appears']) and $result['email']['appears'] > 0) { $allow = false; if ($whitelist = trim($this->options['vb_antispam_sfs_emaillist'])) { $emails = preg_split('#\\s+#', $whitelist, -1, PREG_SPLIT_NO_EMPTY); foreach ($emails as $_email) { if (strtolower($_email) == strtolower($email)) { $allow = true; } } } if (!$allow) { $spammer = true; $daysPast = floor((vB::getRequest()->getTimeNow() - $result['email']['lastseen']) / 86400); $minDaysPast = isset($minDaysPast) ? min($minDaysPast, $daysPast) : $daysPast; $maxConfidence = isset($maxConfidence) ? max($maxConfidence, $result['email']['confidence']) : $result['email']['confidence']; } } if ($spammer) { if (!$this->options['vb_antispam_sfs_days'] or $minDaysPast <= $this->options['vb_antispam_sfs_days']) { return false; } if ($maxConfidence >= $this->options['vb_antispam_sfs_confidence']) { return false; } } return true; }
/** * Fetch a resize image from an existing filedata * * @param array File information * * */ public function fetchResizedImageFromFiledata(&$record, $type) { $options = vB::getDatastore()->get_value('options'); $sizes = @unserialize($options['attachresizes']); $filename = 'temp.' . $record['extension']; if (!isset($sizes[$type]) or empty($sizes[$type])) { throw new vB_Exception_Api('thumbnail_nosupport'); } if ($options['attachfile']) { if ($options['attachfile'] == ATTACH_AS_FILES_NEW) { $path = $options['attachpath'] . '/' . implode('/', preg_split('//', $record['userid'], -1, PREG_SPLIT_NO_EMPTY)) . '/'; } else { $path = $options['attachpath'] . '/' . $record['userid'] . '/'; } $location = $path . $record['filedataid'] . '.attach'; } else { // Must save filedata to a temp file as the img operations require a file read $location = vB_Utilities::getTmpFileName($record['userid'], 'vbimage'); @file_put_contents($location, $record['filedata']); } $resized = $this->fetchThumbnail($filename, $location, $sizes[$type], $sizes[$type], $options['thumbquality']); $record['resize_dateline'] = $resized['filesize']; $record['resize_filesize'] = strlen($resized['filedata']); if ($options['attachfile']) { if ($options['attachfile'] == ATTACH_AS_FILES_NEW) { $path = $options['attachpath'] . '/' . implode('/', preg_split('//', $record['userid'], -1, PREG_SPLIT_NO_EMPTY)) . '/'; } else { $path = $options['attachpath'] . '/' . $record['userid'] . '/'; } @file_put_contents($path . $record['filedataid'] . '.' . $type, $resized['filedata']); } else { $record['resize_filedata'] = $resized['filedata']; } vB::getDbAssertor()->assertQuery('vBForum:replaceIntoFiledataResize', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'filedataid' => $record['filedataid'], 'resize_type' => $type, 'resize_filedata' => $options['attachfile'] ? '' : $record['resize_filedata'], 'resize_filesize' => $record['resize_filesize'], 'resize_dateline' => vB::getRequest()->getTimeNow(), 'resize_width' => $resized['width'], 'resize_height' => $resized['height'], 'reload' => 0)); if (!$options['attachfile']) { @unlink($location); } }
/** * Saves an uploaded file into the filedata system. * * @param int $userid Id of user uploading the image. This user's permissions will be checked when necessary * @param array $filearray Array of data describing the uploaded file with data-types & keys: * string 'name' Filename * int 'size' Filesize * string 'type' Filetype * string 'tmp_name' Filepath to the temporary file created on the server * int 'parentid' Optional. Node/Channelid this file will be uploaded under. If provided * permissions will be checked under this node. * bool 'is_sigpic' Optional. If this is not empty, the saved filedata will replace * the user's sigpicnew record (or inserted for the user if none exists), * and the filedata record will have refcount incremented & publicview * set to 1. * @param string $fileContents String(?) containing file content BLOB * @param int $filesize File size * @param string $extension File extension * @param bool $imageOnly If true, this function will throw an exception if the file is not an image * @param bool $skipUploadPermissionCheck Optional boolean to skip permission checks. Only used internally when the system * saves a theme icon. Do not use for normal calls to this function. * * @return array Array of saved filedata info with data-types & keys: * int 'filedataid' * int 'filesize' * int 'thumbsize' file size of the thumbnail of the saved filedata * string 'extension' * string 'filename' * string[] 'headers' array containing the content-type http header of the saved filedata * boolean 'isimage' * * @throws vB_Exception_Api('invalid_attachment_storage') If 'attachfile' ("Save attachments as File") is enabled and the path specified * by 'attachpath' option is not writable for some reason * @throws vB_Exception_Api('dangerous_image_rejected') If image verification failed for $fileContents or $filearray['tmp_name'] * @throws vB_Exception_Api('upload_attachfull_total') If attachment quota specified by 'attachtotalspace' option is exceeded * @throws vB_Exception_Api('cannot_create_file') If the user fails the permission checks * @throws vB_Exception_Api('upload_invalid_image') If $imageOnly is true and the uploaded file is not an image * @throws vB_Exception_Api('unable_to_add_filedata') If adding the filedata record failed * @throws vB_Exception_Api('attachpathfailed') If 'attachfile' ("Save attachments as File") is enabled and creating or fetching * the path to the attachment directory for the user failed * @throws vB_Exception_Api('upload_file_system_is_not_writable_path') If 'attachfile' ("Save attachments as File") is enabled and the * path retrieved for the user is not writable. * * @access public */ public function saveUpload($userid, $filearray, $fileContents, $filesize, $extension, $imageOnly = false, $skipUploadPermissionCheck = false) { $assertor = vB::getDbAssertor(); $datastore = vB::getDatastore(); $options = $datastore->getValue('options'); $config = vB::getConfig(); $usercontext = vB::getUserContext($userid); //make sure there's a place to put attachments. if ($options['attachfile'] and (empty($options['attachpath']) or !file_exists($options['attachpath']) or !is_writable($options['attachpath']) or !is_dir($options['attachpath']))) { throw new vB_Exception_Api('invalid_attachment_storage'); } //make sure the file is good. if (!$this->imageHandler->verifyImageFile($fileContents, $filearray['tmp_name'])) { @unlink($filearray['tmp_name']); throw new vB_Exception_Api('dangerous_image_rejected'); } // Check if this is an image extension we're dealing with for displaying later. // exif_imagetype() will check the validity of image $isImageExtension = $isImage = $this->imageHandler->isImage($extension); if ($isImage and function_exists('exif_imagetype')) { $imageType = @exif_imagetype($filearray['tmp_name']); $isImage = (bool) $imageType; } else { if ($isImage and function_exists('finfo_open') and function_exists('finfo_file')) { /* * TODO: When pdf thumbnail support is fixed, this check might have to be updated. */ // Just in case exif_imagetype is not there. finfo extension should be installed // by default (except windows), and is an alternative way to detect // if this is an image. // In the future, perhaps we can just use below to set the mimetype in the database, // and have the fetchImage functions return the mimetype as well rather than // trying to set it based on the filedata.extension (which may not be correct). $finfo = finfo_open(FILEINFO_MIME_TYPE); $mimetype = finfo_file($finfo, $filearray['tmp_name']); if ($mimetype) { $mimetype = explode('/', $mimetype); $toplevel = $mimetype[0]; if ($toplevel != 'image') { $isImage = false; } } else { $isImage = false; } } } /* * Note, this is for identification only, NOT for security! * If we're going to depend on the extension to determine if it's an image, * let's at least check that it's an image. */ if ($isImageExtension and !$isImage) { // Do not allow a non-image to use an image extension. throw new vB_Exception_Api('image_extension_but_wrong_type'); } // Thumbnails are a different story altogether. Something like a PDF // might have a thumbnail. $canHaveThumbnail = $this->imageHandler->imageThumbnailSupported($extension); /* * TODO: We might want to check that the extension matches the mimetype. * */ //We check to see if this file already exists. $filehash = md5($fileContents); $fileCheck = $assertor->getRow('vBForum:getFiledataWithThumb', array('filehash' => $filehash, 'filesize' => $filesize)); // Does filedata already exist? if (empty($fileCheck) or $fileCheck['userid'] != $userid) { // Check if we are not exceeding the quota if ($options['attachtotalspace'] > 0) { $usedSpace = $assertor->getField('vBForum:getUserFiledataFilesizeSum', array('userid' => $userid)); $overage = $usedSpace + $filesize - $options['attachtotalspace']; if ($overage > 0) { $overage = vb_number_format($overage, 1, true); $userinfo = vB::getCurrentSession()->fetch_userinfo(); $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases('attachfull', array($userinfo['username'], $options['attachtotalspace'], $options['bburl'], 'admincp'), array($options['bbtitle']), 0); vB_Mail::vbmail($options['webmasteremail'], $maildata['subject'], $maildata['message']); throw new vB_Exception_Api('upload_attachfull_total', $overage); } } // Can we move this permission check out of this library function? if (!$usercontext->canUpload($filesize, $extension, !empty($filearray['parentid']) ? $filearray['parentid'] : false) and !$skipUploadPermissionCheck) { @unlink($filearray['tmp_name']); throw new vB_Exception_Api('cannot_create_file'); } if ($imageOnly and !$isImage) { throw new vB_Exception_Api('upload_invalid_image'); } $timenow = vB::getRequest()->getTimeNow(); if ($canHaveThumbnail) { //Get the image size information. $imageInfo = $this->imageHandler->fetchImageInfo($filearray['tmp_name']); $sizes = @unserialize($options['attachresizes']); if (!isset($sizes['thumb']) or empty($sizes['thumb'])) { $sizes['thumb'] = 100; } $thumbnail = $this->imageHandler->fetchThumbnail($filearray['name'], $filearray['tmp_name'], $sizes['thumb'], $sizes['thumb'], $options['thumbquality']); } else { $thumbnail = array('filesize' => 0, 'width' => 0, 'height' => 0, 'filedata' => null); } $thumbnail_data = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'resize_type' => 'thumb', 'resize_dateline' => $timenow, 'resize_filesize' => $thumbnail['filesize'], 'resize_width' => $thumbnail['width'], 'resize_height' => $thumbnail['height']); // Note, unless this is a sigpic (defined as !empty($filearray['is_sigpic'])), below will set // the refcount of the new filedata record to 0. // So the caller MUST increment the refcount if this image should not be removed by the cron. $data = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'userid' => $userid, 'dateline' => $timenow, 'filesize' => $filesize, 'filehash' => $filehash, 'extension' => $extension, 'refcount' => 0); if (!empty($imageInfo)) { $data['width'] = $imageInfo[0]; $data['height'] = $imageInfo[1]; } //Looks like we're ready to store. But do we put it in the database or the filesystem? if ($options['attachfile']) { //We name the files based on the filedata record, but we don't have that until we create the record. So we need // to do an insert, then create/move the files. $filedataid = $assertor->assertQuery('filedata', $data); if (is_array($filedataid)) { $filedataid = $filedataid[0]; } if (!intval($filedataid)) { throw new vB_Exception_Api('unable_to_add_filedata'); } $path = $this->verifyAttachmentPath($userid); if (!$path) { throw new vB_Exception_Api('attachpathfailed'); } if (!is_writable($path)) { throw new vB_Exception_Api('upload_file_system_is_not_writable_path', array(htmlspecialchars($path))); } if (!empty($thumbnail['filedata'])) { file_put_contents($path . $filedataid . '.thumb', $thumbnail['filedata']); } rename($filearray['tmp_name'], $path . $filedataid . '.attach'); } else { //We put the file contents into the data record. $data['filedata'] = $fileContents; $filedataid = $assertor->assertQuery('filedata', $data); if (is_array($filedataid)) { $filedataid = $filedataid[0]; } $thumbnail_data['resize_filedata'] = $thumbnail['filedata']; } $thumbnail_data['filedataid'] = $filedataid; if ($canHaveThumbnail) { $assertor->assertQuery('vBForum:filedataresize', $thumbnail_data); } if (!empty($filearray['name'])) { $filename = $filearray['name']; } else { $filename = ''; } $result = array('filedataid' => $filedataid, 'filesize' => $filesize, 'thumbsize' => $thumbnail['filesize'], 'extension' => $extension, 'filename' => $filename, 'headers' => $this->getAttachmentHeaders(strtolower($extension)), 'isimage' => $isImage); if (!empty($filearray['is_sigpic'])) { $assertor->assertQuery('replaceSigpic', array('userid' => $userid, 'filedataid' => $filedataid)); $assertor->assertQuery('incrementFiledataRefcountAndMakePublic', array('filedataid' => $filedataid)); } } else { // file already exists so we are not going to insert a new one $filedataid = $fileCheck['filedataid']; if (!empty($filearray['is_sigpic'])) { // Get old signature picture data and decrease refcount $oldfiledata = vB::getDbAssertor()->getRow('vBForum:sigpicnew', array('userid' => $userid)); if ($oldfiledata) { vB::getDbAssertor()->assertQuery('decrementFiledataRefcount', array('filedataid' => $oldfiledata['filedataid'])); } $assertor->assertQuery('replaceSigpic', array('userid' => $fileCheck['userid'], 'filedataid' => $filedataid)); $assertor->assertQuery('incrementFiledataRefcountAndMakePublic', array('filedataid' => $filedataid)); } $result = array('filedataid' => $filedataid, 'filesize' => $fileCheck['filesize'], 'thumbsize' => $fileCheck['resize_filesize'], 'extension' => $extension, 'filename' => $filearray['name'], 'headers' => $this->getAttachmentHeaders(strtolower($extension)), 'isimage' => $isImage); } return $result; }
/** Adjust GMT time back to user's time * * @param string $userinfo * @param type $adjustForServer * * @return integer */ public function fetchTimeOffset($adjustForServer = false) { $userInfo = vB::getCurrentSession()->fetch_userinfo(); if (is_array($userInfo) and isset($userInfo['timezoneoffset'])) { $options = vB::getDatastore()->getValue('options'); if (isset($userInfo['dstonoff']) and $userInfo['dstonoff'] or isset($userInfo['dstauto']) and $userInfo['dstauto'] and $options['dstonoff']) { // DST is on, add an hour $userInfo['timezoneoffset']++; if (substr($userInfo['timezoneoffset'], 0, 1) != '-' and substr($userInfo['timezoneoffset'], 0, 1) != '+') { // recorrect so that it has a + sign, if necessary $userInfo['timezoneoffset'] = '+' . $userInfo['timezoneoffset']; } } if ($options['dstonoff'] and $adjustForServer) { $userInfo['timezoneoffset']--; } $hourdiff = ($userInfo['timezoneoffset'] - date('Z', vB::getRequest()->getTimeNow()) / 3600) * 3600; } else { $hourdiff = vB::getDatastore()->getOption('hourdiff'); } return $hourdiff; }
/** * Halts execution of the entire system and displays an error message * * @param string Text of the error message. Leave blank to use $this->sql as error text. * * @return integer */ function halt($errortext = '') { static $called = false; /* if ($this->inTransaction) { $this->rollbackTransaction(); } */ if ($called) { if (!empty($errortext)) { $this->error = $errortext; } return $this->error; } else { $called = true; } if ($this->connection_recent) { $this->error = $this->error($this->connection_recent); $this->errno = $this->errno($this->connection_recent); } if ($this->errno == -1) { throw new exception('no_vb5_database'); } if ($this->reporterror) { if ($errortext == '') { $this->sql = "Invalid SQL:\r\n" . chop($this->sql) . ';'; $errortext =& $this->sql; if (strlen($errortext) > 2048) { $truncated_errortext = "\r\n[Showing truncated query, original length: " . strlen($this->sql) . "]\r\n[First 500 chars]\r\n" . substr($errortext, 0, 500) . "\r\n[Last 500 chars]\r\n" . substr($errortext, -500); $errortext = $truncated_errortext; unset($truncated_errortext); } } $session = vB::getCurrentSession(); if ($session) { $userinfo = $session->fetch_userinfo(); } //TODO -- need to clean up VB_AREA stuff if (defined('VB_AREA') and (VB_AREA == 'Upgrade' or VB_AREA == 'Install')) { $display_db_error = true; } else { $userContext = vB::getUserContext(); $display_db_error = $userContext ? $userContext->isAdministrator() : false; } // Hide the MySQL Version if its going in the source if (!$display_db_error) { $mysqlversion = ''; } else { if ($this->connection_recent) { $this->hide_errors(); list($mysqlversion) = $this->query_first("SELECT VERSION() AS version", self::DBARRAY_NUM); $this->show_errors(); } } $vb5_config = vB::getConfig(); $request = vB::getRequest(); if ($request) { $timeNow = $request->getTimeNow(); $scriptpath = 'unknown'; $ipAddress = 'unknown'; $scriptpath = $request->getScriptPath(); $ipAddress = $request->getIpAddress(); $referer = $request->getReferrer(); } else { $timeNow = time(); $scriptpath = ''; $ipAddress = ''; $referer = ''; } $vboptions = vB::getDatastore()->getValue('options'); $technicalemail =& $vb5_config['Database']['technicalemail']; $data = array(); $data['error'] = $this->error; $data['errno'] = $this->errno; $data['requestdate'] = date('l, F jS Y @ h:i:s A', $timeNow); $data['date'] = date('l, F jS Y @ h:i:s A'); $data['host'] = ""; //todo figure this out for non http requests $data['scriptpath'] = str_replace('&', '&', $scriptpath); $data['referer'] = $referer; $data['ipaddress'] = $ipAddress; $data['username'] = isset($userinfo['username']) ? $userinfo['username'] : ""; $data['classname'] = get_class($this); $data['mysqlversion'] = $mysqlversion; $data['technicalemail'] = $technicalemail; $data['appname'] = $this->appname; $data['templateversion'] = $vboptions['templateversion']; if ($vb5_config['Misc']['debug']) { $data['trace'] = debug_backtrace(); } $dbexception = new vB_Exception_Database($errortext, $data); //log message require_once DIR . '/includes/functions_log_error.php'; if (function_exists('log_vbulletin_error')) { log_vbulletin_error($dbexception->getMessage(), 'database'); } if ($this->reporterror) { throw $dbexception; } } else { if (!empty($errortext)) { $this->error = $errortext; } } }
/** * Initializes an API client * * @param int $api_c API Client ID * @param array $apiclientdata 'clientname', 'clientversion', 'platformname', 'platformversion', 'uniqueid' * * @throws vB_Exception_Api Throws 'apiclientinfomissing' if any of clientname, clientversion, platformname, platformversion, or uniqueid are missing. * * @return array Api information, format: * array( * apiversion => string * apiaccesstoken => string * bbtitle => string * bburl => string * bbactive => int * bbclosedreason => string (only set if bbactive = 0) * forumhome => string * vbulletinversion => string * contenttypes => array( * content type class => content type id * [...] * ) * features => array( * blogenabled => 1 * cmsenabled => 0 * pmsenabled => int * searchesenabled => tin * groupsenabled => 1 * albumsenabled => 0 * multitypesearch => 1 * visitor_messagingenabled => 1 * taggingenabled => int * visitor_trackingenabled => 0 * paidsubs => int * friendsenabled => 0 * activitystream => 1 * ) * permissions => empty array * show => array( * registerbutton => 1 * ) * apiclientid => int * secret => string (only if API Client ID was specified in the call) * ) */ public function init($clientname, $clientversion, $platformname, $platformversion, $uniqueid, $api_c = 0) { $clientname = strip_tags($clientname); $clientversion = strip_tags($clientversion); $platformname = strip_tags($platformname); $platformversion = strip_tags($platformversion); $uniqueid = strip_tags($uniqueid); $api_c = intval($api_c); $oldclientid = $api_c; if (!$api_c) { // The client doesn't have an ID yet. So we need to generate a new one. // All params are required. // uniqueid is the best to be a permanent unique id such as hardware ID (CPU ID, // Harddisk ID or Mobile IMIE). Some client can not get a such a uniqueid, // so it needs to generate an unique ID and save it in its local storage. If it // requires the client ID and Secret again, pass the same unique ID. if (!$clientname or !$clientversion or !$platformname or !$platformversion or !$uniqueid) { throw new vB_Exception_Api('apiclientinfomissing'); } // Gererate clienthash. $clienthash = md5($clientname . $platformname . $uniqueid); // Generate a new secret $secret = fetch_random_password(32); // If the same clienthash exists, return secret back to the client. $client = $this->dbassertor->getRow('apiclient', array('clienthash' => $clienthash)); $api_c = $client['apiclientid']; if ($api_c) { // Update secret // Also remove userid so it will logout previous loggedin and remembered user. (VBM-553) $this->dbassertor->update('apiclient', array('secret' => $secret, 'apiaccesstoken' => vB::getCurrentSession()->get('apiaccesstoken'), 'lastactivity' => vB::getRequest()->getTimeNow(), 'clientversion' => $clientversion, 'platformversion' => $platformversion, 'userid' => 0), array('apiclientid' => $api_c)); } else { $api_c = $this->dbassertor->insert('apiclient', array('secret' => $secret, 'clienthash' => $clienthash, 'clientname' => $clientname, 'clientversion' => $clientversion, 'platformname' => $platformname, 'platformversion' => $platformversion, 'initialipaddress' => vB::getRequest()->getAltIp(), 'apiaccesstoken' => vB::getCurrentSession()->get('apiaccesstoken'), 'dateline' => vB::getRequest()->getTimeNow(), 'lastactivity' => vB::getRequest()->getTimeNow())); if (is_array($api_c)) { $api_c = array_pop($api_c); } $api_c = (int) $api_c; } // Set session client ID vB::getCurrentSession()->set('apiclientid', $api_c); } else { // api_c and api_sig are verified in init.php so we don't need to verify here again. $api_c = intval($api_c); // Update lastactivity $this->dbassertor->update('apiclient', array('lastactivity' => vB::getRequest()->getTimeNow()), array('apiclientid' => $api_c)); } $contenttypescache = vB_Types::instance()->getContentTypes(); $contenttypes = array(); foreach ($contenttypescache as $contenttype) { $contenttypes[$contenttype['class']] = $contenttype['id']; } $products = vB::getDatastore()->getValue('products'); $vboptions = vB::getDatastore()->getValue('options'); $userinfo = vB::getCurrentSession()->fetch_userinfo(); // Check the status of CMS and Blog $blogenabled = true; $cmsenabled = false; try { vB_Api::instanceInternal('paidsubscription')->checkStatus(); $paidsubs = 1; } catch (Exception $e) { $paidsubs = 0; } $forumHome = vB_Library::instance('content_channel')->getForumHomeChannel(); $forumhomeUrl = vB5_Route::buildUrl($forumHome['routeid'] . '|fullurl'); $data = array('apiversion' => VB_API_VERSION, 'apiaccesstoken' => vB::getCurrentSession()->get('apiaccesstoken'), 'bbtitle' => $vboptions['bbtitle'], 'bburl' => $vboptions['bburl'], 'bbactive' => $vboptions['bbactive'], 'forumhome' => $forumhomeUrl, 'vbulletinversion' => $vboptions['templateversion'], 'contenttypes' => $contenttypes, 'features' => array('blogenabled' => 1, 'cmsenabled' => 0, 'pmsenabled' => $vboptions['enablepms'] ? 1 : 0, 'searchesenabled' => $vboptions['enablesearches'] ? 1 : 0, 'groupsenabled' => 1, 'albumsenabled' => 0, 'multitypesearch' => 1, 'visitor_messagingenabled' => 1, 'taggingenabled' => $vboptions['threadtagging'] ? 1 : 0, 'visitor_trackingenabled' => 0, 'paidsubs' => $paidsubs, 'friendsenabled' => 0, 'activitystream' => 1), 'permissions' => array(), 'show' => array('registerbutton' => 1)); if (!$vboptions['bbactive']) { $data['bbclosedreason'] = $vboptions['bbclosedreason']; } $data['apiclientid'] = $api_c; if (!$oldclientid) { $data['secret'] = $secret; } return $data; }
$faqname = $vbulletin->db->escape_string($vbulletin->GPC['faq']); // set base language versions $baselang = iif($vbulletin->GPC['volatile'], -1, 0); if ($baselang != -1 or $vb5_config['Misc']['debug']) { // can't edit a master version if not in debug mode $vbulletin->GPC['title']["{$baselang}"] =& $vbulletin->GPC['deftitle']; $vbulletin->GPC['text']["{$baselang}"] =& $vbulletin->GPC['deftext']; } $full_product_info = fetch_product_list(true); $product_version = $full_product_info[$vbulletin->GPC['product']]['version']; $insertSql = array(); foreach (array_keys($vbulletin->GPC['title']) as $languageid) { $newtitle = trim($vbulletin->GPC['title']["{$languageid}"]); $newtext = trim($vbulletin->GPC['text']["{$languageid}"]); if ($newtitle or $newtext) { $assertor->assertQuery('vBForum:phrase', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_MULTIPLEINSERT, vB_dB_Query::FIELDS_KEY => array('languageid', 'varname', 'text', 'fieldname', 'product', 'username', 'dateline', 'version'), vB_Db_Query::VALUES_KEY => array(array($languageid, $faqname . "_gfaqtitle", $newtitle, 'faqtitle', $vbulletin->GPC['product'], $vbulletin->userinfo['username'], vB::getRequest()->getTimeNow(), $product_version), array($languageid, $faqname . "_gfaqtext", $newtext, 'faqtext', $vbulletin->GPC['product'], $vbulletin->userinfo['username'], vB::getRequest()->getTimeNow(), $product_version)))); } } /*insert query*/ $set = $assertor->assertQuery('vBForum:replaceIntoFaq', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'faqname' => $faqname, 'faqparent' => $vbulletin->GPC['faqparent'], 'displayorder' => $vbulletin->GPC['displayorder'], 'volatile' => $vbulletin->GPC['volatile'], 'product' => $vbulletin->GPC['product'])); if (defined('DEV_AUTOEXPORT') and DEV_AUTOEXPORT) { require_once DIR . '/includes/functions_filesystemxml.php'; $products_to_export = array($vbulletin->GPC['product']); if (isset($old_product['product'])) { $products_to_export[] = $old_product['product']; } autoexport_write_faq_and_language($baselang, $products_to_export); } vb_Cache::instance()->event('vB_FAQ_chg'); print_stop_message2(array('saved_faq_x_successfully', $vbulletin->GPC['deftitle']), 'faq', array('faq' => $vbulletin->GPC['faqparent'])); }
public static function emailFloodCheck() { $session = vB::getCurrentSession(); if (empty($session)) { return array('valid' => true, 'error' => array()); } $usercontext = $session->fetch_userinfo(); if (empty($usercontext['userid'])) { $usercontext['emailstamp'] = vB::getCurrentSession()->get('emailstamp'); } $timenow = vB::getRequest()->getTimeNow(); $timepassed = $timenow - $usercontext['emailstamp']; $vboptions = vB::getDatastore()->getValue('options'); if ($vboptions['emailfloodtime'] > 0 and $timepassed < $vboptions['emailfloodtime'] and empty($usercontext['is_admin'])) { return array('valid' => false, 'error' => array("emailfloodcheck", array($vboptions['emailfloodtime'], $vboptions['emailfloodtime'] - $timepassed))); } return array('valid' => true, 'error' => array()); }