Example #1
0
 /**
  * Singleton instance getter
  *
  * @return	vB5_User
  */
 public static function instance()
 {
     if (self::$instance === null) {
         $class = __CLASS__;
         self::$instance = new $class();
     }
     return self::$instance;
 }
Example #2
0
 public function replacePlaceholders(&$content)
 {
     $this->fetchPhrases();
     $placeholders = array();
     end($this->stack);
     while (!is_null($placeholder_id = key($this->stack))) {
         $phraseName = current($this->stack);
         $phraseInfo = $this->pending[$phraseName][$placeholder_id];
         $phraseInfo[0] = isset($this->cache[$phraseName]) ? $this->cache[$phraseName] : $phraseInfo[0];
         // do parameter replacements in phrases for notices, since we don't want
         // the extra overhead of pulling these phrases in the api method
         if (strpos($phraseName, 'notice_') === 0 and preg_match('/^notice_[0-9]+_html$/', $phraseName)) {
             $phraseInfo[0] = str_replace(array('{musername}', '{username}', '{userid}', '{sessionurl}', '{sessionurl_q}', '{register_page}', '{help_page}'), array(vB5_User::get('musername'), vB5_User::get('username'), vB5_User::get('userid'), vB::getCurrentSession()->get('sessionurl'), vB::getCurrentSession()->get('sessionurl_q'), vB5_Template_Runtime::buildUrl('register'), vB5_Template_Runtime::buildUrl('help')), $phraseInfo[0]);
         }
         $replace = $this->constructPhraseFromArray($phraseInfo);
         $placeholders[$placeholder_id] = $replace;
         //$content = str_replace($placeholder_id, $replace, $content);
         prev($this->stack);
     }
     // If we passed any phrases as parameters to other phrases, we will
     // still have those placeholders in the "replace" content, for example:
     //   {vb:phrase have_x_posts_in_topic_last_y, {vb:var topic.dot_postcount}, {vb:date {vb:var topic.dot_lastpostdate}}}
     // since the date call can return phrases (today, yesterday, etc.).
     // This only goes one level deep (e.g., it's not recursive), since that's
     // all we need at this time.
     // This searches the replace text to see if there are any placeholders
     // left in them, and if so, replaces those placeholders with the phrase text.
     foreach ($placeholders as $k => $replace) {
         if (strpos($replace, '<!-- ##phrase_') !== false or strpos($replace, '&lt;!-- ##phrase_') !== false) {
             if (preg_match_all('/(?:<|&lt;)!-- ##phrase_([a-z0-9_]+)_[0-9]+## --(?:>|&gt;)/siU', $replace, $matches, PREG_SET_ORDER)) {
                 foreach ($matches as $match) {
                     $placeholder_id = $match[0];
                     $phrase_varname = $match[1];
                     $placeholder_id_lookup = str_replace(array('&lt;', '&gt;'), array('<', '>'), $placeholder_id);
                     $phraseInfo = $this->pending[$phrase_varname][$placeholder_id_lookup];
                     $phraseInfo[0] = isset($this->cache[$phrase_varname]) ? $this->cache[$phrase_varname] : $phraseInfo[0];
                     $phraseText = $this->constructPhraseFromArray($phraseInfo);
                     $placeholders[$k] = str_replace($placeholder_id, $phraseText, $placeholders[$k]);
                 }
             }
         }
     }
     if (!empty($placeholders)) {
         $content = str_replace(array_keys($placeholders), $placeholders, $content);
     }
 }
 public function actionLoadPreview()
 {
     $input = array('parentid' => isset($_POST['parentid']) ? intval($_POST['parentid']) : 0, 'channelid' => isset($_POST['channelid']) ? intval($_POST['channelid']) : 0, 'pagedata' => isset($_POST['pagedata']) ? (array) $_POST['pagedata'] : array(), 'conversationtype' => isset($_POST['conversationtype']) ? trim(strval($_POST['conversationtype'])) : '', 'posttags' => isset($_POST['posttags']) ? trim(strval($_POST['posttags'])) : '', 'rawtext' => isset($_POST['rawtext']) ? trim(strval($_POST['rawtext'])) : '', 'filedataid' => isset($_POST['filedataid']) ? (array) $_POST['filedataid'] : array(), 'link' => isset($_POST['link']) ? (array) $_POST['link'] : array(), 'poll' => isset($_POST['poll']) ? (array) $_POST['poll'] : array(), 'video' => isset($_POST['video']) ? (array) $_POST['video'] : array(), 'htmlstate' => isset($_POST['htmlstate']) ? trim(strval($_POST['htmlstate'])) : '', 'disable_bbcode' => isset($_POST['disable_bbcode']) ? intval($_POST['disable_bbcode']) : 0);
     $results = array();
     if ($input['parentid'] < 1) {
         $results['error'] = 'invalid_parentid';
         $this->sendAsJson($results);
         return;
     }
     if (!in_array($input['htmlstate'], array('off', 'on_nl2br', 'on'), true)) {
         $input['htmlstate'] = 'off';
     }
     // when creating a new content item, channelid == parentid
     $input['channelid'] = $input['channelid'] == 0 ? $input['parentid'] : $input['channelid'];
     $templateName = 'display_contenttype_conversationreply_';
     $templateName .= ucfirst($input['conversationtype']);
     $api = Api_InterfaceAbstract::instance();
     $channelBbcodes = $api->callApi('content_channel', 'getBbcodeOptions', array($input['channelid']));
     // The $node['starter'] and $node['nodeid'] values are just there to differentiate starters and replies
     $node = array('rawtext' => '', 'userid' => vB5_User::get('userid'), 'authorname' => vB5_User::get('username'), 'tags' => $input['posttags'], 'taglist' => $input['posttags'], 'approved' => true, 'created' => time(), 'avatar' => $api->callApi('user', 'fetchAvatar', array('userid' => vB5_User::get('userid'))), 'parentid' => $input['parentid'], 'starter' => $input['channelid'] == $input['parentid'] ? 0 : $input['parentid'], 'nodeid' => $input['channelid'] == $input['parentid'] ? 0 : 1);
     if ($input['conversationtype'] == 'gallery') {
         $node['photopreview'] = array();
         foreach ($input['filedataid'] as $filedataid) {
             $node['photopreview'][] = array('nodeid' => $filedataid, 'htmltitle' => isset($_POST['title_' . $filedataid]) ? vB_String::htmlSpecialCharsUni($_POST['title_' . $filedataid]) : '');
             //photo preview is up to 3 photos only
             if (count($node['photopreview']) == 3) {
                 break;
             }
         }
         $node['photocount'] = count($input['filedataid']);
     }
     if ($input['conversationtype'] == 'link') {
         $node['url_title'] = !empty($input['link']['title']) ? $input['link']['title'] : '';
         $node['url'] = !empty($input['link']['url']) ? $input['link']['url'] : '';
         $node['meta'] = !empty($input['link']['meta']) ? $input['link']['meta'] : '';
         $node['previewImage'] = !empty($input['link']['url_image']) ? $input['link']['url_image'] : '';
     }
     if ($input['conversationtype'] == 'poll') {
         $node['multiple'] = !empty($input['poll']['mutliple']);
         $node['options'] = array();
         if (!empty($input['poll']['options']) and is_array($input['poll']['options'])) {
             $optionIndex = 1;
             foreach ($input['poll']['options'] as $option) {
                 $node['options'][] = array('polloptionid' => $optionIndex, 'title' => $option);
                 $optionIndex++;
             }
         }
         $node['permissions']['canviewthreads'] = 1;
         //TODO: Fix this!!
     }
     if ($input['conversationtype'] == 'video') {
         $node['url_title'] = !empty($input['video']['title']) ? $input['video']['title'] : '';
         $node['url'] = !empty($input['video']['url']) ? $input['video']['url'] : '';
         $node['meta'] = !empty($input['video']['meta']) ? $input['video']['meta'] : '';
         $node['items'] = !empty($input['video']['items']) ? $input['video']['items'] : '';
     }
     try {
         $results = vB5_Template::staticRenderAjax($templateName, array('nodeid' => $node['nodeid'], 'conversation' => $node, 'currentConversation' => $node, 'bbcodeOptions' => $channelBbcodes, 'pagingInfo' => array(), 'postIndex' => 0, 'reportActivity' => false, 'showChannelInfo' => false, 'showInlineMod' => false, 'commentsPerPage' => 1, 'view' => 'stream', 'previewMode' => true));
     } catch (Exception $e) {
         if (vB5_Config::instance()->debug) {
             $results['error'] = 'error_rendering_preview_template ' . (string) $e;
         } else {
             $results['error'] = 'error_rendering_preview_template';
         }
         $this->sendAsJson($results);
         return;
     }
     $bbcodeoptions = array('allowhtml' => in_array($input['htmlstate'], array('on', 'on_nl2br'), true), 'allowbbcode' => !$input['disable_bbcode'], 'htmlstate' => $input['htmlstate']);
     $results = array_merge($results, $this->parseBbCodeForPreview(fetch_censored_text($input['rawtext']), $bbcodeoptions));
     $this->sendAsJson($results);
 }
Example #4
0
 protected function fetchStyleVars()
 {
     $res = Api_InterfaceAbstract::instance()->callApi('style', 'fetchStyleVars', array($this->stylePreference));
     // api method returns unserealized stylevars
     if (empty($res) or !empty($res['errors'])) {
         return;
     }
     $user = vB5_User::instance();
     if (is_null($user['lang_options']) or isset($user['lang_options']) and is_array($user['lang_options']) and !empty($user['lang_options']['direction'])) {
         // if user has a LTR language selected
         $res['textdirection'] = array('datatype' => 'string', 'string' => 'ltr');
         $res['left'] = array('datatype' => 'string', 'string' => 'left');
         $res['right'] = array('datatype' => 'string', 'string' => 'right');
     } else {
         // if user has a RTL language selected
         $res['textdirection'] = array('datatype' => 'string', 'string' => 'rtl');
         $res['left'] = array('datatype' => 'string', 'string' => 'right');
         $res['right'] = array('datatype' => 'string', 'string' => 'left');
     }
     foreach ($res as $key => $value) {
         $this->cache[$key] = $value;
     }
 }
Example #5
0
 /** gets the key used for storing page information
  *
  *	@param	int		the nodeid
  *
  *	@return	string  the cache key string
  */
 protected function getPagingCacheKey($nodeid)
 {
     return 'vB_ArtPaging_' . $nodeid . '_' . vB5_User::getLanguageId();
 }
Example #6
0
 /**
  * This gets the charset based on the current language
  *
  * @return string, stylevar charset value
  */
 public static function getCharset()
 {
     // first check for user info
     $encoding = vB5_User::get('lang_charset');
     if (!$encoding) {
         $encoding = Api_InterfaceAbstract::instance()->callApi('phrase', 'getLanguageid', array('getCharset' => true));
         if (empty($encoding['charset'])) {
             return 'UTF-8';
         }
         $encoding = $encoding['charset'];
     }
     return strtoupper($encoding);
 }
Example #7
0
 public function actionInlinemodLogin()
 {
     $api = Api_InterfaceAbstract::instance();
     $currentuser = vB5_User::instance();
     if (empty($currentuser['userid'])) {
         if (!empty($_POST['username'])) {
             $loginInfo = $api->callApi('user', 'login', array($_POST['username'], $_POST['password']));
             if (empty($loginInfo['errors']) and !empty($loginInfo['userid'])) {
                 $userInfo = $api->callApi('user', 'fetchUserinfo', array($loginInfo['userid']));
                 $username = $userInfo['username'];
                 vB5_Auth::setLoginCookies($loginInfo, '', !empty($_POST['rememberme']));
             } else {
                 $this->sendAsJson(array('error' => 'inlinemod_auth_login_failed'));
                 return false;
             }
         }
         if (empty($username)) {
             $this->sendAsJson(array('error' => 'inlinemod_auth_login_first'));
             return false;
         }
     } else {
         $username = $currentuser['username'];
     }
     if (empty($_POST['password'])) {
         $this->sendAsJson(array('error' => 'inlinemod_auth_password_empty'));
         return false;
     }
     $loginInfo = $api->callApi('user', 'login', array($username, $_POST['password'], '', '', 'cplogin'));
     if (isset($loginInfo['errors']) and !empty($loginInfo['errors'])) {
         $this->sendAsJson(array('error' => 'inlinemod_auth_login_failed'));
         return false;
     } else {
         vB5_Auth::setLoginCookies($loginInfo, 'cplogin', !empty($_POST['rememberme']));
         $this->sendAsJson(true);
         return true;
     }
 }
Example #8
0
 /**
  * Handles the parsing of a signature picture. Most of this is handled
  * based on the $parseUserinfo member.
  *
  * @param	string	Description for the sig pic
  *
  * @return	string	HTML representation of the sig pic
  */
 function handle_bbcode_sigpic($description)
 {
     // remove unnecessary line breaks and escaped quotes
     $description = str_replace(array('<br>', '<br />', '\\"'), array('', '', '"'), $description);
     // permissions are checked on API method
     if (empty($this->parseUserinfo['userid']) or empty($this->parseUserinfo['sigpic'])) {
         // unknown user or no sigpic
         return '';
     }
     if (self::$useFileAvatar) {
         $sigpic_url = $this->registry->options['sigpicurl'] . '/sigpic' . $this->parseUserinfo['userid'] . '_' . $this->parseUserinfo['sigpicrevision'] . '.gif';
     } else {
         $sigpic_url = 'image.php?' . vB::getCurrentSession()->get('sessionurl') . 'u=' . $this->parseUserinfo['userid'] . "&amp;type=sigpic&amp;dateline=" . $this->parseUserinfo['sigpicdateline'];
     }
     /*
     		if (defined('VB_AREA') AND VB_AREA != 'Forum')
     		{
     			// in a sub directory, may need to move up a level
     			if ($sigpic_url[0] != '/' AND !preg_match('#^[a-z0-9]+:#i', $sigpic_url))
     			{
     				$sigpic_url = '../' . $sigpic_url;
     			}
     		}
     */
     $description = str_replace(array('\\"', '"'), '', trim($description));
     if (vB5_User::get('userid') == 0 or vB5_User::get('showimages')) {
         return "<img src=\"{$sigpic_url}\" alt=\"{$description}\" border=\"0\" />";
     } else {
         if (!$description) {
             $description = $sigpic_url;
             if (vB5_String::vB_Strlen($description) > 55 and $this->isWysiwyg() == false) {
                 $description = substr($description, 0, 36) . '...' . substr($description, -14);
             }
         }
         return "<a href=\"{$sigpic_url}\">{$description}</a>";
     }
 }
Example #9
0
 public function getCssFile($filename)
 {
     $options = vB5_Template_Options::instance();
     $storecssasfile = $options->get('options.storecssasfile');
     $user = vB5_User::instance();
     $textdirection = $user['lang_options']['direction'] ? 'ltr' : 'rtl';
     // we cannot query user directly for styleid, we need to consider other parameters
     $styleid = vB5_Template_Stylevar::instance()->getPreferredStyleId();
     $vbcsspath = $this->getCssPath($storecssasfile, $textdirection, $styleid);
     if ($storecssasfile) {
         $cssfiledate = $this->getCssFileDate($options, $styleid);
         $file = htmlspecialchars($vbcsspath . $cssfiledate . '-' . $filename);
     } else {
         if (!($cssdate = intval($options->get('miscoptions.cssdate')))) {
             $cssdate = time();
             // fallback so we get the latest css
         }
         $joinChar = strpos($vbcsspath, '?') === false ? '?' : '&';
         $file = htmlspecialchars($vbcsspath . $filename . "{$joinChar}ts={$cssdate}");
     }
     return $file;
 }
Example #10
0
 public function index($pageid)
 {
     //the api init can redirect.  We need to make sure that happens before we echo anything
     $api = Api_InterfaceAbstract::instance();
     $top = '';
     // We should not cache register page for guest. See VBV-7695.
     if (vB5_Request::get('cachePageForGuestTime') > 0 and !vB5_User::get('userid') and (empty($_REQUEST['routestring']) or $_REQUEST['routestring'] != 'register' and $_REQUEST['routestring'] != 'lostpw')) {
         // languageid should be in the pagekey to fix VBV-8095
         $fullPageKey = 'vBPage_' . md5(serialize($_REQUEST)) . '_' . vB::getCurrentSession()->get('languageid');
         $styleid = vB5_Cookie::get('userstyleid', vB5_Cookie::TYPE_UINT);
         if (!empty($styleid)) {
             $fullPageKey .= '_' . $styleid;
         }
         $fullPage = vB_Cache::instance(vB_Cache::CACHE_LARGE)->read($fullPageKey);
         if (!empty($fullPage)) {
             echo $fullPage;
             exit;
         }
     }
     $preheader = vB5_ApplicationAbstract::getPreheader();
     $top .= $preheader;
     if (vB5_Request::get('useEarlyFlush')) {
         echo $preheader;
         flush();
     }
     $router = vB5_ApplicationAbstract::instance()->getRouter();
     $arguments = $router->getArguments();
     $userAction = $router->getUserAction();
     $pageKey = $router->getPageKey();
     $api->callApi('page', 'preload', array($pageKey));
     if (!empty($userAction)) {
         $api->callApi('wol', 'register', array($userAction['action'], $userAction['params'], $pageKey, vB::getRequest()->getScriptPath(), !empty($arguments['nodeid']) ? $arguments['nodeid'] : 0));
     }
     if (isset($arguments['pagenum'])) {
         $arguments['pagenum'] = intval($arguments['pagenum']) > 0 ? intval($arguments['pagenum']) : 1;
     }
     $pageid = (int) (isset($arguments['pageid']) ? $arguments['pageid'] : (isset($arguments['contentid']) ? $arguments['contentid'] : 0));
     if ($pageid < 1) {
         // @todo This needs to output a user-friendly "page not found" page
         throw new Exception('Could not find page.');
     }
     $page = $api->callApi('page', 'fetchPageById', array($pageid, $arguments));
     if (!$page) {
         // @todo This needs to output a user-friendly "page not found" page
         throw new Exception('Could not find page.');
     }
     // Go to the first new / unread post for this user in this topic
     if (!empty($_REQUEST['goto']) and $_REQUEST['goto'] == 'newpost' and !empty($arguments['nodeid']) and !empty($arguments['channelid'])) {
         if ($this->vboptions['threadmarking'] and vB5_User::get('userid')) {
             // Database read marking
             $channelRead = $api->callApi('node', 'getNodeReadTime', array($arguments['channelid']));
             $topicRead = $api->callApi('node', 'getNodeReadTime', array($arguments['nodeid']));
             $topicView = max($topicRead, $channelRead, time() - $this->vboptions['markinglimit'] * 86400);
         } else {
             // Cookie read marking
             $topicView = intval(vB5_Cookie::fetchBbarrayCookie('discussion_view', $arguments['nodeid']));
             if (!$topicView) {
                 $topicView = vB5_User::get('lastvisit');
             }
         }
         $topicView = intval($topicView);
         // Get the first unread reply
         $goToNodeId = $api->callApi('node', 'getFirstChildAfterTime', array($arguments['nodeid'], $topicView));
         if (empty($goToNodeId)) {
             $thread = $api->callApi('node', 'getNodes', array(array($arguments['nodeid'])));
             if (!empty($thread) and isset($thread[$arguments['nodeid']])) {
                 $goToNodeId = $thread[$arguments['nodeid']]['lastcontentid'];
             }
         }
         if ($goToNodeId) {
             // Redirect to the new post
             $urlCache = vB5_Template_Url::instance();
             $urlKey = $urlCache->register($router->getRouteId(), array('nodeid' => $arguments['nodeid']), array('p' => $goToNodeId));
             $replacements = $urlCache->finalBuildUrls(array($urlKey));
             $url = $replacements[$urlKey];
             if ($url) {
                 $url .= '#post' . $goToNodeId;
                 if (headers_sent()) {
                     echo '<script type="text/javascript">window.location = "' . $url . '";</script>';
                 } else {
                     header('Location: ' . $url);
                 }
                 exit;
             }
         }
     }
     $page['routeInfo'] = array('routeId' => $router->getRouteId(), 'arguments' => $arguments, 'queryParameters' => $router->getQueryParameters());
     $page['crumbs'] = $router->getBreadcrumbs();
     $page['headlinks'] = $router->getHeadLinks();
     $page['pageKey'] = $pageKey;
     // default value for pageSchema
     $page['pageSchema'] = 'http://schema.org/WebPage';
     $queryParameters = $router->getQueryParameters();
     /*
      *	VBV-12506
      *	this is where we would add other things to clean up dangerous query params.
      *	For VBV-12486, I'll just unset anything here that can't use vb:var in the templates,
      *	but really we should just make a whitelist of expected page object parameters that
      *	come from the query string and unset EVERYTHING else. For the expected ones, we
      *	should also force the value into the expected (and hopefully safer) range
      */
     /*
      *	VBV-12506
      *	$doNotReplaceWithQueryParams is a list of parameters that the page object usually
      *	gets naturally/internally, and we NEVER want to replace with a user provided query
      *	parameter. (In fact, *when* exactly DO we want to do this???)
      *	If we don't do this, it's a potential XSS vulnerability for the items that we
      *	cannot send through vb:var for whatever reason (title for ex)
      * 	and even if they *are* sent through vb:var, the replacements can sometimes just
      *	break the page even when it's sent through vb:var (for example, ?pagetemplateid=%0D,
      *	the new line this inserts in var pageData = {...} in the header template tends to
      *	break things (tested on Chrome).
      *	Furthermore, any script that uses the pageData var would get the user injected data
      *	that might cause more problems down the line.
      *	Parameter Notes:
      *		'titleprefix'
      *			As these two should already be html escaped, we don't want to double escape
      *			them. So we can't us vb:var in the templates. As such, we must prevent a
      *			malicious querystring from being injected into the page object here.
      *		'title'
      *			Similar to above, but channels are allowed to have HTML in the title, so
      *			they are intentinoally not escaped in the DB, and the templates can't use
      *			vb:var.
      *		'pageid', 'channelid', 'nodeid'
      *			These are usually set in the arguments, so the array_merge below usually
      *			takes care of not passing a pageid query string through to the page object,
      *			but I'm leaving them in just in case.
      */
     $doNotReplaceWithQueryParams = array('titleprefix', 'title', 'pageid', 'channelid', 'nodeid', 'pagetemplateid', 'url', 'pagenum', 'tagCloudTitle');
     foreach ($doNotReplaceWithQueryParams as $key) {
         unset($queryParameters[$key]);
     }
     $arguments = array_merge($queryParameters, $arguments);
     foreach ($arguments as $key => $value) {
         $page[$key] = $value;
     }
     $options = vB5_Template_Options::instance();
     $page['phrasedate'] = $options->get('miscoptions.phrasedate');
     $page['optionsdate'] = $options->get('miscoptions.optionsdate');
     // if no meta description, use node data or global one instead, prefer node data
     if (empty($page['metadescription']) and !empty($page['nodedescription'])) {
         $page['metadescription'] = $page['nodedescription'];
     }
     if (empty($page['metadescription'])) {
         $page['metadescription'] = $options->get('options.description');
     }
     $config = vB5_Config::instance();
     // Non-persistent notices @todo - change this to use vB_Cookie
     $page['ignore_np_notices'] = vB5_ApplicationAbstract::getIgnoreNPNotices();
     $templateCache = vB5_Template_Cache::instance();
     $templater = new vB5_Template($page['screenlayouttemplate']);
     //IMPORTANT: If you add any variable to the page object here,
     // please make sure you add them to other controllers which create page objects.
     // That includes at a minimum the search controller (in two places currently)
     // and vB5_ApplicationAbstract::showErrorPage
     $templater->registerGlobal('page', $page);
     $page = $this->outputPage($templater->render(), false);
     $fullPage = $top . $page;
     if (!empty($fullPageKey) and is_string($fullPageKey)) {
         vB_Cache::instance(vB_Cache::CACHE_LARGE)->write($fullPageKey, $fullPage, vB5_Request::get('cachePageForGuestTime'), 'vbCachedFullPage');
     }
     // these are the templates rendered for this page
     $loadedTemplates = vB5_Template::getRenderedTemplates();
     $api->callApi('page', 'savePreCacheInfo', array($pageKey));
     if (!vB5_Request::get('useEarlyFlush')) {
         echo $fullPage;
     } else {
         echo $page;
     }
 }
Example #11
0
 /**
  * Handle any delayed rendering. Currently delayed urls and node texts.
  *
  * @param	string
  * @param	boolean	true if we are rendering for a call to /ajax/render/ and we want CSS <link>s separate
  *
  * @return	string
  */
 protected function renderDelayed(&$final_rendered_orig, $isAjaxTemplateRender = false)
 {
     $javascript = vB5_Template_Javascript::instance();
     $javascript->insertJs($final_rendered_orig);
     $javascript->resetPending();
     $stylesheet = vB5_Template_Stylesheet::instance();
     $stylesheet->insertCss($final_rendered_orig, $isAjaxTemplateRender);
     $stylesheet->resetPending();
     $link = vB5_Template_Headlink::instance();
     $link->insertLinks($final_rendered_orig);
     $link->resetPending();
     $phrase = vB5_Template_Phrase::instance();
     $phrase->replacePlaceholders($final_rendered_orig);
     $phrase->resetPending();
     // we do not reset pending urls, since they may be required by nodetext
     vB5_Template_Url::instance()->replacePlaceholders($final_rendered_orig);
     $nodeText = vB5_Template_NodeText::instance();
     $nodeText->replacePlaceholders($final_rendered_orig);
     $nodeText->resetPending();
     $templateCache = vB5_Template_Cache::instance();
     $templateCache->replaceTextOnly($final_rendered_orig);
     //We should keep the debug info for truly last.
     if (vB5_Frontend_Controller_Bbcode::needDebug()) {
         $config = vB5_Config::instance();
         if (!$config->debug) {
             return $final_rendered_orig;
         }
         self::$renderedTemplateNames[] = 'debug_info';
         self::$renderedTemplates[] = array('templateName' => 'debug_info', 'isParentTemplate' => (bool) 0, 'indent' => str_repeat('|----', 2));
         $user = vB5_User::instance();
         $this->register('user', $user, true);
         extract(self::$globalRegistered, EXTR_SKIP | EXTR_REFS);
         extract($this->registered, EXTR_OVERWRITE | EXTR_REFS);
         $vboptions = vB5_Template_Options::instance()->getOptions();
         $vboptions = $vboptions['options'];
         $renderedTemplates = array('count' => count(self::$renderedTemplates), 'countUnique' => count(array_unique(self::$renderedTemplateNames)), 'templates' => self::$renderedTemplates, 'styleid' => vB5_Template_Stylevar::instance()->getPreferredStyleId());
         $cssDebugLog = vB5_Template_Stylesheet::getDebugLog();
         $jsDebugLog = vB5_Template_Javascript::instance()->getDebugLog();
         $templateCode = $templateCache->getTemplate('debug_info');
         if ($templateCache->isTemplateText()) {
             @eval($templateCode);
         } else {
             @(include $templateCode);
         }
         $phrase->replacePlaceholders($final_rendered);
         $phrase->resetPending();
         $final_rendered_orig = str_replace('<!-DebugInfo-->', $final_rendered, $final_rendered_orig);
     }
 }
Example #12
0
 /**
  * Formats a UNIX timestamp into a human-readable string according to vBulletin prefs
  *
  * Note: Ifvbdate() is called with a date format other than than one in $vbulletin->options[],
  * set $locale to false unless you dynamically set the date() and strftime() formats in the vbdate() call.
  *
  * @param	string	Date format string (same syntax as PHP's date() function). It also supports the following vB specific date/time format:
  *                  'registered' - Format For Registration Date
  *                  'cal1' - Format For Birthdays with Year Specified
  *                  'cal2' - Format For Birthdays with Year Unspecified
  *                  'log' - Log Date Format
  * @param	integer	Unix time stamp
  * @param	boolean	If true, attempt to show strings like "Yesterday, 12pm" instead of full date string
  * @param	boolean	If true, and user has a language locale, use strftime() to generate language specific dates
  * @param	boolean	If true, don't adjust time to user's adjusted time .. (think gmdate instead of date!)
  * @param	boolean	If true, uses gmstrftime() and gmdate() instead of strftime() and date()
  *
  * @return	string	Formatted date string
  */
 protected static function vbdate($format, $timestamp = 0, $doyestoday = false, $locale = true, $adjust = true, $gmdate = false)
 {
     $timenow = time();
     if (!$timestamp) {
         $timestamp = $timenow;
     }
     $options = vB5_Template_Options::instance();
     $uselocale = false;
     $timezone = vB5_User::get('timezoneoffset');
     if (vB5_User::get('dstonoff') || (vB5_User::get('dstauto') and $options->get('options.dstonoff'))) {
         // DST is on, add an hour
         $timezone++;
     }
     $hourdiff = (date('Z', time()) / 3600 - $timezone) * 3600;
     if (vB5_User::get('lang_locale')) {
         $userLangLocale = vB5_User::get('lang_locale');
     }
     if (!empty($userLangLocale)) {
         $uselocale = true;
         $currentlocale = setlocale(LC_TIME, 0);
         setlocale(LC_TIME, $userLangLocale);
         if (substr($userLangLocale, 0, 5) != 'tr_TR') {
             setlocale(LC_CTYPE, $userLangLocale);
         }
     }
     if ($uselocale and $locale) {
         if ($gmdate) {
             $datefunc = 'gmstrftime';
         } else {
             $datefunc = 'strftime';
         }
     } else {
         if ($gmdate) {
             $datefunc = 'gmdate';
         } else {
             $datefunc = 'date';
         }
     }
     // vB Specified format
     switch ($format) {
         case 'registered':
             if (($uselocale or vB5_User::get('lang_registereddateoverride')) and $locale) {
                 $format = vB5_User::get('lang_registereddateoverride');
             } else {
                 $format = $options->get('options.registereddateformat');
             }
             break;
         case 'cal1':
             if (($uselocale or vB5_User::get('lang_calformat1override')) and $locale) {
                 $format = vB5_User::get('lang_calformat1override');
             } else {
                 $format = $options->get('options.calformat1');
             }
             break;
         case 'cal2':
             if (($uselocale or vB5_User::get('lang_calformat2override')) and $locale) {
                 $format = vB5_User::get('lang_calformat2override');
             } else {
                 $format = $options->get('options.calformat2');
             }
             break;
         case 'log':
             if (($uselocale or vB5_User::get('lang_logdateoverride')) and $locale) {
                 $format = vB5_User::get('lang_logdateoverride');
             } else {
                 $format = $options->get('options.logdateformat');
             }
             break;
     }
     if (!$adjust) {
         $hourdiff = 0;
     }
     if ($timestamp < 0) {
         $timestamp_adjusted = $timestamp;
     } else {
         $timestamp_adjusted = max(0, $timestamp - $hourdiff);
     }
     if ($format == $options->get('options.dateformat') and ($uselocale or vB5_User::get('lang_dateoverride')) and $locale) {
         $format = vB5_User::get('lang_dateoverride');
     }
     if (!$uselocale and $format == vB5_User::get('lang_dateoverride')) {
         if ($gmdate) {
             $datefunc = 'gmstrftime';
         } else {
             $datefunc = 'strftime';
         }
     }
     if (!$uselocale and $format == vB5_User::get('lang_timeoverride')) {
         if ($gmdate) {
             $datefunc = 'gmstrftime';
         } else {
             $datefunc = 'strftime';
         }
     }
     if (($format == $options->get('options.dateformat') or $format == vB5_User::get('lang_dateoverride')) and $doyestoday and $options->get('options.yestoday')) {
         if ($options->get('options.yestoday') == 1) {
             if (!defined('TODAYDATE')) {
                 define('TODAYDATE', self::vbdate('n-j-Y', $timenow, false, false));
                 define('YESTDATE', self::vbdate('n-j-Y', $timenow - 86400, false, false));
                 define('TOMDATE', self::vbdate('n-j-Y', $timenow + 86400, false, false));
             }
             $datetest = @date('n-j-Y', $timestamp - $hourdiff);
             if ($datetest == TODAYDATE) {
                 $returndate = self::parsePhrase('today');
             } else {
                 if ($datetest == YESTDATE) {
                     $returndate = self::parsePhrase('yesterday');
                 } else {
                     $returndate = $datefunc($format, $timestamp_adjusted);
                 }
             }
         } else {
             $timediff = $timenow - $timestamp;
             if ($timediff >= 0) {
                 if ($timediff < 120) {
                     $returndate = self::parsePhrase('1_minute_ago');
                 } else {
                     if ($timediff < 3600) {
                         $returndate = self::parsePhrase('x_minutes_ago', intval($timediff / 60));
                     } else {
                         if ($timediff < 7200) {
                             $returndate = self::parsePhrase('1_hour_ago');
                         } else {
                             if ($timediff < 86400) {
                                 $returndate = self::parsePhrase('x_hours_ago', intval($timediff / 3600));
                             } else {
                                 if ($timediff < 172800) {
                                     $returndate = self::parsePhrase('1_day_ago');
                                 } else {
                                     if ($timediff < 604800) {
                                         $returndate = self::parsePhrase('x_days_ago', intval($timediff / 86400));
                                     } else {
                                         if ($timediff < 1209600) {
                                             $returndate = self::parsePhrase('1_week_ago');
                                         } else {
                                             if ($timediff < 3024000) {
                                                 $returndate = self::parsePhrase('x_weeks_ago', intval($timediff / 604900));
                                             } else {
                                                 $returndate = $datefunc($format, $timestamp_adjusted);
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             } else {
                 $returndate = $datefunc($format, $timestamp_adjusted);
             }
         }
     } else {
         if ($format == 'Y' and $uselocale and $locale) {
             $format = '%Y';
             // For copyright year
         }
         if ($format == 'r' and $uselocale and $locale) {
             $datefunc = 'date';
             // For debug
         }
         $returndate = $datefunc($format, $timestamp_adjusted);
     }
     if (!empty($userLangLocale)) {
         setlocale(LC_TIME, $currentlocale);
         if (substr($currentlocale, 0, 5) != 'tr_TR') {
             setlocale(LC_CTYPE, $currentlocale);
         }
     }
     return $returndate;
 }
Example #13
0
 function actionResult()
 {
     //the api init can redirect.  We need to make sure that happens before we echo anything
     $api = Api_InterfaceAbstract::instance();
     $top = '';
     if (vB5_Request::get('cachePageForGuestTime') > 0 and !vB5_User::get('userid')) {
         $fullPageKey = md5(serialize($_REQUEST));
         $fullPage = vB_Cache::instance()->read($fullPageKey);
         if (!empty($fullPage)) {
             echo $fullPage;
             exit;
         }
     }
     $preheader = vB5_ApplicationAbstract::getPreheader();
     $top .= $preheader;
     if (vB5_Request::get('useEarlyFlush')) {
         echo $preheader;
         flush();
     }
     $serverData = array_merge($_GET, $_POST);
     $router = vB5_ApplicationAbstract::instance()->getRouter();
     $arguments = $router->getArguments();
     $userAction = $router->getUserAction();
     if (!empty($userAction)) {
         $api->callApi('wol', 'register', array($userAction['action'], $userAction['params']));
     }
     // if Human verification is required, and we don't have 'q' set in serverData (means the user is using
     // the quick search box), we redirect user to advanced search page with HV
     $requirehv = $api->callApi('hv', 'fetchRequireHvcheck', array('search'));
     if (!empty($serverData['AdvSearch']) or $requirehv and isset($serverData['q'])) {
         $adv_search = $api->callApi('route', 'getRoute', array('pathInfo' => 'advanced_search', 'queryString' => ''), true);
         $arguments = $adv_search['arguments'];
     } elseif ($requirehv) {
         // Advanced search form submitted
         if (empty($serverData['humanverify'])) {
             $serverData['humanverify'] = array();
         }
         $return = $api->callApi('hv', 'verifyToken', array($serverData['humanverify'], 'search'));
         if ($return !== true) {
             $adv_search = $api->callApi('route', 'getRoute', array('pathInfo' => 'advanced_search', 'queryString' => ''), true);
             $arguments = $adv_search['arguments'];
             $error = $return['errors'][0][0];
         }
     }
     $pageid = (int) (isset($arguments['pageid']) ? $arguments['pageid'] : $arguments['contentid']);
     $page = $api->callApi('page', 'fetchPageById', array($pageid, $arguments));
     if (!$page) {
         echo 'Could not find page.';
         exit;
     }
     $phrases = $api->callApi('phrase', 'fetch', array(array('advanced_search', 'search_results')));
     $page['crumbs'] = array(0 => array('title' => $phrases['advanced_search'], 'url' => vB5_Template_Runtime::buildUrl('advanced_search', array(), array(), array('noBaseUrl' => true))), 1 => array('title' => $phrases['search_results'], 'url' => ''));
     // avoid search page itself being indexed
     $page['noindex'] = 1;
     if (!empty($serverData['cookie'])) {
         $serverData['searchJSON'] = '{"specific":[' . $_COOKIE[$serverData['cookie']] . ']}';
     }
     if (!empty($serverData['searchJSON'])) {
         if (is_string($serverData['searchJSON'])) {
             if (preg_match('/[^\\x00-\\x7F]/', $serverData['searchJSON'])) {
                 $serverData['searchJSON'] = vB5_String::toUtf8($serverData['searchJSON'], vB5_String::getTempCharset());
             }
             $serverData['searchJSON'] = json_decode($serverData['searchJSON'], true);
         }
         if (!empty($serverData['searchJSON'])) {
             if (!empty($serverData['searchJSON']['keywords'])) {
                 $serverData['searchJSON']['keywords'] = str_replace(array('"', '\\'), '', $serverData['searchJSON']['keywords']);
                 $serverData['searchJSON']['keywords'] = filter_var($serverData['searchJSON']['keywords'], FILTER_SANITIZE_STRING);
             }
             $serverData['searchJSON'] = json_encode($serverData['searchJSON']);
         } else {
             $serverData['searchJSON'] = '';
         }
         $page['searchJSON'] = $serverData['searchJSON'];
         $extra = array('searchJSON' => !empty($serverData['searchJSON']) ? $serverData['searchJSON'] : '{}');
         if (!empty($serverData['AdvSearch'])) {
             $extra['AdvSearch'] = 1;
         }
         $page['url'] = str_replace('&amp;', '&', vB5_Route::buildUrl('search', array(), $extra));
         //$page['searchJSONStructure'] = json_decode($page['searchJSON'],true);
         $page['crumbs'][0]['url'] = vB5_Template_Runtime::buildUrl('advanced_search', array(), array('searchJSON' => $page['searchJSON']), array('noBaseUrl' => true));
     } elseif (!empty($serverData['q'])) {
         $serverData['q'] = str_replace(array('"', '\\'), '', $serverData['q']);
         $serverData['q'] = filter_var($serverData['q'], FILTER_SANITIZE_STRING);
         $searchType = '';
         if (!empty($serverData['type'])) {
             $serverData['type'] = str_replace(array('"', '\\'), '', $serverData['type']);
             $serverData['type'] = filter_var($serverData['type'], FILTER_SANITIZE_STRING);
             $searchType = ',"type":"' . $serverData['type'] . '"';
         }
         $page['searchJSON'] = '{"keywords":"' . $serverData['q'] . '","sort":"title"' . $searchType . '}';
         $extra = array('q' => $serverData['q']);
         if (!empty($serverData['AdvSearch'])) {
             $extra['AdvSearch'] = 1;
         }
         $page['url'] = str_replace('&amp;', '&', vB5_Route::buildUrl('search', array(), $extra));
         $page['searchStr'] = $serverData['q'];
         $page['crumbs'][0]['url'] = vB5_Template_Runtime::buildUrl('advanced_search', array(''), array('searchJSON' => $page['searchJSON']), array('noBaseUrl' => true));
     } elseif (!empty($serverData['r'])) {
         unset($page['crumbs'][0]);
         $page['url'] = str_replace('&amp;', '&', vB5_Route::buildUrl('search', array(), array('r' => $serverData['r'])));
         $page['resultId'] = $serverData['r'];
         if (!empty($serverData['p']) && is_numeric($serverData['p'])) {
             $page['currentPage'] = intval($serverData['p']);
         }
         $page['crumbs'][0]['url'] = vB5_Template_Runtime::buildUrl('advanced_search', array(), array('r' => $serverData['r']), array('noBaseUrl' => true));
     } else {
         return $this->actionIndex();
     }
     $page['ignore_np_notices'] = vB5_ApplicationAbstract::getIgnoreNPNotices();
     if (!empty($error)) {
         $page['error'] = $error;
     }
     $templater = new vB5_Template($page['screenlayouttemplate']);
     $templater->registerGlobal('page', $page);
     $page = $this->outputPage($templater->render(), false);
     $fullPage = $top . $page;
     if (vB5_Request::get('cachePageForGuestTime') > 0 and !vB5_User::get('userid')) {
         vB_Cache::instance()->write($fullPageKey, $fullPage, vB5_Request::get('cachePageForGuestTime'));
     }
     if (!vB5_Request::get('useEarlyFlush')) {
         echo $fullPage;
     } else {
         echo $page;
     }
 }
Example #14
0
 public function actionGet()
 {
     $filters = isset($_POST['filters']) ? $_POST['filters'] : array();
     if (empty($filters['view'])) {
         $result = array('error' => 'invalid_request');
         $this->sendAsJson($result);
         return;
     }
     $search = array();
     $stickySearchOptions = array('sticky_only' => 1);
     $stickynodes = array();
     $incrementNodeview = false;
     // call node API's incrementNodeview if we're viewing a thread
     if (isset($filters['q']) and trim($filters['q']) != '') {
         $search['keywords'] = $filters['q'];
     } else {
         $filters['q'] = false;
     }
     if (!empty($filters['exclude_type'])) {
         $search['exclude_type'] = $filters['exclude_type'];
     }
     if (!empty($filters['userid'])) {
         $search['authorid'] = $filters['userid'];
     } else {
         if (!empty($filters['filter_blogs']) and $filters['filter_blogs'] == 'show_my') {
             $search['authorid'] = vB5_User::get('userid');
         }
     }
     if (isset($filters['filter_prefix'])) {
         if (!empty($filters['filter_prefix'])) {
             if ($filters['filter_prefix'] == '-1') {
                 $search['no_prefix'] = 1;
             } else {
                 if ($filters['filter_prefix'] == '-2') {
                     $search['has_prefix'] = 1;
                 } else {
                     $search['prefix'] = $filters['filter_prefix'];
                 }
             }
         } else {
             // Any thread, regardless of prefix, don't set $search['prefix']
         }
     }
     if (isset($filters['nodeid']) and intval($filters['nodeid']) > 0) {
         $search['channel'] = $filters['nodeid'];
     }
     switch ($filters['view']) {
         case 'topic':
             $search['view'] = vB_Api_Search::FILTER_VIEW_TOPIC;
             $search['exclude_sticky'] = true;
             $search['nolimit'] = !empty($filters['nolimit']);
             if (!empty($filters['depth'])) {
                 $search['depth'] = $filters['depth'];
             }
             $search['depth_exact'] = !empty($filters['depth_exact']);
             break;
         case 'channel':
             //Channel view is the same with Activity view except that Channel view's search scope is within that channel only as specified by the channel nodeid in the 'channel' filter
             $search['include_sticky'] = true;
             // drop through to 'activity'
         // drop through to 'activity'
         case 'activity':
             //Per Product, if New Topics filter in activity stream is ON, display latest starters only.
             //if OFF, display latest starter, reply or comment per topic
             if (isset($filters['filter_new_topics']) and $filters['filter_new_topics'] == '1') {
                 $search['starter_only'] = true;
             }
             $search['view'] = vB_Api_Search::FILTER_VIEW_ACTIVITY;
             break;
         case 'stream':
             $search['view'] = vB_Api_Search::FILTER_VIEW_CONVERSATION_STREAM;
             $search['include_starter'] = true;
             $search['depth'] = 2;
             break;
         case 'thread':
             $search['view'] = vB_Api_Search::FILTER_VIEW_CONVERSATION_THREAD;
             $search['include_sticky'] = true;
             $search['include_starter'] = true;
             $search['depth'] = 1;
             $search['nolimit'] = !empty($filters['nolimit']);
             if ($filters['q']) {
                 $search['view'] = vB_Api_Search::FILTER_VIEW_CONVERSATION_THREAD_SEARCH;
             }
             $incrementNodeview = true;
             break;
         case 'article':
             $search['starter_only'] = true;
             $search['view'] = vB_Api_Search::FILTER_VIEW_ACTIVITY;
             $search['include_sticky'] = true;
             $search['include_starter'] = true;
             //$search['depth'] = 1;
             //$search['nolimit'] = !empty($filters['nolimit']);
             break;
     }
     if (!empty($filters[vB_Api_Node::FILTER_DEPTH])) {
         $search['depth'] = intval($filters[vB_Api_Node::FILTER_DEPTH]);
     }
     if (isset($filters['filter_sort'])) {
         switch ($filters['filter_sort']) {
             case vB_Api_Node::FILTER_SORTFEATURED:
                 $search['featured'] = 1;
                 break;
             case vB_Api_Node::FILTER_SORTPOPULAR:
                 $search['sort']['votes'] = 'desc';
                 break;
             case vB_Api_Node::FILTER_SORTOLDEST:
                 if (isset($filters['view']) and $filters['view'] == 'topic') {
                     $search['sort']['lastcontent'] = 'asc';
                 } else {
                     $search['sort']['created'] = 'asc';
                 }
                 break;
             case vB_Api_Node::FILTER_SORTMOSTRECENT:
             default:
                 if (empty($filters['filter_order'])) {
                     $filters['filter_order'] = 'desc';
                 }
                 if (isset($filters['view']) and $filters['view'] == 'topic') {
                     $search['sort'][$filters['filter_sort']] = $filters['filter_order'];
                 } else {
                     $search['sort']['created'] = 'desc';
                 }
                 break;
         }
     } elseif ($filters['view'] == 'thread') {
         $search['sort']['created'] = 'asc';
     } elseif ($filters['view'] == 'topic') {
         $search['sort']['lastcontent'] = 'desc';
     }
     if (isset($filters['checkSince']) and is_numeric($filters['checkSince'])) {
         $search['date']['from'] = $filters['checkSince'] + 1;
     } elseif (isset($filters['date']) or isset($filters['filter_time'])) {
         $date_filter = empty($filters['date']) ? $filters['filter_time'] : $filters['date'];
         switch ($date_filter) {
             case 'time_today':
                 $search['date']['from'] = 'lastDay';
                 //vB_Api_Search::FILTER_LASTDAY;
                 break;
             case 'time_lastweek':
                 $search['date']['from'] = 'lastWeek';
                 //vB_Api_Search::FILTER_LASTWEEK;
                 break;
             case 'time_lastmonth':
                 $search['date']['from'] = 'lastMonth';
                 //vB_Api_Search::FILTER_LASTMONTH;
                 break;
             case 'time_lastyear':
                 $search['date']['from'] = 'lastYear';
                 //vB_Api_Search::FILTER_LASTYEAR;
                 break;
             case 'time_all':
             default:
                 $search['date'] = 'all';
                 break;
         }
     }
     if (isset($filters[vB_Api_Node::FILTER_SHOW]) and strcasecmp($filters[vB_Api_Node::FILTER_SHOW], vB_Api_Node::FILTER_SHOWALL) != 0) {
         $search['type'] = $filters[vB_Api_Node::FILTER_SHOW];
     }
     $search['ignore_protected'] = 1;
     $nodes = Api_InterfaceAbstract::instance()->callApi('search', 'getInitialResults', array($search, empty($filters['per-page']) ? false : $filters['per-page'], empty($filters['pagenum']) ? false : $filters['pagenum'], true));
     if ($incrementNodeview) {
         Api_InterfaceAbstract::instance()->callApi('node', 'incrementNodeview', array($filters['nodeid']));
     }
     if (!empty($nodes) and !empty($nodes['errors'])) {
         $result = array('error' => $nodes['errors'][0][0]);
         $this->sendAsJson($result);
         return;
     }
     //the same selected search filters except 'exclude_sticky' should also be applied when fetching sticky topics
     if ($filters['view'] == 'topic' and (empty($filters['pagenum']) or $filters['pagenum'] == 1 or vB::getDatastore()->getOption('showstickies'))) {
         $stickySearchOptions = array_merge($search, $stickySearchOptions);
         unset($stickySearchOptions['exclude_sticky']);
         $stickynodes = Api_InterfaceAbstract::instance()->callApi('search', 'getInitialResults', array($stickySearchOptions));
     }
     if (empty($filters['maxpages'])) {
         $filters['maxpages'] = 0;
     }
     switch ($filters['view']) {
         case 'activity':
             $result = $this->processActivityStream($nodes, true, $filters['maxpages']);
             break;
         case 'thread':
         case 'stream':
             $result = $this->processConversationDetail($nodes, $filters, $filters['maxpages']);
             break;
         case 'topic':
             $result = $this->processTopics($nodes, $stickynodes, $filters['maxpages']);
             break;
         case 'article':
             $articleDisplayColumns = !empty($_POST['article_display_columns']) ? strval($_POST['article_display_columns']) : '';
             $result = $this->processArticles($nodes, $filters['maxpages'], $articleDisplayColumns);
             break;
         case 'channel':
         default:
             $result = $this->processActivityStream($nodes, false, $filters['maxpages']);
             break;
     }
     if (!$result['lastDate']) {
         $result['lastDate'] = time();
     }
     $this->sendAsJson($result);
 }