2016-04-12 11:00:47 +08:00
#encoding: utf-8
2015-04-07 13:47:39 +08:00
# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Message < ActiveRecord :: Base
2016-04-12 11:00:47 +08:00
require 'net/http'
require 'json'
2015-04-07 13:47:39 +08:00
include Redmine :: SafeAttributes
include UserScoreHelper
include ApplicationHelper
has_many_kindeditor_assets :assets , :dependent = > :destroy
2015-11-26 16:43:10 +08:00
belongs_to :board , :touch = > true
2015-04-07 13:47:39 +08:00
belongs_to :author , :class_name = > 'User' , :foreign_key = > 'author_id'
has_many :praise_tread , as : :praise_tread_object , dependent : :destroy
2015-12-30 15:46:01 +08:00
# has_many :org_subfield_messages, :dependent => :destroy
# has_many :org_subfields, :through => :org_subfield_messages
2015-04-07 13:47:39 +08:00
acts_as_tree :counter_cache = > :replies_count , :order = > " #{ Message . table_name } .created_on ASC "
acts_as_attachable
belongs_to :last_reply , :class_name = > 'Message' , :foreign_key = > 'last_reply_id'
# added by fq
has_many :acts , :class_name = > 'Activity' , :as = > :act , :dependent = > :destroy
# 被ForgeActivity虚拟关联
has_many :forge_acts , :class_name = > 'ForgeActivity' , :as = > :forge_act , :dependent = > :destroy
2015-08-11 15:54:05 +08:00
# 课程动态
has_many :course_acts , :class_name = > 'CourseActivity' , :as = > :course_act , :dependent = > :destroy
2016-01-12 15:53:15 +08:00
2015-04-07 13:47:39 +08:00
# end
2015-08-18 10:31:40 +08:00
# 课程/项目 消息
2015-08-14 17:35:10 +08:00
has_many :course_messages , :class_name = > 'CourseMessage' , :as = > :course_message , :dependent = > :destroy
2015-08-18 10:31:40 +08:00
has_many :forge_messages , :class_name = > 'ForgeMessage' , :as = > :forge_message , :dependent = > :destroy
2015-12-17 15:14:52 +08:00
has_many :at_messages , as : :at_message , dependent : :destroy
2015-04-07 13:47:39 +08:00
2015-06-04 15:55:41 +08:00
has_many :ActivityNotifies , :as = > :activity , :dependent = > :destroy
2016-02-25 16:22:42 +08:00
#转发表
has_many :forwards , :as = > :from , :dependent = > :destroy
2015-12-30 18:44:54 +08:00
after_destroy :delete_org_activities
2015-04-07 13:47:39 +08:00
acts_as_searchable :columns = > [ 'subject' , 'content' ] ,
:include = > { :board = > :project } ,
:project_key = > " #{ Board . table_name } .project_id " ,
:date_column = > " #{ table_name } .created_on "
acts_as_searchable :columns = > [ 'subject' , 'content' ] ,
:include = > { :board = > :course } ,
:course_key = > " #{ Board . table_name } .course_id " ,
:date_column = > " #{ table_name } .created_at "
acts_as_event :title = > Proc . new { | o | " #{ o . board . name } : #{ o . subject } " } ,
:description = > :content ,
:datetime = > :updated_on ,
# :datetime => "#{Message.table_name}.created_on",
:group = > :parent ,
:type = > Proc . new { | o | o . parent_id . nil? ? 'message' : 'reply' } ,
:url = > Proc . new { | o | { :controller = > 'messages' , :action = > 'show' , :board_id = > o . board_id } . merge ( o . parent_id . nil? ? { :id = > o . id } :
{ :id = > o . parent_id , :r = > o . id , :anchor = > " message- #{ o . id } " } ) }
acts_as_activity_provider :find_options = > { :include = > [ { :board = > :project } , :author ] } ,
:author_key = > :author_id
acts_as_activity_provider :find_options = > { :include = > [ { :board = > :course } , :author ] } ,
:type = > 'course_messages' ,
:author_key = > :author_id
acts_as_watchable
validates_presence_of :board , :subject , :content
validates_length_of :subject , :maximum = > 255
validate :cannot_reply_to_locked_topic , :on = > :create
2016-04-18 15:37:32 +08:00
# after_create :add_author_as_watcher, :reset_counters!, :add_boards_count
2016-01-12 15:53:15 +08:00
after_update :update_messages_board , :update_activity
2016-03-08 17:38:38 +08:00
after_destroy :reset_counters! , :down_user_score , :delete_kindeditor_assets , :decrease_boards_count , :down_course_score
2016-04-22 14:14:21 +08:00
after_create :act_as_course_activity , :act_as_forge_activity , :act_as_student_score , act_as_at_message ( :content , :author_id ) , :add_author_as_watcher , :reset_counters! , :add_boards_count
2015-04-07 13:47:39 +08:00
#before_save :be_user_score
scope :visible , lambda { | * args |
includes ( :board = > :project ) . where ( Project . allowed_to_condition ( args . shift || User . current , :view_messages , * args ) )
}
scope :course_visible , lambda { | * args |
includes ( :board = > :course ) . where ( Course . allowed_to_condition ( args . shift || User . current , :view_course_messages , * args ) )
}
2015-09-24 16:38:36 +08:00
safe_attributes 'subject' , 'content' , 'reply_id'
2015-04-07 13:47:39 +08:00
safe_attributes 'board_id' , 'locked' , 'sticky' ,
:if = > lambda { | message , user |
if message . project
user . allowed_to? ( :edit_messages , message . project )
else
user . allowed_to? ( :edit_messages , message . course )
end
}
2015-12-17 15:14:52 +08:00
def topic?
parent_id . nil?
end
2015-04-07 13:47:39 +08:00
def visible? ( user = User . current )
if project
! user . nil? && user . allowed_to? ( :view_messages , project )
elsif course
! user . nil? && user . allowed_to? ( :view_messages , course )
end
end
def cannot_reply_to_locked_topic
# Can not reply to a locked topic
errors . add :base , 'Topic is locked' if root . locked? && self != root
end
def update_messages_board
if board_id_changed?
Message . update_all ( { :board_id = > board_id } , [ " id = ? OR parent_id = ? " , root . id , root . id ] )
Board . reset_counters! ( board_id_was )
Board . reset_counters! ( board_id )
end
end
2016-01-13 10:08:48 +08:00
# 发帖精辟更新发帖总数
def add_boards_count
2016-01-14 15:42:27 +08:00
if self . project && ! project . project_score . nil?
# 讨论区
if self . parent_id . nil?
2016-04-18 15:37:32 +08:00
count = self . project . project_score . board_num . to_i + 1
self . project . project_score . update_column ( :board_num , count )
2016-01-14 15:42:27 +08:00
else # 回复
2016-04-18 15:37:32 +08:00
count = self . project . project_score . board_message_num . to_i + 1
self . project . project_score . update_column ( :board_message_num , count )
2016-01-14 14:32:19 +08:00
end
end
end
# 删除帖子的时候更新帖子总数, 删除回复的时候总数不减少
def decrease_boards_count
2016-01-14 15:42:27 +08:00
if self . project && ! project . project_score . nil?
# 讨论区
if self . parent_id . nil?
count = self . project . project_score . board_num - 1
2016-02-23 13:24:20 +08:00
self . project . project_score . update_attribute ( :board_num , count < 0 ? 0 : count )
2016-01-14 15:42:27 +08:00
else # 回复
count = self . project . project_score . board_message_num - 1
2016-02-23 13:24:20 +08:00
self . project . project_score . update_attribute ( :board_message_num , count < 0 ? 0 : count )
2016-01-13 15:29:29 +08:00
end
2016-01-13 10:08:48 +08:00
end
end
2015-04-07 13:47:39 +08:00
def reset_counters!
if parent && parent . id
Message . update_all ( { :last_reply_id = > parent . children . maximum ( :id ) } , { :id = > parent . id } )
end
board . reset_counters!
end
def sticky = ( arg )
write_attribute :sticky , ( arg == true || arg . to_s == '1' ? 1 : 0 )
end
def sticky?
sticky == 1
end
def project
board . project
end
def course
board . course
end
def course_editable_by? ( usr )
usr && usr . logged? && ( usr . allowed_to? ( :edit_messages , course ) || ( self . author == usr && usr . allowed_to? ( :edit_own_messages , course ) ) )
end
2015-12-30 15:46:01 +08:00
def org_subfield_editable_by? ( usr )
2015-12-30 17:25:06 +08:00
usr && usr . logged? && ( usr . admin? || self . author == usr || usr . admin_of_org? ( self . board . org_subfield . organization ) )
2015-12-30 15:46:01 +08:00
end
2015-04-07 13:47:39 +08:00
def course_destroyable_by? ( usr )
usr && usr . logged? && ( usr . allowed_to? ( :delete_messages , course ) || ( self . author == usr && usr . allowed_to? ( :delete_own_messages , course ) ) )
end
def editable_by? ( usr )
usr && usr . logged? && ( usr . allowed_to? ( :edit_messages , project ) || ( self . author == usr && usr . allowed_to? ( :edit_own_messages , project ) ) )
end
def destroyable_by? ( usr )
usr && usr . logged? && ( usr . allowed_to? ( :delete_messages , project ) || ( self . author == usr && usr . allowed_to? ( :delete_own_messages , project ) ) )
end
2015-06-04 15:55:41 +08:00
def set_notify_id ( notify_id )
@notify_id = notify_id
end
def get_notify_id ( )
return @notify_id
end
def set_notify_is_read ( notify_is_read )
@notify_is_read = notify_is_read
end
def get_notify_is_read ( )
return @notify_is_read
end
2016-01-12 15:53:15 +08:00
#动态的更新
def update_activity
update_course_activity ( self . class , self . id )
update_user_activity ( self . class , self . id )
update_forge_activity ( self . class , self . id )
update_org_activity ( self . class , self . id )
end
2015-06-04 15:55:41 +08:00
2015-04-07 13:47:39 +08:00
private
def add_author_as_watcher
Watcher . create ( :watchable = > self . root , :user = > author )
end
# fq
def act_as_activity
self . acts << Activity . new ( :user_id = > self . author_id )
end
# end
# Time 2015-02-27 14:32:25
# Author lizanle
# Description
def act_as_forge_activity
# 如果project为空, 那么就是课程相关的消息
2015-12-30 15:46:01 +08:00
if self . board . project_id != - 1 && self . parent_id . nil?
2016-01-05 15:59:13 +08:00
self . forge_acts << ForgeActivity . new ( :user_id = > self . author_id , :project_id = > self . board . project . id )
2015-04-07 13:47:39 +08:00
end
end
2015-08-11 15:54:05 +08:00
#课程动态公共表记录
def act_as_course_activity
2015-09-25 16:29:47 +08:00
if self . course && self . parent_id . nil?
2015-08-11 15:54:05 +08:00
self . course_acts << CourseActivity . new ( :user_id = > self . author_id , :course_id = > self . board . course_id )
end
end
2015-08-15 00:08:05 +08:00
2015-08-18 10:31:40 +08:00
# 课程讨论区添加消息:
2015-08-15 00:08:05 +08:00
# 老师发帖所有人都能收到消息
# 学生发帖,有人回复则给该学生消息,没回复则不给其它人发送消息
# 帖子被回复的可以收到消息通知
2015-08-18 10:31:40 +08:00
# 项目讨论区添加消息:
# 主贴项目成员都能收到
# 回帖:帖子的发布人收到
def act_as_system_message
2016-04-14 10:47:53 +08:00
ws = WechatService . new
2015-08-15 00:08:05 +08:00
if self . course
2015-08-18 10:31:40 +08:00
if self . parent_id . nil? # 主贴
2016-04-22 12:44:37 +08:00
self . course . members . includes ( :user ) . each do | m |
2015-08-18 10:31:40 +08:00
if self . author . allowed_to? ( :as_teacher , self . course ) && m . user_id != self . author_id # 老师 自己的帖子不给自己发送消息
self . course_messages << CourseMessage . new ( :user_id = > m . user_id , :course_id = > self . board . course_id , :viewed = > false )
2016-04-27 10:28:36 +08:00
if ShieldWechatMessage . where ( " container_type='User' and container_id= #{ m . user_id } and shield_type='Course' and shield_id= #{ self . course . id } " ) . count == 0
content = strip_html self . subject , 200
ws . topic_publish_template m . user_id , " course_discussion " , self . id , " #{ l ( :label_course_topic_template ) } " , content , self . author . try ( :realname ) , format_time ( self . created_on )
end
2015-08-15 00:08:05 +08:00
end
end
else # 回帖
2016-04-27 10:28:36 +08:00
parent_author_id = Message . find ( self . parent_id ) . author_id
if parent_author_id != self . author_id # 只针对主贴回复,回复自己的帖子不发消息
self . course_messages << CourseMessage . new ( :user_id = > parent_author_id , :course_id = > self . board . course_id , :viewed = > false )
if ShieldWechatMessage . where ( " container_type='User' and container_id= #{ parent_author_id } and shield_type='Course' and shield_id= #{ self . board . course_id } " ) . count == 0
2016-04-20 10:44:54 +08:00
content = strip_html self . content . html_safe , 200
2016-04-27 10:28:36 +08:00
ws . comment_template parent_author_id , " course_discussion " , self . parent_id , " #{ l ( :label_topic_comment_template ) } " , self . author . try ( :realname ) , format_time ( self . created_on ) , content
2015-08-15 00:08:05 +08:00
end
2015-08-18 10:31:40 +08:00
end
end
2015-12-30 15:46:01 +08:00
elsif self . project # 项目相关
2015-08-18 10:31:40 +08:00
if self . parent_id . nil? # 主贴
2016-04-22 12:44:37 +08:00
self . project . members . includes ( :user ) . each do | m |
2015-08-18 10:31:40 +08:00
if m . user_id != self . author_id
self . forge_messages << ForgeMessage . new ( :user_id = > m . user_id , :project_id = > self . board . project_id , :viewed = > false )
2016-04-27 10:28:36 +08:00
if ShieldWechatMessage . where ( " container_type='User' and container_id= #{ m . user_id } and shield_type='Project' and shield_id= #{ self . project . id } " ) . count == 0
content = strip_html self . subject , 200
ws . topic_publish_template m . user_id , " project_discussion " , self . id , " #{ l ( :label_project_topic_template ) } " , content , self . author . try ( :realname ) , format_time ( self . created_on )
end
2015-08-18 10:31:40 +08:00
end
end
else # 回帖
2016-04-27 10:28:36 +08:00
parent_author_id = Message . find ( self . parent_id ) . author_id
if parent_author_id != self . author_id # 只针对主贴回复,回复自己的帖子不发消息
self . forge_messages << ForgeMessage . new ( :user_id = > parent_author_id , :project_id = > self . board . project_id , :viewed = > false )
if ShieldWechatMessage . where ( " container_type='User' and container_id= #{ parent_author_id } and shield_type='Project' and shield_id= #{ self . board . project_id } " ) . count == 0
2016-04-20 10:44:54 +08:00
content = strip_html self . content . html_safe , 200
2016-04-27 10:28:36 +08:00
ws . comment_template parent_author_id , " project_discussion " , self . parent_id , " #{ l ( :label_topic_comment_template ) } " , self . author . try ( :realname ) , format_time ( self . created_on ) , content
2015-08-18 10:31:40 +08:00
end
end
2015-08-15 00:08:05 +08:00
end
end
end
2015-12-17 15:14:52 +08:00
2015-04-07 13:47:39 +08:00
#更新用户分数 -by zjc
def be_user_score
#新建message且无parent的为发帖
if self . parent_id . nil? && ! self . board . project . nil?
UserScore . joint ( :post_message , self . author , nil , self , { message_id : self . id } )
update_memo_number ( self . author , 1 )
if self . board . project_id != - 1
update_memo_number ( self . author , 2 , self . board . project )
end
#新建message且有parent的为回帖
elsif ! self . parent_id . nil? && ! self . board . project . nil?
UserScore . joint ( :reply_posting , self . author , self . parent . author , self , { message_id : self . id } )
update_replay_for_memo ( self . author , 1 )
if self . board . project_id != - 1
update_replay_for_memo ( self . author , 2 , self . board . project )
end
end
end
#减少用户分数
def down_user_score
if self . parent_id . nil? && ! self . board . project . nil?
UserScore . joint ( :delete_message , self . author , nil , self , { message_id : self . id } )
update_memo_number ( User . current , 1 )
if self . board . project_id != - 1
update_memo_number ( self . author , 2 , self . board . project )
end
elsif ! self . parent_id . nil? && ! self . board . project . nil?
UserScore . joint ( :reply_deleting , self . author , self . parent . author , self , { message_id : self . id } )
update_replay_for_memo ( User . current , 1 )
if self . board . project_id != - 1
update_replay_for_memo ( self . author , 2 , self . board . project )
end
end
end
def send_mail
Mailer . run . message_posted ( self ) if Setting . notified_events . include? ( 'message_posted' )
end
# Time 2015-03-31 09:15:06
# Author lizanle
# Description 删除对应消息的图片资源
def delete_kindeditor_assets
delete_kindeditor_assets_from_disk self . id , OwnerTypeHelper :: MESSAGE
end
2015-06-04 15:55:41 +08:00
2016-03-05 03:13:58 +08:00
# 课程成员得分(活跃度)
2015-11-26 18:22:03 +08:00
def act_as_student_score
2015-11-27 18:36:38 +08:00
if self . course
2016-03-05 03:13:58 +08:00
if self . parent_id . nil?
# 发帖
course_member_score ( self . course . id , self . author_id , " Message " )
else
# 回帖
course_member_score ( self . course . id , self . author_id , " MessageReply " )
2015-11-26 18:22:03 +08:00
end
end
end
2015-12-30 18:44:54 +08:00
2016-03-08 17:38:38 +08:00
# 删除帖子的时候更新课程帖子总数, 删除回复的时候减少总数
def down_course_score
if self . course
if self . parent_id . nil? # 发帖
down_course_score_num ( self . course . id , self . author_id , " Message " )
else
# 回帖
down_course_score_num ( self . course . id , self . author_id , " MessageReply " )
end
end
end
2015-12-30 18:44:54 +08:00
def delete_org_activities
OrgActivity . where ( " org_act_type='Message' and org_act_id = #{ self . id } and container_type='OrgSubfield' " ) . destroy_all
end
2015-04-07 13:47:39 +08:00
end