Пример #1
0
 /**
  * This takes a list of nodes, and returns node records for all that are valid nodeids.
  *
  * 	@param mixed $nodeList array of ints
  *	@param bool $withJoinableContent Include joinable content
  *
  *	@return array list of node records
  **/
 protected function cleanNodeList(&$nodeList, $withJoinableContent = false)
 {
     if (!is_array($nodeList)) {
         $nodeList = array($nodeList);
     }
     $nodeList = array_unique($nodeList);
     //many of them may be in cache.
     $cached = vB_Library_Content::fetchFromCache($nodeList, vB_Library_Content::CACHELEVEL_NODE);
     $listIndex = array_flip($nodeList);
     if (!empty($cached['found'])) {
         foreach ($cached['found'] as $node) {
             $nodeid = $node['nodeid'];
             if (isset($listIndex[$nodeid])) {
                 $nodeList[$listIndex[$nodeid]] = $node;
                 unset($listIndex[$nodeid]);
             }
         }
     }
     if (!empty($cached['notfound'])) {
         if ($withJoinableContent) {
             $nodes = vB::getDbAssertor()->assertQuery('vBForum:fetchNodeWithContent', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_METHOD, 'nodeid' => $cached['notfound']));
         } else {
             $nodes = vB::getDbAssertor()->assertQuery('vBForum:node', array('nodeid' => $cached['notfound']));
         }
         foreach ($nodes as $node) {
             $nodeid = $node['nodeid'];
             if (isset($listIndex[$nodeid])) {
                 $nodeList[$listIndex[$nodeid]] = $node;
                 unset($listIndex[$nodeid]);
             }
         }
     }
     //if we filtered out a node in the query, remove it from the list.
     foreach ($listIndex as $key => $value) {
         unset($nodeList[$value]);
     }
 }
Пример #2
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);
     }
 }