/** * @see EventListener::execute() */ public function execute($eventObj, $className, $eventName) { if (!MODULE_USER_NOTIFICATION) { return; } try { $notificationObject = $this->getNotificationObject($eventObj->eventName, $eventObj->placeholders + array('contestID' => $eventObj->contestID)); } catch (Exception $e) { // just fun, errors don't need to be handled return; } switch ($eventName) { case 'create': foreach ($notificationObject->getRecipients() as $recipientUserID) { // remove current user from recipient list if ($recipientUserID == WCF::getUser()->userID) { continue; } NotificationHandler::fireEvent($eventObj->eventName, self::OBJECT_TYPE, $notificationObject, $recipientUserID); } break; case 'delete': NotificationHandler::revokeEvent(array($eventObj->eventName), self::OBJECT_TYPE, array($notificationObject)); break; case 'confirm': // anybody affected by current confirmation? $objectIDScope = array(); foreach ($notificationObject->getObjects() as $objectID) { $objectIDScope[] = $objectID; } $recipientUserID = WCF::getUser()->userID; NotificationEditor::markConfirmedByObjectVisit($recipientUserID, array($eventObj->eventName), self::OBJECT_TYPE, $objectIDScope); break; } }
/** * Will process the data from the server after it's been decrypted and parsed. * * This also provides a convenient method to use to unit test the event framework. * @param ProtocolNode $node * @param $type * * @throws Exception */ protected function processInboundDataNode(ProtocolNode $node) { $this->timeout = time(); $this->debugPrint($node->nodeString("rx ") . "\n"); $this->serverReceivedId = $node->getAttribute('id'); if ($node->getTag() == "challenge") { $this->processChallenge($node); } elseif ($node->getTag() == "failure") { $this->loginStatus = Constants::DISCONNECTED_STATUS; $this->eventManager()->fire("onLoginFailed", array($this->phoneNumber, $node->getChild(0)->getTag())); if ($node->getChild(0)->getTag() == 'not-authorized') { $this->logFile('error', 'Blocked number or wrong password. Use blockChecker.php'); } } elseif ($node->getTag() == "success") { if ($node->getAttribute("status") == "active") { $this->loginStatus = Constants::CONNECTED_STATUS; $challengeData = $node->getData(); file_put_contents($this->challengeFilename, $challengeData); $this->writer->setKey($this->outputKey); $this->eventManager()->fire("onLoginSuccess", array($this->phoneNumber, $node->getAttribute("kind"), $node->getAttribute("status"), $node->getAttribute("creation"), $node->getAttribute("expiration"))); } elseif ($node->getAttribute("status") == "expired") { $this->eventManager()->fire("onAccountExpired", array($this->phoneNumber, $node->getAttribute("kind"), $node->getAttribute("status"), $node->getAttribute("creation"), $node->getAttribute("expiration"))); } } elseif ($node->getTag() == 'ack') { if ($node->getAttribute("class") == "message") { $this->eventManager()->fire("onMessageReceivedServer", array($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('class'), $node->getAttribute('t'))); } } elseif ($node->getTag() == 'receipt') { if ($node->hasChild("list")) { foreach ($node->getChild("list")->getChildren() as $child) { $this->eventManager()->fire("onMessageReceivedClient", array($this->phoneNumber, $node->getAttribute('from'), $child->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('participant'))); } } if ($node->hasChild("retry")) { $this->sendGetCipherKeysFromUser(ExtractNumber($node->getAttribute('from')), true); } $this->eventManager()->fire("onMessageReceivedClient", array($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('participant'))); $this->sendAck($node, 'receipt'); } if ($node->getTag() == "message") { $handler = new MessageHandler($this, $node); } if ($node->getTag() == "presence" && $node->getAttribute("status") == "dirty") { //clear dirty $categories = array(); if (count($node->getChildren()) > 0) { foreach ($node->getChildren() as $child) { if ($child->getTag() == "category") { $categories[] = $child->getAttribute("name"); } } } $this->sendClearDirty($categories); } if (strcmp($node->getTag(), "presence") == 0 && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0 && strpos($node->getAttribute('from'), "-") === false) { $presence = array(); if ($node->getAttribute('type') == null) { $this->eventManager()->fire("onPresenceAvailable", array($this->phoneNumber, $node->getAttribute('from'))); } else { $this->eventManager()->fire("onPresenceUnavailable", array($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('last'))); } } if ($node->getTag() == "presence" && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0 && strpos($node->getAttribute('from'), "-") !== false && $node->getAttribute('type') != null) { $groupId = $this->parseJID($node->getAttribute('from')); if ($node->getAttribute('add') != null) { $this->eventManager()->fire("onGroupsParticipantsAdd", array($this->phoneNumber, $groupId, $this->parseJID($node->getAttribute('add')))); } elseif ($node->getAttribute('remove') != null) { $this->eventManager()->fire("onGroupsParticipantsRemove", array($this->phoneNumber, $groupId, $this->parseJID($node->getAttribute('remove')))); } } if (strcmp($node->getTag(), "chatstate") == 0 && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0 && strpos($node->getAttribute('from'), "-") === false) { if ($node->getChild(0)->getTag() == "composing") { $this->eventManager()->fire("onMessageComposing", array($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), "composing", $node->getAttribute('t'))); } else { $this->eventManager()->fire("onMessagePaused", array($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), "paused", $node->getAttribute('t'))); } } if ($node->getTag() == "receipt") { $this->eventManager()->fire("onGetReceipt", array($node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('offline'), $node->getAttribute('retry'))); } if ($node->getTag() == "iq") { $handler = new IqHandler($this, $node); } if ($node->getTag() == "notification") { $handler = new NotificationHandler($this, $node); } if ($node->getTag() == "call") { if ($node->getChild(0)->getTag() == "offer") { $callId = $node->getChild(0)->getAttribute("call-id"); $this->sendReceipt($node, null, null, $callId); $this->eventManager()->fire("onCallReceived", array($this->phoneNumber, $node->getAttribute("from"), $node->getAttribute("id"), $node->getAttribute("notify"), $node->getAttribute("t"), $node->getChild(0)->getAttribute("call-id"))); } else { $this->sendAck($node, 'call'); } } if ($node->getTag() == "ib") { foreach ($node->getChildren() as $child) { switch ($child->getTag()) { case "dirty": $this->sendClearDirty(array($child->getAttribute("type"))); break; case "account": $this->eventManager()->fire("onPaymentRecieved", array($this->phoneNumber, $child->getAttribute("kind"), $child->getAttribute("status"), $child->getAttribute("creation"), $child->getAttribute("expiration"))); break; case "offline": break; default: throw new Exception("ib handler for " . $child->getTag() . " not implemented"); } } } // Disconnect socket on stream error. if ($node->getTag() == "stream:error") { $this->eventManager()->fire("onStreamError", array($node->getChild(0)->getTag())); $this->logFile('error', 'Stream error {error}', array('error' => $node->getChild(0)->getTag())); $this->disconnect(); } if (isset($handler)) { $handler->Process(); unset($handler); } }
/** * Will process the data from the server after it's been decrypted and parsed. * * This also provides a convenient method to use to unit test the event framework. * * @param ProtocolNode $node * @param $type * * @throws Exception */ protected function processInboundDataNode(ProtocolNode $node) { $this->timeout = time(); //echo niceVarDump($node); $this->debugPrint($node->nodeString('rx ') . "\n"); $this->serverReceivedId = $node->getAttribute('id'); if ($node->getTag() == 'challenge') { $this->processChallenge($node); } elseif ($node->getTag() == 'failure') { $this->loginStatus = Constants::DISCONNECTED_STATUS; $this->eventManager()->fire('onLoginFailed', [$this->phoneNumber, $node->getChild(0)->getTag()]); if ($node->getChild(0)->getTag() == 'not-authorized') { $this->logFile('error', 'Blocked number or wrong password. Use blockChecker.php'); } } elseif ($node->getTag() == 'success') { if ($node->getAttribute('status') == 'active') { $this->loginStatus = Constants::CONNECTED_STATUS; $challengeData = $node->getData(); file_put_contents($this->challengeFilename, $challengeData); $this->writer->setKey($this->outputKey); $this->eventManager()->fire('onLoginSuccess', [$this->phoneNumber, $node->getAttribute('kind'), $node->getAttribute('status'), $node->getAttribute('creation'), $node->getAttribute('expiration')]); } elseif ($node->getAttribute('status') == 'expired') { $this->eventManager()->fire('onAccountExpired', [$this->phoneNumber, $node->getAttribute('kind'), $node->getAttribute('status'), $node->getAttribute('creation'), $node->getAttribute('expiration')]); } } elseif ($node->getTag() == 'ack') { if ($node->getAttribute('class') == 'message') { $this->eventManager()->fire('onMessageReceivedServer', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('class'), $node->getAttribute('t')]); } } elseif ($node->getTag() == 'receipt') { if ($node->hasChild('list')) { foreach ($node->getChild('list')->getChildren() as $child) { $this->eventManager()->fire('onMessageReceivedClient', [$this->phoneNumber, $node->getAttribute('from'), $child->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('participant')]); } } if ($node->hasChild('retry')) { $this->sendGetCipherKeysFromUser(ExtractNumber($node->getAttribute('from')), true); $this->messageStore->setPending($node->getAttribute('id'), $node->getAttribute('from')); } if ($node->hasChild('error') && $node->getChild('error')->getAttribute('type') == 'enc-v1') { $this->v1Only[ExtractNumber($node->getAttribute('from'))] = true; $this->messageStore->setPending($node->getAttribute('id'), $node->getAttribute('from')); $this->sendPendingMessages($node->getAttribute('from')); } $this->eventManager()->fire('onMessageReceivedClient', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('participant')]); $this->sendAck($node, 'receipt'); } if ($node->getTag() == 'message') { $handler = new MessageHandler($this, $node); } if ($node->getTag() == 'presence' && $node->getAttribute('status') == 'dirty') { //clear dirty $categories = []; if (count($node->getChildren()) > 0) { foreach ($node->getChildren() as $child) { if ($child->getTag() == 'category') { $categories[] = $child->getAttribute('name'); } } } $this->sendClearDirty($categories); } if (strcmp($node->getTag(), 'presence') == 0 && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0 && strpos($node->getAttribute('from'), '-') === false) { $presence = []; if ($node->getAttribute('type') == null) { $this->eventManager()->fire('onPresenceAvailable', [$this->phoneNumber, $node->getAttribute('from')]); } else { $this->eventManager()->fire('onPresenceUnavailable', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('last')]); } } if ($node->getTag() == 'presence' && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0 && strpos($node->getAttribute('from'), '-') !== false && $node->getAttribute('type') != null) { $groupId = $this->parseJID($node->getAttribute('from')); if ($node->getAttribute('add') != null) { $this->eventManager()->fire('onGroupsParticipantsAdd', [$this->phoneNumber, $groupId, $this->parseJID($node->getAttribute('add'))]); } elseif ($node->getAttribute('remove') != null) { $this->eventManager()->fire('onGroupsParticipantsRemove', [$this->phoneNumber, $groupId, $this->parseJID($node->getAttribute('remove'))]); } } if (strcmp($node->getTag(), 'chatstate') == 0 && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0) { // remove if isn't group if (strpos($node->getAttribute('from'), '-') === false) { if ($node->getChild(0)->getTag() == 'composing') { $this->eventManager()->fire('onMessageComposing', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), 'composing', $node->getAttribute('t')]); } else { $this->eventManager()->fire('onMessagePaused', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), 'paused', $node->getAttribute('t')]); } } else { if ($node->getChild(0)->getTag() == 'composing') { $this->eventManager()->fire('onGroupMessageComposing', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('participant'), $node->getAttribute('id'), 'composing', $node->getAttribute('t')]); } else { $this->eventManager()->fire('onGroupMessagePaused', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('participant'), $node->getAttribute('id'), 'paused', $node->getAttribute('t')]); } } } if ($node->getTag() == 'receipt') { $this->eventManager()->fire('onGetReceipt', [$node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('offline'), $node->getAttribute('retry')]); } if ($node->getTag() == 'iq') { $handler = new IqHandler($this, $node); } if ($node->getTag() == 'notification') { $handler = new NotificationHandler($this, $node); } if ($node->getTag() == 'call') { if ($node->getChild(0)->getTag() == 'offer') { $callId = $node->getChild(0)->getAttribute('call-id'); $this->sendReceipt($node, null, null, $callId); $this->eventManager()->fire('onCallReceived', [$this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('notify'), $node->getAttribute('t'), $node->getChild(0)->getAttribute('call-id')]); } else { $this->sendAck($node, 'call'); } } if ($node->getTag() == 'ib') { foreach ($node->getChildren() as $child) { switch ($child->getTag()) { case 'dirty': $this->sendClearDirty([$child->getAttribute('type')]); break; case 'account': $this->eventManager()->fire('onPaymentRecieved', [$this->phoneNumber, $child->getAttribute('kind'), $child->getAttribute('status'), $child->getAttribute('creation'), $child->getAttribute('expiration')]); break; case 'offline': break; default: throw new Exception('ib handler for ' . $child->getTag() . ' not implemented'); } } } // Disconnect socket on stream error. if ($node->getTag() == 'stream:error') { $this->eventManager()->fire('onStreamError', [$node->getChild(0)->getTag()]); $this->logFile('error', 'Stream error {error}', ['error' => $node->getChild(0)->getTag()]); $this->disconnect(); } if (isset($handler)) { $handler->Process(); unset($handler); } }
/** * @see EventListener::execute() */ public function execute($eventObj, $className, $eventName) { if (MODULE_USER_NOTIFICATION) { if ($className === 'PostActionPage') { $markedPostIDs = WCF::getSession()->getVar('markedPosts'); if ($eventObj->post !== null && $eventObj->post->userID != WCF::getUser()->userID) { if ($eventObj->action === 'trash') { if (!THREAD_ENABLE_RECYCLE_BIN || !$eventObj->board->getModeratorPermission('canDeletePost') || $eventObj->post->isDeleted) { return; } NotificationHandler::fireEvent('trashed', 'postDelete', $eventObj->post->postID, $eventObj->post->userID, array('trashedByUserID' => WCF::getUser()->userID, 'trashedByUsername' => WCF::getUser()->username, 'trashReason' => $eventObj->reason, 'threadID' => $eventObj->thread->threadID, 'threadTopic' => $eventObj->thread->topic)); return true; } else { if ($eventObj->action === 'delete') { if (!$eventObj->board->getModeratorPermission('canDeletePostCompletely')) { return; } NotificationHandler::revokeEvent(array('trashed'), 'postDelete', $eventObj->post->postID); NotificationHandler::fireEvent('deleted', 'postDelete', $eventObj->post->postID, $eventObj->post->userID, array('deletedByUserID' => WCF::getUser()->userID, 'deletedByUsername' => WCF::getUser()->username, 'threadID' => $eventObj->thread->threadID, 'threadTopic' => $eventObj->thread->topic)); return true; } else { if ($eventObj->action === 'recover') { if (!$eventObj->board->getModeratorPermission('canDeletePostCompletely') || !$eventObj->post->isDeleted) { return; } NotificationHandler::revokeEvent(array('trashed'), 'postDelete', $eventObj->post); return true; } } } } if ($markedPostIDs !== null && count($markedPostIDs)) { if ($eventObj->action === 'deleteAll') { $trashPosts = array(); $trashPostsThreadIDs = array(); $deletePosts = array(); $deletePostsThreadIDs = array(); $sql = "SELECT\t\tpost.*, thread.threadID, thread.topic\n\t\t\t\t\t\t\tFROM\t\twbb" . WBB_N . "_post post\n\t\t\t\t\t\t\tLEFT JOIN\twbb" . WBB_N . "_thread thread\n\t\t\t\t\t\t\tON\t\t(post.threadID = thread.threadID)\n\t\t\t\t\t\t\tWHERE\t\tpost.postID IN (" . implode(',', $markedPostIDs) . ")"; $result = WCF::getDB()->sendQuery($sql); while ($row = WCF::getDB()->fetchArray($result)) { if ($row['userID'] != WCF::getUser()->userID) { if ($row['isDeleted'] || !THREAD_ENABLE_RECYCLE_BIN) { $deletePosts[$row['postID']] = new PostDeleteNotificationObject(null, $row); $deletePostsThreadIDs[] = $row['threadID']; } else { $trashPosts[$row['postID']] = new PostDeleteNotificationObject(null, $row); $trashPostsThreadIDs[] = $row['threadID']; } } } list($trashPostsBoards, $trashPostsBoardIDs) = ThreadEditor::getBoards(implode(',', $trashPostsThreadIDs)); list($deletePostsBoards, $deletePostsBoardIDs) = ThreadEditor::getBoards(implode(',', $deletePostsThreadIDs)); foreach ($trashPostsBoards as $trashPostsBoard) { $trashPostsBoard->checkModeratorPermission('canDeletePost'); } foreach ($deletePostsBoards as $deletePostsBoard) { $deletePostsBoard->checkModeratorPermission('canDeletePostCompletely'); } unset($trashPostsThreadIDs, $deletePostsThreadIDs, $trashPostsBoards, $deletePostsBoards, $trashPostsBoardIDs, $deletePostsBoardIDs); foreach ($trashPosts as $trashPost) { NotificationHandler::fireEvent('trashed', 'postDelete', $trashPost, $trashPost->userID, array('trashedByUserID' => WCF::getUser()->userID, 'trashedByUsername' => WCF::getUser()->username, 'trashReason' => $eventObj->reason, 'threadID' => $trashPost->threadID, 'threadTopic' => $trashPost->topic)); } foreach ($deletePosts as $deletePost) { NotificationHandler::revokeEvent(array('trashed'), 'postDelete', $deletePost); NotificationHandler::fireEvent('deleted', 'postDelete', $deletePost, $deletePost->userID, array('deletedByUserID' => WCF::getUser()->userID, 'deletedByUsername' => WCF::getUser()->username, 'threadID' => $deletePost->threadID, 'threadTopic' => $deletePost->topic)); } return true; } else { if ($eventObj->action === 'recoverAll') { $threadIDs = PostEditor::getThreadIDs(implode(',', $markedPostIDs)); $notificationObjectObjects = NotificationHandler::getNotificationObjectTypeObject('postDelete')->getObjects($markedPostIDs); list($boards, $boardIDs) = ThreadEditor::getBoards($threadIDs); foreach ($boards as $board) { $board->checkModeratorPermission('canDeletePostCompletely'); } unset($threadIDs, $boards, $boardIDs); foreach ($notificationObjectObjects as $notificationObjectObject) { NotificationHandler::revokeEvent(array('trashed'), 'postDelete', $notificationObjectObject); } return true; } } } } else { if ($className === 'ThreadPage') { $posts = $eventObj->postList->posts; $postIDs = array(); $user = new NotificationUser(null, WCF::getUser(), false); $packageID = NotificationHandler::getNotificationObjectTypeObject('postDelete')->getPackageID(); foreach ($posts as $post) { if ($post->isDeleted && $post->userID == $user->userID) { $postIDs[] = $post->postID; } } unset($posts); if (isset($user->notificationFlags[$packageID]) && $user->notificationFlags[$packageID] > 0) { $count = NotificationEditor::markConfirmedByObjectVisit($user->userID, array('trashed'), 'postDelete', $postIDs); $user->removeOutstandingNotification($packageID, $count); } } else { if ($className === 'PostEditForm' && $eventObj->post->userID != WCF::getUser()->userID && isset($_POST['deletePost']) && isset($_POST['sure'])) { if ((!THREAD_ENABLE_RECYCLE_BIN || THREAD_ENABLE_RECYCLE_BIN && $eventObj->post->isDeleted) && $eventObj->board->getModeratorPermission('canDeletePostCompletely')) { NotificationHandler::revokeEvent(array('trashed'), 'postDelete', $eventObj->post->postID); NotificationHandler::fireEvent('deleted', 'postDelete', $eventObj->post->postID, $eventObj->post->userID, array('deletedByUserID' => WCF::getUser()->userID, 'deletedByUsername' => WCF::getUser()->username, 'threadID' => $eventObj->thread->threadID, 'threadTopic' => $eventObj->thread->topic)); } else { if (!$eventObj->post->isDeleted && THREAD_ENABLE_RECYCLE_BIN && $eventObj->board->getModeratorPermission('canDeletePost')) { NotificationHandler::fireEvent('trashed', 'postDelete', $eventObj->post->postID, $eventObj->post->userID, array('trashedByUserID' => WCF::getUser()->userID, 'trashedByUsername' => WCF::getUser()->username, 'trashReason' => $eventObj->deleteReason, 'threadID' => $eventObj->thread->threadID, 'threadTopic' => $eventObj->thread->topic)); } } } } } } }
/** * Display the public notification email subscription form */ function subscribeMailList() { $this->setupTemplate(); $user = Request::getUser(); if (!isset($user)) { import('notification.form.NotificationMailingListForm'); $notificationMailingListForm = new NotificationMailingListForm(); $notificationMailingListForm->display(); } else { PKPRequest::redirect(NotificationHandler::getContextDepthArray(), 'notification'); } }