socialforge/app/controllers/projects_controller.rb

880 lines
31 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.
class ProjectsController < ApplicationController
# if @project.project_type == 1
# layout 'base_projects'# by young
layout :select_project_layout
menu_item :overview
menu_item :roadmap, :only => :roadmap
menu_item :settings, :only => :settings
menu_item l(:label_sort_by_time), :only => :index
menu_item l(:label_sort_by_active), :only => :index
menu_item l(:label_sort_by_influence), :only => :index
# menu_item l(:label_homework), :only => :homework
# menu_item l(:label_course_feedback), :only => :feedback
menu_item :homework, :only => [:homework, :new_homework]
menu_item :feedback, :only => :feedback
menu_item l(:label_course_file), :only => :index
menu_item l(:label_course_news), :only => :index
# end
# layout 'base_courses'# by young
# menu_item :overview
# menu_item l(:label_homework), :only => :homework
# menu_item :files, :only => :files
#
# layout 'base_courses'
# menu_item l(:label_homework), :only => homework
# menu_item l(:label_course_file), :only => files
# menu_item l(:label_settings), :only => settings
before_filter :find_project, :except => [ :index, :search,:list, :new, :create, :copy, :statistics, :new_join, :course, :enterprise_course, :course_enterprise]
# 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]
before_filter :authorize, :only => [:show, :settings, :edit, :sort_project_members, :update, :modules, :close, :reopen]
before_filter :authorize_global, :only => [:new, :create]
before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy, :calendar]
#by young
# before_filter :member, :file, :statistics, :watcherlist
# modified by fq
before_filter :file, :statistics, :watcherlist
#
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 :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
### added by william
include ActsAsTaggableOn::TagsHelper
# Lists visible projects
# def index
# respond_to do |format|
# format.html {
# scope = Project
# unless params[:closed]
# scope = scope.active
# end
# @projects = scope.visible.order('lft').all
# }
# format.api {
# @offset, @limit = api_offset_and_limit
# @project_count = Project.visible.count
# @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all
# }
# 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
def enterprise_course
session[:enterprise_college] = 2
respond_to do |format|
format.html { redirect_to :back }
#format.api { render_api_ok }
end
end
def course_enterprise
session[:enterprise_college] = 1
respond_to do |format|
format.html { redirect_to :back }
#format.api { render_api_ok }
end
end
def index
#Modified by nie
@project_type = params[:project_type]
per_page_option = 10
@projects_all = Project.active.visible.
joins("LEFT JOIN #{ProjectStatus.table_name} ON #{Project.table_name}.id = #{ProjectStatus.table_name}.project_id").
where("#{Project.table_name}.project_type = ? ", Project::ProjectType_project)
@project_count = @projects_all.count
@project_pages = Paginator.new @project_count, per_page_option, params['page']
case params[:project_sort_type]
when '0'
@projects = @projects_all.order("created_on desc")
@s_type = 0
when '1'
@projects = @projects_all.order("grade desc")
@s_type = 1
when '2'
@projects = @projects_all.order("watchers_count desc")
@s_type = 2
else
@projects = @projects = @projects_all.order("grade desc")
@s_type = 1
end
@projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page)
respond_to do |format|
format.html {
render :layout => 'base'
# scope = Project
# unless params[:closed]
# scope = scope.active
# end
}
format.api {
# @offset, @limit = api_offset_and_limit
# @project_count = Project.visible.count
# @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all
}
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
def course
@project_type = params[:project_type]
per_page_option = 10
@projects_all = Project.active.visible.
joins("LEFT JOIN #{ProjectStatus.table_name} ON #{Project.table_name}.id = #{ProjectStatus.table_name}.project_id").
where("#{Project.table_name}.project_type = ? ", Project::ProjectType_course)
@project_count = @projects_all.count
@project_pages = Paginator.new @project_count, per_page_option, params['page']
case params[:project_sort_type]
when '0'
@projects = @projects_all.order("created_on desc")
@s_type = 0
when '1'
@projects = @projects_all.order("course_ac_para desc")
@s_type = 1
when '2'
@projects = @projects_all.order("watchers_count desc")
@s_type = 2
else
@s_type = 0
@projects = @projects_all.order("created_on desc")
end
@projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page)
respond_to do |format|
format.html {
render :layout => 'base'
}
format.api {
# @offset, @limit = api_offset_and_limit
# @project_count = Project.visible.count
# @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all
}
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
def search
#modified by nie
@projects = Project.visible
@projects = @projects.visible.where('project_type = ?', params[:project_type]).like(params[:name]) if params[:name].present?
@offset, @limit = api_offset_and_limit({:limit => 10})
@project_count = @projects.visible.count
@project_pages = Paginator.new @project_count, @limit, params['page']
@offset ||= @project_pages.offset
@projects = @projects.visible.offset(@offset).limit(@limit).all
respond_to do |format|
format.html {
render :layout => 'base'
scope = Project
unless params[:closed]
scope = scope.active
end
}
format.api {
# @offset, @limit = api_offset_and_limit
# @project_count = Project.visible.count
# @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all
}
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
# added by fq
def new_join
@course = Project.find(params[:object_id])
end
#Added by young
def homework
@offset, @limit = api_offset_and_limit({:limit => 10})
@bids = @project.homeworks
@bids = @bids.like(params[:name]) if params[:name].present?
@bid_count = @bids.count
@bid_pages = Paginator.new @bid_count, @limit, params['page']
@offset ||= @bid_pages.reverse_offset
#@bids = @bids.offset(@offset).limit(@limit).all.reverse
unless @offset == 0
@bids = @bids.offset(@offset).limit(@limit).all.reverse
else
limit = @bid_count % @limit
@bids = @bids.offset(@offset).limit(limit).all.reverse
end
render :layout => 'base_courses'
end
def new_homework
# Dear maintainer:
# once you are done trying to 'optimize' this Magic routine,
# well, it's on you, I'll leave it to you.
if (User.current.logged? &&
(User.current.admin? ||
(
!Member.where('user_id = ? and project_id = ?', User.current.id, @project.id).first.nil? &&
(
Member.where('user_id = ? and project_id = ?', User.current.id, @project.id).first.roles &&
( Role.where(id: [3, 4, 7, 9]).size > 0 )
)
)
)
)
@homework = Bid.new
@homework.safe_attributes = params[:bid]
render :layout => 'base_courses'
else
render_404
end
end
#Ended by young
def feedback
page = params[:page]
# Find the page of the requested reply
@jours = @project.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
@limit = 10
if params[:r] && page.nil?
offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i])
page = 1 + offset / @limit
end
@feedback_count = @jours.count
@feedback_pages = Paginator.new @feedback_count, @limit, page
@offset ||= @feedback_pages.offset
@jour = @jours[@offset, @limit]
@state = false
@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 project_respond
# will_reply = JournalsForMessage.find(params[:reference_id]) if params[:reference_id]
project_id = request.headers["Referer"].match((%r|/([0-9]{1,})/|))[1]
# @project = Project.find_by_id(project_id)
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?
# flash[:notice]=l(:label_projects_feedback_respond_success)
respond_to do |format|
# format.html { redirect_to :back }
format.js
#format.api { render_api_ok }
end
end
def new
@project_type = params[:project_type]
@issue_custom_fields = IssueCustomField.sorted.all
@trackers = Tracker.sorted.all
case @project_type
when '0' # Project
@project = Project.new
@project.safe_attributes = params[:project]
when '1' # Course
@project = Project.new
@project.safe_attributes = params[:project]
@course_tag = params[:course]
@course = Course.new
@course.safe_attributes = params[:course]
else
render_404
return -1
end
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
@course_tag = params[:project][:project_type]
if(@course_tag=="1")
if User.current.user_extensions.identity#.include?(UserExtensions::TEACHER,UserExtensions::DEVELOPER)
@course = Course.new
@course.extra='course' + DateTime.parse(Time.now.to_s).strftime('%Y-%m-%d_%H-%M-%S').to_s
@course.safe_attributes = params[:project][:course]
@course.tea_id = User.current.id
# added by bai
@course.term = params[:term]
@course.time = params[:time]
@course.school_id = params[:school]
@course.setup_time = params[:setup_time]
@course.endup_time = params[:endup_time]
@course.class_period = params[:class_period]
end
end
@issue_custom_fields = IssueCustomField.sorted.all
@trackers = Tracker.sorted.all
@project = Project.new
@project.safe_attributes = params[:project]
if @course_tag == '1'
@project.identifier = @course.extra
end
if @course_tag == '1'
if User.current.user_extensions.identity == 0
if@course.save
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 = ProjectInfo.new(:user_id => User.current.id, :project_id => @project.id)
user_grades = UserGrade.create(:user_id => User.current.id, :project_id => @project.id)
if params[:project][:is_public] == '1'
project_status = ProjectStatus.create(:project_id => @project.id, :watchers_count => 0, :changesets_count => 0, :grade => 0, :project_type => @course_tag)
end
@project.members << m
@project.project_infos << project
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_path(attrs, :course => '0')
#Added by young
elsif params[:course_continue]
redirect_to new_project_path(:course => '1')
#Ended by young
else
redirect_to settings_project_path(@project,:project_type => 1)
end
}
format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
end
else
@course.destroy
respond_to do |format|
format.html { render :action => 'new', :layout => 'base'}#Added by young
format.api { render_validation_errors(@project) }
end
end
else
if validate_parent_id && @project.save
@project.delete
respond_to do |format|
format.html { render :action => 'new', :layout => 'base'}#Added by young
format.api { render_validation_errors(@project) }
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
end
else
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 = ProjectInfo.new(:user_id => User.current.id, :project_id => @project.id)
user_grades = UserGrade.create(:user_id => User.current.id, :project_id => @project.id)
if params[:project][:is_public] == '1' || @course_tag=="1"
project_status = ProjectStatus.create(:project_id => @project.id, :watchers_count => 0, :changesets_count => 0, :project_type => @project.project_type)
end
@project.members << m
@project.project_infos << project
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_path(attrs, :course => '0')
#Added by young
elsif params[:course_continue]
redirect_to new_project_path(:course => '1')
#Ended by young
else
redirect_to settings_project_path(@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
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_path(@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_path(@project)
end
end
end
rescue ActiveRecord::RecordNotFound
# source_project not found
render_404
end
# Show @project
def show
@project_type = params[:project_type]
# try to redirect to the requested menu item
if params[:jump] && redirect_to_project_menu_item(@project, params[:jump])
return
end
@users_by_role = @project.users_by_role
@subprojects = @project.children.visible.all
@news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").all
@trackers = @project.rolled_up_trackers
if(User.find_by_id(ProjectInfo.find_by_project_id(@project.id).try(:user_id)))
@user = User.find_by_id(ProjectInfo.find_by_project_id(@project.id).user_id)
end
cond = @project.project_condition(Setting.display_subprojects_issues?)
@open_issues_by_tracker = Issue.visible.open.where(cond).count(:group => :tracker)
@total_issues_by_tracker = Issue.visible.where(cond).count(:group => :tracker)
if User.current.allowed_to?(:view_time_entries, @project)
@total_hours = TimeEntry.visible.sum(:hours, :include => :project, :conditions => cond).to_f
end
@key = User.current.rss_key
#新增内容
@days = Setting.activity_days_default.to_i
if params[:from]
begin; @date_to = params[:from].to_date + 1; rescue; end
end
has = {
"show_issues" => true,
"show_files" => true,
"show_documents" => true,
"show_messages" => true,
"show_news" => true,
"show_bids" => true,
"show_journals_for_messages" => true
}
@date_to ||= Date.today + 1
@date_from = @date_to - @days
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
@author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id]))
# 决定显示所用用户或单个用户活动
@activity = Redmine::Activity::Fetcher.new(User.current, :project => @project,
:with_subprojects => @with_subprojects,
:author => @author)
@activity.scope_select {|t| !has["show_#{t}"].nil?}
# logger.debug "=========================================#{@activity.scope}"
# @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty?
#Added by young
events = @activity.events(@date_from, @date_to)
@offset, @limit = api_offset_and_limit({:limit => 10})
@events_count = events.count
@events_pages = Paginator.new @events_count, @limit, params['page']
@offset ||= @events_pages.offset
events = events.slice(@offset,@limit)
#Ended by young
@events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)}
# documents
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
documents = @project.documents.includes(:attachments, :category).all
case @sort_by
when 'date'
@grouped = documents.group_by {|d| d.updated_on.to_date }
when 'title'
@grouped = documents.group_by {|d| d.title.first.upcase}
when 'author'
@grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
else
@grouped = documents.group_by(&:category)
end
@document = @project.documents.build
#
@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 settings
@issue_custom_fields = IssueCustomField.sorted.all
@issue_category ||= IssueCategory.new
@member ||= @project.members.new
@trackers = Tracker.sorted.all
@wiki ||= @project.wiki
#Added by young
# @course_tag = params[:course]
# if @course_tag == '1'
@course = Course.find_by_extra(@project.identifier)
# if @project.project_type == 1
# render :layout => 'base_courses'
# else
# render :layout => 'base_projects'
# end
#Ended by young
end
def edit
end
#by young
include CoursesHelper
def member
## 有角色参数的才是课程,没有的就是项目
@render_file = 'member_list'
# 判断是否课程
if @project.project_type == Project::ProjectType_course
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 # @project.project_type == Project::ProjectType_project
roles = Role.find_all_givable
@subPage_title = l :label_member_list
@members = @project.member_principals.includes(:roles, :principal).all
@members = sort_project_members(@project, @members)
end
@members = paginateHelper @members
render :layout => 'base_courses' if @project.project_type == 1
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 news
# if @project.project_type == 1
# render :layout => 'base_courses'
# end
# end
def file
# if @project.project_type == 1
# render :layout => 'base_courses'
# end
# @course_tag = params[:course]
# if @course_tag == '1'
# render :layout => 'base_courses'
# end
# User.current
end
def statistics
end
#end
def update
@project.safe_attributes = params[:project]
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
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_path(@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_path(@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_path(:status => params[:status])
end
def unarchive
@project.unarchive if request.post? && !@project.active?
redirect_to admin_projects_path(:status => params[:status])
end
def close
@project.close
redirect_to project_path(@project)
end
def reopen
@project.reopen
redirect_to project_path(@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_path }
format.api { render_api_ok }
end
else
render :layout => "base"
end
# hide project in layout
@project = nil
end
# added by bai
def show_projects_score
end
def issue_score_index
end
def news_score_index
end
def file_score_index
end
def code_submit_score_index
end
def projects_topic_score_index
end
# end
# TODO:#finishcourse and #restartcourse 没有设置权限也就是说任何人的调用都会关闭or重启课程。
# 最好通过用户与项目的权限解决这种事情。还没写
def finishcourse
course_prefs = Course.find_by_extra(@project.identifier)
# setup_time = Time.parse(course_prefs.setup_time)
# end_time = Time.parse(course_prefs.endup_time)
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
course_prefs = Course.find_by_extra(@project.identifier)
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
private
def select_project_layout
project = Project.find_by_id(params[:id])
project ||= @project
project ||= @course
(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
end