socialforge/app/controllers/projects_controller.rb

671 lines
22 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
# Time 2015-01-28 16:34:21
# Author lizanle
# Description 封装代码,简化代码,格式化代码,
class ProjectsController < ApplicationController
layout :select_project_layout
before_filter :authorize1, :only => [:show]
menu_item :overview, :only => :show
menu_item :roadmap, :only => :roadmap
menu_item :settings, :only => :settings
menu_item :homework, :only => [:homework, :new_homework]
menu_item :feedback, :only => :feedback
menu_item :share, :only => :share
before_filter :find_project, :except => [ :index, :search,:list, :new, :create, :copy, :statistics, :new_join,
:course, :enterprise_course, :course_enterprise,:view_homework_attaches]
before_filter :authorize, :only => [:show, :settings, :edit, :sort_project_members, :update, :modules, :close,
:reopen,:view_homework_attaches,:course]
before_filter :find_project, :except => [ :index, :search,:list, :new, :create, :copy, :statistics, :new_join, :course, :enterprise_course, :course_enterprise,:view_homework_attaches,:join_project]
# before_filter :authorize, :except => [:new_join, :new_homework, :homework, :statistics, :search, :watcherlist, :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy, :member, :focus, :file,
# :statistics, :feedback, :course, :enterprise_course, :course_enterprise, :project_respond, :share,
# :show_projects_score, :issue_score_index, :news_score_index, :file_score_index, :code_submit_score_index, :projects_topic_score_index]
#此条勿删 课程相关权限 ,:new_homework,:homework,:feedback,,:member
before_filter :authorize, :only => [:show, :settings, :edit, :sort_project_members, :update, :modules, :close, :reopen,:view_homework_attaches,:course]
before_filter :authorize_global, :only => [:new, :create,:view_homework_attaches]
before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy, :calendar]
before_filter :file, :statistics, :watcherlist
# 除非项目内人员,不可查看成员, TODO: 完了写报表里去
before_filter :memberAccess, only: :member
# accept_rss_auth :index
accept_api_auth :index, :show, :create, :update, :destroy
after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller|
if controller.request.post?
controller.send :expire_action, :controller => 'welcome', :action => 'robots'
end
end
helper :bids
include BidsHelper
helper :contests
include ContestsHelper
helper :sort
include SortHelper
helper :custom_fields
include CustomFieldsHelper
helper :issues
helper :queries
include QueriesHelper
helper :repositories
include RepositoriesHelper
include ProjectsHelper
helper :members
helper :activities
helper :documents
helper :watchers
# helper :watcherlist
helper :words
helper :project_score
helper :user_score
### added by william
include ActsAsTaggableOn::TagsHelper
def index
render_404
end
def course
render_404
end
# Time 2015-01-29 11:19:11
# Author lizanle
# Description 项目搜索方法
def search
# 如果有名字,就按名字搜索,如果没有,就展示所有,用Karminari分页
if params[:name].present?
@project_pages = Project.project_entities.visible.like(params[:name]).page(params[:page]).per(10)
else
@project_pages = Project.project_entities.visible.page(params[:page] ).per(10)
end
@projects = @project_pages.order("created_on desc")
respond_to do |format|
format.html {
render :layout => 'base'
scope = Project
unless params[:closed]
scope = scope.active
end
}
# 需要到处atom使用的格式 redmine自带
format.atom {
projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all
render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
}
end
end
# Time 2015-01-29 16:13:20
# Author lizanle
# Description 项目首页中用户反馈 方法
def feedback
@page = params[:page].to_i
# Find the page of the requested reply
@jours = @project.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
limit = 10
offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i])
page = 1 + offset / limit
if params[:r] && @page.nil?
@page = @page < 0 ? 1 : @page
end
@page = @page > page ? page : @page
@jour = paginateHelper @jours,10
@state = false
respond_to do |format|
format.html
format.api
end
end
def project_respond
project_id = request.headers["Referer"].match((%r|/([0-9]{1,})/|))[1]
parent_id = params[:reference_id]
author_id = User.current.id
reply_user_id = params[:reference_user_id]
reply_id = params[:reference_message_id]
content = params[:project_respond]
options = {:user_id => author_id,
:m_parent_id => parent_id,
:m_reply_id => reply_id,
:reply_id => reply_user_id,
:notes => content,
:is_readed => false}
@jfm = Project.add_new_jour(nil, nil, project_id, options)
@save_succ = @jfm.errors.empty?
respond_to do |format|
format.js
end
end
def new
@issue_custom_fields = IssueCustomField.sorted.all
@trackers = Tracker.sorted.all
@project = Project.new
@project.safe_attributes = params[:project]
render :layout => 'base'
end
def share
@shares = @project.shares.reverse
@base_courses_tag = @project.project_type
respond_to do |format|
format.html{render :layout => 'base_courses' if @base_courses_tag==1}
format.api
end
end
def create
@issue_custom_fields = IssueCustomField.sorted.all
@trackers = Tracker.sorted.all
@project = Project.new
@project.safe_attributes = params[:project]
@project.organization_id = params[:organization_id]
if validate_parent_id && @project.save
@project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
# Add current user as a project member if he is not admin
#unless User.current.admin?
r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first
m = Member.new(:user => User.current, :roles => [r])
project_info = ProjectInfo.new(:user_id => User.current.id, :project_id => @project.id)
user_grades = UserGrade.create(:user_id => User.current.id, :project_id => @project.id)
Rails.logger.debug "UserGrade created: #{user_grades.to_json}"
#if params[:project][:is_public] == '1'
project_status = ProjectStatus.create(:project_id => @project.id, :watchers_count => 0, :changesets_count => 0, :project_type => @project.project_type,:grade => 0)
Rails.logger.debug "ProjectStatus created: #{project_status.to_json}"
#end
@project.members << m
@project.project_infos << project_info
#end
respond_to do |format|
format.html {
flash[:notice] = l(:notice_successful_create)
if params[:continue]
attrs = {:parent_id => @project.parent_id}.reject {|k,v| v.nil?}
redirect_to new_project_url(attrs, :course => '0')
else
redirect_to settings_project_url(@project)
end
}
format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
end
else
respond_to do |format|
format.html { render :action => 'new', :layout => 'base'}#Added by young
format.api { render_validation_errors(@project) }
end
end
end
def copy
@issue_custom_fields = IssueCustomField.sorted.all
@trackers = Tracker.sorted.all
@source_project = Project.find(params[:id])
if request.get?
@project = Project.copy_from(@source_project)
@project.identifier = Project.next_identifier if Setting.sequential_project_identifiers?
else
Mailer.with_deliveries(params[:notifications] == '1') do
@project = Project.new
@project.safe_attributes = params[:project]
if validate_parent_id && @project.copy(@source_project, :only => params[:only])
@project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
flash[:notice] = l(:notice_successful_create)
redirect_to settings_project_url(@project)
elsif !@project.new_record?
# Project was created
# But some objects were not copied due to validation failures
# (eg. issues from disabled trackers)
# TODO: inform about that
redirect_to settings_project_url(@project)
end
end
end
rescue ActiveRecord::RecordNotFound
# source_project not found
render_404
end
# Time 2015-01-29 10:42:00
# Author lizanle
# Description 项目动态展示方法,删除了不必要的代码
def show
# 试图跳转到请求的按钮
if params[:login]
login = params[:login]
login = login.sub(/%40/,'@')
mail = params[:login]
password = params[:password]
us = UsersService.new
user = us.register_auto(login,mail, password)
Member.create(:role_ids => [4], :user_id => user.id,:project_id => @project.id)
UserGrade.create(:user_id => user.id, :project_id => @project.id)
User.current = user unless User.current.nil?
end
if params[:jump] && redirect_to_project_menu_item(@project, params[:jump])
return
end
=begin
cond = @project.project_condition(Setting.display_subprojects_issues?)
has = {
"show_issues" => true ,
"show_files" => true,
"show_documents" => true,
"show_messages" => true,
"show_news" => true,
"show_bids" => true,
"show_contests" => true,
"show_wiki_edits"=>true,
"show_journals_for_messages" => true
}
# 读取项目默认展示的动态时间天数
@days = Setting.activity_days_default.to_i
@date_to ||= Date.today + 1
# 时间跨度不能太大,不然很慢,所以删掉了-1.years
@date_from = @date_to - @days
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
=end
@author = params[:user_id].blank? ? nil : User.active.find(params[:user_id])
# 决定显示所用用户或单个用户活动
=begin
@activity = Redmine::Activity::Fetcher.new(User.current,
:project => @project,
:with_subprojects => @with_subprojects,
:author => @author)
@activity.scope_select {|t| !has["show_#{t}"].nil?}
=end
# 根据私密性,取出符合条件的所有数据
if User.current.member_of?(@project) || User.current.admin?
@events_pages = ForgeActivity.where("project_id = ?",@project).order("created_at desc").page(params['page'|| 1]).per(20);
#events = @activity.events(@date_from, @date_to)
else
@events_pages = ForgeActivity.includes(:project).where("forge_activities.project_id = ? and projects.is_public
= ?",@project,1).order("created_at desc")
.page(params['page'|| 1]).per(10);
# @events = @activity.events(@date_from, @date_to, :is_public => 1)
end
=begin
@events_pages = Paginator.new events.count, 10, params['page']
# 总的数据中取出某一页
events = events.slice(@events_pages.offset,10)
# 按天分组
@events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)}
=end
boards = @project.boards.includes(:last_message => :author).all
@topic_count = @project.boards.count
# 根据对应的请求,返回对应的数据
respond_to do |format|
format.html
format.api
format.js
end
end
def settings
@issue_custom_fields = IssueCustomField.sorted.all
@issue_category ||= IssueCategory.new
@member ||= @project.members.new
@trackers = Tracker.sorted.all
@wiki ||= @project.wiki
end
def send_mail_to_member
if !params[:mail].nil? && User.find_by_mail(params[:mail].to_s).nil?
email = params[:mail]
Mailer.send_invite_in_project(email, @project, User.current).deliver
@is_zhuce =false
else
@is_zhuce = true
end
respond_to do |format|
format.js
end
end
#发送邮件邀请新用户
def invite_members_by_mail
@is_zhuce =false
respond_to do |format|
format.html
format.js
end
end
# 邀请Trustie注册用户
def invite_members
@member ||= @project.members.new
end
def edit
end
# by young
# include CoursesHelper
def member
## 有角色参数的才是课程,没有的就是项目
@render_file = 'member_list'
# 判断是否课程
if @project.project_type == Project::ProjectType_course
@teachers= searchTeacherAndAssistant(@project)
@canShowCode = isCourseTeacher(User.current.id)
case params[:role]
when '1'
@subPage_title = l :label_teacher_list
@members = searchTeacherAndAssistant(@project)
when '2'
@subPage_title = l :label_student_list
@members = searchStudent(@project)
else
@subPage_title = ''
@members = @project.member_principals.includes(:roles, :principal).all.sort
end
else
roles = Role.find_all_givable
@subPage_title = l :label_member_list
@members = @project.member_principals.includes(:roles, :principal).joins("LEFT JOIN #{OptionNumber.table_name} ON #{OptionNumber.table_name}.user_id = #{Member.table_name}.user_id and #{OptionNumber.table_name}.score_type = 2 AND #{Member.table_name}.project_id = #{OptionNumber.table_name}.project_id").order("#{OptionNumber.table_name}.total_score DESC").all
@applied_members = appied_project_members(@project, @members)
end
@members = paginateHelper @members
render :layout => 'base_courses' if @project.project_type == 1
end
#判断指定用户是否为课程教师
def isCourseTeacher(id)
result = false
if @teachers.find_by_user_id(id) != nil
result = true
end
result
end
def sort_project_members project, members
#userGrade = UserGrade.where(:project_id => project.id)
users = UserGrade.where(:project_id => project.id).
order('grade DESC').
joins("LEFT JOIN users ON users.id = user_grades.id").
select("DISTINCT user_grades.user_id")
memberlist = []
users.each do |user|
members.each do |member|
if member[:user_id] == user[:user_id]
memberlist << member
end
end
end
memberlist
end
def appied_project_members (project, members)
users = AppliedProject.where(:project_id => project.id)
memberlist = []
users.each do |user|
members.each do |member|
if member[:user_id] == user[:user_id]
memberlist << member
end
end
end
memberlist
end
def file
end
def statistics
end
#end
def update
@project.safe_attributes = params[:project]
@project.organization_id = params[:organization_id]
#@project.dts_test = params[:project][:dts_test]
if validate_parent_id && @project.save
@course = Course.find_by_extra(@project.identifier)
unless @course.nil?
@course.password = params[:project][:course][:password]
# added by bai
@course.term = params[:term]
@course.time = params[:time]
@course.setup_time = params[:setup_time]
@course.endup_time = params[:endup_time]
@course.class_period = params[:class_period]
# end
@course.save
end
@project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
if params[:project][:is_public] == '0'
project_status = ProjectStatus.find_by_project_id(@project.id)
project_status.destroy if project_status
elsif params[:project][:is_public] == '1'
project_status = ProjectStatus.create(:project_id => @project.id, :watchers_count => @project.watchers.count, :changesets_count => @project.changesets.count,:grade => 0, :project_type => @project.project_type)
end
respond_to do |format|
format.html {
flash[:notice] = l(:notice_successful_update)
redirect_to settings_project_url(@project,:course => @project.project_type)
}
format.api { render_api_ok }
end
else
respond_to do |format|
format.html {
settings
render :action => 'settings'
}
format.api { render_validation_errors(@project) }
end
end
end
def modules
@project.enabled_module_names = params[:enabled_module_names]
flash[:notice] = l(:notice_successful_update)
redirect_to settings_project_url(@project, :tab => 'modules')
end
def archive
if request.post?
unless @project.archive
flash[:error] = l(:error_can_not_archive_project)
end
end
redirect_to admin_projects_url(:status => params[:status])
end
def unarchive
@project.unarchive if request.post? && !@project.active?
redirect_to admin_projects_url(:status => params[:status])
end
def close
@project.close
redirect_to project_url(@project)
end
def reopen
@project.reopen
redirect_to project_url(@project)
end
# Delete @project
def destroy
@project_to_destroy = @project
if api_request? || params[:confirm]
@project_to_destroy.destroy
respond_to do |format|
format.html { redirect_to admin_projects_url }
format.api { render_api_ok }
end
else
render :layout => "project_base"
end
# hide project in layout
@project = nil
end
def show_projects_score
respond_to do |format|
format.html { render :layout => "project_base"}
format.js
end
end
def issue_score_index
respond_to do |format|
format.js
end
end
def news_score_index
end
def file_score_index
end
def code_submit_score_index
end
def projects_topic_score_index
end
# end
before_filter :toggleCourse, only: [:finishcourse, :restartcourse]
# 最好通过用户与项目的权限解决这种事情。还没写
def finishcourse
yesterday = Date.today.prev_day.to_time
@course_prefs.endup_time = yesterday
@save_flag = @course_prefs.save
respond_to do |format|
format.js
end
end
def restartcourse
day = Time.parse("3000-01-01")
@course_prefs.endup_time = day
@save_flag = @course_prefs.save
respond_to do |format|
format.js {
render action:'finishcourse'
}
end
end
def exit_project
@project = Project.find params[:id]
if User.current.login?
members = Member.where(:user_id => User.current.id, :project_id=>params[:id]).first
if members != nil && members.roles.first.to_s != "Manager"
members.destroy
end
respond_to do |format|
format.js
end
end
end
#加入私有项目
def join_project
respond_to do |format|
format.js
end
end
private
def memberAccess
# 是课程,则判断当前用户是否参加了课程
return 0 if @project.project_type == Project::ProjectType_project
currentUser = User.current
render_403 unless currentUser.member_of?(@project)
end
def toggleCourse
@course_prefs = Course.find_by_extra(@project.identifier)
unless (@course_prefs.teacher == User.current || User.current.admin?)
render_403
end
end
def select_project_layout
project = Project.find_by_id(params[:id])
project ||= @project ||= @course ||= params[:course] ||= params[:project_type]
(project.try(:project_type) == Project::ProjectType_project) ? 'base_projects' : 'base_courses'
end
# Validates parent_id param according to user's permissions
# TODO: move it to Project model in a validation that depends on User.current
def validate_parent_id
return true if User.current.admin?
parent_id = params[:project] && params[:project][:parent_id]
if parent_id || @project.new_record?
parent = parent_id.blank? ? nil : Project.find_by_id(parent_id.to_i)
unless @project.allowed_parents.include?(parent)
@project.errors.add :parent_id, :invalid
return false
end
end
true
end
# added by huang
def watcherlist
if @watched
@users -= watched.watcher_users
end
end
#gcm
def desc_sort_course_by_avtivity(activity_count,projects)
return projects if activity_count.size<2
(activity_count.size-2).downto(0) do |i|
(0..i).each do |j|
if activity_count[j]<activity_count[j+1]
projects[j],projects[j+1]=projects[j+1],projects[j]
activity_count[j],activity_count[j+1]=activity_count[j+1],activity_count[j]
end
end
end
return projects
end
#gcmend
end