/mess.php
PHP | 4102 lines | 3193 code | 407 blank | 502 comment | 1102 complexity | a0dc3cca20036ba39a066f4ec41c4dde MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- *
- * @category Edmodo
- * @package Edmodo_Helper
- * @copyright Copyright (c) 2012 Edmodo USA Inc. (http://www.edmodo.com)
- *
- */
- /**
- *
- * @category Edmodo
- * @package Edmodo_Helper
- *
- */
- class MessagingHelper
- {
- const MESSAGE='message';
- const MESSAGE_ID='message_id';
- const CREATOR_ID='creator_id';
- const TYPE='type';
- const CREATION_DATE='creation_date';
- const COLUMN_PUBLIC='public';
- const MESSAGE_TYPE_TEXT='text';
- const MESSAGE_TYPE_LINK='link';
- const MESSAGE_TYPE_VIDEO='video';
- const MESSAGE_TYPE_FILE='file';
- const MESSAGE_TYPE_ASSIGNMENT='assignment';
- const MESSAGE_TYPE_SYSTEM='system';
- const MESSAGE_TYPE_COMMENT='comment';
- const MESSAGE_TYPE_ALERT='alert';
- const MESSAGE_TYPE_GRADE='grade';
- const MESSAGE_TYPE_POLL='poll';
- const MESSAGE_TYPE_FEED='feed';
- const MESSAGE_TYPE_EMBED='embed';
- const MESSAGE_TYPE_QUIZ='quiz';
- const MESSAGE_TYPE_APP_MESSAGE='app_message';
-
- public static $VALID_MESSAGE_TYPES = array(
- MessagingHelper::MESSAGE_TYPE_TEXT,
- MessagingHelper::MESSAGE_TYPE_LINK,
- MessagingHelper::MESSAGE_TYPE_VIDEO,
- MessagingHelper::MESSAGE_TYPE_FILE,
- MessagingHelper::MESSAGE_TYPE_ASSIGNMENT,
- MessagingHelper::MESSAGE_TYPE_SYSTEM,
- MessagingHelper::MESSAGE_TYPE_COMMENT,
- MessagingHelper::MESSAGE_TYPE_ALERT,
- MessagingHelper::MESSAGE_TYPE_GRADE,
- MessagingHelper::MESSAGE_TYPE_POLL,
- MessagingHelper::MESSAGE_TYPE_FEED,
- MessagingHelper::MESSAGE_TYPE_EMBED,
- MessagingHelper::MESSAGE_TYPE_QUIZ,
- MessagingHelper::MESSAGE_TYPE_APP_MESSAGE,
- );
- private $use_gearman = NOTIFICATIONS_USE_GEARMAN;
- private $last_direct_msg_receivers;
- private $last_indirect_msg_receivers;
- private $spotted_replies;
- private $feed_type;
- private $user_id;
- private $user_groups;
- private $community_groups;
- private $parent_info;
- private $institutional_info;
- private static $layout_translator;
- private static $system_msgs_translator;
- public $post_limit_reached = false;
- public static $is_api_call = false;
- public static $limit_comments_query = true;
- /**
- *
- * @var MessagingHelper
- */
- private static $_instance;
- /**
- * Implements the "singleton" pattern for this class
- *
- * @param string $feed_type
- * @return MessagingHelper
- */
- static function getInstance ($feed_type = 'HOME_FEED')
- {
- if (! isset(self::$_instance)) {
- self::$_instance = new self($feed_type);
- } else {
- self::$_instance->setFeedType($feed_type);
- }
- return self::$_instance;
- }
- /**
- * Set class instance
- * Use only to mock/stub instance for tests
- *
- * @param MessagingHelper $instance
- * @throws Exception
- */
- static function setInstance ($instance)
- {
- if (! $instance instanceof MessagingHelper) {
- throw new Exception('Invalid instance class');
- }
- self::$_instance = $instance;
- }
- /**
- */
- static function clearInstance ()
- {
- self::$_instance = null;
- }
- private function __construct($feed_type = 'HOME_FEED')
- {
- //----------------------------
- // Stores the user_ids of the users who received the msg
- // directly (people typed their names in the sharebox)
- $this->last_direct_msg_receivers = array();
- //----------------------------
- // Stores the user_ids of the users who received the msg
- // indirectly (they are part of a group who received a post)
- $this->last_indirect_msg_receivers = array();
- //----------------------------
- // Stores a boolean map of the comments that have been already spotted by the user
- $this->spotted_replies = array();
- //----------------------------
- // Stores a boolean map of the comments that have been already spotted by the user
- $this->feed_type = $feed_type;
- //----------------------------
- // Stores id of the user of the feed we are looking at
- $this->viewed_user_id = 0;
- //----------------------------
- // Stores the status of the user with respect to the community stream being viewed
- $this->community_user_status = null;
- //----------------------------
- // Stores the groups that the user whose feed we are looking at is part of
- $this->viewed_user_groups = array();
- //----------------------------
- // Stores the groups that are being viewed as a receiver on the community page
- $this->community_groups = array();
- //----------------------------
- // Stores the schools/districts that the user whose feed we are looking at is part of
- $this->institutional_info = array();
- //Stores the parent's info about his students
- $this->parent_info = array();
- //----------------------------
- // Layout translator
- self::$layout_translator = null;
- //----------------------------
- // System messages translator
- self::$system_msgs_translator = null;
- }
- public function setFeedType($feed_type = 'HOME_FEED')
- {
- $this->feed_type = $feed_type;
- }
- public static function initializeTranslators($language){
- if(!isset(self::$layout_translator)){
- // self::$layout_translator = new TranslationHelper(new Zend_Translate('tmx', PATH2_LANGUAGES . 'layout.tmx', $language));
- self::$layout_translator = TranslationHelper::getInstance(PATH2_LANGUAGES . 'layout.tmx', $language);
- }
- if(!isset(self::$system_msgs_translator)){
- // self::$system_msgs_translator = new TranslationHelper(new Zend_Translate('tmx', PATH2_LANGUAGES . 'system.tmx', $language));
- self::$system_msgs_translator = TranslationHelper::getInstance(PATH2_LANGUAGES . 'system.tmx', $language);
- }
- }
- /**
- * This sends a message from the system to a user
- * @param string $message_identifier is the system message identifier
- * @param array $receiver_id is the id of the intended message recipient
- */
- public function sendSystemMessage($message_identifier, $receiver_ids = array()){
- $message_data = array(
- 'type' => 'system',
- 'message' => $message_identifier
- );
- $this->sendMessage(
- $message_data,
- array('people' => $receiver_ids),
- Users::getInstance()->getUserInfo(EDMODO_SYSTEM_USER_ID)
- );
- }
- /**
- * This sends a message to one or more peers
- * @param array $message_data contains the message's content plus additional info about the message
- * @param array $receivers contains the intended message recipients (people or locations or both)
- * @param array $sender_info is the sender's account info.
- * @param Boolean $resource_resending weather this message is being sent to resend a resource (eg from the Library).
- * @param $attached_resources
- * @param bool $check_send_rights, flag to indicate if a check should be performed to verify that the sender has rights to send the message
- * @param bool $use_response_obj_return, flag to indicate if a HandlerResponseObj should be returned instead of the normal returns
- * @param bool $bypass_moderation, flag to indicate if the message should be sent even if the poster is a student and one of the recipients a moderated group
- * @return message_id
- */
- public function sendMessage($message_data, $receivers, $sender_info, $resource_resending = FALSE, $attached_resources = '', $check_send_rights = true, $use_response_obj_return = false, $bypass_moderation = false )
- {
- $response_obj = new HandlerResponseObj();
- if($this->isSpammer($sender_info, $message_data)){
- if($use_response_obj_return){
- $response_obj->setUnsuccessful();
- $response_obj->post_limit_reached = true;
- $response_obj->addError('User has reached maximum limit of posts for the last hour');
- return $response_obj;
- }else{
- return false;
- }
- }
- if($check_send_rights){
- if ( $sender_info['user_id'] != EDMODO_SYSTEM_USER_ID && !$this->userHasRightsToSendMessage( $sender_info, $receivers, $message_data ))
- {
- if ($use_response_obj_return) {
- $response_obj->setUnsuccessful();
- $response_obj->addError('User does not have rights to send message to the specified recipients');
- return $response_obj;
- } else {
- return false;
- }
- }
- }
- $community_id=null;
- // Messages are only sent immediately if none of the recipients is a moderated group
- if ( !$bypass_moderation && !empty($receivers['locations']) ){
- $groups_db = Groups::getInstance();
- foreach ( $receivers['locations'] as $location ){
- if ( $location['type'] == 'group' ){
- $group = $groups_db->find($location['id'])->current();
- // For small groups, the parent group is checked for moderation
- $main_group_info = SmallGroups::getInstance()->getGroupsMainGroup($location['id']);
- if ( empty($main_group_info) ){
- $main_group_info = $group;
- }
- if ( $main_group_info['moderated'] && ( $sender_info['type'] == 'STUDENT' || !$groups_db->userOwnsGroup( $sender_info['user_id'], $main_group_info['group_id'], true )) ){
- // Post moderated message here
- ModeratedMessagesHandler::sendModeratedMessage($message_data, $attached_resources, $group, $sender_info);
- if ($use_response_obj_return) {
- $response_obj->setSuccessful();
- $response_obj->is_moderated = true;
- $response_obj->message_id = 0;
- $response_obj->scheduled_message_id = 0;
- return $response_obj;
- } else {
- return false;
- }
- }
- }
- }
- }
- // Scheduled message
- if ( $sender_info['type'] == 'TEACHER' && isset($message_data['scheduled']) && $message_data['scheduled'] ){
- $scheduled_message_id = ScheduledMessagesHandler::sendScheduledMessage($message_data, $attached_resources, $receivers, $sender_info);
- if ($use_response_obj_return) {
- $response_obj->setSuccessful();
- $response_obj->is_scheduled = true;
- $response_obj->message_id = 0;
- $response_obj->scheduled_message_id = $scheduled_message_id;
- return $response_obj;
- } else {
- return $scheduled_message_id;
- }
- }
- if(empty($message_data['posted_in'])) $message_data['posted_in'] = null;
- if(empty($message_data['posted_in_id'])) $message_data['posted_in_id'] = null;
- if(empty($message_data['comment_to'])) $message_data['comment_to'] = null;
- $message_data['other_reply_count'] = 0;
- if ($message_data['comment_to']) {
- $message_data['other_reply_count'] = ArrayHelper::elem(NewComments::getInstance()->getCommentCount(array($message_data['comment_to'])), $message_data['comment_to'], 1) - 1;
- }
- //--------------------------------
- // Clean up the Message Receiver arrays
- $this->last_direct_msg_receivers= array();
- $this->last_indirect_msg_receivers= array();
- // STORE MESSAGE
- $message = array(
- 'creator_id' => $sender_info['user_id'],
- 'type' => $message_data['type'],
- 'comment_to' => $message_data['comment_to']
- );
- if (isset($message_data['creation_date'])) {
- $message['creation_date'] = $message_data['creation_date'];
- }
- $message_id = Messages::getInstance()->store( $message );
- // send a 'community post' message to the activity stream
- // add to the user's share score
- if(isset($receivers['locations'])){
- foreach ( $receivers['locations'] as $location ){
- if($location['type']=='community'){
- //ActivityHandler::triggerCommunityPost($location['id'],$message_id,ActivityCommunityPost::TYPE_SUBJECT);
- ShareScore::getInstance()->incrementShareScoreByValue($sender_info['user_id'], 10);
- }
- }
- }
- /*
- if(isset($receivers['people'])){
- foreach($receivers['people'] as $user_id){
- $user=Users::getInstance()->find($user_id);
- if(isset($user[Users::TYPE]) && $user[Users::TYPE]==Users::TYPE_PUBLISHER){
- ActivityHandler::triggerCommunityPost($user_id,$message_id,ActivityCommunityPost::TYPE_PUBLISHER);
- }
- }
- }
- */
- // STORE THINGS ASSOCIATED WITH MESSAGE
- $store_message_data_response = $this->storeMessageData($message_id, $message_data, $sender_info, $receivers, $resource_resending, $attached_resources);
- if (isset($store_message_data_response['assignment_id'])) {
- $response_obj->assignment_id = $store_message_data_response['assignment_id'];
- }
- if (isset($store_message_data_response['quiz_run_id'])) {
- $response_obj->quiz_run_id = $store_message_data_response['quiz_run_id'];
- }
- $has_link_or_embed = $store_message_data_response['has_link_or_embed'];
- $message_data['has_community_relevance'] = $has_link_or_embed ? $this->hasCommunityRelevance($message_data) : false;
- $this->storeMessageReceiversNotification($sender_info, $message_id, $receivers, $message_data);
- // System messages for which a notification won't be sent
- $silent_system_messages = array('added-to-small-group', 'twitter-off-no-email', 'twitter-off-with-email');
- $send_system_message = true;
- foreach ( $silent_system_messages as $silent_system_message ){
- if ( strpos($message_data['message'], $silent_system_message) == false ){
- $send_system_message = false;
- break;
- }
- }
- // Notifications are sent
- if( ENABLE_EMAIL_NOTIFICATIONS && $message_data['type'] != MessagingHelper::MESSAGE_TYPE_FEED && $message_data['type'] != MessagingHelper::MESSAGE_TYPE_APP_MESSAGE && ($message_data['type'] != MessagingHelper::MESSAGE_TYPE_SYSTEM || $send_system_message ) ) {
- $message_data['message_id'] = $message_id;
- if ($message_data['type'] == 'quiz') {
- $quiz_info = Quiz::getInstance()->search(array('quiz_id' => $message_data['quiz_id']));
- $message_data['quiz_title'] = $quiz_info[0]['title'];
- $message_data['quiz_description'] = $quiz_info[0]['description'];
- }
- $message_data[TrackingHelper::DATA_DATE_REQUESTED] = time();
- $workerArray = array(
- 'message_data' => $message_data,
- 'selected_receivers' => $receivers,
- 'account_info' => $sender_info,
- 'server_name' => ENVIROMENT_DOMAIN //will now use this .ini variable that should be: "edmodo.com", "edmodoqa.com", or "clubmodo.com" for dev env
- );
- $serialized_data = serialize($workerArray);
- if ($this->use_gearman)
- {
- GearmanHelper::getInstance()->doBackgroundJob('sendNotifications', $serialized_data);
- }
- else
- {
- NotificationsWorker::send_notifications(new NotificationTestJob($serialized_data));
- }
- }
- $this->setMaxMessageIdForReceivers($sender_info['user_id'], $receivers, $message_id);
- // Add this post to the publisher's cached messages
- if ( $sender_info['type'] == 'PUBLISHER' ){
- Messages::getInstance()->cachePublisherMessageId( $sender_info['user_id'], $message_id );
- }
- $this->preProcessPossibleGdocs($message_data, $attached_resources);
- //Processing google docs
- if(isset($message_data['google_docs']) && !empty($message_data['google_docs']))
- {
- $google_handler = GoogleApiHandler::getInstance();
- if(isset($message_data['google_docs']['docs_info'])){
- }
- $docs_info = isset($message_data['google_docs']['docs_info']) ? $message_data['google_docs']['docs_info']: NULL;
- $role = isset($message_data['google_docs']['role']) ? $message_data['google_docs']['role']: NULL;
- $scope = isset($message_data['google_docs']['scope']) ? $message_data['google_docs']['scope']: NULL;
- $google_info = UsersGoogleInfo::getInstance()->getUserGoogleInfo( $sender_info["user_id"] );
- if(is_array($google_info))
- $full_info = array_merge($sender_info,$google_info);
- else
- $full_info = $sender_info;
- $message_data_tmp = $message_data;
- $message_data_tmp['message_id'] = $message_id;
- $message_data_tmp['obj_type'] = 'MESSAGE';
- $gdocs_links = $google_handler->setPermissionsForReceivers($docs_info,$receivers,$full_info,$role,$scope, $message_data_tmp);
- }
- if ($use_response_obj_return) {
- $response_obj->setSuccessful();
- $response_obj->is_moderated = false;
- $response_obj->message_id = $message_id;
- $response_obj->scheduled_message_id = 0;
- return $response_obj;
- } else {
- return $message_id;
- }
- }
- private function isSpammer($sender_info, $message_data){
- $is_spammer = false;
- $user_id = $sender_info['user_id'];
- if($message_data['type'] != 'feed' && $user_id != EDMODO_SYSTEM_USER_ID){
- $rate_limiter = RateLimitHandler::getInstance();
- $rate_limiter->increment('posts_per_user_per_hour', $user_id);
- if ($rate_limiter->isLimited('posts_per_user_per_hour', $user_id)) {
- $is_spammer = true;
- }
- }
- return $is_spammer;
- }
- public function sendComment($comment_data, $receivers, $sender_info, $check_send_rights = true, $bypass_moderation = false, $use_response_obj_return = false)
- {
- $response_obj = new HandlerResponseObj();
- if($check_send_rights){
- if ( $sender_info['user_id'] != EDMODO_SYSTEM_USER_ID && !$this->userHasRightsToSendMessage( $sender_info, $receivers, $comment_data, true )){
- if ($use_response_obj_return) {
- $response_obj->setUnsuccessful();
- $response_obj->addError('User does not have rights to reply to this message.');
- return $response_obj;
- } else {
- return false;
- }
- }
- }
- // check that the number of replies to this post has not exceeded the limit
- if(NewComments::getInstance()->postHasExceededReplyCount($comment_data['comment_to'])){
- // update the message's last updated timestamp to indicate that it should be re-fetched by clients that cache the data (e.g. Android App)
- if (!MessageData::getInstance()->updateMessageLastUpdatedTime($comment_data['comment_to'])) {
- throw new Exception('Failed to update message last updated timestamp');
- }
- if ($use_response_obj_return) {
- $response_obj->setUnsuccessful();
- $response_obj->reply_count_exceeded = true;
- $response_obj->addError('Reply count exceeded for this post.');
- return $response_obj;
- } else {
- return false;
- }
- }
- // Comments sent by students are only sent immediately if none of the recipients of the original message is a moderated group
- if ( !$bypass_moderation && !empty($receivers['locations']) ){
- $groups_db = Groups::getInstance();
- foreach ( $receivers['locations'] as $location ){
- if ( $location['type'] == 'group' ){
- $group = $groups_db->find($location['id'])->current();
- if ( $group['moderated'] && ( $sender_info['type'] == 'STUDENT' || !$groups_db->userOwnsGroup( $sender_info['user_id'], $group['group_id'], true )) ){
- // Post moderated message here
- $comment_data['group_id'] = $group['group_id'];
- ModeratedMessagesHandler::sendModeratedComment($comment_data, $receivers['locations'], $sender_info);
- if ($use_response_obj_return) {
- $response_obj->setSuccessful();
- $response_obj->is_moderated = true;
- $response_obj->comment_id = 0;
- return $response_obj;
- } else {
- return false;
- }
- }
- }
- }
- }
- if(empty($comment_data['posted_in'])) $comment_data['posted_in'] = null;
- if(empty($comment_data['posted_in_id'])) $comment_data['posted_in_id'] = null;
- $comment_data['type'] = 'comment';
- //--------------------------------
- // Clean up the Message Receiver arrays
- $this->last_direct_msg_receivers= array();
- $this->last_indirect_msg_receivers= array();
- // STORE MESSAGE
- $comment = array(
- 'creator_id' => $sender_info['user_id'],
- 'comment_to' => $comment_data['comment_to'],
- 'content' => $comment_data['message']
- );
- if (isset($comment_data['creation_date'])) {
- $comment['creation_date'] = $comment_data['creation_date'];
- }
- $comment_id = NewComments::getInstance()->store( $comment );
- $comment_data['other_reply_count'] = 0;
- if ($comment_data['comment_to']) {
- $comment_data['other_reply_count'] = ArrayHelper::elem(NewComments::getInstance()->getCommentCount(array($comment_data['comment_to'])), $comment_data['comment_to'], 1) - 1;
- }
- // Parse the assignment's description for latex math expressions and generate images
- LatexHandler::getInstance()->extractMathExpressions($comment_data['message']);
- $this->storeMessageReceiversNotification($sender_info, $comment_id, $receivers, $comment_data, true);
- if( ENABLE_EMAIL_NOTIFICATIONS ){
- $comment_data['comment_id'] = $comment_id;
- $comment_data[TrackingHelper::DATA_DATE_REQUESTED] = time();
- $workerArray = array(
- 'message_data' => $comment_data,
- 'selected_receivers'=> $receivers,
- 'account_info' => $sender_info,
- 'server_name' => $_SERVER['HTTP_HOST']
- );
- $serialized_data = serialize($workerArray);
- if ($this->use_gearman)
- {
- GearmanHelper::getInstance()->doBackgroundJob('sendNotifications', $serialized_data);
- }
- else
- {
- NotificationsWorker::send_notifications(new NotificationTestJob($serialized_data));
- }
- }
- $this->setMaxMessageIdForReceivers($sender_info['user_id'], $receivers, $comment_id, true);
- if ($use_response_obj_return) {
- $response_obj->setSuccessful();
- $response_obj->is_moderated = false;
- $response_obj->comment_id = $comment_id;
- return $response_obj;
- } else {
- return $comment_id;
- }
- }
- private function hasCommunityRelevance( $message_data ){
- $has_community_relevance = true;
- $unwanted_urls = array(
- 'spreadsheets.google.com',
- 'docs.google.com',
- 'chalk.edmodo.com',
- 'surveymonkey.com',
- 'pbworks.com',
- 'sites.google.com',
- 'coveritlive.com'
- );
- if (isset( $message_data['links'] )){
- foreach ( $message_data['links'] as $link ){
- foreach ( $unwanted_urls as $unwanted_url ){
- if ( strpos($link['url'], $unwanted_url) !== false ){
- $has_community_relevance = false;
- break;
- }
- }
- }
- }
- if ($has_community_relevance && isset( $message_data['embeds'] )){
- foreach ( $message_data['embeds'] as $embed ){
- foreach ( $unwanted_urls as $unwanted_url ){
- if ( strpos($embed['url'], $unwanted_url) !== false ){
- $has_community_relevance = false;
- break;
- }
- }
- }
- }
- return $has_community_relevance;
- }
- private function setMaxMessageIdForReceivers($sender_id, $receivers, $message_id, $is_comment = false){
- $cache_handler = MemcacheHandler::getInstance();
- if ( $cache_handler->cachingAvailable() ){
- $user_ids = array();
- $user_ids[] = $sender_id;
- if(isset($receivers['people']))
- {
- foreach( $receivers['people'] as $person ){
- $user_ids[] = $person;
- }
- }
- if(!empty($receivers['locations'])){
- foreach( $receivers['locations'] as $location ){
- switch( $location['type'] ){
- case 'all-groups':
- $groups_db = Groups::getInstance();
- $groups = $groups_db->getUserGroups($sender_id);
- foreach( $groups as $group ){
- $members = $groups_db->getGroupMembers($group['group_id'], true);
- if(count($members) < 100){
- //if the group is too big, don't do this
- foreach( $members as $member ){
- $user_ids[] = $member['user_id'];
- }
- }
- }
- break;
- case 'connections':
- $connections = Connections::getInstance()->getConnectedUserIds($sender_id);
- foreach( $connections as $connection_id ){
- $user_ids[] = $connection_id;
- }
- break;
- case 'all':
- $groups_db = Groups::getInstance();
- $groups = $groups_db->getUserGroups($sender_id);
- foreach( $groups as $group ){
- $members = $groups_db->getGroupMembers($group['group_id'], true);
- foreach( $members as $member ){
- $user_ids[] = $member['user_id'];
- }
- }
- $connections = Connections::getInstance()->getConnectedUserIds($sender_id);
- foreach( $connections as $connection_id){
- $user_ids[] = $connection_id;
- }
- break;
- case 'group':
- $members = Groups::getInstance()->getGroupMembers($location['id'], true);
- if(count($members) < 100){
- foreach( $members as $member ){
- $user_ids[] = $member['user_id'];
- }
- }
- break;
- case 'group-parents':
- $parents = ParentsStudents::getParents($location['id'], true);
- foreach( $parents as $parent ){
- $user_ids[] = $parent['parent_id'];
- }
- break;
- case 'school':
- $member_ids = Schools::getInstance()->getSchoolMembers($location['id']);
- if(count($member_ids) < 1000){
- $user_ids = array_merge($user_ids, $member_ids);
- }
- break;
- case 'school_vip':
- $member_ids = Schools::getInstance()->getSchoolMembers($location['id'], true, 'teachers-admins');
- $user_ids = array_merge($user_ids, $member_ids);
- break;
- case 'district':
- $member_ids = Districts::getInstance()->getDistrictMembers($location['id']);
- if(count($member_ids) < 2000){
- $user_ids = array_merge($user_ids, $member_ids);
- }
- break;
- case 'district_vip':
- $member_ids = Districts::getInstance()->getDistrictMembers($location['id'], true, 'teachers-admins');
- if(count($member_ids) < 1000){
- $user_ids = array_merge($user_ids, $member_ids);
- }
- break;
- }
- }
- }
- $max_identifier = 'max_message_id';
- if ( $is_comment ){
- $max_identifier = 'max_comment_id';
- }
- foreach( $user_ids as $user_id ){
- $cache_handler->save($message_id, $user_id.$max_identifier);
- }
- }
- }
- /**
- * Stores the message's data
- * @return array An array containing two keys: has_link_or_embed and assignment_id
- */
- private function storeMessageData
- ($message_id, $message_data, $sender_info, $receivers = null, $resource_resending = FALSE, $attached_resources = '')
- {
- $response = array();
- $has_link_or_embed = false;
- $content = $message_data['message'];
- // handle special post types
- switch ($message_data['type']){
- case ASSIGNMENT:
- // For some reason, message_data sometimes does not have this optional field.
- // Setting to NULL, because Assignments->store() checks to see if this field = NULL.
- if (empty($message_data['default_total'])) {
- $message_data['default_total'] = null;
- }
-
- // if lock_after_due is not specified, set it to 0 by default
- $lock_after_due = isset($message_data['lock_after_due']) ? $message_data['lock_after_due'] : 0;
-
- $assignment_id = Assignments::getInstance()->store($message_id, $message_data['assignment-description'], $message_data['due-date'], $message_data['default_total'], $lock_after_due);
- $response['assignment_id'] = $assignment_id;
- $content = $message_data[ASSIGNMENT];
- // Parse the assignment's description for latex math expressions and generate images
- LatexHandler::getInstance()->extractMathExpressions($message_data['assignment-description']);
- break;
- case 'quiz':
- $quiz_info = Quiz::getInstance()->search(array('quiz_id' => $message_data['quiz_id']));
- $record = array
- (
- QuizRun::QUIZ_ID=>$message_data['quiz_id'],
- QuizRun::DUE_DATE=>$message_data['quiz-due-date'],
- QuizRun::AUTO_GRADE=>'1',
- QuizRun::SAVE_TO_GRADEBOOK=>$message_data['auto-grade'],
- QuizRun::MESSAGE_ID=>$message_id,
- QuizRun::SHOW_RESULTS=>$quiz_info[0]['show_results'],
- QuizRun::TIME_LIMIT=>$quiz_info[0]['time_limit'],
- QuizRun::STATUS=>QuizRun::STATUS_ASSIGNED,
- );
- $quizRunModel=QuizRun::getInstance();
- $quiz_run_id=$quizRunModel->store($record);
- //delete any 'preview' quiz_runs for this $quiz_id
- $quiz_runs=$quizRunModel->search(array(QuizRun::QUIZ_ID=>$message_data['quiz_id'],QuizRun::PREVIEW=>'1'));
- foreach($quiz_runs as $quiz_run){
- $quizRunModel->delete($quiz_run[QuizRun::QUIZ_RUN_ID]);
- }
- $response['quiz_run_id'] = $quiz_run_id;
- $content = '';
- break;
- case 'poll':
- // insert the answers as well...
- PollAnswers::getInstance()->storeAnswers($message_id, $message_data['poll_answers']);
- $content = $message_data['poll_question'];
- break;
- default:
- break;
- }
- // Parse the message's content for latex math expressions and generate images
- LatexHandler::getInstance()->extractMathExpressions($content);
- // Message data is stored in the database
- $data = array
- (
- 'message_id' => $message_id,
- 'content' => $content //if it's a link, it's the same as the link's title, for now
- );
- MessageData::getInstance()->store( $data );
- if( ! empty($message_data['links']) )
- {
- $has_link_or_embed = true;
- // Store links
- LinkHandler::getInstance()->processAttachedLinks($message_data['links'],$message_id,$sender_info,$receivers, 'MESSAGE', $message_data['type']);
- }
- if( ! empty($message_data['files']) ){
- // Store files
- FileHandler::getInstance()->processAttachedFiles($message_data['files'],$message_id,$sender_info,$receivers);
- }
- if (is_array($attached_resources)) {
- foreach ($attached_resources as $item_id) {
- $item_info = LibraryItems::getInstance()->getLibraryItem($item_id);
- if ($sender_info['type'] != 'PUBLISHER') {
- LibraryItems::getInstance()->updateRelations($item_id, $receivers);
- }
- if ($item_info['library_item_type'] == 'FILE') {
- MessagesFiles::getInstance()->store(array('message_id' => $message_id, 'file_id' => $item_info['library_item_resource_id']));
- } else if ($item_info['library_item_type'] == 'LINK') {
- MessagesLinks::getInstance()->store(array('message_id' => $message_id, 'link_id' => $item_info['library_item_resource_id']));
- $has_link_or_embed = true;
- } else if ($item_info['library_item_type'] == 'EMBED') {
- MessagesEmbeds::getInstance()->store(array('message_id' => $message_id, 'embed_id' => $item_info['library_item_resource_id']));
- $has_link_or_embed = true;
- }
- }
- }
- $response['has_link_or_embed'] = $has_link_or_embed;
- return $response;
- }
- /**
- * Stores the corresponding notifications for a message's receivers
- * @param $sender_info is the message's sender info
- * @param $message_origin is the location where the message was posted
- * @param $receivers is an array with all the message's receivers
- */
- private function storeMessageReceiversNotification($sender_info, $message_id, $receivers, $message_data, $is_comment = false){
- $locations = null;
- $message_sent_to_group = false;
- if(!empty($receivers['locations'])){
- $message_sent_to_group = true;
- $locations = $receivers['locations'];
- }
- $message_data[TrackingHelper::DATA_DATE_REQUESTED] = time();
- $db_recipients_array = array();
- if($message_sent_to_group) {
- $this->checkIfMessageSentToEveryone($sender_info, $locations);
- $already_cached_in_community = array();
- $communities_model = SubjectCommunities::getInstance();
- $all_community_ids = $communities_model->getSubjectCommunityIds();
- $is_verified_teacher = false;
- if($sender_info['type'] == 'TEACHER'){
- $is_verified_teacher = CoppaHandler::userIsCoppaVerified($sender_info['user_id']);
- }
- foreach($locations as $location) {
- //store this message location...
- if ( $location['type'] == 'connections' ){
- // Messages sent to connections have the sender's user id in the posted_in_id field of message_recipients_connections
- $location['id'] = $sender_info['user_id'];
- }
- $recipient = array(
- 'type' => $location['type'],
- 'message_id' => $message_id,
- 'posted_in_id' => $location['id'],
- );
- $db_recipients_array[] = $recipient;
- switch( $location['type'] )
- {
- case 'group':
- case 'GROUP':
- $this->setGroupLastMessageReceivers($location['id']);
- if ( !$is_comment ){
- Messages::getInstance()->cacheGroupMessageId($location['id'], $message_id);
- }
- break;
- case 'group_parents':
- case 'GROUP_PARENTS':
- if ( !$is_comment ){
- Messages::getInstance()->cacheGroupMessageId($location['id'], $message_id);
- // If the message was sent to a group's parents receiver (and not to the group itself), its message_id
- // is stored in a cached array later used to avoid displaying it to students viewing the group's stream
- $message_sent_to_group_parents_only = true;
- foreach($locations as $other_location){
- if ( ($other_location['type'] == 'group' || $other_location['type'] == 'GROUP') && $other_location['id'] == $location['id'] ){
- $message_sent_to_group_parents_only = false;
- break;
- }
- }
- if ( $message_sent_to_group_parents_only ){
- Messages::getInstance()->cacheGroupParentsMessageId($location['id'], $message_id);
- }
- }
- break;
- case 'connections':
- $this->setConnectionsLastMessageReceivers($sender_info['user_id']);
- break;
- case 'community':
- if( $is_verified_teacher &&
- $message_data['type'] != 'comment' &&
- !isset($already_cached_in_community[$location['id']])){
- Messages::getInstance()->cacheCommunityMessageId($location['id'], $message_id);
- $already_cached_in_community[$location['id']] = true;
- }
- if($location['id'] == SUPPORT_COMMUNITY_ID && !$is_comment){
- //Send an email to the support address
- $title = 'Post from ' . $sender_info['first_name'] . ' ' . $sender_info['last_name'] . ' (' . $sender_info['username'] . ')';
- $body_text = $message_data['message'];
- $recipients = array(
- array(
- 'email' => SUPPORT_COMMUNITY_EMAIL,
- 'username' => 'Support',
- ),
- );
- $tracking_data = TrackingHelper::makeTrackingData(TrackingHelper::EMAILTYPE_SUPPORT_COMMUNITY__NOTIFICATION, null, null, TrackingHelper::TYPE_SYSTEM, null, TrackingHelper::TYPE_INTERNAL, SUPPORT_COMMUNITY_EMAIL, $message_id, TrackingHelper::TYPE_MESSAGE);
- MailHandler::getInstance($body_text)->setTrackingData($tracking_data)->sendEmailWrapper($recipients, $title);
- }
- break;
- }
- }
- }
- $people_count = 0;
- if (isset($receivers['people'])){
- $people_count = count($receivers['people']);
- }
- if($people_count > 0){
- //add direct notifications for people
- if($people_count == 1){
- $receiver_info = Users::getInstance()->find($receivers['people'][0]);
- if ( $receiver_info['type'] == 'PUBLISHER' ){
- Messages::getInstance()->cachePublisherMessageId( $receiver_info['user_id'], $message_id );
- }
- }
- foreach($receivers['people'] as $user_id){
- $recipient = array(
- 'type' => 'user',
- 'message_id' => $message_id,
- 'posted_in_id' => $user_id,
- );
- $db_recipients_array[] = $recipient;
- $this->last_direct_msg_receivers[] = $user_id;
- $this->last_message_receivers[] = $user_id;
- }
- }
- // this is what actually writes to the message_recipients_* tables for the given message_id
- if ( !$is_comment ){
- Messages::getInstance()->bulkStore($db_recipients_array);
- }
- }
- /**
- * Check if a message was sent to Everyone (all the user's groups)
- */
- private function checkIfMessageSentToEveryone($sender_info, &$locations){
- $all_groups = $all_connections = false;
- $list = $locations;
- foreach ($list as $i => $location) {
- switch ($location['type']) {
- case 'all-groups':
- $all_groups = true;
- $locations = array();
- break;
- case 'connections':
- $all_connections = true;
- unset($locations[$i]);
- break;
- case 'all':
- // the message was sent to everyone
- $all_groups = true;
- $all_connections = true;
- unset($locations[$i]);
- break;
- default:
- }
- }
- if($all_groups){
- //send to all the user's groups
- $all_user_groups = Groups::getInstance()->getUserGroups($sender_info['user_id'], false, false);
- foreach($all_user_groups as $group){
- //new rule - the user must own the group in order to send the message
- if ($group['read_only'] != 1 && !empty($group['user_owns_group'])) {
- $locations[] = array('type' => GROUP, 'id' => $group['group_id']);
- }
- }
- }
- if($all_connections && ($sender_info['type'] == 'TEACHER' || $sender_info['type'] == 'PUBLISHER')){
- //send to all the teacher's connections
- $locations[] = array('type' => 'connections', 'id' => 0);
- }
- }
- /*
- * Adds the corresponding user_ids to the last_indirect_msg_receivers array (for spotlight purposes)
- */
- private function setConnectionsLastMessageReceivers($sender_id)
- {
- $user_ids = Connections::getInstance()->getConnectedUserIds($sender_id);
- foreach($user_ids as $user_id){
- $this->last_indirect_msg_receivers[] = $user_id;
- $this->last_message_receivers[] = $user_id;
- }
- }
- /*
- * Adds the corresponding user_ids to the last_indirect_msg_receivers array (for spotlight purposes)
- */
- private function setGroupLastMessageReceivers($group_id){
- $user_ids = Groups::getInstance()->getUserIds($group_id);
- foreach($user_ids as $user_id){
- $this->last_indirect_msg_receivers[] = $user_id;
- $this->last_message_receivers[] = $user_id;
- }
- }
- /**
- * Returns a list of user_ids who received the last message
- * @return array
- */
- public function getLastMessageReceivers()
- {
- $last_msg_receivers = array_merge($this->last_direct_msg_receivers,$this->last_indirect_msg_receivers);
- return $last_msg_receivers;
- }
- /**
- * Returns a list of direct user_ids who received the last message
- * @return array
- */
- public function getLastMessageDirectReceivers()
- {
- return $this->last_direct_msg_receivers;
- }
- /*
- * Modifies the contents of a mesage
- * $params string message_id is the id of the message to edit
- */
- public function editMessage($message_id, $content, $link_id = null, $new_url = null){
- if(!empty($link_id)){
- Links::getInstance()->editLink($link_id, $new_url);
- }
- MessageData::getInstance()->editMessage($message_id, $content);
- // Parse the message's content for latex math expressions and generate images
- LatexHandler::getInstance()->extractMathExpressions($content);
- }
- public function checkFilteredMessages($language, &$filters, $library_button = false, $get_community_counters = false, $get_html = false, $view = null)
- {
- $result = array();
- $the_filters = array
- (
- 'get_all_messages' => (!isset($filters['all_msgs']) || $filters['all_msgs'] == 'true') ? true : false,
- 'get_comments_only' => (!isset($filters['comments_only']) || $filters['comments_only'] == 'false') ? false : true,
- 'search_str' => isset($filters['search_str']) ? $filters['search_str'] : '',
- 'people_filter' => (!isset($filters['people_filter']) || $filters['people_filter'] == 'null') ? 'EVERYONE' : $filters['people_filter'],
- 'group_id' => (!isset($filters['group_id']) || $filters['group_id'] == 'null') ? null : $filters['group_id'],
- 'direct_user_id' => (!isset($filters['direct_user_id']) || $filters['direct_user_id'] == 'null') ? null : $filters['direct_user_id'],
- 'tag_id' => (!isset($filters['tag_id']) || $filters['tag_id'] == 'null') ? null : $filters['tag_id'],
- 'community_id' => (!isset($filters['community_id']) || $filters['community_id'] == 'null') ? null : $filters['community_id'],
- 'include_communities' => (!isset($filters['include_communities']) || $filters['include_communities'] == 'null') ? null : $filters['include_communities'],
- 'connections' => (!isset($filters['connections']) || $filters['connections'] == 'null') ? null : $filters['connections'],
- 'publishers' => (!isset($filters['publishers']) || $filters['publishers'] == 'null') ? null : $filters['publishers'],
- 'current_last_msg_id' => isset($filters['current_last_msg_id']) ? $filters['current_last_msg_id'] : 0,
- 'max_messages' => isset($filters['max_messages']) ? $filters['max_messages'] : 20,
- 'page' => isset($filters['page']) ? $filters['page'] : false,
- 'sqllimit' => isset($filters['sqllimit']) ? true : false,
- 'max_message_id' => (!isset($filters['max_message_id']) || $filters['max_message_id'] == 'null') ? null : $filters['max_message_id'],
- 'max_comment_id' => (!isset($filters['max_comment_id']) || $filters['max_comment_id'] == 'null') ? null : $filters['max_comment_id'],
- 'public_only' => (!isset($filters['public_only']) || $filters['public_only'] == 'false' || !$filters['public_only']) ? false : true,
- 'sender_id' => isset($filters['sender_id']) ? $filters['sender_id'] : false,
- 'user_feed_id' => (!isset($filters['user_feed_id']) || $filters['user_feed_id'] == 'null') ? null : $filters['user_feed_id'],
- 'students_info_for_parent' => isset($filters['students_info_for_parent'])? $filters['students_info_for_parent'] : null,
- 'parents' => isset($filters['parents'])? $filters['parents'] : null,
- 'is_inst_subdomain' => isset($filters['is_inst_subdomain'])? $filters['is_inst_subdomain'] : false,
- 'message_ids_in_stream' => isset($filters['message_ids_in_stream']) && !empty($filters['message_ids_in_stream'])? $filters['message_ids_in_stream'] : null,
- 'get_school_vip_msgs' => isset($filters['get_school_vip_msgs'])? $filters['get_school_vip_msgs'] : false,
- 'trending_posts' => isset($filters['trending_posts'])? $filters['trending_posts'] : false,
- 'max_spotlight_id' => (!isset($filters['max_spotlight_id']) || $filters['max_spotlight_id'] == 'null') ? null : $filters['max_spotlight_id']
- );
- //Set the message feed type to HOME_FEED if it's the case:
- if(empty($the_filters['people_filter']) || $the_filters['people_filter'] == 'EVERYONE'){
- $this->s…
Large files files are truncated, but you can click here to view the full file