Пример #1
0
 /**
  * Creates a new redirect 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).
  */
 public function add($data, array $options = array(), $convertWysiwygTextToBbcode = false)
 {
     $options['skipFloodCheck'] = true;
     $options['skipDupCheck'] = true;
     $options['skipNotification'] = true;
     $options['skipUpdateLastContent'] = true;
     return parent::add($data, $options, $convertWysiwygTextToBbcode);
 }
Пример #2
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	array	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)
 {
     try {
         //Store this so we know whether we should call afterAdd()
         $skipTransaction = !empty($options['skipTransaction']);
         if (!$skipTransaction) {
             $this->assertor->beginTransaction();
         }
         $options['skipTransaction'] = true;
         $result = parent::add($data, $options, $convertWysiwygTextToBbcode);
         // @todo is this not already done in the vB_Library_Content_Text class?
         //We want to save in one batch. Otherwise if moderation is set the attached photos will be lost.
         //See VBV-12360
         if (is_int($result['nodeid']) and !empty($data['photos'])) {
             // Note, photos' data are now cleaned at the vB_Api_Content_Text level in cleanInput()
             if (!empty($data['photos']) and is_array($data['photos'])) {
                 $photoLib = vB_Library::instance('content_photo');
                 $node = $this->getFullContent($result['nodeid']);
                 $node = array_pop($node);
                 $published = $node['showpublished'];
                 foreach ($data['photos'] as $photo) {
                     $photo['parentid'] = $result['nodeid'];
                     $photo['showpublished'] = $published;
                     $photo['showapproved'] = $published;
                     if (!isset($photo['options'])) {
                         $photo['options'] = $options;
                     }
                     //We must have skipTransaction set or the photo api will attempt to start a transaction and cause an exception
                     $photo['options']['skipTransaction'] = true;
                     $photoLib->add($photo, $photo['options']);
                 }
             }
         }
         // Obtain and set generic conversation route
         $conversation = $this->getConversationParent($result['nodeid']);
         $routeid = vB_Api::instanceInternal('route')->getChannelConversationRoute($conversation['parentid']);
         $this->assertor->update('vBForum:node', array('routeid' => $routeid), array('nodeid' => $result['nodeid']));
         if (!$skipTransaction) {
             $this->assertor->commitTransaction();
         }
     } catch (exception $e) {
         if (!$skipTransaction) {
             $this->assertor->rollbackTransaction();
         }
         throw $e;
     }
     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']);
     }
     //basic cache events are cleared in the parent class
     return $result;
 }
Пример #3
0
 /**
  * Adds a new node.
  *
  * @param	mixed		Array of field => value pairs which define the record.
  * 						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)
 {
     // TODO: Permission check
     //		$loginuser = &vB::getCurrentSession()->fetch_userinfo();
     //		$usercontext = &vB::getUserContext($loginuser['userid']);
     //		if (!$usercontext->hasPermission('forumpermissions', 'canpostvideo'))
     //		{
     //			throw new Exception('no_permission');
     //		}
     //Store this so we know whether we should call afterAdd()
     $skipTransaction = !empty($options['skipTransaction']);
     $videoitems = $this->checkVideoData($data);
     unset($data['videoitems']);
     if (!$videoitems) {
         throw new vB_Exception_Api("invalid_videoitems");
     }
     try {
         if (!$skipTransaction) {
             $this->assertor->beginTransaction();
         }
         $options['skipTransaction'] = true;
         $result = parent::add($data, $options, $convertWysiwygTextToBbcode);
         // Save video items
         foreach ($videoitems as $item) {
             $this->assertor->assertQuery("videoitem", array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'nodeid' => $result['nodeid'], 'provider' => $item['provider'], 'code' => $item['code'], 'url' => $item['url']));
         }
         if (!$skipTransaction) {
             $this->assertor->commitTransaction();
         }
     } catch (exception $e) {
         if (!$skipTransaction) {
             $this->assertor->rollbackTransaction();
         }
         throw $e;
     }
     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']);
     }
     //indexing is done in the parent class
     return $result;
 }
Пример #4
0
 public function add($data, array $options = array(), $convertWysiwygTextToBbcode = true)
 {
     //Store this so we know whether we should call afterAdd()
     $skipTransaction = !empty($options['skipTransaction']);
     $this->checkPollOptions($data);
     // Add the poll options (answers) to the standard content add method $options array
     $options = array_merge($data['options'], $options);
     // Keep an array of *only* the poll options, without the other options in the standard array
     $pollOptions = $data['options'];
     if (isset($data['parseurl'])) {
         $parseurl = $data['parseurl'];
         if ($parseurl) {
             require_once DIR . '/includes/functions_newpost.php';
         }
     }
     unset($data['options'], $data['parseurl']);
     // skip the index in the parent and do it here so it can include the options
     $data['noIndex'] = true;
     try {
         if (!$skipTransaction) {
             $this->assertor->beginTransaction();
         }
         $options['skipTransaction'] = true;
         $result = parent::add($data, $options, $convertWysiwygTextToBbcode);
         // Save poll options
         foreach ($pollOptions as $option) {
             if (isset($parseurl) and $parseurl) {
                 $option['title'] = convert_url_to_bbcode($option['title']);
             }
             // Insert new option
             $this->assertor->assertQuery('vBForum:polloption', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'nodeid' => $result['nodeid'], 'title' => $option['title']));
         }
         if (!$skipTransaction) {
             $this->assertor->commitTransaction();
         }
     } catch (exception $e) {
         if (!$skipTransaction) {
             $this->assertor->rollbackTransaction();
         }
         throw $e;
     }
     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']);
     }
     $this->updatePollCache($result['nodeid']);
     // do the indexing after the options are added
     $this->nodeApi->clearCacheEvents(array($result['nodeid'], $data['parentid']));
     vB_Api::instance('Search')->index($result['nodeid']);
     return $result;
 }
Пример #5
0
 /**
  * Adds a new infraction 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).
  * 	@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']);
     $infractionLevels = $this->getInfractionLevels();
     $this->validateInfractionData($data, $infractionLevels);
     //An infraction should never be rejected because of duplication.
     $options['skipDupCheck'] = true;
     $infractedNode = $this->getInfractedNode($data);
     $infractedUserInfo = vB_User::fetchUserinfo($data['infracteduserid']);
     $infractionLevelInfo = $this->getInfractionLevelInfo($data, $infractionLevels);
     $isWarning = $this->isWarning($data, $infractionLevelInfo);
     $banToApply = $this->getAutomaticBanToApply($infractedUserInfo, $data, $infractionLevelInfo, $isWarning);
     // set infraction level info
     $data['points'] = $isWarning ? 0 : $infractionLevelInfo['points'];
     $data['reputation_penalty'] = $isWarning ? 0 : $infractionLevelInfo['reputation_penalty'];
     $data['expires'] = $this->getExpires($infractionLevelInfo, $data['infracteduserid']);
     $data['customreason'] = !empty($data['customreason']) ? $data['customreason'] : '';
     // make sure we have something for admin note and pm message
     $data['note'] = empty($data['note']) ? '' : $data['note'];
     $data['message'] = empty($data['message']) ? '' : $data['message'];
     // set parentid
     $data['parentid'] = $this->infractionChannel;
     // set title & pagetext
     $data['title'] = $this->getInfractionTitle($data, $infractedNode, $infractedUserInfo, $infractionLevelInfo, $isWarning);
     $data['rawtext'] = $this->getInfractionPagetext($data, $infractedNode, $infractedUserInfo, $infractionLevelInfo);
     try {
         if (!$skipTransaction) {
             $this->assertor->beginTransaction();
         }
         $options['skipTransaction'] = true;
         // *** add the infraction and populate the return info***
         $result = parent::add($data, $options, $convertWysiwygTextToBbcode);
         $result['infractionNodeid'] = $result['nodeid'];
         $result['isWarning'] = $isWarning ? 1 : 0;
         // applying the reputation penalty
         if ($data['reputation_penalty']) {
             $this->assertor->assertQuery('decUserReputation', array('penalty' => $data['reputation_penalty'], 'userid' => $infractedUserInfo['userid']));
             vB_Cache::allCacheEvent('userChg_' . $infractedUserInfo['userid']);
         }
         // invalidate cache
         $clearCacheNodeIds = array($data['parentid']);
         if (!$skipTransaction) {
             $this->assertor->commitTransaction();
         }
     } catch (exception $e) {
         if (!$skipTransaction) {
             $this->assertor->rollbackTransaction();
         }
         throw $e;
     }
     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']);
     }
     // update denormalized values
     if (empty($result['errors'])) {
         if ($data['infractednodeid']) {
             // mark the infracted node's text record as having an infraction or warning
             // 1 = infraction, 2 = warning, 0 = no infraction or warning (or an expired/reversed infraction)
             $this->assertor->update('vBforum:text', array('infraction' => $isWarning ? 2 : 1), array('nodeid' => $data['infractednodeid']));
         }
         // update user info for infractions, warnings, and ipoints
         $this->updateDenormalizedUserData($data['infracteduserid']);
         // update infractiongroupids
         $this->buildInfractionGroupIds(array($infractedUserInfo['userid']));
         // send PM to infracted user
         if (!empty($data['message'])) {
             $result['pmNodeid'] = $this->sendPm($data, $infractedNode, $infractedUserInfo, $infractionLevelInfo, $isWarning, $banToApply);
         }
         $clearCacheNodeIds[] = $result['nodeid'];
         $clearCacheNodeIds[] = $data['infractednodeid'];
     }
     // ban user if applicable
     if ($banToApply) {
         $this->applyAutomaticBan($infractedUserInfo, $banToApply, $data);
     }
     $this->nodeApi->clearCacheEvents($clearCacheNodeIds);
     return $result;
 }
Пример #6
0
 /**
  * This adds a new message
  *
  * @param	mixed	must include 'sentto', 'contenttypeid', and the necessary data for that contenttype.
  * @param	array	Array of options for the content being created.
  * 						Understands skipTransaction, skipFloodCheck, floodchecktime, skipDupCheck, skipNotification, nl2br, autoparselinks, skipNonExistentRecipients.
  *							- nl2br: if TRUE, all \n will be converted to <br /> so that it's not removed by the html parser (e.g. comments).
  *						- skipNonExistentRecipients (bool) skips recipients that don't exist instead of throwing an exception.
  *
  * 	@return	mixed		array with errors, or nodeid.
  *
  * Notes: 		For Notifications, go through the notification library.
  **/
 public function add($data, array $options = array(), $convertWysiwygTextToBbcode = true)
 {
     //If we're installing, just abort.
     if (defined('VBINSTALL')) {
         return true;
     }
     //Store this so we know whether we should call afterAdd()
     $skipTransaction = !empty($options['skipTransaction']);
     $sender = $data['sender'];
     if (isset($data['msgRecipients']) and empty($data['sentto'])) {
         $recipientNames = explode(',', $data['msgRecipients']);
         foreach ($recipientNames as $k => $name) {
             $recipientNames[$k] = vB_String::htmlSpecialCharsUni($name);
         }
         $recipQry = $this->assertor->getRows('fetchPmRecipients', array('usernames' => $recipientNames, 'userid' => $sender));
         if (!$recipQry or !empty($recipQry['errors'])) {
             throw new vB_Exception_Api('invalid_pm_recipients');
         }
         foreach ($recipQry as $recipient) {
             $this->checkCanReceivePM($recipient);
             $data['sentto'][] = $recipient['userid'];
         }
     }
     if (!isset($data['msgtype']) or $data['msgtype'] != 'request' and $data['msgtype'] != 'notification') {
         $data['msgtype'] = 'message';
     } else {
         if ($data['msgtype'] == 'notification') {
             if (empty($data['about']) or empty($data['aboutid']) or empty($data['sentto'])) {
                 throw new vB_Exception_Api('invalid_data');
             }
         }
     }
     //If we have a message we need text content
     if ($data['msgtype'] == 'message' and (empty($data['rawtext']) and empty($data['pagetext']))) {
         throw new vB_Exception_Api('need_privatemessage_text');
     }
     if ($data['msgtype'] == 'request' and (empty($data['rawtext']) and empty($data['pagetext'])) and !empty($data['sentto'])) {
         $recipient = vB_User::fetchUserinfo($data['sentto']);
         switch ($data['about']) {
             case vB_Api_Node::REQUEST_TAKE_OWNER:
                 $channel = vB_Library::instance('node')->getNodeBare($data['aboutid']);
                 $phrase = vB_Api::instanceInternal('phrase')->fetch(array('sent_ownership_transfer_request_for_x_to_y'));
                 $data['rawtext'] = $data['pagetext'] = vsprintf($phrase['sent_ownership_transfer_request_for_x_to_y'], array($channel['title'], $recipient['username']));
                 break;
             case vB_Api_Node::REQUEST_TAKE_MODERATOR:
                 $channel = vB_Library::instance('node')->getNodeBare($data['aboutid']);
                 $phrase = vB_Api::instanceInternal('phrase')->fetch(array('sent_moderation_request_for_x_to_y'));
                 $data['rawtext'] = $data['pagetext'] = vsprintf($phrase['sent_moderation_request_for_x_to_y'], array($channel['title'], $recipient['username']));
                 break;
             case vB_Api_Node::REQUEST_GRANT_MEMBER:
                 $channel = vB_Library::instance('node')->getNodeBare($data['aboutid']);
                 $phrase = vB_Api::instanceInternal('phrase')->fetch(array('sent_subscription_request_to_x'));
                 $data['rawtext'] = $data['pagetext'] = vsprintf($phrase['sent_subscription_request_to_x'], $channel['title']);
                 break;
             case vB_Api_Node::REQUEST_SG_GRANT_SUBSCRIBER:
                 $channel = vB_Library::instance('node')->getNodeBare($data['aboutid']);
                 $phrase = vB_Api::instanceInternal('phrase')->fetch(array('sent_subscription_request_to_x'));
                 $data['rawtext'] = $data['pagetext'] = vsprintf($phrase['sent_subscription_request_to_x'], $channel['title']);
                 break;
             default:
                 $phrase = vB_Api::instanceInternal('phrase')->fetch(array('sent_follow_request_to_x'));
                 $data['rawtext'] = $data['pagetext'] = vsprintf($phrase['sent_follow_request_to_x'], $recipient['username']);
                 break;
         }
     }
     // don't check the skipNonExistentRecipients option since
     // we're actually checking the *sender's* folders here.
     // I have added this option because of upgrade failure in specific circumstances described in VBV-13331
     $skipNonExistentRecipients = !empty($options['skipNonExistentRecipients']);
     $this->checkFolders($sender, $skipNonExistentRecipients);
     $sendto = array();
     if (isset($data['respondto'])) {
         //We have a forward/reply. We maintain the node hierarchy. If it's a reply
         // we also need to keep the list of recipients.
         $data['parentid'] = $data['respondto'];
         //Obviously we've read this, if we're forwarding it.
         $this->setRead($data['respondto'], 1, $sender);
         $recipients = $this->assertor->getRows('vBForum:getRecipientsForNode', array('nodeid' => $data['respondto']));
         $msgSender = 0;
         $senderIncluded = false;
         foreach ($recipients as $recipient) {
             if ($msgSender) {
                 continue;
             }
             if ($recipient['folder'] == self::SENT_FOLDER) {
                 $msgSender = $recipient['userid'];
             }
         }
         foreach ($recipients as $recipient) {
             $this->checkCanReceivePM($recipient);
             if ($recipient['userid'] == $msgSender and $recipient['folder'] != self::SENT_FOLDER) {
                 $senderIncluded = true;
             }
             $data['sentto'][] = intval($recipient['userid']);
         }
     } else {
         if (isset($data['forward'])) {
             if (empty($data['sentto'])) {
                 throw new vB_Exception_Api('invalid_request');
             }
             $data['parentid'] = $this->pmChannel;
             //Obviously we've read this, if we're forwarding it.
             $this->setRead($data['forward'], 1, $sender);
         } else {
             //We'll get the folders into which we need to insert this record. In the process we'll
             // validate that all the sentto id's are valid.
             $data['parentid'] = $this->pmChannel;
         }
     }
     if (empty($data['sentto'])) {
         throw new vB_Exception_Api('invalid_data');
     }
     if (!is_array($data['sentto'])) {
         $sendto = array($data['sentto']);
     } else {
         $sendto = array_unique($data['sentto']);
     }
     //We can't pass recipients to the parent add method.
     $data['userid'] = $sender;
     $fields = array('parentid', 'rawtext', 'pagetext', 'msgtype', 'title', 'userid', 'about', 'aboutid', 'folderid', 'deleted', 'msgread', 'publishdate', 'url', 'filedataid', 'url_title', 'url_meta', 'url_image', 'attachments');
     $contentData = array();
     foreach ($fields as $field) {
         if (isset($data[$field])) {
             $contentData[$field] = $data[$field];
         }
     }
     try {
         $options['skipTransaction'] = true;
         // create the node, unless it's a notification
         if (!($data['msgtype'] == 'notification')) {
             if (!$skipTransaction) {
                 $this->assertor->beginTransaction();
             }
             $result = parent::add($contentData, $options, $convertWysiwygTextToBbcode);
         } else {
             // USE THE NOTIFICATION LIBRARY
             throw new vB_Exception_Api('invalid_data');
         }
         if (!$result or !empty($result['errors']) or !intval($result['nodeid'])) {
             if (!$skipTransaction) {
                 $this->assertor->rollbackTransaction();
             }
             throw new vB_Exception_Api('invalid_data');
         }
         if (!$skipTransaction) {
             $this->assertor->commitTransaction();
         }
     } catch (exception $e) {
         if (!$skipTransaction) {
             $this->assertor->rollbackTransaction();
         }
         throw $e;
     }
     $nodeid = $result['nodeid'];
     //If we are passed 'request', then this is just inserted for the recipient. But the user must be an admin.
     $insertSent = false;
     if ($data['msgtype'] == 'notification') {
         // USE THE NOTIFICATION LIBRARY
         throw new vB_Exception_Api('invalid_request');
         //$folderKey = self::NOTIFICATION_FOLDER;
     } else {
         if ($data['msgtype'] == 'request') {
             $folderKey = self::REQUEST_FOLDER;
         } else {
             $folderKey = self::MESSAGE_FOLDER;
             $insertSent = true;
         }
     }
     $userOptions = vB::getDatastore()->getValue('bf_misc_useroptions');
     //Note that if this is a response, sendto is empty.
     foreach ($sendto as $recipient) {
         // verify recipient's folders, but instruct checkFolders to not throw
         // an exception if we have an invalid recipient
         $folderCheck = $this->checkFolders($recipient, $skipNonExistentRecipients);
         if ($skipNonExistentRecipients and isset($folderCheck['result']) and $folderCheck['result'] === 'user_skipped') {
             // bad recipient; skip this notification and continue
             continue;
         }
         $sendData = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'userid' => $recipient, 'nodeid' => $result['nodeid'], 'folderid' => $this->folders[$recipient]['systemfolders'][$folderKey]);
         // create a sentto record only if it's not an existing notification
         if (!($data['msgtype'] == 'notification' and ($existingNotification and !empty($existingNotification) and empty($existingNotification['errors'])))) {
             $this->assertor->assertQuery('vBForum:sentto', $sendData);
         }
         // Going through user LIB not API. The API will mask the email field unless current user
         // has canadminusers.
         $recipientInfo = vB_Library::instance('User')->fetchUserinfo($recipient);
         $emailOnPm = $recipientInfo['options'] & $userOptions['emailonpm'];
         if ($recipientInfo['emailnotification'] == 1) {
             if ($contentData['msgtype'] == 'request') {
                 $contentData['sentto'] = $data['sentto'];
                 $contentData['folderid'] = $this->folders[$recipient]['systemfolders'][$folderKey];
                 $contentData['email'] = $recipientInfo['email'];
                 $contentData['username'] = $recipientInfo['username'];
                 $this->sendEmailNotification($contentData);
             }
         }
         // only send email about PM if this is a message, recipient isn't the sender &  the recipient opted in.
         $sendPMEmail = ($data['msgtype'] == 'message' and $recipient != vB::getCurrentSession()->get('userid') and $emailOnPm);
         if ($sendPMEmail) {
             $data['folderid'] = $this->folders[$recipient]['systemfolders'][$folderKey];
             $data['recipient'] = $recipient;
             $data['contentid'] = $result['nodeid'];
             $data['email'] = $recipientInfo['email'];
             $data['username'] = $recipientInfo['username'];
             $this->sendEmailNotification($data);
         }
     }
     // insert message starter for sender if needed
     if (isset($data['respondto']) and $data['respondto'] and ($msgSender and !$senderIncluded)) {
         // don't check the skipNonExistentRecipients option since
         // we're actually checking the *sender's* folders here.
         // I added the flag bacause update failures described in VBV-13331
         $this->checkFolders($msgSender, $skipNonExistentRecipients);
         $sendData = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'userid' => $msgSender, 'nodeid' => $data['respondto'], 'folderid' => $this->folders[$msgSender]['systemfolders'][$folderKey], 'msgread' => 1);
         $this->assertor->assertQuery('vBForum:sentto', $sendData);
     }
     //If this is a new message, we also insert a "sentto" record for the sender, but we mark that "read".
     //That ensures we properly handle replies.
     if (!in_array($data['msgtype'], array('notification', 'request'))) {
         //If someone deleted their message we need to restore it. For that we need the starter.
         //This can only occur, of course, if this is a response.
         $existing = $this->nodeApi->getNode($data['parentid']);
         // only check the "trash" and "messages" folders for everyone. We don't want to accidentally change
         // something in the sent_items folder, for instance
         $includeFoldersQry = $this->assertor->getRows('vBForum:messagefolder', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'titlephrase' => array(self::TRASH_FOLDER, self::MESSAGE_FOLDER), vB_Db_Query::COLUMNS_KEY => array('folderid')));
         $includeFolders = array(-1);
         // -1 so that array is not empty. Other wise IN clause breaks
         foreach ($includeFoldersQry as $includeFolder) {
             $includeFolders[] = $includeFolder['folderid'];
         }
         $queryData = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'nodeid', 'value' => $existing['starter']), array('field' => 'userid', 'value' => $sender, 'operator' => vB_dB_Query::OPERATOR_NE), 'folderid' => $includeFolders), 'msgread' => 0, 'deleted' => 0);
         $this->assertor->assertQuery('vBForum:sentto', $queryData);
         // @TODO : Shouldn't we move the "restored" messages back to the inbox...?
         $this->setRead($nodeid, 1, $sender, 'sent_items');
     }
     if ($insertSent) {
         // don't check the skipNonExistentRecipients option since
         // we're actually checking the *sender's* folders here.
         $this->checkFolders($sender, $skipNonExistentRecipients);
         $queryData = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'userid' => $sender, 'nodeid' => $result['nodeid'], 'folderid' => $this->folders[$sender]['systemfolders'][self::SENT_FOLDER], 'msgread' => 1);
         $this->assertor->assertQuery('vBForum:sentto', $queryData);
     }
     $sendto[] = $sender;
     // duplicate ids is fine in this array
     $this->buildPmTotals($sendto);
     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']);
     }
     vB_Api::instance('Search')->index($result['nodeid']);
     //update user cached info
     if ($folderKey == self::MESSAGE_FOLDER) {
         vB_Library::instance('user')->clearUserInfo($sendto);
     }
     return $result;
 }
Пример #7
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;
 }
Пример #8
0
 public function add($data, array $options = array(), $convertWysiwygTextToBbcode = true)
 {
     $this->validateLinkData($data, __FUNCTION__);
     //Store this so we know whether we should call afterAdd()
     $skipTransaction = !empty($options['skipTransaction']);
     /** Validate Filedata */
     if (!empty($data["filedataid"])) {
         $this->validateFileData($data['filedataid']);
     }
     // increment refcount for the image (if it has one)
     if ($data['filedataid'] > 0) {
         vB::getDbAssertor()->assertQuery('updateFiledataRefCount', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'countChange' => 1, 'filedataid' => $data["filedataid"]));
     }
     $options['skipTransaction'] = true;
     $result = parent::add($data, $options, $convertWysiwygTextToBbcode);
     //indexing and cache clear are done in the parent
     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']);
     }
     return $result;
 }