예제 #1
0
 protected function validateAndCleanNotificationData($notificationData)
 {
     // Very similar to the vB_Notification_Content, but has to skip the "channel" check since
     // VM's go to their own channel. Instead, there's a isVisitorMessage() check.
     $newData = parent::validateAndCleanNotificationData($notificationData);
     unset($notificationData);
     if (!isset($newData['sentbynodeid'])) {
         throw new Exception("Missing Notification Data: sentbynodeid");
     }
     $nodeid = $newData['sentbynodeid'];
     $node = vB_Library::instance('node')->getNode($nodeid, false, true);
     // we need to get the full content, to ensure 'channeltype' is there.
     if (!isset($node['nodeid'])) {
         throw new Exception("Invalid Notification Data: sentbynodeid");
     }
     if (!isset($node['setfor'])) {
         throw new Exception("Invalid Node Data: setfor");
     }
     // only explictly specified content types are allowed to send notifications
     $topLevelContentTypes = array('Gallery' => 1, 'Link' => 1, 'Poll' => 1, 'Text' => 1, 'Video' => 1);
     $contenttypeclass = vB_Types::instance()->getContentTypeClass($node['contenttypeid']);
     if (!isset($topLevelContentTypes[$contenttypeclass])) {
         throw new Exception("Cannot send this notification for the node's content type.");
     }
     // Only allow visitor messages.
     /*
     // node lib's fetchClosureParent() does not seem functional for the 2nd param that content lib's isVisitorMessage()
     // relies on, VBV-14367. Let's just check the closure table directly for now.
     $contentLib = vB_Library::instance('Content_' . vB_Types::instance()->getContentTypeClass($node['contenttypeid']));
     if (!$contentLib->isVisitorMessage($nodeid))
     {
     	throw new Exception("Not a visitor message.");
     }
     */
     $vmChannel = vB_Library::instance('node')->fetchVMChannel();
     $closureCheck = vB::getDbAssertor()->getRows('vBForum:closure', array('child' => $nodeid, 'parent' => $vmChannel));
     if (empty($closureCheck)) {
         throw new Exception("Not a visitor message.");
     }
     // We're good if we got to this point.
     $newData['sentbynodeid'] = (int) $node['nodeid'];
     if (!isset($node['userid'])) {
         throw new Exception("Invalid Notification Data: sentbynodeid");
     }
     $newData['sender'] = (int) $node['userid'];
     return $newData;
 }
예제 #2
0
 protected final function validateAndCleanNotificationData($notificationData)
 {
     $newData = parent::validateAndCleanNotificationData($notificationData);
     unset($notificationData);
     if (!isset($newData['sender'])) {
         throw new Exception("Missing Notification Data: sender");
     }
     // sender cannot be a guest, as guests cannot have relations with members ATM.
     if (empty($newData['sender'])) {
         throw new Exception("Invalid Notification Data: sender");
     }
     $newData['sentbynodeid'] = NULL;
     /*
     If we could, we'd also check recipients here, but recipients are added later
     */
     return $newData;
 }
예제 #3
0
 protected function validateAndCleanNotificationData($notificationData)
 {
     $newData = parent::validateAndCleanNotificationData($notificationData);
     unset($notificationData);
     if (!isset($newData['sentbynodeid'])) {
         throw new Exception("Missing Notification Data: sentbynodeid");
     }
     $nodeid = $newData['sentbynodeid'];
     $node = vB_Library::instance('node')->getNode($nodeid, false, true);
     // we need to get the full content, to ensure 'channeltype' is there.
     if (!isset($node['nodeid'])) {
         throw new Exception("Invalid Notification Data: sentbynodeid");
     }
     // Don't send notification if it's not visible to a "regular" user.
     if (!($node['showpublished'] and $node['showapproved'])) {
         throw new Exception("Invalid Notification Data: showpublished or showapproved");
     }
     // The sentbynodeid MUST BE A POLL TYPE
     $topLevelContentTypes = array('Poll' => 1);
     $contenttypeclass = vB_Types::instance()->getContentTypeClass($node['contenttypeid']);
     if (!isset($topLevelContentTypes[$contenttypeclass])) {
         throw new Exception("Cannot send this notification for the node's content type.");
     }
     // Let's restrict it to certain channel types, just in case we can create polls anywhere.
     // Keep this in sync with vB_Channel::$channelTypes
     $allowedChannelTypes = array('forum' => 1, 'blog' => 1, 'article' => 1, 'group' => 1);
     if (!isset($allowedChannelTypes[$node['channeltype']])) {
         throw new Exception("Cannot send this notification for the node's channel type.");
     }
     // We're good if we got to this point.
     $newData['sentbynodeid'] = (int) $node['nodeid'];
     // Sender must be specified when constructing this type. Set by parent::validateAndCleanNotificationData()
     if (!isset($newData['sender'])) {
         throw new Exception("Invalid Notification Data: sender");
     }
     return $newData;
 }
예제 #4
0
 /**
  * Validates the notification data, checks the context to see if we should send this
  * notification type, and throws exceptions if we should not or cannot send this notification
  * type. If all is okay, it may set additional notification data specific to this notification type.
  *
  * @param	Array	$notificationData
  *
  * @throws Exception()	If for some reason this notification type cannot be sent given
  *						the context data in $notificationData
  *
  * @access protected
  */
 protected function validateAndCleanNotificationData($notificationData)
 {
     $newData = parent::validateAndCleanNotificationData($notificationData);
     unset($notificationData);
     if (!isset($newData['sentbynodeid'])) {
         throw new Exception("Missing Notification Data: sentbynodeid");
     }
     $nodeid = $newData['sentbynodeid'];
     $node = vB_Library::instance('node')->getNode($nodeid, false, true);
     // we need to get the full content, to ensure 'channeltype' is there.
     if (!isset($node['nodeid'])) {
         throw new Exception("Invalid Notification Data: sentbynodeid");
     }
     // Don't send notification if it's not visible to a "regular" user.
     if (!($node['showpublished'] and $node['showapproved'])) {
         throw new Exception("Invalid Notification Data: showpublished or showapproved");
     }
     // only explictly specified content types are allowed to send notifications
     $topLevelContentTypes = array('Gallery' => 1, 'Link' => 1, 'Poll' => 1, 'Text' => 1, 'Video' => 1);
     $contenttypeclass = vB_Types::instance()->getContentTypeClass($node['contenttypeid']);
     if (!isset($topLevelContentTypes[$contenttypeclass])) {
         throw new Exception("Cannot send this notification for the node's content type.");
     }
     // Similar to above, but for channeltypes. Keep this in sync with vB_Channel::$channelTypes
     $allowedChannelTypes = array('forum' => 1, 'blog' => 1, 'article' => 1, 'group' => 1);
     if (!isset($allowedChannelTypes[$node['channeltype']])) {
         throw new Exception("Cannot send this notification for the node's channel type.");
     }
     // We're good if we got to this point.
     $newData['sentbynodeid'] = (int) $node['nodeid'];
     if (!isset($node['userid'])) {
         throw new Exception("Invalid Notification Data: sentbynodeid");
     }
     $newData['sender'] = (int) $node['userid'];
     return $newData;
 }
예제 #5
0
 public function triggerNotificationEvent($eventstring, $data = array(), $recipients = array())
 {
     $events = $this->getNotificationEvents();
     $types = $this->getNotificationTypes();
     if (!isset($events[$eventstring])) {
         return;
     }
     /*
     Expecting $classname => event type
     */
     foreach ($events[$eventstring] as $class => $type) {
         switch ($type) {
             case 'trigger':
                 if (!isset($data['sentbynodeid']) and isset($data['nodeid'])) {
                     $data['sentbynodeid'] = $data['nodeid'];
                 }
                 $notification = new $class($eventstring, $data, $recipients);
                 $notificationData = $notification->getNotificationData();
                 if (empty($notificationData)) {
                     continue 2;
                 }
                 $notificationData['typeid'] = $types[$notificationData['typename']]['typeid'];
                 $notificationRecipients = $notification->getRecipients();
                 $recipientsCache = $notification->getCachedRecipientData();
                 // holds email, languageid, emailupdate etc that we already grabbed from user table.
                 $aboutString = vB_Library::instance('content_privatemessage')->convertNotificationTypeToLegacyAboutString($notificationData['typename']);
                 if ($aboutString == 'subscription') {
                     // Required for emails.
                     // TODO figure out how to get rid of this double call to follow API (this is also called in
                     // vB_Notification_Content_GroupByStarter_Subscription)
                     $apiResult = vB_Api::instanceInternal('follow')->getSubscribersForNotifications($notificationData['sentbynodeid']);
                     $subscribers = $apiResult['subscribers'];
                 }
                 foreach ($notificationRecipients as $userid) {
                     $notificationData['recipient'] = $userid;
                     /*
                     						TODO: move emails generation into notification objects so we can get rid of this ugly block below
                     */
                     $sendEmail = (!empty($aboutString) and isset($recipientsCache[$userid]['emailnotification']) and $recipientsCache[$userid]['emailnotification'] == 1);
                     if ($sendEmail) {
                         $emailData = array('userid' => $userid, 'about' => $aboutString, 'email' => $recipientsCache[$userid]['email'], 'username' => $recipientsCache[$userid]['username'], 'languageid' => $recipientsCache[$userid]['languageid'], 'contentnodeid' => $notificationData['sentbynodeid'], 'senderid' => $notificationData['sender']);
                         if ($aboutString == 'subscription') {
                             $emailData['subscriptionnodeid'] = reset($subscribers[$userid]['nodeid']);
                         }
                     } else {
                         $emailData = array();
                     }
                     // Queue up notifications & Emails
                     if (empty($notificationData['lookupid'])) {
                         $this->notificationQueue[] = $notificationData;
                         if ($sendEmail) {
                             $this->emailQueue[] = $emailData;
                         }
                     } else {
                         // Only alphamerics and '_' are allowed in typenames, and the unique prefix in the
                         // lookupid is json_encoded (so have the form of {"blah":"cool"}) so using _{$userid}
                         // in the array key should prevent conflicts from super weird/creative custom type names.
                         // I hope.
                         $key = "_{$userid}" . vB_Notification::DELIM . $notificationData['lookupid'];
                         if (isset($this->notificationQueue[$key])) {
                             if ($notificationData['priority'] > $this->notificationQueue[$key]['priority']) {
                                 $this->notificationQueue[$key] = $notificationData;
                                 if ($sendEmail) {
                                     $this->emailQueue[$key] = $emailData;
                                 }
                             }
                         } else {
                             $this->notificationQueue[$key] = $notificationData;
                             if ($sendEmail) {
                                 $this->emailQueue[$key] = $emailData;
                             }
                         }
                     }
                     unset($notificationData['recipient'], $sendEmail, $emailData);
                 }
                 break;
             case 'update':
                 $class::handleUpdateEvents($eventstring, $data);
                 break;
             default:
                 break;
         }
     }
     vB_Notification::clearMemory();
 }
예제 #6
0
 public static final function clearMemory()
 {
     // Required for unit testing... Usually we can probably ignore user info changes
     // that happen *within* a pageload / session, but unit tests have a single PHP session
     // that lasts for multiple "user sessions".
     // This is called by vB_Library_Notification->triggerNotificationEvent().
     self::$recipientsInfoCache = array();
 }