Ejemplo n.º 1
0
 protected function sendLegacyEmailNotification($data)
 {
     $options = vB::getDatastore()->getValue('options');
     if (isset($options['enableemail']) and !$options['enableemail']) {
         return;
         // email notifications are globally disabled
     }
     /*
      *	Save some data for this page load. Since we can potentially fetch a bunch of the same
      *	data over and over if multiple users are getting notifications about the same content
      *	that was just created, let's get rid of the redundant calls when this function is called
      *	in a loop.
      *	Todo: we should write a bulk-send-email-notification function
      *
      *	I can't actually think of a case where a single content creation that triggers a number
      *	of email notifications will have different contentnodeid in its group of notifications,
      *	but let's just be safe and allow for that possibility.
      */
     static $recipientIndependentDataArray;
     $contentnodeid = isset($data['contentnodeid']) ? $data['contentnodeid'] : 0;
     if (!empty($contentnodeid) and empty($recipientIndependentDataArray[$contentnodeid])) {
         //we need to load this using the correct library class or things get weird.
         //note that if we load it from cache here it will be in the local memory cache
         //when we load the full content and we won't do it twice.
         $cached = vB_Library_Content::fetchFromCache(array($contentnodeid), vB_Library_Content::CACHELEVEL_FULLCONTENT);
         if (isset($cached['found'][$contentnodeid])) {
             $contenttypeid = $cached['found'][$contentnodeid]['contenttypeid'];
         } else {
             $row = $this->assertor->getRow('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('contenttypeid'), 'nodeid' => $contentnodeid));
             $contenttypeid = $row['contenttypeid'];
         }
         $contentLib = vB_Library_Content::getContentLib($contenttypeid);
         $currentNode = $contentLib->getContent($contentnodeid);
         $currentNode = $currentNode[$contentnodeid];
         /*
          *	These data are static & independent of the recipient of this message, assuming that
          *	we're not trying to hide any data. If we are going to check permissions for each
          *	recipient, we should probably check view perms & remove from the recipients list
          *	BEFORE we ever get to this function, and just not send them a notification instead of
          *	hiding data.
          */
         $recipientIndependentDataArray[$contentnodeid] = array('authorname' => $currentNode['userinfo']['username'], 'nodeurl' => vB5_Route::buildUrl('node|fullurl', array('nodeid' => $contentnodeid)), 'previewtext' => vB_String::getPreviewText($currentNode['rawtext']), 'nodeid' => $currentNode['nodeid'], 'starter' => $currentNode['starter'], 'startertitle' => isset($currentNode['startertitle']) ? $currentNode['startertitle'] : '', 'parentid' => $currentNode['parentid'], 'channeltitle' => $currentNode['channeltitle'], 'channeltype' => $currentNode['channeltype']);
     }
     // additional data used for subscription notifications
     if (isset($data['subscriptionnodeid'])) {
         $subId = $data['subscriptionnodeid'];
         if (!isset($recipientIndependentDataArray[$contentnodeid]['add_sub_data'][$subId])) {
             //we need to load this using the correct library class or things get weird.
             //note that if we load it from cache here it will be in the local memory cache
             //when we load the full content and we won't do it twice.
             $cached = vB_Library_Content::fetchFromCache(array($subId), vB_Library_Content::CACHELEVEL_FULLCONTENT);
             if (isset($cached['found'][$subId])) {
                 $contenttypeid = $cached['found'][$subId]['contenttypeid'];
             } else {
                 $row = $this->assertor->getRow('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('contenttypeid'), 'nodeid' => $subId));
                 $contenttypeid = $row['contenttypeid'];
             }
             if ($contenttypeid) {
                 $contentLib = vB_Library_Content::getContentLib($contenttypeid);
                 $subbedNode = $contentLib->getContent($subId);
                 $subbedNode = $subbedNode[$subId];
                 $channelTypeId = vB_Types::instance()->getContentTypeID('vBForum_Channel');
                 if ($subbedNode['contenttypeid'] == $channelTypeId) {
                     $nodetype = 'channel';
                 } else {
                     $nodetype = 'post';
                 }
                 $recipientIndependentDataArray[$contentnodeid]['add_sub_data'][$subId] = array('title' => $subbedNode['title'], 'nodetype' => $nodetype);
             }
         }
         // We only expect channeltype_forum, channeltype_article, channeltype_blog, channeltype_group, but
         // a channeltype_<> phrase for each of vB_Channel::$channelTypes should exist, so we can do this
         $channeltype = "channeltype_" . $recipientIndependentDataArray[$contentnodeid]['channeltype'];
         $nodetype = $recipientIndependentDataArray[$contentnodeid]['add_sub_data'][$subId]['nodetype'];
         // While phrases are dependent on languageid, it's not really recipient or userid
         // dependent and is shared/static among different recipients, so let's keep track
         // of them.
         if (!isset($phrases[$data['languageid']])) {
             $phrases[$data['languageid']] = vB_Api::instanceInternal('phrase')->fetch(array($channeltype, $nodetype), $data['languageid']);
         }
     }
     // keep track of the about strings that are for "content" notifications
     $temporary = array(vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_REPLY, vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_COMMENT, vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_THREADCOMMENT, vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_SUBSCRIPTION, vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_USERMENTION);
     $contentNotificationAboutStrings = array();
     foreach ($temporary as $aboutString) {
         $contentNotificationAboutStrings[$aboutString] = $aboutString;
     }
     if ($data['about'] == vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_VM) {
         // A VM should have only 1 recipient, so no good reason to cache this like other URLs. Also
         // VMs don't seem to work with the /node/ route, so we can't rely on that.
         $vmURL = vB5_Route::buildUrl('visitormessage|fullurl', array('nodeid' => $contentnodeid));
         $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases('visitormessage', array($data['username'], $recipientIndependentDataArray[$contentnodeid]['authorname'], $vmURL, $recipientIndependentDataArray[$contentnodeid]['previewtext'], $options['bbtitle']), array(), $data['languageid']);
     } elseif ($data['about'] == vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_VOTE) {
         // Vote notifications have their own section because their phrases aren't in the same format as the others
         // Since a vote doesn't have a node associated with it, we don't have a "currentnode" data.
         // Note that the poll library sets aboutid & contentid both to the nodeid of the poll-post
         $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases('vote', array($data['username'], vB_Api::instanceInternal('user')->fetchUserName(vB::getCurrentSession()->get('userid')), $recipientIndependentDataArray[$contentnodeid]['nodeurl'], $options['bbtitle']), array($recipientIndependentDataArray[$contentnodeid]['startertitle']), $data['languageid']);
     } elseif (isset($contentNotificationAboutStrings[$data['about']])) {
         // Normally the subject would contain the topic title, but if it's a subscription let's pass in the
         // title of the actual subscription node whether it's a channel, thread, blog etc.
         $emailSubjectVars = array($recipientIndependentDataArray[$contentnodeid]['startertitle']);
         // Since subscription email subjects don't have a title, we'll include the title in
         // the email body as a 7th variable.
         $emailBodyVars = array($data['username'], $recipientIndependentDataArray[$contentnodeid]['authorname'], $recipientIndependentDataArray[$contentnodeid]['nodeurl'], $recipientIndependentDataArray[$contentnodeid]['previewtext'], $options['bbtitle'], $options['frontendurl'] . '/member/' . $data['userid'] . '/subscriptions');
         // blog & social groups have special phrases, unless it's a subscription notification or a user mention.
         // If the latter, just send the generic subscription or user mention email.
         // As of 5.1.4, we do not expect to hit this block for blogs, because the people who *would*
         // receive this (the blog poster) are automatically subscribed to the blog channel, and
         // subscription notifications always trump other types of notifications. See VBV-13466
         if ($recipientIndependentDataArray[$contentnodeid]['channeltype'] == 'blog' and $data['about'] != vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_SUBSCRIPTION and $data['about'] != vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_USERMENTION) {
             $mailPhrase = 'comment_blogentry';
         } else {
             if ($recipientIndependentDataArray[$contentnodeid]['channeltype'] == 'group' and $data['about'] != vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_SUBSCRIPTION and $data['about'] != vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_USERMENTION) {
                 $mailPhrase = 'comment_grouptopic';
             } else {
                 switch ($data['about']) {
                     case vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_REPLY:
                         $mailPhrase = 'reply_thread';
                         break;
                     case vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_COMMENT:
                         $mailPhrase = 'comment_post';
                         break;
                     case vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_THREADCOMMENT:
                         $mailPhrase = 'comment_thread';
                         break;
                     case vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_SUBSCRIPTION:
                         $mailPhrase = 'subscribed_thread';
                         // $subId, $nodetype, $channeltype aer set above as long as 'subscriptionnodeid' was passed in.
                         if (!empty($subId)) {
                             // A new post in your {2} {3} subscription: {1}
                             $emailSubjectVars = array($recipientIndependentDataArray[$contentnodeid]['add_sub_data'][$subId]['title'], $phrases[$data['languageid']][$channeltype], $phrases[$data['languageid']][$nodetype]);
                             // Since we removed the starter title from the subject, add it to the message.
                             $emailBodyVars[] = $recipientIndependentDataArray[$contentnodeid]['startertitle'];
                         }
                         break;
                     case vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_USERMENTION:
                         $mailPhrase = 'usermention_post';
                         // subject: <username> mentioned you in <content item title>
                         $emailSubjectVars = array($recipientIndependentDataArray[$contentnodeid]['authorname'], $recipientIndependentDataArray[$contentnodeid]['startertitle']);
                         break;
                     default:
                         if ($recipientIndependentDataArray[$contentnodeid]['starter'] == $recipientIndependentDataArray[$contentnodeid]['parentid']) {
                             $mailPhrase = 'reply_thread';
                         } else {
                             $mailPhrase = 'reply_post';
                         }
                         break;
                 }
             }
         }
         $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases($mailPhrase, $emailBodyVars, $emailSubjectVars, $data['languageid']);
     } elseif ($data['about'] == vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_RATE) {
         $node = $recipientIndependentDataArray[$contentnodeid];
         // It doesn't make sense to call blog & article starters as "threads", so just go with "post"
         if ($node['nodeid'] == $node['starter'] and ($node['channeltype'] == 'forum' or $node['channeltype'] == 'group')) {
             $mailPhrase = 'like_thread';
         } else {
             $mailPhrase = 'like_post';
         }
         $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases($mailPhrase, array($data['username'], vB_Api::instanceInternal('user')->fetchUserName($data['senderid']), $node['nodeurl'], $options['bbtitle']), array($options['bbtitle']));
     } elseif ($data['about'] == vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_FOLLOW) {
         // the use of vB5_Route::buildUrl() below should be ok performant wise, because we're not expecting to send a bulk email for this
         // notification type. We should avoid hacky hacks (see above in the content notification section for avoiding vB5_Route::buildUrl()
         // to each recipient's subscription page) when forgivable.
         $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases('follow_approve', array($data['username'], vB_Api::instanceInternal('user')->fetchUserName($data['senderid']), vB5_Route::buildUrl('profile|fullurl', array('userid' => $data['senderid'], 'tab' => 'subscribed')), $options['bbtitle']), array($options['bbtitle']));
     } elseif ($data['about'] == vB_Library_Content_Privatemessage::NOTIFICATION_TYPE_FOLLOWING) {
         /*
         	Per dev chat discussion, this never existed. Since there doesn't seem to be a strong customer request for this,
         	I'm gonna leave it out. I'm leaving this section in so that it's trivial to add in the future.
         */
         $maildata = array();
     } else {
         // We don't know how to handle this.
         $maildata = array();
     }
     if (!empty($data['email']) and !empty($maildata)) {
         // Send the email
         vB_Mail::vbmail($data['email'], $maildata['subject'], $maildata['message'], false);
     }
 }
Ejemplo n.º 2
0
 /**
  * Publish this node to facebook feed
  *
  * @param array $node -- the $node array
  * @param boolean $explicit -- is this message explicitly shared? See
  *		https://developers.facebook.com/docs/opengraph/using-actions/v2.2#explicitsharing
  * @return bool
  */
 public function publishNode($node, $explicit)
 {
     if (!$this->userIsLoggedIn()) {
         return false;
     }
     $options = vB::getDatastore()->getValue('options');
     // is the node published/visible/public in vB?
     if ($node['showpublished'] != 1 or $node['approved'] != 1) {
         return false;
     }
     $isStarter = $node['nodeid'] == $node['starter'];
     // can new discussion, photo, link, poll etc be published?
     if ($isStarter and !$options['fbfeednewthread']) {
         return false;
     }
     // can replies to discussion, photo, link, poll etc be published?
     if (!$isStarter and !$options['fbfeedpostreply']) {
         return false;
     }
     // get node URL
     $extra = array();
     $anchor = '';
     if (!$isStarter) {
         $extra['p'] = $node['nodeid'];
         $anchor = 'post' . $node['nodeid'];
     }
     $nodeUrl = vB5_Route::buildUrl($node['routeid'] . '|fullurl', $node, $extra, $anchor);
     // $message should *really* be set by the plaintext parser, which hasn't been
     // brought over from vB4
     $message = vB_String::stripBbcode($node['content']['rawtext'], false, false, false, true);
     $previewtext = vB_String::getPreviewText($message);
     //we need a title otherwise it just doesn't look good
     $title = $node['title'];
     if (!$title and !empty($node['content']['startertitle'])) {
         $title = $node['content']['startertitle'];
     }
     $image_url = '';
     if (!empty($node['content']['previewimage'])) {
         $image_url = $node['content']['previewimage'];
         if (is_numeric($image_url)) {
             $image_url = $options['frontendurl'] . "/filedata/fetch?id={$image_url}&type=thumb";
         }
     }
     return $this->publishMessage('', $title, $nodeUrl, $previewtext, $image_url, $explicit);
 }
Ejemplo n.º 3
0
 /**
  * This lists messages for current user
  *
  * @param mixed- can pass sort direction, type, page, perpage, or folderid.
  * @return mixed - array-includes folderId, title, quantity not read. Also 'page' is array of node records for page 1.
  */
 public function listSpecialPrivateMessages($data = array())
 {
     $params = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_METHOD, 'userid' => vB::getCurrentSession()->get('userid'));
     foreach (array('sortDir', vB_dB_Query::PARAM_LIMITSTART, 'contenttypeid', 'folderid', 'userid') as $param) {
         if (isset($data[$param])) {
             $params[$param] = $data[$param];
         }
     }
     if (isset($params['perpage']) and intval($params['perpage'])) {
         $params[vB_dB_Query::PARAM_LIMIT] = 50;
     } else {
         $params[vB_dB_Query::PARAM_LIMIT] = 50;
     }
     if (empty($params[vB_dB_Query::PARAM_LIMITSTART])) {
         $params[vB_dB_Query::PARAM_LIMITSTART] = 1;
     }
     $messageQry = $this->assertor->assertQuery('vBForum:listSpecialMessages', $params);
     $messages = array();
     if ($messageQry and is_object($messageQry)) {
         foreach ($messageQry as $message) {
             $messages[$message['nodeid']] = $message;
         }
         if (!empty($messages)) {
             $userApi = vB_Api::instanceInternal('user');
             foreach ($messages as $key => $message) {
                 $messages[$key]['senderAvatar'] = $userApi->fetchAvatar($message['userid']);
                 if (empty($message['previewtext'])) {
                     $messages[$key]['previewtext'] = vB_String::getPreviewText($message['rawtext']);
                 }
             }
         }
     }
     return $messages;
 }
Ejemplo n.º 4
0
 /**
  * 	Adds a new node.
  *
  *	@param	mixed		Array of field => value pairs which define the record.
  *	@param	array		Array of options for the content being created.
  *						Understands skipTransaction, skipFloodCheck, floodchecktime, skipDupCheck, skipNotification, nl2br, autoparselinks.
  *							- nl2br: if TRUE, all \n will be converted to <br /> so that it's not removed by the html parser (e.g. comments).
  *	@param	bool		Convert text to bbcode
  *
  * 	@return	mixed		array with nodeid (int), success (bool), cacheEvents (array of strings), nodeVals (array of field => value), attachments (array of attachment records).
  */
 public function add($data, array $options = array(), $convertWysiwygTextToBbcode = true)
 {
     //Store this so we know whether we should call afterAdd()
     $skipTransaction = !empty($options['skipTransaction']);
     $vboptions = vB::getDatastore()->getValue('options');
     $reportemail = ($vboptions['enableemail'] and $vboptions['rpemail']);
     $data['reportnodeid'] = intval($data['reportnodeid']);
     // Build node title based on reportnodeid
     if (!$data['reportnodeid']) {
         throw new vB_Exception_Api('invalid_report_node');
     }
     $data['parentid'] = $this->ReportChannel;
     if (empty($data['title'])) {
         $reportnode = $this->nodeApi->getNodeFullContent($data['reportnodeid']);
         $reportnode = $reportnode[$data['reportnodeid']];
         $phraseapi = vB_Api::instanceInternal('phrase');
         if ($reportnode['nodeid'] == $reportnode['starter']) {
             // Thread starter
             $data['title'] = $reportnode['title'];
         } elseif ($reportnode['parentid'] == $reportnode['starter']) {
             $phrases = $phraseapi->fetch(array('reply_to'));
             $data['title'] = $phrases['reply_to'] . ' ' . $reportnode['startertitle'];
         } else {
             $phrases = $phraseapi->fetch(array('comment_in_a_topic'));
             $data['title'] = $phrases['comment_in_a_topic'] . ' ' . $reportnode['startertitle'];
         }
     }
     $result = parent::add($data, $options, $convertWysiwygTextToBbcode);
     if (!$skipTransaction) {
         //The child classes that have their own transactions all set this to true so afterAdd is always called just once.
         $this->afterAdd($result['nodeid'], $data, $options, $result['cacheEvents'], $result['nodeVals']);
     }
     // send an email
     if ($reportemail) {
         $reporterInfo = vB::getCurrentSession()->fetch_userinfo();
         $nodeLib = vB_Library::instance('node');
         $moderators = array();
         $moderatorUsernames = '';
         // Get moderators on the reported node
         $moderatorsArray = $nodeLib->getNodeModerators($reportnode['nodeid']);
         foreach ($moderatorsArray as $moderator) {
             $moderators[$moderator['userid']] = $moderator['userid'];
         }
         if ($vboptions['rpemail'] == 2) {
             // Fetch admins and super moderators
             $allmoderators = $nodeLib->getForumSupermoderatorsAdmins($moderators);
             foreach ($allmoderators as $moderator) {
                 $moderators[$moderator['userid']] = $moderator['userid'];
             }
         }
         // get user info
         foreach ($moderators as $moderatorid => $moderator) {
             $moderators[$moderatorid] = vB_Library::instance('user')->fetchUserinfo($moderatorid);
             $moderatorUsernames .= $moderators[$moderatorid]['username'] . ', ';
         }
         // Compose the email
         if ($reportnode['starter'] == $reportnode['nodeid']) {
             $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases('reportpost_newthread', array(vB5_Route::buildUrl('profile|fullurl', array('userid' => $reporterInfo['userid'])), $reporterInfo['username'], $data['rawtext'], vB5_Route::buildUrl($reportnode['routeid'] . '|fullurl', array('nodeid' => $reportnode['nodeid'], 'title' => $reportnode['title'])), $reportnode['title'], vB::getDatastore()->getOption('bbtitle'), substr($moderatorUsernames, 0, -2), $reportnode['authorname'], vB5_Route::buildUrl('profile|fullurl', array('userid' => $reportnode['userid'])), vB_String::getPreviewText($reportnode['rawtext'])), array($reporterInfo['username']));
         } else {
             $maildata = vB_Api::instanceInternal('phrase')->fetchEmailPhrases('reportpost', array($reporterInfo['username'], $reporterInfo['email'], $reportnode['title'], vB5_Route::buildUrl($reportnode['routeid'] . '|fullurl', array('nodeid' => $reportnode['starter'], 'userid' => $reportnode['starteruserid'], 'username' => $reportnode['starterauthorname'], 'innerPost' => $reportnode['nodeid'], 'innerPostParent' => $reportnode['parentid'])), $reportnode['startertitle'], vB5_Route::buildUrl($reportnode['routeid'] . '|fullurl', array('nodeid' => $reportnode['starter'], 'title' => $reportnode['startertitle'])), $data['rawtext']), array(vB::getDatastore()->getOption('bbtitle')));
         }
         // Send out the emails
         foreach ($moderators as $moderator) {
             if (!empty($moderator['email'])) {
                 vB_Mail::vbmail($moderator['email'], $maildata['subject'], $maildata['message'], false);
             }
         }
     }
     return $result;
 }
Ejemplo n.º 5
0
 /**
  * Adds a new node.
  *
  * @param	mixed		Array of field => value pairs which define the record.
  *  -- htmlstate
  *  -- parentid
  *  -- disable_bbcode
  *  -- rawtext
  *  -- and others
  * @param	array		Array of options for the content being created
  * 						Understands skipTransaction, skipFloodCheck, floodchecktime, skipDupCheck, skipNotification, nl2br, autoparselinks.
  *							- nl2br: if TRUE, all \n will be converted to <br /> so that it's not removed by the html parser (e.g. comments).
  * @param	bool		Convert text to bbcode
  *
  * 	@return	mixed		array with nodeid (int), success (bool), cacheEvents (array of strings), nodeVals (array of field => value), attachments (array of attachment records).
  */
 public function add($data, array $options = array(), $convertWysiwygTextToBbcode = true)
 {
     //Store this so we know whether we should call afterAdd()
     $skipTransaction = !empty($options['skipTransaction']);
     // html permission already checked in the api
     if (isset($data['htmlstate']) and $data['htmlstate'] == 'on' and isset($data['disable_bbcode']) and $data['disable_bbcode'] == 1) {
         // article 'static html' type
         $convertWysiwygTextToBbcode = false;
         if (isset($options['nl2br'])) {
             $options['nl2br'] = false;
         }
     }
     if (empty($data['parentid'])) {
         throw new Exception('need_parent_node');
     }
     // Get parents for cleaning cache and checking permissions
     $parents = vB_Library::instance('node')->getParents($data['parentid']);
     $parents = array_reverse($parents);
     // convert to bbcode for saving
     if (isset($data['rawtext']) and !empty($data['rawtext'])) {
         // Converts new lines when CKEditor is not in use (plain text area) VBV-11279
         // also used for the mobile app.
         if (isset($options['nl2br']) and $options['nl2br']) {
             $data['rawtext'] = nl2br($data['rawtext']);
         }
         if ($convertWysiwygTextToBbcode) {
             $channelType = vB_Types::instance()->getContentTypeId('vBForum_Channel');
             // check if we can autoparselinks
             $options['autoparselinks'] = true;
             foreach ($parents as $parent) {
                 // currently only groups and blogs seem to disallow this
                 if (($parent['contenttypeid'] == $channelType and vB_Api::instanceInternal('socialgroup')->isSGNode($parent['nodeid']) or vB_Api::instanceInternal('blog')->isBlogNode($parent['nodeid'])) and $channelOptions = vB_Library::instance('node')->getNodeOptions($parent['nodeid'])) {
                     $options['autoparselinks'] = $channelOptions['autoparselinks'];
                 }
             }
             $data['rawtext'] = vB_Api::instanceInternal('bbcode')->convertWysiwygTextToBbcode($data['rawtext'], $options);
             if (empty($data['description'])) {
                 $data['description'] = vB_String::getPreviewText($this->parseAndStrip($data['rawtext']));
             } else {
                 $data['description'] = vB_String::getPreviewText($this->parseAndStrip($data['description']));
             }
         }
     } else {
         if (empty($data['description'])) {
             $data['description'] = isset($data['title']) ? vB_String::getPreviewText($this->parseAndStrip($data['title'])) : '';
         } else {
             $data['description'] = vB_String::getPreviewText($this->parseAndStrip($data['description']));
         }
     }
     if (empty($data['userid'])) {
         $user = vB::getCurrentSession()->fetch_userinfo();
         $data['authorname'] = $user['username'];
         $userid = $data['userid'] = $user['userid'];
     } else {
         $userid = $data['userid'];
         if (empty($data['authorname'])) {
             $data['authorname'] = vB_Api::instanceInternal('user')->fetchUserName($userid);
         }
         $user = vB_Api::instance('user')->fetchUserinfo($userid);
     }
     $userContext = vB::getUserContext($userid);
     $isSpam = false;
     $skipSpam = ($userContext->getChannelPermission('forumpermissions2', 'exemptfromspamcheck', $data['parentid']) or $userContext->getChannelPermission('moderatorpermissions', 'canmoderateposts', $data['parentid']) or isset($options['skipSpamCheck']) and $options['skipSpamCheck'] and vB::getUserContext()->getChannelPermission('moderatorpermissions', 'canmoderateposts', $data['parentid']));
     //run the spam check.
     if (!$skipSpam and $this->spamType !== false) {
         if (empty($this->akismet)) {
             $this->akismet = vB_Akismet::instance();
         }
         $params = array('comment_type' => 'user_post', 'comment_content' => $data['rawtext']);
         $params['comment_author'] = $data['authorname'];
         $params['comment_author_email'] = $user['email'];
         $result = $this->akismet->verifyText($params);
         if ($result == 'spam') {
             $data['approved'] = 0;
             $data['showapproved'] = 0;
             $isSpam = true;
         }
     }
     if (!$skipSpam and !$isSpam and $blacklist = trim($this->options['vb_antispam_badwords'])) {
         $badwords = preg_split('#\\s+#', $blacklist, -1, PREG_SPLIT_NO_EMPTY);
         if (str_replace($badwords, '', strtolower($data['rawtext'])) != strtolower($data['rawtext'])) {
             $data['approved'] = 0;
             $data['showapproved'] = 0;
             $isSpam = true;
         }
     }
     if (!$skipSpam and !$isSpam) {
         preg_match_all('#\\[(url|email).*\\[/(\\1)\\]#siU', $data['rawtext'], $matches);
         if (isset($matches[0]) and count($matches[0]) > intval($this->options['vb_antispam_maxurl'])) {
             $data['approved'] = 0;
             $data['showapproved'] = 0;
             $isSpam = true;
         }
     }
     //We need a copy of the data, maybe
     $updates = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED);
     //Set the "hasvideo" value;
     if (!empty($data['rawtext'])) {
         $filter = '~\\[video.*\\[\\/video~i';
         $matches = array();
         $count = preg_match_all($filter, $data['rawtext'], $matches);
         if ($count > 0) {
             $data['hasvideo'] = 1;
         } else {
             $data['hasvideo'] = 0;
         }
     }
     //publishdate is set in the parent class and api. If not set in data, it'll be set to vB::getRequest()->getTimeNow() in parent::add()
     if (isset($data['publishdate'])) {
         $updates['lastcontent'] = $data['publishdate'];
     } else {
         $updates['lastcontent'] = vB::getRequest()->getTimeNow();
     }
     if (isset($data['userid'])) {
         $updates['lastauthorid'] = $data['userid'];
     } else {
         $updates['lastauthorid'] = $data['userid'] = vB::getCurrentSession()->get('userid');
     }
     if (isset($data['authorname'])) {
         $updates['lastcontentauthor'] = $data['authorname'];
     } else {
         $author = $this->assertor->getRow('user', array(vB_Db_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'userid' => $data['userid']));
         $data['authorname'] = $author['username'];
         $updates['lastcontentauthor'] = $author['username'];
     }
     $published = $this->isPublished($data);
     try {
         if (!$skipTransaction) {
             $this->assertor->beginTransaction();
         }
         $options['skipTransaction'] = true;
         $results = parent::add($data, $options);
         $newNode = $this->getFullContent($results['nodeid']);
         $newNode = array_pop($newNode);
         // Obtain and set generic conversation route
         $conversation = $this->getConversationParent($results['nodeid']);
         $routeid = vB_Api::instanceInternal('route')->getChannelConversationRoute($conversation['parentid']);
         $this->assertor->update('vBForum:node', array('routeid' => $routeid), array('nodeid' => $results['nodeid']));
         if (!$skipTransaction) {
             $this->assertor->commitTransaction();
         }
     } catch (exception $e) {
         if (!$skipTransaction) {
             $this->assertor->rollbackTransaction();
         }
         throw $e;
     }
     //set the last post and count data.
     /* 	We do something similar (vBForum:fixNodeLast) that ends up affect parent last data in the parent add(),
      *	downstream of updateParentCounts(). We should probably refactor to just do it in one place. I tried to
      *	comment this section out, but the node test told me that they're not *quite* the same and this is
      *	necessary.
      */
     $approved = (isset($data['showapproved']) ? $data['showapproved'] : true and isset($data['approved']) ? $data['approved'] : true);
     if ($published and $approved and (!isset($options['skipUpdateLastContent']) or !$options['skipUpdateLastContent'])) {
         $updates['nodeid'] = $results['nodeid'];
         $updates['lastcontentid'] = $results['nodeid'];
         $parentids = array();
         foreach ($parents as $node) {
             $parentids[] = $node['nodeid'];
         }
         $updates['parentlist'] = $parentids;
         $this->qryAfterAdd[] = array('definition' => 'vBForum:setLastDataParentList', 'data' => $updates);
     }
     if (!$skipTransaction) {
         //The child classes that have their own transactions all set this to true so afterAdd is always called just once.
         $this->afterAdd($results['nodeid'], $data, $options, $results['cacheEvents'], $results['nodeVals']);
     }
     if ($isSpam) {
         $this->assertor->assertQuery('spamlog', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERTIGNORE, 'nodeid' => $results['nodeid']));
     }
     $cachedNodes = array($results['nodeid']);
     foreach ($parents as $node) {
         $cachedNodes[] = $node['nodeid'];
     }
     $this->nodeApi->clearCacheEvents($cachedNodes);
     $this->nodeApi->clearCacheEvents(array($results['nodeid'], $data['parentid']));
     return $results;
 }
Ejemplo n.º 6
0
 /**
  * Gets the preview for the messages
  *
  * @return mixed array of record-up to five each messages, then requests, then notifications
  */
 public function previewMessages()
 {
     if (!$this->canUsePmSystem()) {
         throw new vB_Exception_Api('not_logged_no_permission');
     }
     $userid = vB::getCurrentSession()->get('userid');
     $this->library->checkFolders($userid);
     $folders = $this->library->fetchFolders($userid);
     $exclude = array($folders['systemfolders'][vB_Library_Content_Privatemessage::TRASH_FOLDER], $folders['systemfolders'][vB_Library_Content_Privatemessage::NOTIFICATION_FOLDER]);
     $lastnodeidsQry = $this->assertor->getRows('vBForum:lastNodeids', array('userid' => $userid, 'excludeFolders' => $exclude));
     // since the above query might not return anything, if there are no privatemessages for the user, add a -1 to prevent
     // the qryResults query from breaking
     $lastnodeids = array(-1);
     foreach ($lastnodeidsQry as $lastnode) {
         $lastnodeids[] = $lastnode['nodeid'];
     }
     $ignoreUsersQry = $this->assertor->getRows('vBForum:getIgnoredUserids', array('userid' => $userid));
     $ignoreUsers = array(-1);
     foreach ($ignoreUsersQry as $ignoreUser) {
         $ignoreUsers[] = $ignoreUser['userid'];
     }
     $qryResults = $this->assertor->assertQuery('vBForum:pmPreview', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'userid' => $userid, 'ignoreUsers' => $ignoreUsers, 'excludeFolders' => $exclude, 'nodeids' => $lastnodeids));
     $results = array('message' => array('count' => 0, 'title' => vB_Phrase::fetchSinglePhrase('messages'), 'folderid' => 0, 'messages' => array()), 'request' => array('count' => 0, 'title' => vB_Phrase::fetchSinglePhrase('requests'), 'folderid' => 0, 'messages' => array()), 'notification' => array('count' => 0, 'title' => vB_Phrase::fetchSinglePhrase('notifications'), 'folderid' => 0, 'messages' => array()));
     $messageIds = array();
     $nodeIds = array();
     $userIds = array();
     $userApi = vB_Api::instanceInternal('user');
     $receiptDetail = vB::getUserContext()->hasPermission('genericpermissions', 'canseewholiked');
     $needLast = array();
     if ($qryResults->valid()) {
         foreach ($qryResults as $result) {
             if (empty($result['previewtext'])) {
                 $result['previewtext'] = vB_String::getPreviewText($result['rawtext']);
             }
             if ($result['titlephrase'] == 'messages') {
                 $messageIds[] = $result['nodeid'];
             } else {
                 $nodeIds[] = $result['nodeid'];
             }
             // privatemessage_requestdetail template requires you to pass back the phrase name for requests.
             // See listRequests() for more details
             if ($result['msgtype'] == 'request') {
                 // remove starting sg_ and ending _to from the about string
                 $cleanAboutStr = preg_replace('/(^sg_)?|(_to$)?/', '', $result['about']);
                 $result['phrasename'] = 'received_' . $cleanAboutStr . '_request_from_x_link_y';
                 // grab channel request types
                 $channelRequests = $this->library->getChannelRequestTypes();
                 // append correct suffix for channel requests
                 if (in_array($result['about'], $channelRequests)) {
                     // should have a "_to_channel_z" (take request) or "_for_channel_z" (grant request) appended
                     if (strpos($result['about'], '_to') !== false) {
                         $result['phrasename'] .= '_to_channel_z';
                     } else {
                         $result['phrasename'] .= '_for_channel_z';
                     }
                 }
             }
             $result['senderAvatar'] = $userApi->fetchAvatar($result['userid']);
             $result['recipients'] = array();
             $result['otherRecipients'] = 0;
             $result['responded'] = 0;
             $results[$result['msgtype']]['messages'][$result['nodeid']] = $result;
             $results[$result['msgtype']]['count']++;
             $userIds[] = $result['userid'];
             if (intval($result['lastauthorid'])) {
                 $userIds[] = $result['lastauthorid'];
             }
             if (!$results[$result['msgtype']]['folderid']) {
                 $results[$result['msgtype']]['folderid'] = $result['folderid'];
             }
             // set recipients needed
             if ($result['msgtype'] == 'message') {
                 if (empty($result['lastauthorid']) or $result['lastauthorid'] == $userid) {
                     $needLast[] = $result['nodeid'];
                 }
             }
         }
         // @TODO check for a way to implement a generic protected library method to fetch recipients instead of cloning code through methods.
         // drag the needed info
         if (!empty($needLast)) {
             $needLast = array_unique($needLast);
             $neededUsernames = $this->assertor->assertQuery('vBForum:getPMLastAuthor', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'nodeid' => $needLast, 'userid' => $userid));
             foreach ($neededUsernames as $username) {
                 if (isset($results['message']['messages'][$username['nodeid']])) {
                     $results['message']['messages'][$username['nodeid']]['lastcontentauthor'] = $username['username'];
                     $results['message']['messages'][$username['nodeid']]['lastauthorid'] = $username['userid'];
                 }
             }
         }
         //Now we need to sort out the other recipients for this message.
         $recipients = array();
         if (!empty($nodeIds)) {
             $recipientQry = $this->assertor->assertQuery('vBForum:getPMRecipients', array('nodeid' => array_unique($nodeIds), 'userid' => $userid));
             foreach ($recipientQry as $recipient) {
                 $recipients[$recipient['nodeid']][$recipient['userid']] = $recipient;
             }
         }
         $messageRecipients = array();
         if (!empty($messageIds)) {
             $recipientsInfo = $this->assertor->assertQuery('vBForum:getPMRecipientsForMessage', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'nodeid' => $messageIds));
             $recipients = array();
             if (!empty($recipientsInfo)) {
                 foreach ($recipientsInfo as $recipient) {
                     if (isset($results['message']['messages'][$recipient['starter']])) {
                         if ($recipient['userid'] == $userid) {
                             if (empty($results['message']['messages'][$recipient['starter']]['included'])) {
                                 $results['message']['messages'][$recipient['starter']]['included'] = true;
                             }
                             continue;
                         } else {
                             if ($results['message']['messages'][$recipient['starter']]['lastcontentauthor'] == $recipient['username']) {
                                 continue;
                             }
                         }
                         if (!isset($results['message']['messages'][$recipient['starter']]['recipients'][$recipient['userid']])) {
                             $results['message']['messages'][$recipient['starter']]['recipients'][$recipient['userid']] = $recipient;
                         }
                     }
                 }
             }
         }
         //Collect the user info. Doing it this way we get a lot of info in one query.
         $userQuery = $this->assertor->assertQuery('user', array('userid' => array_unique($userIds)));
         $userInfo = array();
         $userApi = vB_Api::instanceInternal('user');
         foreach ($userQuery as $userRecord) {
             //some information we shouldn't pass along.
             foreach (array('token', 'scheme', 'secret', 'coppauser', 'securitytoken_raw', 'securitytoken', 'logouthash', 'fbaccesstoken', 'passworddate', 'parentemail', 'logintype', 'ipaddress', 'passworddate', 'referrerid', 'ipoints', 'infractions', 'warnings', 'infractiongroupids', 'infractiongroupid') as $field) {
                 unset($userRecord[$field]);
             }
             $userRecord['avatar'] = $userApi->fetchAvatar($userRecord['userid'], true, $userRecord);
             $userInfo[$userRecord['userid']] = $userRecord;
         }
         //Now we need to scan the results list and assign the other recipients.
         foreach ($results as $key => $folder) {
             foreach ($folder['messages'] as $msgkey => $message) {
                 if ($message['titlephrase'] == 'messages') {
                     // set the first recipient
                     if (!empty($message['lastcontentauthor']) and !empty($message['lastauthorid']) and $message['lastauthorid'] != $userid) {
                         $results[$key]['messages'][$msgkey]['firstrecipient'] = array('userid' => $message['lastauthorid'], 'username' => $message['lastcontentauthor']);
                     } else {
                         if (!empty($message['recipients'])) {
                             $firstrecip = reset($message['recipients']);
                             $results[$key]['messages'][$msgkey]['firstrecipient'] = $firstrecip;
                             unset($results[$key]['messages'][$msgkey]['recipients'][$firstrecip['userid']]);
                         }
                     }
                     $results[$key]['messages'][$msgkey]['otherRecipients'] = count($results[$key]['messages'][$msgkey]['recipients']);
                 } else {
                     if (!empty($recipients[$message['nodeid']])) {
                         $results[$key]['messages'][$msgkey]['recipients'] = $recipients[$message['nodeid']];
                         $results[$key]['messages'][$msgkey]['otherRecipients'] = count($recipients[$message['nodeid']]);
                         $results[$key]['messages'][$msgkey]['userinfo'] = $userInfo[$message['userid']];
                     }
                 }
                 if ($message['lastauthorid']) {
                     $results[$key]['messages'][$msgkey]['lastauthor'] = $userInfo[$message['lastauthorid']]['username'];
                     $results[$key]['messages'][$msgkey]['lastcontentauthorid'] = $message['lastauthorid'];
                     $results[$key]['messages'][$msgkey]['lastcontentavatar'] = $userInfo[$message['lastauthorid']]['avatar'];
                 }
             }
             if (empty($message['previewtext'])) {
                 $results[$key]['previewtext'] = vB_String::getPreviewText($message['rawtext']);
             }
         }
     }
     $channelRequests = $this->library->getChannelRequestTypes();
     $nodeIds = array();
     foreach ($results['request']['messages'] as $message) {
         if (in_array($message['about'], $channelRequests)) {
             $nodeIds[] = $message['aboutid'];
         }
     }
     if (!empty($nodeIds)) {
         $nodesInfo = vB_Library::instance('node')->getNodes($nodeIds);
         $arrayNodeInfo = array();
         foreach ($nodesInfo as $node) {
             $arrayNodeInfo[$node['nodeid']] = array('title' => $node['title'], 'routeid' => $node['routeid']);
         }
         foreach ($results['request']['messages'] as $key => &$val) {
             if (isset($arrayNodeInfo[$val['aboutid']])) {
                 $val['abouttitle'] = $arrayNodeInfo[$val['aboutid']]['title'];
                 $val['aboutrouteid'] = $arrayNodeInfo[$val['aboutid']]['routeid'];
             }
         }
     }
     // add notifications
     $params = array('showdetail' => $receiptDetail, 'perpage' => 5, 'page' => 1, 'sortDir' => "DESC");
     $notifications = vB_Library::instance('notification')->fetchNotificationsForCurrentUser($params);
     $results['notification']['messages'] = $notifications;
     $results['notification']['count'] = count($notifications);
     $results['notification']['folderid'] = $folders['systemfolders'][vB_Library_Content_Privatemessage::NOTIFICATION_FOLDER];
     return $results;
 }