2014-11-13 09:59:20 +08:00
2014-10-23 11:30:34 +08:00
class Course < ActiveRecord :: Base
include Redmine :: SafeAttributes
STATUS_ACTIVE = 1
STATUS_CLOSED = 5
STATUS_ARCHIVED = 9
2014-11-03 17:00:01 +08:00
attr_accessible :code , :extra , :name , :state , :tea_id , :time , :location , :state , :term , :password , :is_public , :description , :class_period , :open_student
2014-12-02 16:25:49 +08:00
#belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier
2014-10-23 11:30:34 +08:00
belongs_to :teacher , :class_name = > 'User' , :foreign_key = > :tea_id # 定义一个方法teacher, 该方法通过tea_id来调用User表
belongs_to :school , :class_name = > 'School' , :foreign_key = > :school_id #定义一个方法school, 该方法通过school_id来调用School表
has_many :bid
has_many :members , :include = > [ :principal , :roles ] , :conditions = > " #{ Principal . table_name } .type='User' AND #{ Principal . table_name } .status= #{ Principal :: STATUS_ACTIVE } "
has_many :memberships , :class_name = > 'Member'
has_many :member_principals , :class_name = > 'Member' ,
:include = > :principal ,
:conditions = > " #{ Principal . table_name } .type='Group' OR ( #{ Principal . table_name } .type='User' AND #{ Principal . table_name } .status= #{ Principal :: STATUS_ACTIVE } ) "
has_many :principals , :through = > :member_principals , :source = > :principal
has_many :users , :through = > :members
has_many :homeworks , :through = > :homework_for_courses , :source = > :bid , :dependent = > :destroy
has_many :journals_for_messages , :as = > :jour , :dependent = > :destroy
has_many :homework_for_courses , :dependent = > :destroy
has_many :student , :class_name = > 'StudentsForCourse' , :source = > :user
has_many :course_infos , :class_name = > 'CourseInfos' , :dependent = > :destroy
has_many :enabled_modules , :dependent = > :delete_all
has_many :boards , :dependent = > :destroy , :order = > " position ASC "
#has_many :course_journals_for_messages, :class_name => 'CourseJournalsForMessage', :as => :jour, :dependent => :destroy
has_many :news , :dependent = > :destroy , :include = > :author
has_one :course_status , :class_name = > " CourseStatus " , :dependent = > :destroy
2014-12-02 14:41:36 +08:00
has_many :course_groups , :dependent = > :destroy
2014-10-23 11:30:34 +08:00
acts_as_taggable
acts_as_nested_set :order = > 'name' , :dependent = > :destroy
2014-12-02 16:25:49 +08:00
acts_as_attachable :view_permission = > :view_course_files ,
2014-10-23 11:30:34 +08:00
:delete_permission = > :manage_files
2014-11-13 09:59:20 +08:00
validates_presence_of :password , :term , :name , :description
validates_format_of :class_period , :with = > / ^[1-9] \ d*$ /
validates_format_of :name , :with = > / ^[a-zA-Z0-9_ \ u4e00- \ u9fa5]+$ /
validates_length_of :description , :maximum = > 10000
2014-10-23 11:30:34 +08:00
before_save :self_validate
after_create :create_board_sync
before_destroy :delete_all_members
safe_attributes 'extra' ,
'time' ,
'name' ,
'extra' ,
'code' ,
'location' ,
'tea_id' ,
'password' ,
'term' ,
'is_public' ,
'description' ,
2014-11-03 17:00:01 +08:00
'class_period' ,
'open_student'
2014-10-23 11:30:34 +08:00
acts_as_customizable
scope :all_course
scope :active , lambda { where ( :status = > STATUS_ACTIVE ) }
scope :status , lambda { | arg | where ( arg . blank? ? nil : { :status = > arg . to_i } ) }
scope :all_public , lambda { where ( :is_public = > true ) }
scope :visible , lambda { | * args | where ( Course . visible_condition ( args . shift || User . current , * args ) ) }
scope :allowed_to , lambda { | * args |
user = User . current
permission = nil
if args . first . is_a? ( Symbol )
permission = args . shift
else
user = args . shift
permission = args . shift
end
where ( Course . allowed_to_condition ( user , permission , * args ) )
}
scope :like , lambda { | arg |
if arg . blank?
where ( nil )
else
pattern = " % #{ arg . to_s . strip . downcase } % "
where ( " LOWER(name) LIKE :p " , :p = > pattern )
end
}
def visible? ( user = User . current )
user . allowed_to? ( :view_course , self )
end
def parent_id_changed?
false
end
# Returns the mail adresses of users that should be always notified on project events
def recipients
notified_users . collect { | user | user . mail }
end
# Returns the users that should be notified on project events
def notified_users
# TODO: User part should be extracted to User#notify_about?
members . select { | m | m . principal . present? && ( m . mail_notification? || m . principal . mail_notification == 'all' ) } . collect { | m | m . principal }
end
# 课程的短描述信息
def short_description ( length = 255 )
description . gsub ( / < \/ ?.*?> / , " " ) . html_safe if description
#description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description
end
# 课程的短名称信息
def short_name ( length = 8 )
name . gsub ( / < \/ ?.*?> / , " " ) . html_safe if name
end
def strip_html ( html )
return html if html . empty? || ! html . include? ( '<' )
output = " "
tokenizer = HTML :: Tokenizer . new ( html )
while token = tokenizer . next
node = HTML :: Node . parse ( nil , 0 , 0 , token , false )
output += token unless ( node . kind_of? HTML :: Tag ) or ( token =~ / ^<! / )
end
return output
end
def extra_frozen?
errors [ :extra ] . blank? && ! ( new_record? || extra . blank? )
end
def archived?
self . status == STATUS_ARCHIVED
end
def self . visible_condition ( user , options = { } )
allowed_to_condition ( user , :view_course , options )
end
# 获取课程的资源类型列表
def attachmenttypes
@attachmenttypes = Attachmentstype . find ( :all , :conditions = > [ " #{ Attachmentstype . table_name } .typeId= ? " , self . attachmenttype ] )
end
# 获取资源后缀名列表
def contenttypes
attachmenttypes
if @attachmenttypes . length > 0
@attachmenttypes . last ( ) . suffixArr
end
end
def active?
self . status == STATUS_ACTIVE
end
#课程权限判断
def allows_to? ( action )
if archived?
# No action allowed on archived projects
return false
end
unless active? || Redmine :: AccessControl . read_action? ( action )
# No write action allowed on closed projects
return false
end
# No action allowed on disabled modules
if action . is_a? Hash
allowed_actions . include? " #{ action [ :controller ] } / #{ action [ :action ] } "
else
allowed_permissions . include? action
end
end
# 课程允许的权限集合
def allowed_permissions
@allowed_permissions || = begin
module_names = enabled_modules . all ( :select = > :name ) . collect { | m | m . name }
Redmine :: AccessControl . modules_permissions ( module_names ) . collect { | p | p . name }
end
end
# 课程允许的动作集合
def allowed_actions
@actions_allowed || = allowed_permissions . inject ( [ ] ) { | actions , permission | actions += Redmine :: AccessControl . allowed_actions ( permission ) } . flatten
end
# 返回用户组可以访问的课程
def users_by_role
members . includes ( :user , :roles ) . all . inject ( { } ) do | h , m |
m . roles . each do | r |
h [ r ] || = [ ]
h [ r ] << m . user
end
h
end
end
#自定义验证
def self_validate
end
# 创建课程讨论区
def create_board_sync
@board = self . boards . build
2015-01-05 16:58:11 +08:00
#self.name=" #{l(:label_borad_course) }"
@board . name = " #{ l ( :label_borad_course ) } " #self.name
2014-10-23 11:30:34 +08:00
@board . description = self . name . to_s
@board . project_id = - 1
if @board . save
logger . debug " [Course Model] ===> #{ @board . to_json } "
else
logger . error " [Course Model] ===> Auto create board when course saved, because #{ @board . full_messages } "
end
end
# 新增课程留言
# add by nwb
def self . add_new_jour ( user , notes , id , options = { } )
course = Course . find ( id )
if options . count == 0
pjfm = course . journals_for_messages . build ( :user_id = > user . id , :notes = > notes , :reply_id = > 0 )
else
pjfm = course . journals_for_messages . build ( options )
end
pjfm . save
pjfm
end
# 删除课程所有成员
def delete_all_members
if self . members && self . members . count > 0
me , mr = Member . table_name , MemberRole . table_name
connection . delete ( " DELETE FROM #{ mr } WHERE #{ mr } .member_id IN (SELECT #{ me } .id FROM #{ me } WHERE #{ me } .course_id = #{ id } ) " )
Member . delete_all ( [ 'course_id = ?' , id ] )
end
end
def get_endup_time
begin
end_time = Time . parse ( self . endup_time )
rescue Exception = > e
end_time = Time . parse ( " 3000-01-01 " )
Rails . logger . error " [Error] course endup_time error. ===> #{ e } "
ensure
return end_time
end
end
def get_time
begin
time = Date . new ( self . time ) . to_time
rescue Exception = > e
time = Time . parse ( " 3000-01-01 " )
Rails . logger . error " [Error] course time error. ===> #{ e } "
ensure
return time
end
end
def self . allowed_to_condition ( user , permission , options = { } )
perm = Redmine :: AccessControl . permission ( permission )
base_statement = ( perm && perm . read? ? " #{ Course . table_name } .status <> #{ Course :: STATUS_ARCHIVED } " : " #{ Course . table_name } .status = #{ Course :: STATUS_ACTIVE } " )
if perm && perm . course_module
base_statement << " AND #{ Course . table_name } .id IN (SELECT em.course_id FROM #{ EnabledModule . table_name } em WHERE em.name=' #{ perm . course_module } ') "
end
if options [ :course ]
course_statement = " #{ Course . table_name } .id = #{ options [ :course ] . id } "
course_statement << " OR ( #{ Course . table_name } .lft > #{ options [ :course ] . lft } AND #{ Course . table_name } .rgt < #{ options [ :course ] . rgt } ) " if options [ :with_subcourses ]
base_statement = " ( #{ course_statement } ) AND ( #{ base_statement } ) "
end
if user . admin?
base_statement
else
statement_by_role = { }
unless options [ :member ]
role = user . logged? ? Role . non_member : Role . anonymous
if role . allowed_to? ( permission )
statement_by_role [ role ] = " #{ Course . table_name } .is_public = #{ connection . quoted_true } "
end
end
if user . logged?
user . courses_by_role . each do | role , courses |
if role . allowed_to? ( permission ) && courses . any?
statement_by_role [ role ] = " #{ Course . table_name } .id IN ( #{ courses . collect ( & :id ) . join ( ',' ) } ) "
end
end
end
if statement_by_role . empty?
" 1=0 "
else
if block_given?
statement_by_role . each do | role , statement |
if s = yield ( role , user )
statement_by_role [ role ] = " ( #{ statement } AND ( #{ s } )) "
end
end
end
" (( #{ base_statement } ) AND ( #{ statement_by_role . values . join ( ' OR ' ) } )) "
end
end
end
#项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题
#def name
# read_attribute('name') || Project.find_by_identifier(self.extra).try(:name)
#end
end
2014-11-13 09:59:20 +08:00