diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index d87bc6d2c..4525176ac 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -1,373 +1,373 @@ -# 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 AttachmentsController < ApplicationController - layout "users_base" - before_filter :find_project, :only => [:show, :download, :thumbnail, :destroy, :delete_homework]#, :except => [:upload, :autocomplete] - before_filter :file_readable, :read_authorize, :only => [:show, :thumbnail]#Modified by young - before_filter :delete_authorize, :only => :destroy - before_filter :authorize_global, :only => :upload - - before_filter :login_without_softapplication, only: [:download] - accept_api_auth :show, :download, :upload - require 'iconv' - - - def show - respond_to do |format| - format.html { - if @attachment.is_diff? - @diff = File.new(@attachment.diskfile, "rb").read - @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline' - @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type) - # Save diff type as user preference - if User.current.logged? && @diff_type != User.current.pref[:diff_type] - User.current.pref[:diff_type] = @diff_type - User.current.preference.save - end - render :action => 'diff' - elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte - @content = File.new(@attachment.diskfile, "rb").read - # 编码为非 UTF-8先进行间接转码 - # 部分unicode编码不直接支持转为 UTF-8 - # modify by nwb - if @content.encoding.name != 'UTF-8' - @content = @content.force_encoding('GBK') - @content = @content.encode('UTF-8') - end - render :action => 'file' - else - download - end - } - format.api - end - end - - def download - # modify by nwb - # 下载添加权限设置 - candown = false - if (@attachment.container.has_attribute?(:project) || @attachment.container.has_attribute?(:project_id)) && @attachment.container.project - project = @attachment.container.project - candown= User.current.member_of?(project) || (project.is_public && @attachment.is_public == 1) - elsif @attachment.container.is_a?(Project) - project = @attachment.container - candown= User.current.member_of?(project) || (project.is_public && @attachment.is_public == 1) - elsif (@attachment.container.has_attribute?(:course) ||@attachment.container.has_attribute?(:course_id) ) && @attachment.container.course - course = @attachment.container.course - candown= User.current.member_of_course?(course) || (course.is_public==1 && @attachment.is_public == 1) - elsif @attachment.container.is_a?(Course) - course = @attachment.container - candown= User.current.member_of_course?(course) || (course.is_public==1 && @attachment.is_public == 1) - elsif @attachment.container.class.to_s=="HomeworkAttach" && @attachment.container.bid.reward_type == 3 - candown = true - else - candown = @attachment.is_public == 1 - end - if candown || User.current.admin? || User.current.id == @attachment.author_id - @attachment.increment_download - - if stale?(:etag => @attachment.digest) - # images are sent inline - send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename), - :type => detect_content_type(@attachment), - :disposition => (@attachment.image? ? 'inline' : 'attachment') - end - - else - render_403 :message => :notice_not_authorized - end - - rescue => e - redirect_to "http://" + (Setting.host_name.to_s) +"/file_not_found.html" - end - - #更新资源文件类型 - def updateType - @attachment = Attachment.find(params[:attachmentid]) - if @attachment != nil - @attachment.attachtype = params[:newtype] - @attachment.save - render :text =>'success' - else - render :text=>'error' - end - end - - # 更新文件密级 - def updateFileDense - @attachment = Attachment.find(params[:attachmentid]) - if @attachment != nil - filedense = params[:newtype].to_s - # d = Iconv.conv("unicodebig","utf-8",filedense) - if filedense == "%E5%85%AC%E5%BC%80" #l(:field_is_public) - @attachment.is_public = 1 - else - @attachment.is_public = 0 - end - @attachment.save - @newfiledense = filedense - end - respond_to do |format| - format.js - end - end - - def thumbnail - if @attachment.thumbnailable? && thumbnail = @attachment.thumbnail(:size => params[:size]) - if stale?(:etag => thumbnail) - send_file thumbnail, - :filename => filename_for_content_disposition(@attachment.filename), - :type => detect_content_type(@attachment), - :disposition => 'inline' - end - else - # No thumbnail for the attachment or thumbnail could not be created - render :nothing => true, :status => 404 - end - end - - - def upload - # Make sure that API users get used to set this content type - # as it won't trigger Rails' automatic parsing of the request body for parameters - unless request.content_type == 'application/octet-stream' - render :nothing => true, :status => 406 - return - end - - @attachment = Attachment.new(:file => request.raw_post) - @attachment.author = User.current - @attachment.filename = params[:filename].presence || Redmine::Utils.random_hex(16) - saved = @attachment.save - - respond_to do |format| - format.js - format.api { - if saved - render :action => 'upload', :status => :created - else - render_validation_errors(@attachment) - end - } - end - end - - def destroy - if @attachment.container.respond_to?(:init_journal) - @attachment.container.init_journal(User.current) - end - if @attachment.container - # Make sure association callbacks are called - @attachment.container.attachments.delete(@attachment) - else - @attachment.destroy - end - - respond_to do |format| - if !@attachment.container.nil? && - (@attachment.container.is_a?(Course) || ((@attachment.container.has_attribute?(:course) || @attachment.container.has_attribute?(:course_id) ) && - @attachment.container.course ) || ((@attachment.container.has_attribute?(:board) || @attachment.container.has_attribute?(:board_id)) && - @attachment.container.board && @attachment.container.board.course ) ) - if @attachment.container.is_a?(News) - format.html { redirect_to_referer_or news_path(@attachment.container) } - elsif @attachment.container.is_a?(Message) - format.html { redirect_to_referer_or new_board_message_path(@attachment.container) } - elsif @course.nil? - format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } - else - format.html { redirect_to_referer_or course_path(@course) } - end - else - if @project.nil? - format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } - else - format.html { redirect_to_referer_or project_path(@project) } - end - end - - format.js - end - end - - def delete_homework - @bid = @attachment.container.bid - # Make sure association callbacks are called - container = @attachment.container - @attachment.container.attachments.delete(@attachment) - #if container.attachments.empty? - #container.delete - #end - - respond_to do |format| - format.html { redirect_to_referer_or respond_path(@bid) } - format.js - end - end - - #删除竞赛作品的附件 - def delete_softapplications - @attachment = Attachment.find params[:id] - @softapplication = @attachment.container if @attachment!=nil - @attachment.container.attachments.delete(@attachment) if @attachment!=nil - respond_to do |format| - format.html { redirect_to_referer_or edit_softapplication_path(@softapplication) } - #format.js - end - end - - def autocomplete - # modify by nwb - if params[:project_id] - @project = Project.find_by_id(params[:project_id]) - elsif params[:course_id] - @course = Course.find_by_id(params[:course_id]) - end - - respond_to do |format| - format.js - end - end - - def add_exist_file_to_project - classname = params[:class_name] - class_id = params[:class_id] - attachments = params[:attachment][:attach] - - obj = Object.const_get(classname).find_by_id(class_id) - attachments.collect do |attach_id| - ori = Attachment.find_by_id(attach_id) - next if ori.blank? - attach_copied_obj = ori.copy - attach_copied_obj.tag_list.add(ori.tag_list) # tag关联 - attach_copied_obj.container = obj - attach_copied_obj.created_on = Time.now - attach_copied_obj.author_id = User.current.id - if attach_copied_obj.attachtype == nil - attach_copied_obj.attachtype = 1 - end - @obj = obj - @save_flag = attach_copied_obj.save - @save_message = attach_copied_obj.errors.full_messages - end - - respond_to do |format| - format.js - end - rescue NoMethodError - @save_flag = false - @save_message = [] << l(:error_attachment_empty) - respond_to do |format| - format.js - end - end - - def add_exist_file_to_course - class_id = params[:class_id] - attachments = params[:attachment][:attach] - - obj = Course.find_by_id(class_id) - attachments.collect do |attach_id| - ori = Attachment.find_by_id(attach_id) - next if ori.blank? - attach_copied_obj = ori.copy - attach_copied_obj.tag_list.add(ori.tag_list) # tag关联 - attach_copied_obj.container = obj - attach_copied_obj.created_on = Time.now - attach_copied_obj.author_id = User.current.id - if attach_copied_obj.attachtype == nil - attach_copied_obj.attachtype = 4 - end - @obj = obj - @save_flag = attach_copied_obj.save - @save_message = attach_copied_obj.errors.full_messages - end - - respond_to do |format| - format.js - end - rescue NoMethodError - @save_flag = false - @save_message = [] << l(:error_attachment_empty) - respond_to do |format| - format.js - end - end - -private - def find_project - @attachment = Attachment.find(params[:id]) - # Show 404 if the filename in the url is wrong - # modify by nwb - raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename - if @attachment.container_type == 'Course' - @course = @attachment.course - elsif !@attachment.container.nil? && (@attachment.container.has_attribute?(:course) || @attachment.container.has_attribute?(:course)) && @attachment.container.course - @course = @attachment.container.course - else - unless @attachment.container_type == 'Bid' || @attachment.container_type == 'HomeworkAttach' || @attachment.container_type == 'Memo' || @attachment.container_type == 'Softapplication' - @project = @attachment.project - end - end - rescue ActiveRecord::RecordNotFound - render_404 - end - - # Checks that the file exists and is readable - def file_readable - if @attachment.readable? - true - else - logger.error "Cannot send attachment, #{@attachment.diskfile} does not exist or is unreadable." - render_404 - end - end - - def read_authorize - if @attachment.container_type == "HomeworkAttach" || @attachment.container_type == 'Bid' - true - #User.current.allowed_to?(:view_homework_attaches, @attachment.project) ? true : deny_access - else - @attachment.visible? ? true : deny_access - end - end - - def delete_authorize - @attachment.deletable? ? true : deny_access - end - - def detect_content_type(attachment) - content_type = attachment.content_type - if content_type.blank? - content_type = Redmine::MimeType.of(attachment.filename) - end - content_type.to_s - end - - def login_without_softapplication - referer = request.headers['Referer'] - require_login unless referer =~ /softapplication/ - end - - def renderTag - @attachmentNew = Attachment.find(params[:attchmentId]) - respond_to do |format| - format.js - end - end -end +# 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 AttachmentsController < ApplicationController + layout "users_base" + before_filter :find_project, :only => [:show, :download, :thumbnail, :destroy, :delete_homework]#, :except => [:upload, :autocomplete] + before_filter :file_readable, :read_authorize, :only => [:show, :thumbnail]#Modified by young + before_filter :delete_authorize, :only => :destroy + before_filter :authorize_global, :only => :upload + + before_filter :login_without_softapplication, only: [:download] + accept_api_auth :show, :download, :upload + require 'iconv' + + + def show + respond_to do |format| + format.html { + if @attachment.is_diff? + @diff = File.new(@attachment.diskfile, "rb").read + @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline' + @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type) + # Save diff type as user preference + if User.current.logged? && @diff_type != User.current.pref[:diff_type] + User.current.pref[:diff_type] = @diff_type + User.current.preference.save + end + render :action => 'diff' + elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte + @content = File.new(@attachment.diskfile, "rb").read + # 编码为非 UTF-8先进行间接转码 + # 部分unicode编码不直接支持转为 UTF-8 + # modify by nwb + if @content.encoding.name != 'UTF-8' + @content = @content.force_encoding('GBK') + @content = @content.encode('UTF-8') + end + render :action => 'file' + else + download + end + } + format.api + end + end + + def download + # modify by nwb + # 下载添加权限设置 + candown = false + if (@attachment.container.has_attribute?(:project) || @attachment.container.has_attribute?(:project_id)) && @attachment.container.project + project = @attachment.container.project + candown= User.current.member_of?(project) || (project.is_public && @attachment.is_public == 1) + elsif @attachment.container.is_a?(Project) + project = @attachment.container + candown= User.current.member_of?(project) || (project.is_public && @attachment.is_public == 1) + elsif (@attachment.container.has_attribute?(:course) ||@attachment.container.has_attribute?(:course_id) ) && @attachment.container.course + course = @attachment.container.course + candown= User.current.member_of_course?(course) || (course.is_public==1 && @attachment.is_public == 1) + elsif @attachment.container.is_a?(Course) + course = @attachment.container + candown= User.current.member_of_course?(course) || (course.is_public==1 && @attachment.is_public == 1) + elsif @attachment.container.class.to_s=="HomeworkAttach" && @attachment.container.bid.reward_type == 3 + candown = true + else + candown = @attachment.is_public == 1 + end + if candown || User.current.admin? || User.current.id == @attachment.author_id + @attachment.increment_download + + if stale?(:etag => @attachment.digest) + # images are sent inline + send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename), + :type => detect_content_type(@attachment), + :disposition => (@attachment.image? ? 'inline' : 'attachment') + end + + else + render_403 :message => :notice_not_authorized + end + + rescue => e + redirect_to "http://" + (Setting.host_name.to_s) +"/file_not_found.html" + end + + #更新资源文件类型 + def updateType + @attachment = Attachment.find(params[:attachmentid]) + if @attachment != nil + @attachment.attachtype = params[:newtype] + @attachment.save + render :text =>'success' + else + render :text=>'error' + end + end + + # 更新文件密级 + def updateFileDense + @attachment = Attachment.find(params[:attachmentid]) + if @attachment != nil + filedense = params[:newtype].to_s + # d = Iconv.conv("unicodebig","utf-8",filedense) + if filedense == "%E5%85%AC%E5%BC%80" #l(:field_is_public) + @attachment.is_public = 1 + else + @attachment.is_public = 0 + end + @attachment.save + @newfiledense = filedense + end + respond_to do |format| + format.js + end + end + + def thumbnail + if @attachment.thumbnailable? && thumbnail = @attachment.thumbnail(:size => params[:size]) + if stale?(:etag => thumbnail) + send_file thumbnail, + :filename => filename_for_content_disposition(@attachment.filename), + :type => detect_content_type(@attachment), + :disposition => 'inline' + end + else + # No thumbnail for the attachment or thumbnail could not be created + render :nothing => true, :status => 404 + end + end + + + def upload + # Make sure that API users get used to set this content type + # as it won't trigger Rails' automatic parsing of the request body for parameters + unless request.content_type == 'application/octet-stream' + render :nothing => true, :status => 406 + return + end + + @attachment = Attachment.new(:file => request.raw_post) + @attachment.author = User.current + @attachment.filename = params[:filename].presence || Redmine::Utils.random_hex(16) + saved = @attachment.save + + respond_to do |format| + format.js + format.api { + if saved + render :action => 'upload', :status => :created + else + render_validation_errors(@attachment) + end + } + end + end + + def destroy + if @attachment.container.respond_to?(:init_journal) + @attachment.container.init_journal(User.current) + end + if @attachment.container + # Make sure association callbacks are called + @attachment.container.attachments.delete(@attachment) + else + @attachment.destroy + end + + respond_to do |format| + if !@attachment.container.nil? && + (@attachment.container.is_a?(Course) || ((@attachment.container.has_attribute?(:course) || @attachment.container.has_attribute?(:course_id) ) && + @attachment.container.course ) || ((@attachment.container.has_attribute?(:board) || @attachment.container.has_attribute?(:board_id)) && + @attachment.container.board && @attachment.container.board.course ) ) + if @attachment.container.is_a?(News) + format.html { redirect_to_referer_or news_path(@attachment.container) } + elsif @attachment.container.is_a?(Message) + format.html { redirect_to_referer_or new_board_message_path(@attachment.container) } + elsif @course.nil? + format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } + else + format.html { redirect_to_referer_or course_path(@course) } + end + else + if @project.nil? + format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } + else + format.html { redirect_to_referer_or project_path(@project) } + end + end + + format.js + end + end + + def delete_homework + @bid = @attachment.container.bid + # Make sure association callbacks are called + container = @attachment.container + @attachment.container.attachments.delete(@attachment) + #if container.attachments.empty? + #container.delete + #end + + respond_to do |format| + format.html { redirect_to_referer_or respond_path(@bid) } + format.js + end + end + + #删除竞赛作品的附件 + def delete_softapplications + @attachment = Attachment.find params[:id] + @softapplication = @attachment.container if @attachment!=nil + @attachment.container.attachments.delete(@attachment) if @attachment!=nil + respond_to do |format| + format.html { redirect_to_referer_or edit_softapplication_path(@softapplication) } + #format.js + end + end + + def autocomplete + # modify by nwb + if params[:project_id] + @project = Project.find_by_id(params[:project_id]) + elsif params[:course_id] + @course = Course.find_by_id(params[:course_id]) + end + + respond_to do |format| + format.js + end + end + + def add_exist_file_to_project + classname = params[:class_name] + class_id = params[:class_id] + attachments = params[:attachment][:attach] + + obj = Object.const_get(classname).find_by_id(class_id) + attachments.collect do |attach_id| + ori = Attachment.find_by_id(attach_id) + next if ori.blank? + attach_copied_obj = ori.copy + attach_copied_obj.tag_list.add(ori.tag_list) # tag关联 + attach_copied_obj.container = obj + attach_copied_obj.created_on = Time.now + attach_copied_obj.author_id = User.current.id + if attach_copied_obj.attachtype == nil + attach_copied_obj.attachtype = 1 + end + @obj = obj + @save_flag = attach_copied_obj.save + @save_message = attach_copied_obj.errors.full_messages + end + + respond_to do |format| + format.js + end + rescue NoMethodError + @save_flag = false + @save_message = [] << l(:error_attachment_empty) + respond_to do |format| + format.js + end + end + + def add_exist_file_to_course + class_id = params[:class_id] + attachments = params[:attachment][:attach] + + obj = Course.find_by_id(class_id) + attachments.collect do |attach_id| + ori = Attachment.find_by_id(attach_id) + next if ori.blank? + attach_copied_obj = ori.copy + attach_copied_obj.tag_list.add(ori.tag_list) # tag关联 + attach_copied_obj.container = obj + attach_copied_obj.created_on = Time.now + attach_copied_obj.author_id = User.current.id + if attach_copied_obj.attachtype == nil + attach_copied_obj.attachtype = 4 + end + @obj = obj + @save_flag = attach_copied_obj.save + @save_message = attach_copied_obj.errors.full_messages + end + + respond_to do |format| + format.js + end + rescue NoMethodError + @save_flag = false + @save_message = [] << l(:error_attachment_empty) + respond_to do |format| + format.js + end + end + +private + def find_project + @attachment = Attachment.find(params[:id]) + # Show 404 if the filename in the url is wrong + # modify by nwb + raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename + if @attachment.container_type == 'Course' + @course = @attachment.course + elsif !@attachment.container.nil? && (@attachment.container.has_attribute?(:course) || @attachment.container.has_attribute?(:course)) && @attachment.container.course + @course = @attachment.container.course + else + unless @attachment.container_type == 'Bid' || @attachment.container_type == 'HomeworkAttach' || @attachment.container_type == 'Memo' || @attachment.container_type == 'Softapplication' + @project = @attachment.project + end + end + rescue ActiveRecord::RecordNotFound + render_404 + end + + # Checks that the file exists and is readable + def file_readable + if @attachment.readable? + true + else + logger.error "Cannot send attachment, #{@attachment.diskfile} does not exist or is unreadable." + render_404 + end + end + + def read_authorize + if @attachment.container_type == "HomeworkAttach" || @attachment.container_type == 'Bid' + true + #User.current.allowed_to?(:view_homework_attaches, @attachment.project) ? true : deny_access + else + @attachment.visible? ? true : deny_access + end + end + + def delete_authorize + @attachment.deletable? ? true : deny_access + end + + def detect_content_type(attachment) + content_type = attachment.content_type + if content_type.blank? + content_type = Redmine::MimeType.of(attachment.filename) + end + content_type.to_s + end + + def login_without_softapplication + referer = request.headers['Referer'] + require_login unless referer =~ /softapplication/ + end + + def renderTag + @attachmentNew = Attachment.find(params[:attchmentId]) + respond_to do |format| + format.js + end + end +end diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index e2f5e3731..b099a1db5 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -2,33 +2,44 @@ # class BidsController < ApplicationController class ContestsController < ApplicationController layout "contest_base" + menu_item :respond menu_item :project, :only => :show_project menu_item :application, :only => :show_softapplication menu_item :attendingcontests, :only => :show_attendingcontest menu_item :contestnotifications, :only => :index - before_filter :can_show_contest,except: [] - before_filter :find_contest, :only => [:show_contest, :show_project, :show_softapplication, :show_attendingcontest, :index, :set_reward_project, :set_reward_softapplication, :create,:destroy,:more,:back,:add,:add_softapplication,:new,:show_results, :set_reward, - :show_contest_project, :show_contest_user, :join_in_contest, :unjoin_in_contest, :new_join,:show_participator, :settings] - + before_filter :can_show_contest, :except => [] # modified by alan + + # modified by longjun + before_filter :find_contest, :only => [ + :show_contest, :show_project, :show_softapplication, + :show_attendingcontest, :index, :set_reward_project, + :set_reward_softapplication, :create, :destroy, :more, + :back, :add, :add_softapplication, :new,:show_results, + :set_reward, :show_contest_project, :show_contest_user, + :join_in_contest, :unjoin_in_contest, :new_join, :show_participator, :settings + ] + # end longjun + # added by fq before_filter :require_login, :only => [:join_in_contest, :unjoin_in_contest] # end - before_filter :require_login,:only => [:set_reward, :destroy, :add, :new, ] + before_filter :require_login,:only => [:set_reward, :destroy, :add, :new ] helper :watchers helper :attachments - include AttachmentsHelper - include ApplicationHelper helper :projects helper :words + include AttachmentsHelper + include ApplicationHelper + def index # @contests = Contest.visible # @contests ||= [] - @offset, @limit = api_offset_and_limit({:limit => 10}) + @offset, @limit = api_offset_and_limit(:limit => 10) #@contests = Contest.visible #@contests = @contests.like(params[:name]) if params[:name].present? @contests = Contest.visible.where("name like '%#{params[:name]}%'") @@ -41,43 +52,55 @@ class ContestsController < ApplicationController @offset ||= @contest_pages.reverse_offset if params[:contest_sort_type].present? case params[:contest_sort_type] - when '0' - unless @offset == 0 - @contests = @contests.reorder('contests.commit').offset(@offset).limit(@limit).all.reverse - else - limit = @contest_count % @limit - limit = @limit if limit == 0 - @contests = @contests.reorder('contests.commit').offset(@offset).limit(limit).all.reverse - end - @s_state = 0 - when '1' - unless @offset == 0 - @contests = @contests.reorder('contests.created_on').offset(@offset).limit(@limit).all.reverse - else - limit = @contest_count % @limit - limit = @limit if limit == 0 - @contests = @contests.reorder('contests.created_on').offset(@offset).limit(limit).all.reverse - end - @s_state = 1 - when '2' - unless @offset == 0 - @contests = @contests.offset(@offset).limit(@limit).all.reverse - else - limit = @contest_count % @limit - limit = @limit if limit == 0 - @contests = @contests.offset(@offset).limit(@limit).all.reverse - end - @s_state = 0 + when '0' + # modified by longjun + # never use unless and else + # unless @offset == 0 + if @offset != 0 + @contests = @contests.reorder('contests.commit').offset(@offset).limit(@limit).all.reverse + else + limit = @contest_count % @limit + limit = @limit if limit == 0 + @contests = @contests.reorder('contests.commit').offset(@offset).limit(limit).all.reverse end + @s_state = 0 + when '1' + # modified by longjun + # never use unless and else + # unless @offset == 0 + if @offset != 0 + @contests = @contests.reorder('contests.created_on').offset(@offset).limit(@limit).all.reverse else - unless @offset == 0 - @contests = @contests.reorder('contests.created_on').offset(@offset).limit(@limit).all.reverse - else - limit = @contest_count % @limit - limit = @limit if limit == 0 - @contests = @contests.reorder('contests.created_on').offset(@offset).limit(limit).all.reverse - end - @s_state = 1 + limit = @contest_count % @limit + limit = @limit if limit == 0 + @contests = @contests.reorder('contests.created_on').offset(@offset).limit(limit).all.reverse + end + @s_state = 1 + when '2' + # modified by longjun + # never use unless and else + # unless @offset == 0 + if @offset != 0 + @contests = @contests.offset(@offset).limit(@limit).all.reverse + else + limit = @contest_count % @limit + limit = @limit if limit == 0 + @contests = @contests.offset(@offset).limit(@limit).all.reverse + end + @s_state = 0 + end + else + # modified by longjun + # never use unless and else + # unless @offset == 0 + if @offset != 0 + @contests = @contests.reorder('contests.created_on').offset(@offset).limit(@limit).all.reverse + else + limit = @contest_count % @limit + limit = @limit if limit == 0 + @contests = @contests.reorder('contests.created_on').offset(@offset).limit(limit).all.reverse + end + @s_state = 1 end end @@ -93,7 +116,10 @@ class ContestsController < ApplicationController @bid_pages = Paginator.new @bid_count, @limit, params['page'] @offset ||= @bid_pages.reverse_offset - unless @offset == 0 + # modified by longjun + # never use unless and else + # unless @offset == 0 + if @offset != 0 @bids = @bids.offset(@offset).limit(@limit).all.reverse else limit = @bid_count % @limit @@ -149,10 +175,7 @@ class ContestsController < ApplicationController end end - def new_join - - end def show_participator render :layout => 'base_newcontest' @@ -186,26 +209,43 @@ class ContestsController < ApplicationController def show_contest_project contests = Contest.where('parent_id = ?', @contest.id) @projects = [] - for contest in contests - @projects += contest.contesting_projects - end + + # Modified by longjun + # 用 arr.each 替换 for [ according to the style guide ] + + # for contest in contests + # @projects += contest.contesting_projects + # end + + contests.each do |contest| + @projects += contest.contesting_projects + end + + # end respond_to do |format| format.html { render :layout => 'base_newcontest' } format.api - end end def show_contest_softapplication contests = Contest.where('parent_id = ?', @contest.id) @softapplications = [] - for contest in contests - @softapplications += contest.contesting_softapplications - end - + + # Modified by Longjun + # for contest in contests + # @softapplications += contest.contesting_softapplications + + + contests.each do |contest| + @softapplications += contest.contesting_softapplications + end + + # end + respond_to do |format| format.html { render :layout => 'base_newcontest' @@ -218,12 +258,21 @@ class ContestsController < ApplicationController def show_contest_user contests = Contest.find(:all) @users = [] - for contest in contests - for project in contest.projects - @users += project.users - end + + # Modified by Longjun + # for contest in contests + # for project in contest.projects + # @users += project.users + # end + + + contests.each do |contest| + contest.projects.each do |project| + @uers += project.users + end end - + # end + respond_to do |format| format.html { render :layout => 'base_newcontest' @@ -239,11 +288,20 @@ class ContestsController < ApplicationController # @contesting_project_count = @contesting_project_all.count # @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page'] @membership.each do |membership| - unless(membership.project.project_type==1) - if User.current.allowed_to?(:quote_project, membership.project) + + # Modified by Longjun + # 将两个判断语句合并 + # unless membership.project.project_type==1 + # if User.current.allowed_to?(:quote_project, membership.project) + # @option << membership.project + # end + # end + if membership.project.project_type != 1 && User.current.allowed_to?(:quote_project, membership.project) @option << membership.project - end + end + # end + end @user = @contest.author @contesting_project = @contest.contesting_projects.all @@ -262,16 +320,19 @@ class ContestsController < ApplicationController @temp = [] @contesting_project.each do |pro| - if pro.project && pro.project.project_status - @temp << pro - end + # modified by longjun + # if pro.project && pro.project.project_status + # @temp << pro + # end + @temp << pro if pro.project && pro.project.project_status + # end longjun @temp end if @temp.size > 0 @contesting_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} end end - @contesting_project = paginateHelper @contesting_project + @contesting_project = paginateHelper(@contesting_project) respond_to do |format| format.html { render :layout => 'base_newcontest' @@ -290,7 +351,7 @@ class ContestsController < ApplicationController @softapplication = Softapplication.all @contesting_softapplication = @contest.contesting_softapplications - @contesting_softapplication = paginateHelper @contesting_softapplication, 10 + @contesting_softapplication = paginateHelper(@contesting_softapplication, 10) # @temp = [] # @softapplicationt.each do |pro| @@ -328,7 +389,7 @@ class ContestsController < ApplicationController # @contesting_project_count = @contesting_project_all.count # @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page'] @membership.each do |membership| - unless(membership.project.project_type==1) + unless membership.project.project_type==1 #拥有编辑项目权限的可将该项目参赛 if User.current.allowed_to?(:quote_project, membership.project) @option << membership.project @@ -352,27 +413,31 @@ class ContestsController < ApplicationController @temp = [] @contesting_project.each do |pro| - if pro.project && pro.project.project_status - @temp << pro - end + # modified by longjun + # if pro.project && pro.project.project_status + # @temp << pro + # end + @temp << pro if pro.project && pro.project.project_status + # end longjun @temp end if @temp.size > 0 @contesting_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} end end -##取出参赛应用 --应用列表 + # 取出参赛应用 --应用列表 @softapplication = Softapplication.all @contesting_softapplication = @contest.contesting_softapplications. joins("LEFT JOIN softapplications ON contesting_softapplications.softapplication_id=softapplications.id"). joins("LEFT JOIN ( - SELECT * FROM seems_rateable_cached_ratings WHERE cacheable_type='Softapplication' AND DIMENSION = 'quality') AS cached - ON cached.cacheable_id=softapplications.id"). + SELECT * FROM seems_rateable_cached_ratings + WHERE cacheable_type='Softapplication' AND DIMENSION = 'quality') AS cached + ON cached.cacheable_id=softapplications.id"). order("cached.avg").reverse_order @contesting_softapplication = paginateHelper @contesting_softapplication, 10 -##引用base_newcontest整体样式 + #引用base_newcontest整体样式 @contest = Contest.find_by_id(params[:id]) respond_to do |format| format.html { @@ -384,15 +449,15 @@ class ContestsController < ApplicationController ###end -def show_notification - @contest = Contest.find_by_id(params[:id]) - respond_to do |format| - format.html { - render :layout => 'base_newcontest' - } - format.api - end -end + def show_notification + @contest = Contest.find_by_id(params[:id]) + respond_to do |format| + format.html { + render :layout => 'base_newcontest' + } + format.api + end + end def set_reward_project @@ -437,7 +502,11 @@ end project = Project.find(params[:contest]) contest_message = params[:contest_for_save][:contest_message] if ContestingProject.where("project_id = ? and contest_id = ?", project.id, @contest.id).size == 0 - if ContestingProject.cerate_contesting(@contest.id, project.id, contest_message) + # modified by longjun, create 写错了 + # if ContestingProject.cerate_contesting(@contest.id, project.id, contest_message) + if ContestingProject.create_contesting(@contest.id, project.id, contest_message) + # end longjun + flash.now[:notice] = l(:label_bidding_contest_succeed) end else @@ -633,9 +702,7 @@ end end - def manage - end private diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index e1af9ca34..63ac3baaa 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -1,202 +1,202 @@ -# 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 MessagesController < ApplicationController - include ApplicationHelper - menu_item :boards - default_search_scope :messages - before_filter :find_board, :only => [:new, :preview,:edit] - before_filter :find_attachments, :only => [:preview] - before_filter :find_message, :except => [:new, :preview] - before_filter :authorize, :except => [:preview, :edit, :destroy, :new] - - helper :boards - helper :watchers - helper :attachments - include AttachmentsHelper - helper :project_score - - REPLIES_PER_PAGE = 25 unless const_defined?(:REPLIES_PER_PAGE) - - # Show a topic and its replies - def show - @isReply = true - page = params[:page] - # Find the page of the requested reply - if params[:r] && page.nil? - offset = @topic.children.count(:conditions => ["#{Message.table_name}.id < ?", params[:r].to_i]) - page = 1 + offset / REPLIES_PER_PAGE - end - - @reply_count = @topic.children.count - @reply_pages = Paginator.new @reply_count, REPLIES_PER_PAGE, page - @replies = @topic.children. - includes(:author, :attachments, {:board => :project}). - reorder("#{Message.table_name}.created_on DESC"). - limit(@reply_pages.per_page). - offset(@reply_pages.offset). - all - - @reply = Message.new(:subject => "RE: #{@message.subject}") - if @course - render :action => "show", :layout => "base_courses"#by young - else - render :action => "show", :layout => "base_projects"#by young - end - end - - # Create a new topic - def new - @message = Message.new - @message.author = User.current - @message.board = @board - @message.safe_attributes = params[:message] - if request.post? - @message.save_attachments(params[:attachments]) - if @message.save - call_hook(:controller_messages_new_after_save, { :params => params, :message => @message}) - render_attachment_warning_if_needed(@message) - redirect_to board_message_path(@board, @message) - else - layout_file = @project ? 'base_projects' : 'base_courses' - render :action => 'new', :layout => layout_file - end - end - end - - # Reply to a topic - def reply - if params[:reply][:content] == "" - (redirect_to board_message_path(@board, @topic, :r => @reply), :notice => l(:label_reply_empty);return) - end - @quote = params[:quote][:quote] - @reply = Message.new - @reply.author = User.current - @reply.board = @board - @reply.safe_attributes = params[:reply] - @reply.content = @quote + @reply.content - @topic.children << @reply - #@topic.update_attribute(:updated_on, Time.now) - if !@reply.new_record? - call_hook(:controller_messages_reply_after_save, { :params => params, :message => @reply}) - attachments = Attachment.attach_files(@reply, params[:attachments]) - render_attachment_warning_if_needed(@reply) - else - #render file: 'messages#show', layout: 'base_courses' - end - redirect_to board_message_path(@board, @topic, :r => @reply) - - end - - # Edit a message - def edit - @isReply = false - if @project - (render_403; return false) unless @message.editable_by?(User.current) - else - (render_403; return false) unless @message.course_editable_by?(User.current) - end - @message.safe_attributes = params[:message] - if request.post? && @message.save - attachments = Attachment.attach_files(@message, params[:attachments]) - render_attachment_warning_if_needed(@message) - flash[:notice] = l(:notice_successful_update) - @message.reload - redirect_to board_message_path(@message.board, @message.root, :r => (@message.parent_id && @message.id)) - elsif request.get? - respond_to do |format| - format.html { - layout_file = @project ? 'base_projects' : 'base_courses' - render :layout => layout_file - } - end - end - end - - # Delete a messages - def destroy - if @project - (render_403; return false) unless @message.destroyable_by?(User.current) - else - (render_403; return false) unless @message.course_destroyable_by?(User.current) - end - r = @message.to_param - @message.destroy - # modify by nwb - if @project - if @message.parent - redirect_to board_message_path(@board, @message.parent, :r => r) - else - redirect_to project_board_path(@project, @board) - end - elsif @course - if @message.parent - redirect_to board_message_path(@board, @message.parent, :r => r) - else - redirect_to course_board_path(@course, @board) - end - end - end - - def quote - @subject = @message.subject - @subject = "RE: #{@subject}" unless @subject.starts_with?('RE:') - - @content = "> #{ll(Setting.default_language, :text_user_wrote, @message.author)}\n> " - @temp = Message.new - #@temp.content = "> #{ll(Setting.default_language, :text_user_wrote, @message.author)}> " - @content << @message.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - @content_html = textilizable(@content) - @temp.content = @content_html - #@content = "#{ll(Setting.default_language, :text_user_wrote, @message.author)}
  " - #@content << @message.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n") + "\n\n
" - #@content = "
" << @content - #@temp = Message.new - #@temp.content = @content - - end - - def preview - message = @board.messages.find_by_id(params[:id]) - @text = (params[:message] || params[:reply])[:content] - @previewed = message - render :partial => 'common/preview' - end - -private - def find_message - return unless find_board - @message = @board.messages.find(params[:id], :include => :parent) - @topic = @message.root - rescue ActiveRecord::RecordNotFound - render_404 - end - - def find_board - #modify by nwb - @board = Board.find(params[:board_id]) - if @board.project_id != -1 && @board.project_id != nil - @project = @board.project - elsif @board.course_id - @course = @board.course - end - - rescue ActiveRecord::RecordNotFound - render_404 - nil - end -end +# 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 MessagesController < ApplicationController + include ApplicationHelper + menu_item :boards + default_search_scope :messages + before_filter :find_board, :only => [:new, :preview,:edit] + before_filter :find_attachments, :only => [:preview] + before_filter :find_message, :except => [:new, :preview] + before_filter :authorize, :except => [:preview, :edit, :destroy, :new] + + helper :boards + helper :watchers + helper :attachments + include AttachmentsHelper + helper :project_score + + REPLIES_PER_PAGE = 25 unless const_defined?(:REPLIES_PER_PAGE) + + # Show a topic and its replies + def show + @isReply = true + page = params[:page] + # Find the page of the requested reply + if params[:r] && page.nil? + offset = @topic.children.count(:conditions => ["#{Message.table_name}.id < ?", params[:r].to_i]) + page = 1 + offset / REPLIES_PER_PAGE + end + + @reply_count = @topic.children.count + @reply_pages = Paginator.new @reply_count, REPLIES_PER_PAGE, page + @replies = @topic.children. + includes(:author, :attachments, {:board => :project}). + reorder("#{Message.table_name}.created_on DESC"). + limit(@reply_pages.per_page). + offset(@reply_pages.offset). + all + + @reply = Message.new(:subject => "RE: #{@message.subject}") + if @course + render :action => "show", :layout => "base_courses"#by young + else + render :action => "show", :layout => "base_projects"#by young + end + end + + # Create a new topic + def new + @message = Message.new + @message.author = User.current + @message.board = @board + @message.safe_attributes = params[:message] + if request.post? + @message.save_attachments(params[:attachments]) + if @message.save + call_hook(:controller_messages_new_after_save, { :params => params, :message => @message}) + render_attachment_warning_if_needed(@message) + redirect_to board_message_path(@board, @message) + else + layout_file = @project ? 'base_projects' : 'base_courses' + render :action => 'new', :layout => layout_file + end + end + end + + # Reply to a topic + def reply + if params[:reply][:content] == "" + (redirect_to board_message_path(@board, @topic, :r => @reply), :notice => l(:label_reply_empty);return) + end + @quote = params[:quote][:quote] + @reply = Message.new + @reply.author = User.current + @reply.board = @board + @reply.safe_attributes = params[:reply] + @reply.content = @quote + @reply.content + @topic.children << @reply + #@topic.update_attribute(:updated_on, Time.now) + if !@reply.new_record? + call_hook(:controller_messages_reply_after_save, { :params => params, :message => @reply}) + attachments = Attachment.attach_files(@reply, params[:attachments]) + render_attachment_warning_if_needed(@reply) + else + #render file: 'messages#show', layout: 'base_courses' + end + redirect_to board_message_path(@board, @topic, :r => @reply) + + end + + # Edit a message + def edit + @isReply = false + if @project + (render_403; return false) unless @message.editable_by?(User.current) + else + (render_403; return false) unless @message.course_editable_by?(User.current) + end + @message.safe_attributes = params[:message] + if request.post? && @message.save + attachments = Attachment.attach_files(@message, params[:attachments]) + render_attachment_warning_if_needed(@message) + flash[:notice] = l(:notice_successful_update) + @message.reload + redirect_to board_message_path(@message.board, @message.root, :r => (@message.parent_id && @message.id)) + elsif request.get? + respond_to do |format| + format.html { + layout_file = @project ? 'base_projects' : 'base_courses' + render :layout => layout_file + } + end + end + end + + # Delete a messages + def destroy + if @project + (render_403; return false) unless @message.destroyable_by?(User.current) + else + (render_403; return false) unless @message.course_destroyable_by?(User.current) + end + r = @message.to_param + @message.destroy + # modify by nwb + if @project + if @message.parent + redirect_to board_message_path(@board, @message.parent, :r => r) + else + redirect_to project_board_path(@project, @board) + end + elsif @course + if @message.parent + redirect_to board_message_path(@board, @message.parent, :r => r) + else + redirect_to course_board_path(@course, @board) + end + end + end + + def quote + @subject = @message.subject + @subject = "RE: #{@subject}" unless @subject.starts_with?('RE:') + + @content = "> #{ll(Setting.default_language, :text_user_wrote, @message.author)}\n> " + @temp = Message.new + #@temp.content = "> #{ll(Setting.default_language, :text_user_wrote, @message.author)}> " + @content << @message.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + @content_html = textilizable(@content) + @temp.content = @content_html + #@content = "#{ll(Setting.default_language, :text_user_wrote, @message.author)}
  " + #@content << @message.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n") + "
\n\n
" + #@content = "
" << @content + #@temp = Message.new + #@temp.content = @content + + end + + def preview + message = @board.messages.find_by_id(params[:id]) + @text = (params[:message] || params[:reply])[:content] + @previewed = message + render :partial => 'common/preview' + end + +private + def find_message + return unless find_board + @message = @board.messages.find(params[:id], :include => :parent) + @topic = @message.root + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_board + #modify by nwb + @board = Board.find(params[:board_id]) + if @board.project_id != -1 && @board.project_id != nil + @project = @board.project + elsif @board.course_id + @course = @board.course + end + + rescue ActiveRecord::RecordNotFound + render_404 + nil + end +end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 943718392..c1593e320 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -468,8 +468,8 @@ class ProjectsController < ApplicationController def new @issue_custom_fields = IssueCustomField.sorted.all - @trackers = Tracker.sorted.all - @project = Project.new + @trackers = Tracker.sorted.all + @project = Project.new @project.safe_attributes = params[:project] render :layout => 'base' end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index a705d6934..39865d4e9 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -1,606 +1,606 @@ -# 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. - -require 'SVG/Graph/Bar' -require 'SVG/Graph/BarHorizontal' -require 'digest/sha1' -require 'redmine/scm/adapters/abstract_adapter' -require 'tempfile' - -class ChangesetNotFound < Exception; end -class InvalidRevisionParam < Exception; end - -class RepositoriesController < ApplicationController - menu_item :repository - menu_item :settings, :only => [:new, :create, :edit, :update, :destroy, :committers] - default_search_scope :changesets - - before_filter :find_project_by_project_id, :only => [:new, :create, :newrepo] - before_filter :find_repository, :only => [:edit, :update, :destroy, :committers] - before_filter :find_project_repository, :except => [:new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo] - before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] - before_filter :authorize , :except => [:newrepo,:newcreate,:fork] - accept_rss_auth :revisions - # hidden repositories filter // 隐藏代码过滤器 - before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ] - helper :repositories - include RepositoriesHelper - helper :project_score - #@root_path = RepositoriesHelper::ROOT_PATH - - - rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed - def new - scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first - @repository = Repository.factory(scm) - @repository.is_default = @project.repository.nil? - @repository.project = @project - @course_tag = params[:course] - if @course_tag == 1 - render :layout => 'base_courses' - else - render :layout => 'base_projects' - end - end - - - def newrepo - scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first - @repository = Repository.factory(scm) - @repository.is_default = @project.repository.nil? - @repository.project = @project - @course_tag = params[:course] - if @course_tag == 1 - render :layout => 'base_courses' - else - render :layout => 'base_projects' - end - end - - def fork - @repository_url = params[:repository_url] - - # @repository.url - # system "htpasswd -mb "+@root_path+"user.passwd "+params[:repository][:identifier]+" "+@upasswd - # system "echo -e '"+params[:project_id]+"-"+params[:repository][:identifier]+"-write:"+ - # " "+params[:repository][:identifier]+"' >> "+@root_path+"group.passwd" - system "git clone --bare "+@repository_url - # system "mv "+@project_path+"/hooks/post-update{.sample,}" - # system "chmod a+x "+@project_path+"/hooks/post-update" - # system "."+@project_path+"/hooks/post-update" - # system "echo -e 'Allow from all \n Order Deny,Allow \n "+ - # " \n"+ - # "Require group "+params[:project_id]+"-"+params[:repository][:identifier]+"-write \n "+ - # " \n ' >>"+ - # @project_path+"/.htaccess" - flash[:notice] = l(:label_notice_fork_successed) - @repositories = @project.repositories - render :action => 'show', :layout => 'base_projects' - end - - def create - if params[:repository_scm].to_s == 'Gitlab' - # add by nwb - # 增加对gitlab版本库的支持 - attrs = pickup_extra_info - @repository = Repository.factory('Git') - @repository.safe_attributes = params[:repository] - if attrs[:attrs_extra].keys.any? - @repository.merge_extra_info(attrs[:attrs_extra]) - end - @repository.project = @project - if request.post? && @repository.save - redirect_to settings_project_path(@project, :tab => 'repositories') - else - render :action => 'new' - end - else # 原逻辑 - ##xianbo - @root_path=RepositoriesHelper::ROOT_PATH - @repository_name=User.current.login.to_s+"/"+params[:repository][:identifier]+".git" - @project_path=@root_path+"htdocs/"+@repository_name - @repository_tag=params[:repository][:upassword] - @repo_name=User.current.login.to_s+"_"+params[:repository][:identifier] - logger.info "htpasswd -mb "+@root_path+"user.passwd "+@repo_name+": "+@repository_tag - logger.info "the value of create repository"+@root_path+": "+@repository_name+": "+@project_path+": "+@repo_name - attrs = pickup_extra_info - if((@repository_tag!="")&¶ms[:repository_scm]=="Git") - params[:repository][:url]=@project_path - end - ###xianbo - @repository = Repository.factory(params[:repository_scm]) - @repository.safe_attributes = params[:repository] - if attrs[:attrs_extra].keys.any? - @repository.merge_extra_info(attrs[:attrs_extra]) - end - #by xianbo - - @repository.project = @project - if request.post? && @repository.save - if(params[:repository_scm]=="Git") - system "htpasswd -mb "+@root_path+"user.passwd "+@repo_name+" "+@repository_tag - system "echo -e '"+@repo_name+"-write:"+ - " "+@repo_name+"' >> "+@root_path+"group.passwd" - system "mkdir "+@root_path+"htdocs/"+User.current.login.to_s - system "git init --bare "+@project_path - system "mv "+@project_path+"/hooks/post-update{.sample,}" - system "chmod a+x "+@project_path+"/hooks/post-update" - system "echo -e 'Allow from all \n Order Deny,Allow \n "+ - " \n"+ - "Require group "+@repo_name+"-write \n "+ - " \n ' >> "+ - @root_path+"htdocs/"+ @repository_name+"/.htaccess" - system "cd "+@project_path+" ;git update-server-info" - # if(create_repo_file&&create_passwd&&create_group&&init_repository&&add_privilege&&init_server_info) - # else - # logger.info "An error occured when authenticating "+"create passwd"+@creat_passwd+"create_group"+ - # crate_group+"create repository file "+create_repo_file+"init repository"+init_repostory+ - # "aad privilege to rpository"+add_privilege+"init server infos"+init_server_info - # end - @repository.update_attributes(:login => User.current.login.to_s) - end - redirect_to settings_project_path(@project, :tab => 'repositories') - else if(@repository_tag) - render :action => 'newrepo', :layout =>'base_projects' - else - render :action => 'new', :layout =>'base_projects' - end - end - end - end - - def edit - end - - def update - attrs = pickup_extra_info - @repository.safe_attributes = attrs[:attrs] - if attrs[:attrs_extra].keys.any? - @repository.merge_extra_info(attrs[:attrs_extra]) - end - @repository.project = @project - if request.put? && @repository.save - redirect_to settings_project_path(@project, :tab => 'repositories') - else - render :action => 'edit' - end - end - - def pickup_extra_info - p = {} - p_extra = {} - params[:repository].each do |k, v| - if k =~ /^extra_/ - p_extra[k] = v - else - p[k] = v - end - end - {:attrs => p, :attrs_extra => p_extra} - end - private :pickup_extra_info - - def committers - @committers = @repository.committers - @users = @project.users - additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id) - @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty? - @users.compact! - @users.sort! - if request.post? && params[:committers].is_a?(Hash) - # Build a hash with repository usernames as keys and corresponding user ids as values - @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h} - flash[:notice] = l(:notice_successful_update) - redirect_to settings_project_path(@project, :tab => 'repositories') - elsif request.get? - respond_to do |format| - format.html{ - render :layout => "project_base" - } - end - - - end - end - - def destroy - @root_path=RepositoriesHelper::ROOT_PATH - @repo_name=User.current.login.to_s+"_"+@repository.identifier.to_s - @repository_name=User.current.login.to_s+"/"+@repository.identifier.to_s+".git" - @middle=User.current.login.to_s+"_"+@repository.identifier.to_s+"-write:" - @repository.destroy if request.delete? - redirect_to settings_project_path(@project, :tab => 'repositories') - if(@repository.type=="Repository::Git") - logger.info "destory the repository value"+"root path"+@root_path+"repo_name"+@repo_name+ - "repository_name"+@repository_name+"user group"+@middle - system "sed -i /"+@repo_name+"/{d} "+@root_path+"user.passwd" - system "sed -i /"+@middle+"/{d} "+@root_path+"group.passwd" - system "rm -r "+@root_path+"htdocs/"+@repository_name - # if(@sed_user&&@sed_group&&@remove) - # else - # logger.info "An error occured when destory the repository"+"delete form passwd: \n"+ - # @sed_user+"delete from group"+@sed_group+"delete from file"+@remove - # end - end - end - - def show - ## TODO: the below will move to filter, done. - # if !User.current.member_of?(@project) - # if @project.hidden_repo - # render_403 - # return -1 - # end - # end - #if( !User.current.member_of?(@project) || @project.hidden_repo) - @repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty? - - @entries = @repository.entries(@path, @rev) - @changeset = @repository.find_changeset_by_name(@rev) - - #@project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT - #@ip = RepositoriesHelper::REPO_IP_ADDRESS - - if request.xhr? - @entries ? render(:partial => 'dir_list_content') : render(:nothing => true) - else - #Modified by young - # (show_error_not_found; return) unless @entries - @changesets = @repository.latest_changesets(@path, @rev) - @properties = @repository.properties(@path, @rev) - @repositories = @project.repositories - @course_tag = params[:course] - project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT - ip = RepositoriesHelper::REPO_IP_ADDRESS - @repos_url = "http://"+@repository.login.to_s+"_"+@repository.identifier.to_s+"@"+ip.to_s+ - @repository.url.slice(project_path_cut, @repository.url.length).to_s - if @course_tag == 1 - render :action => 'show', :layout => 'base_courses' - else - render :action => 'show', :layout => 'base_projects' - end - end - end - - alias_method :browse, :show - - def changes - @entry = @repository.entry(@path, @rev) - (show_error_not_found; return) unless @entry - @changesets = @repository.latest_changesets(@path, @rev, Setting.repository_log_display_limit.to_i) - @properties = @repository.properties(@path, @rev) - @changeset = @repository.find_changeset_by_name(@rev) - render :layout => 'base_projects' - end - - def revisions - @changeset_count = @repository.changesets.count - @changeset_pages = Paginator.new @changeset_count, - per_page_option, - params['page'] - @changesets = @repository.changesets. - limit(@changeset_pages.per_page). - offset(@changeset_pages.offset). - includes(:user, :repository, :parents). - all - - respond_to do |format| - format.html { render :layout => 'base_projects' } - format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") } - end - end - - def raw - entry_and_raw(true) - end - - def entry - entry_and_raw(false) - end - - def entry_and_raw(is_raw) - @entry = @repository.entry(@path, @rev) - (show_error_not_found; return) unless @entry - - # If the entry is a dir, show the browser - (show; return) if @entry.is_dir? - - @content = @repository.cat(@path, @rev) - (show_error_not_found; return) unless @content - if is_raw || - (@content.size && @content.size > Setting.file_max_size_displayed.to_i.kilobyte) || - ! is_entry_text_data?(@content, @path) - # Force the download - send_opt = { :filename => filename_for_content_disposition(@path.split('/').last) } - send_type = Redmine::MimeType.of(@path) - send_opt[:type] = send_type.to_s if send_type - send_opt[:disposition] = (Redmine::MimeType.is_type?('image', @path) && !is_raw ? 'inline' : 'attachment') - send_data @content, send_opt - else - # Prevent empty lines when displaying a file with Windows style eol - # TODO: UTF-16 - # Is this needs? AttachmentsController reads file simply. - @content.gsub!("\r\n", "\n") - @changeset = @repository.find_changeset_by_name(@rev) - end - end - private :entry_and_raw - - def is_entry_text_data?(ent, path) - # UTF-16 contains "\x00". - # It is very strict that file contains less than 30% of ascii symbols - # in non Western Europe. - return true if Redmine::MimeType.is_type?('text', path) - # Ruby 1.8.6 has a bug of integer divisions. - # http://apidock.com/ruby/v1_8_6_287/String/is_binary_data%3F - return false if ent.is_binary_data? - true - end - private :is_entry_text_data? - - def annotate - @entry = @repository.entry(@path, @rev) - (show_error_not_found; return) unless @entry - - @annotate = @repository.scm.annotate(@path, @rev) - if @annotate.nil? || @annotate.empty? - (render_error l(:error_scm_annotate); return) - end - ann_buf_size = 0 - @annotate.lines.each do |buf| - ann_buf_size += buf.size - end - if ann_buf_size > Setting.file_max_size_displayed.to_i.kilobyte - (render_error l(:error_scm_annotate_big_text_file); return) - end - @changeset = @repository.find_changeset_by_name(@rev) - end - - def revision - respond_to do |format| - format.html{render :layout => 'project_base'} - format.js {render :layout => false} - end - end - - # Adds a related issue to a changeset - # POST /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues - def add_related_issue - @issue = @changeset.find_referenced_issue_by_id(params[:issue_id]) - if @issue && (!@issue.visible? || @changeset.issues.include?(@issue)) - @issue = nil - end - - if @issue - @changeset.issues << @issue - end - end - - # Removes a related issue from a changeset - # DELETE /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues/:issue_id - def remove_related_issue - @issue = Issue.visible.find_by_id(params[:issue_id]) - if @issue - @changeset.issues.delete(@issue) - end - end - - def diff - if params[:format] == 'diff' - @diff = @repository.diff(@path, @rev, @rev_to) - (show_error_not_found; return) unless @diff - filename = "changeset_r#{@rev}" - filename << "_r#{@rev_to}" if @rev_to - send_data @diff.join, :filename => "#{filename}.diff", - :type => 'text/x-patch', - :disposition => 'attachment' - else - @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline' - @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type) - - # Save diff type as user preference - if User.current.logged? && @diff_type != User.current.pref[:diff_type] - User.current.pref[:diff_type] = @diff_type - User.current.preference.save - end - @cache_key = "repositories/diff/#{@repository.id}/" + - Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}-#{current_language}") - unless read_fragment(@cache_key) - @diff = @repository.diff(@path, @rev, @rev_to) - unless @diff - show_error_not_found - return - end - end - - @changeset = @repository.find_changeset_by_name(@rev) - @changeset_to = @rev_to ? @repository.find_changeset_by_name(@rev_to) : nil - @diff_format_revisions = @repository.diff_format_revisions(@changeset, @changeset_to) - end - render :layout => 'base_projects' - end - - def stats - @project_id = params[:id] - @repository_id = @repository.identifier - render :layout => 'base_projects' - end - - def graph - data = nil - case params[:graph] - when "commits_per_month" - data = graph_commits_per_month(@repository) - when "commits_per_author" - data = graph_commits_per_author(@repository) - end - if data - headers["Content-Type"] = "image/svg+xml" - send_data(data, :type => "image/svg+xml", :disposition => "inline") - else - render_404 - end - end - - private - - def find_repository - @repository = Repository.find(params[:id]) - @project = @repository.project - rescue ActiveRecord::RecordNotFound - render_404 - end - - REV_PARAM_RE = %r{\A[a-f0-9]*\Z}i - - def find_project_repository - @project = Project.find(params[:id]) - if params[:repository_id].present? - @repository = @project.repositories.find_by_identifier_param(params[:repository_id]) - else - @repository = @project.repository - end - (render_404; return false) unless @repository - @path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s - @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].to_s.strip - @rev_to = params[:rev_to] - - unless @rev.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE) - if @repository.branches.blank? - raise InvalidRevisionParam - end - end - rescue ActiveRecord::RecordNotFound - render_404 - rescue InvalidRevisionParam - show_error_not_found - end - - def find_changeset - if @rev.present? - @changeset = @repository.find_changeset_by_name(@rev) - end - show_error_not_found unless @changeset - end - - def show_error_not_found - render_error :message => l(:error_scm_not_found), :status => 404 - end - - def show_error_forbidden - render_error :status => 403 - end - - # Handler for Redmine::Scm::Adapters::CommandFailed exception - def show_error_command_failed(exception) - render_error l(:error_scm_command_failed, exception.message) - end - - def graph_commits_per_month(repository) - @date_to = Date.today - @date_from = @date_to << 11 - @date_from = Date.civil(@date_from.year, @date_from.month, 1) - commits_by_day = Changeset.count( - :all, :group => :commit_date, - :conditions => ["repository_id = ? AND commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) - commits_by_month = [0] * 12 - commits_by_day.each {|c| commits_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last } - - changes_by_day = Change.count( - :all, :group => :commit_date, :include => :changeset, - :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) - changes_by_month = [0] * 12 - changes_by_day.each {|c| changes_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last } - - fields = [] - 12.times {|m| fields << month_name(((Date.today.month - 1 - m) % 12) + 1)} - - graph = SVG::Graph::Bar.new( - :height => 300, - :width => 600, - :fields => fields.reverse, - :stack => :side, - :scale_integers => true, - :step_x_labels => 2, - :show_data_values => false, - :graph_title => l(:label_commits_per_month), - :show_graph_title => true - ) - - graph.add_data( - :data => commits_by_month[0..11].reverse, - :title => l(:label_revision_plural) - ) - - graph.add_data( - :data => changes_by_month[0..11].reverse, - :title => l(:label_change_plural) - ) - - graph.burn - end - - def graph_commits_per_author(repository) - commits_by_author = Changeset.count(:all, :group => :committer, :conditions => ["repository_id = ?", repository.id]) - commits_by_author.to_a.sort! {|x, y| x.last <=> y.last} - - changes_by_author = Change.count(:all, :group => :committer, :include => :changeset, :conditions => ["#{Changeset.table_name}.repository_id = ?", repository.id]) - h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o} - - fields = commits_by_author.collect {|r| r.first} - commits_data = commits_by_author.collect {|r| r.last} - changes_data = commits_by_author.collect {|r| h[r.first] || 0} - - fields = fields + [""]*(10 - fields.length) if fields.length<10 - commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10 - changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10 - - # Remove email adress in usernames - fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') } - - graph = SVG::Graph::BarHorizontal.new( - :height => 400, - :width => 600, - :fields => fields, - :stack => :side, - :scale_integers => true, - :show_data_values => false, - :rotate_y_labels => false, - :graph_title => l(:label_commits_per_author), - :show_graph_title => true - ) - graph.add_data( - :data => commits_data, - :title => l(:label_revision_plural) - ) - graph.add_data( - :data => changes_data, - :title => l(:label_change_plural) - ) - graph.burn - end - def check_hidden_repo - project = Project.find(params[:id]) - if !User.current.member_of?(project) - if project.hidden_repo - #render_403 - end - end - rescue ActiveRecord::RecordNotFound - render_404 - end -end +# 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. + +require 'SVG/Graph/Bar' +require 'SVG/Graph/BarHorizontal' +require 'digest/sha1' +require 'redmine/scm/adapters/abstract_adapter' +require 'tempfile' + +class ChangesetNotFound < Exception; end +class InvalidRevisionParam < Exception; end + +class RepositoriesController < ApplicationController + menu_item :repository + menu_item :settings, :only => [:new, :create, :edit, :update, :destroy, :committers] + default_search_scope :changesets + + before_filter :find_project_by_project_id, :only => [:new, :create, :newrepo] + before_filter :find_repository, :only => [:edit, :update, :destroy, :committers] + before_filter :find_project_repository, :except => [:new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo] + before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] + before_filter :authorize , :except => [:newrepo,:newcreate,:fork] + accept_rss_auth :revisions + # hidden repositories filter // 隐藏代码过滤器 + before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ] + helper :repositories + include RepositoriesHelper + helper :project_score + #@root_path = RepositoriesHelper::ROOT_PATH + + + rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed + def new + scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first + @repository = Repository.factory(scm) + @repository.is_default = @project.repository.nil? + @repository.project = @project + @course_tag = params[:course] + if @course_tag == 1 + render :layout => 'base_courses' + else + render :layout => 'base_projects' + end + end + + + def newrepo + scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first + @repository = Repository.factory(scm) + @repository.is_default = @project.repository.nil? + @repository.project = @project + @course_tag = params[:course] + if @course_tag == 1 + render :layout => 'base_courses' + else + render :layout => 'base_projects' + end + end + + def fork + @repository_url = params[:repository_url] + + # @repository.url + # system "htpasswd -mb "+@root_path+"user.passwd "+params[:repository][:identifier]+" "+@upasswd + # system "echo -e '"+params[:project_id]+"-"+params[:repository][:identifier]+"-write:"+ + # " "+params[:repository][:identifier]+"' >> "+@root_path+"group.passwd" + system "git clone --bare "+@repository_url + # system "mv "+@project_path+"/hooks/post-update{.sample,}" + # system "chmod a+x "+@project_path+"/hooks/post-update" + # system "."+@project_path+"/hooks/post-update" + # system "echo -e 'Allow from all \n Order Deny,Allow \n "+ + # " \n"+ + # "Require group "+params[:project_id]+"-"+params[:repository][:identifier]+"-write \n "+ + # " \n ' >>"+ + # @project_path+"/.htaccess" + flash[:notice] = l(:label_notice_fork_successed) + @repositories = @project.repositories + render :action => 'show', :layout => 'base_projects' + end + + def create + if params[:repository_scm].to_s == 'Gitlab' + # add by nwb + # 增加对gitlab版本库的支持 + attrs = pickup_extra_info + @repository = Repository.factory('Git') + @repository.safe_attributes = params[:repository] + if attrs[:attrs_extra].keys.any? + @repository.merge_extra_info(attrs[:attrs_extra]) + end + @repository.project = @project + if request.post? && @repository.save + redirect_to settings_project_path(@project, :tab => 'repositories') + else + render :action => 'new' + end + else # 原逻辑 + ##xianbo + @root_path=RepositoriesHelper::ROOT_PATH + @repository_name=User.current.login.to_s+"/"+params[:repository][:identifier]+".git" + @project_path=@root_path+"htdocs/"+@repository_name + @repository_tag=params[:repository][:upassword] + @repo_name=User.current.login.to_s+"_"+params[:repository][:identifier] + logger.info "htpasswd -mb "+@root_path+"user.passwd "+@repo_name+": "+@repository_tag + logger.info "the value of create repository"+@root_path+": "+@repository_name+": "+@project_path+": "+@repo_name + attrs = pickup_extra_info + if((@repository_tag!="")&¶ms[:repository_scm]=="Git") + params[:repository][:url]=@project_path + end + ###xianbo + @repository = Repository.factory(params[:repository_scm]) + @repository.safe_attributes = params[:repository] + if attrs[:attrs_extra].keys.any? + @repository.merge_extra_info(attrs[:attrs_extra]) + end + #by xianbo + + @repository.project = @project + if request.post? && @repository.save + if(params[:repository_scm]=="Git") + system "htpasswd -mb "+@root_path+"user.passwd "+@repo_name+" "+@repository_tag + system "echo -e '"+@repo_name+"-write:"+ + " "+@repo_name+"' >> "+@root_path+"group.passwd" + system "mkdir "+@root_path+"htdocs/"+User.current.login.to_s + system "git init --bare "+@project_path + system "mv "+@project_path+"/hooks/post-update{.sample,}" + system "chmod a+x "+@project_path+"/hooks/post-update" + system "echo -e 'Allow from all \n Order Deny,Allow \n "+ + " \n"+ + "Require group "+@repo_name+"-write \n "+ + " \n ' >> "+ + @root_path+"htdocs/"+ @repository_name+"/.htaccess" + system "cd "+@project_path+" ;git update-server-info" + # if(create_repo_file&&create_passwd&&create_group&&init_repository&&add_privilege&&init_server_info) + # else + # logger.info "An error occured when authenticating "+"create passwd"+@creat_passwd+"create_group"+ + # crate_group+"create repository file "+create_repo_file+"init repository"+init_repostory+ + # "aad privilege to rpository"+add_privilege+"init server infos"+init_server_info + # end + @repository.update_attributes(:login => User.current.login.to_s) + end + redirect_to settings_project_path(@project, :tab => 'repositories') + else if(@repository_tag) + render :action => 'newrepo', :layout =>'base_projects' + else + render :action => 'new', :layout =>'base_projects' + end + end + end + end + + def edit + end + + def update + attrs = pickup_extra_info + @repository.safe_attributes = attrs[:attrs] + if attrs[:attrs_extra].keys.any? + @repository.merge_extra_info(attrs[:attrs_extra]) + end + @repository.project = @project + if request.put? && @repository.save + redirect_to settings_project_path(@project, :tab => 'repositories') + else + render :action => 'edit' + end + end + + def pickup_extra_info + p = {} + p_extra = {} + params[:repository].each do |k, v| + if k =~ /^extra_/ + p_extra[k] = v + else + p[k] = v + end + end + {:attrs => p, :attrs_extra => p_extra} + end + private :pickup_extra_info + + def committers + @committers = @repository.committers + @users = @project.users + additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id) + @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty? + @users.compact! + @users.sort! + if request.post? && params[:committers].is_a?(Hash) + # Build a hash with repository usernames as keys and corresponding user ids as values + @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h} + flash[:notice] = l(:notice_successful_update) + redirect_to settings_project_path(@project, :tab => 'repositories') + elsif request.get? + respond_to do |format| + format.html{ + render :layout => "project_base" + } + end + + + end + end + + def destroy + @root_path=RepositoriesHelper::ROOT_PATH + @repo_name=User.current.login.to_s+"_"+@repository.identifier.to_s + @repository_name=User.current.login.to_s+"/"+@repository.identifier.to_s+".git" + @middle=User.current.login.to_s+"_"+@repository.identifier.to_s+"-write:" + @repository.destroy if request.delete? + redirect_to settings_project_path(@project, :tab => 'repositories') + if(@repository.type=="Repository::Git") + logger.info "destory the repository value"+"root path"+@root_path+"repo_name"+@repo_name+ + "repository_name"+@repository_name+"user group"+@middle + system "sed -i /"+@repo_name+"/{d} "+@root_path+"user.passwd" + system "sed -i /"+@middle+"/{d} "+@root_path+"group.passwd" + system "rm -r "+@root_path+"htdocs/"+@repository_name + # if(@sed_user&&@sed_group&&@remove) + # else + # logger.info "An error occured when destory the repository"+"delete form passwd: \n"+ + # @sed_user+"delete from group"+@sed_group+"delete from file"+@remove + # end + end + end + + def show + ## TODO: the below will move to filter, done. + # if !User.current.member_of?(@project) + # if @project.hidden_repo + # render_403 + # return -1 + # end + # end + #if( !User.current.member_of?(@project) || @project.hidden_repo) + @repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty? + + @entries = @repository.entries(@path, @rev) + @changeset = @repository.find_changeset_by_name(@rev) + + #@project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT + #@ip = RepositoriesHelper::REPO_IP_ADDRESS + + if request.xhr? + @entries ? render(:partial => 'dir_list_content') : render(:nothing => true) + else + #Modified by young + # (show_error_not_found; return) unless @entries + @changesets = @repository.latest_changesets(@path, @rev) + @properties = @repository.properties(@path, @rev) + @repositories = @project.repositories + @course_tag = params[:course] + project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT + ip = RepositoriesHelper::REPO_IP_ADDRESS + @repos_url = "http://"+@repository.login.to_s+"_"+@repository.identifier.to_s+"@"+ip.to_s+ + @repository.url.slice(project_path_cut, @repository.url.length).to_s + if @course_tag == 1 + render :action => 'show', :layout => 'base_courses' + else + render :action => 'show', :layout => 'base_projects' + end + end + end + + alias_method :browse, :show + + def changes + @entry = @repository.entry(@path, @rev) + (show_error_not_found; return) unless @entry + @changesets = @repository.latest_changesets(@path, @rev, Setting.repository_log_display_limit.to_i) + @properties = @repository.properties(@path, @rev) + @changeset = @repository.find_changeset_by_name(@rev) + render :layout => 'base_projects' + end + + def revisions + @changeset_count = @repository.changesets.count + @changeset_pages = Paginator.new @changeset_count, + per_page_option, + params['page'] + @changesets = @repository.changesets. + limit(@changeset_pages.per_page). + offset(@changeset_pages.offset). + includes(:user, :repository, :parents). + all + + respond_to do |format| + format.html { render :layout => 'base_projects' } + format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") } + end + end + + def raw + entry_and_raw(true) + end + + def entry + entry_and_raw(false) + end + + def entry_and_raw(is_raw) + @entry = @repository.entry(@path, @rev) + (show_error_not_found; return) unless @entry + + # If the entry is a dir, show the browser + (show; return) if @entry.is_dir? + + @content = @repository.cat(@path, @rev) + (show_error_not_found; return) unless @content + if is_raw || + (@content.size && @content.size > Setting.file_max_size_displayed.to_i.kilobyte) || + ! is_entry_text_data?(@content, @path) + # Force the download + send_opt = { :filename => filename_for_content_disposition(@path.split('/').last) } + send_type = Redmine::MimeType.of(@path) + send_opt[:type] = send_type.to_s if send_type + send_opt[:disposition] = (Redmine::MimeType.is_type?('image', @path) && !is_raw ? 'inline' : 'attachment') + send_data @content, send_opt + else + # Prevent empty lines when displaying a file with Windows style eol + # TODO: UTF-16 + # Is this needs? AttachmentsController reads file simply. + @content.gsub!("\r\n", "\n") + @changeset = @repository.find_changeset_by_name(@rev) + end + end + private :entry_and_raw + + def is_entry_text_data?(ent, path) + # UTF-16 contains "\x00". + # It is very strict that file contains less than 30% of ascii symbols + # in non Western Europe. + return true if Redmine::MimeType.is_type?('text', path) + # Ruby 1.8.6 has a bug of integer divisions. + # http://apidock.com/ruby/v1_8_6_287/String/is_binary_data%3F + return false if ent.is_binary_data? + true + end + private :is_entry_text_data? + + def annotate + @entry = @repository.entry(@path, @rev) + (show_error_not_found; return) unless @entry + + @annotate = @repository.scm.annotate(@path, @rev) + if @annotate.nil? || @annotate.empty? + (render_error l(:error_scm_annotate); return) + end + ann_buf_size = 0 + @annotate.lines.each do |buf| + ann_buf_size += buf.size + end + if ann_buf_size > Setting.file_max_size_displayed.to_i.kilobyte + (render_error l(:error_scm_annotate_big_text_file); return) + end + @changeset = @repository.find_changeset_by_name(@rev) + end + + def revision + respond_to do |format| + format.html{render :layout => 'project_base'} + format.js {render :layout => false} + end + end + + # Adds a related issue to a changeset + # POST /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues + def add_related_issue + @issue = @changeset.find_referenced_issue_by_id(params[:issue_id]) + if @issue && (!@issue.visible? || @changeset.issues.include?(@issue)) + @issue = nil + end + + if @issue + @changeset.issues << @issue + end + end + + # Removes a related issue from a changeset + # DELETE /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues/:issue_id + def remove_related_issue + @issue = Issue.visible.find_by_id(params[:issue_id]) + if @issue + @changeset.issues.delete(@issue) + end + end + + def diff + if params[:format] == 'diff' + @diff = @repository.diff(@path, @rev, @rev_to) + (show_error_not_found; return) unless @diff + filename = "changeset_r#{@rev}" + filename << "_r#{@rev_to}" if @rev_to + send_data @diff.join, :filename => "#{filename}.diff", + :type => 'text/x-patch', + :disposition => 'attachment' + else + @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline' + @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type) + + # Save diff type as user preference + if User.current.logged? && @diff_type != User.current.pref[:diff_type] + User.current.pref[:diff_type] = @diff_type + User.current.preference.save + end + @cache_key = "repositories/diff/#{@repository.id}/" + + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}-#{current_language}") + unless read_fragment(@cache_key) + @diff = @repository.diff(@path, @rev, @rev_to) + unless @diff + show_error_not_found + return + end + end + + @changeset = @repository.find_changeset_by_name(@rev) + @changeset_to = @rev_to ? @repository.find_changeset_by_name(@rev_to) : nil + @diff_format_revisions = @repository.diff_format_revisions(@changeset, @changeset_to) + end + render :layout => 'base_projects' + end + + def stats + @project_id = params[:id] + @repository_id = @repository.identifier + render :layout => 'base_projects' + end + + def graph + data = nil + case params[:graph] + when "commits_per_month" + data = graph_commits_per_month(@repository) + when "commits_per_author" + data = graph_commits_per_author(@repository) + end + if data + headers["Content-Type"] = "image/svg+xml" + send_data(data, :type => "image/svg+xml", :disposition => "inline") + else + render_404 + end + end + + private + + def find_repository + @repository = Repository.find(params[:id]) + @project = @repository.project + rescue ActiveRecord::RecordNotFound + render_404 + end + + REV_PARAM_RE = %r{\A[a-f0-9]*\Z}i + + def find_project_repository + @project = Project.find(params[:id]) + if params[:repository_id].present? + @repository = @project.repositories.find_by_identifier_param(params[:repository_id]) + else + @repository = @project.repository + end + (render_404; return false) unless @repository + @path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s + @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].to_s.strip + @rev_to = params[:rev_to] + + unless @rev.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE) + if @repository.branches.blank? + raise InvalidRevisionParam + end + end + rescue ActiveRecord::RecordNotFound + render_404 + rescue InvalidRevisionParam + show_error_not_found + end + + def find_changeset + if @rev.present? + @changeset = @repository.find_changeset_by_name(@rev) + end + show_error_not_found unless @changeset + end + + def show_error_not_found + render_error :message => l(:error_scm_not_found), :status => 404 + end + + def show_error_forbidden + render_error :status => 403 + end + + # Handler for Redmine::Scm::Adapters::CommandFailed exception + def show_error_command_failed(exception) + render_error l(:error_scm_command_failed, exception.message) + end + + def graph_commits_per_month(repository) + @date_to = Date.today + @date_from = @date_to << 11 + @date_from = Date.civil(@date_from.year, @date_from.month, 1) + commits_by_day = Changeset.count( + :all, :group => :commit_date, + :conditions => ["repository_id = ? AND commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) + commits_by_month = [0] * 12 + commits_by_day.each {|c| commits_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last } + + changes_by_day = Change.count( + :all, :group => :commit_date, :include => :changeset, + :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) + changes_by_month = [0] * 12 + changes_by_day.each {|c| changes_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last } + + fields = [] + 12.times {|m| fields << month_name(((Date.today.month - 1 - m) % 12) + 1)} + + graph = SVG::Graph::Bar.new( + :height => 300, + :width => 600, + :fields => fields.reverse, + :stack => :side, + :scale_integers => true, + :step_x_labels => 2, + :show_data_values => false, + :graph_title => l(:label_commits_per_month), + :show_graph_title => true + ) + + graph.add_data( + :data => commits_by_month[0..11].reverse, + :title => l(:label_revision_plural) + ) + + graph.add_data( + :data => changes_by_month[0..11].reverse, + :title => l(:label_change_plural) + ) + + graph.burn + end + + def graph_commits_per_author(repository) + commits_by_author = Changeset.count(:all, :group => :committer, :conditions => ["repository_id = ?", repository.id]) + commits_by_author.to_a.sort! {|x, y| x.last <=> y.last} + + changes_by_author = Change.count(:all, :group => :committer, :include => :changeset, :conditions => ["#{Changeset.table_name}.repository_id = ?", repository.id]) + h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o} + + fields = commits_by_author.collect {|r| r.first} + commits_data = commits_by_author.collect {|r| r.last} + changes_data = commits_by_author.collect {|r| h[r.first] || 0} + + fields = fields + [""]*(10 - fields.length) if fields.length<10 + commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10 + changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10 + + # Remove email adress in usernames + fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') } + + graph = SVG::Graph::BarHorizontal.new( + :height => 400, + :width => 600, + :fields => fields, + :stack => :side, + :scale_integers => true, + :show_data_values => false, + :rotate_y_labels => false, + :graph_title => l(:label_commits_per_author), + :show_graph_title => true + ) + graph.add_data( + :data => commits_data, + :title => l(:label_revision_plural) + ) + graph.add_data( + :data => changes_data, + :title => l(:label_change_plural) + ) + graph.burn + end + def check_hidden_repo + project = Project.find(params[:id]) + if !User.current.member_of?(project) + if project.hidden_repo + #render_403 + end + end + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index d15036fa0..d8ecb4ef7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,822 +1,822 @@ -# 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 UsersController < ApplicationController - layout :setting_layout - #Added by young - menu_item :activity - menu_item :user_information, :only => :info - menu_item :user_course, :only => :user_courses - menu_item :user_homework, :only => :user_homeworks - menu_item :user_project, :only => [:user_projects, :watch_projects] - menu_item :requirement_focus, :only => :watch_bids - menu_item :requirement_focus, :only => :watch_contests - menu_item :user_newfeedback, :only => :user_newfeedback - - - #Ended by young - - before_filter :can_show_course, :only => [:user_courses,:user_homeworks] - before_filter :require_admin, :except => [:show, :index, :search, :tag_save, :tag_saveEx,:user_projects, :user_newfeedback, :user_comments, :watch_bids, :watch_contests, :info, - :user_watchlist, :user_fanslist,:update, :user_courses, :user_homeworks, :watch_projects, :show_score, :topic_score_index, :project_score_index, - :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, - :activity_new_score_index, :influence_new_score_index, :score_new_index,:update_score,:user_activities] - #edit has been deleted by huang, 2013-9-23 - before_filter :find_user, :only => [:user_fanslist, :user_watchlist, :show, :edit, :update, :destroy, :edit_membership, :user_courses, - :user_homeworks, :destroy_membership, :user_activities, :user_projects, :user_newfeedback, :user_comments, - :watch_bids, :watch_contests, :info, :watch_projects, :show_score, :topic_score_index, :project_score_index, - :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, - :activity_new_score_index, :influence_new_score_index, :score_new_index] - before_filter :auth_user_extension, only: :show - before_filter :rest_user_score, only: :show - accept_api_auth :index, :show, :create, :update, :destroy,:tag_save , :tag_saveEx - - #william - before_filter :require_login, :only => [:tag_save,:tag_saveEx] - #before_filter :refresh_changests, :only =>[:user_activities,:user_courses,:user_projects,:user_newfeedback] - - - helper :sort - include SortHelper - helper :custom_fields - include CustomFieldsHelper - include AvatarHelper - include WordsHelper - include GitlabHelper - include UserScoreHelper - helper :user_score - - # added by liuping 关注 - - helper :watchers - helper :activities - - ### added by william - include ActsAsTaggableOn::TagsHelper - - # fq - helper :words - - def refresh_changests - if !(@user.nil?) && !(@user.memberships.nil?) - @user.memberships.each do |member| - unless member.project.nil? - member.project.repository.fetch_changesets if Setting.autofetch_changesets? - end - end - end - end - - #added by young - def user_projects - - if User.current.admin? - @memberships = @user.memberships.all(conditions: "projects.project_type = #{Project::ProjectType_project}") - else - cond = Project.visible_condition(User.current) + " AND projects.project_type <> 1" - @memberships = @user.memberships.all(:conditions => cond) - end - #events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 20) - #@events_by_day = events.group_by(&:event_date) - @state = 0 - - - #add by huang - unless User.current.admin? - if !@user.active? #|| (@user != User.current && @memberships.empty? && events.empty?) - render_404 - return - end - end - #end - - respond_to do |format| - format.html - format.api - end - end - -# added by bai - def show_score - - end - - def show_new_score - render :layout => false - end -# end - - ##added by fq - def watch_bids - cond = 'bids.reward_type <> 1' - @bids = Bid.watched_by(@user).where('reward_type = ?', 1) # added by huang - @offset, @limit = api_offset_and_limit({:limit => 10}) - @bid_count = @bids.count - @bid_pages = Paginator.new @bid_count, @limit, params['page'] - @offset ||= @bid_pages.reverse_offset - unless @offset == 0 - @bid = @bids.offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - @bid = @bids.offset(@offset).limit(limit).all.reverse - end - - respond_to do |format| - format.html { - render :layout => 'base_users' - } - format.api - end - end - -#new add by linchun - def watch_contests - @bids = Contest.watched_by(@user) - @offset, @limit = api_offset_and_limit({:limit => 10}) - @contest_count = @contests.count - @contest_pages = Paginator.new @contest_count, @limit, params['page'] - @offset ||= @contest_pages.reverse_offset - unless @offset == 0 - @contest = @contests.offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - @contest = @contests.offset(@offset).limit(limit).all.reverse - end - - respond_to do |format| - format.html { - render :layout => 'base_users' - } - format.api - end - end - - # added by fq - def user_activities - redirect_to user_path(@user, type: params[:type], page: params[:page]) - return - # useless abort. - @watcher = User.watched_by_id(@user) - events = [] - for user in @watcher - events << Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 30) - end - - - - @events_by_day = events.group_by(&:event_date) - - unless User.current.admin? - if !@user.active? || (@user != User.current && @memberships.empty? && events.empty?) - render_404 - return - end - end - - respond_to do |format| - format.html - format.api - end - end - # end - - # added by huang - def user_homeworks - @membership = @user.memberships.all(:conditions => Project.visible_condition(User.current)) - @memberships = [] - @membership.each do |membership| - if membership.project.project_type == 1 - @memberships << membership - end - end - @bid = [] - @memberships.each do |membership| - @bid += membership.project.homeworks - end - @bid = @bid.group_by {|bid| bid.courses.first.id} - unless User.current.admin? - if !@user.active? - render_404 - return - end - end - end - - - include CoursesHelper - def user_courses - - unless User.current.admin? - if !@user.active? #|| (@user != User.current && @memberships.empty? && events.empty?) - render_404 - return - end - end - - membership = @user.coursememberships.all#@user.coursememberships.all(:conditions => Course.visible_condition(User.current)) - membership.sort! {|older, newer| newer.created_on <=> older.created_on } - @memberships = [] - membership.collect { |e| - @memberships.push(e) - } - ## 判断课程是否过期 [需封装] - @memberships_doing = [] - @memberships_done = [] - now_time = Time.now.year - @memberships.map { |e| - end_time = e.course.get_time.year - isDone = course_endTime_timeout?(e.course) - if isDone - @memberships_done.push e - else - @memberships_doing.push e - end - } - # respond_to do |format| - # format.html - # format.api - # end - end - -# modified by fq - def user_newfeedback - @jours = @user.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - @jours.update_all(:is_readed => true, :status => false) - @jours.each do |journal| - fetch_user_leaveWord_reply(journal).update_all(:is_readed => true, :status => false) - end - - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - @state = false - end - # end - - def user_comments - - end - - #end - def index - @status = params[:status] || 1 - sort_init 'login', 'asc' - sort_update %w(login firstname lastname mail admin created_on last_login_on) - - case params[:format] - when 'xml', 'json' - @offset, @limit = api_offset_and_limit({:limit => 15}) - else - @limit = 15 - end - - # retrieve all users - # 先内连一下statuses 保证排序之后数量一致 - scope = User.visible. - joins("INNER JOIN user_statuses ON users.id = user_statuses.user_id") - - # unknow - scope = scope.in_group(params[:group_id]) if params[:group_id].present? - - # pagination - @user_count = scope.count - @user_pages = Paginator.new @user_count, @limit, params['page'] - - # users classify - case params[:user_sort_type] - when '0' - # 创建时间排序 - @s_type = 0 - @users = scope.reorder('users.created_on DESC') - when '1' - # 活跃度排序, 就是所谓的得分情况 - @s_type = 1 - @users = scope. - joins("LEFT JOIN option_numbers ON users.id = option_numbers.user_id and option_numbers.score_type = 1"). - reorder('option_numbers.total_score DESC') - when '2' - # 粉丝数排序 - @s_type = 2 - @users = scope. - #joins("INNER JOIN user_statuses ON users.id = user_statuses.user_id"). - reorder('user_statuses.watchers_count DESC') - - else - # 默认活跃度排序 - @s_type = 1 - @users = scope. - joins("LEFT JOIN option_numbers ON users.id = option_numbers.user_id and option_numbers.score_type = 1"). - reorder('option_numbers.total_score DESC') - end - - # limit and offset - @users = @users.limit(@user_pages.per_page).offset(@user_pages.offset) - - @user_base_tag = params[:id] ? 'base_users':'users_base' - respond_to do |format| - format.html { - @groups = Group.all.sort - render :layout => @user_base_tag - } - format.api - end - end - - def search - sort_init 'login', 'asc' - sort_update %w(login firstname lastname mail admin created_on last_login_on) - (redirect_to users_path, :notice => l(:label_sumbit_empty);return) if params[:name].blank? - case params[:format] - when 'xml', 'json' - @offset, @limit = api_offset_and_limit({:limit => 15}) - else - @limit = 15#per_page_option - end - - @status = params[:status] || 1 - has = { - "show_changesets" => true - } - scope = User.logged.status(@status) - scope = scope.like(params[:name]) if params[:name].present? - @user_count = scope.count - @user_pages = Paginator.new @user_count, @limit, params['page'] - @user_base_tag = params[:id] ? 'base_users':'users_base' - @offset ||= @user_pages.reverse_offset - unless @offset == 0 - @users = scope.offset(@offset).limit(@limit).all.reverse - else - limit = @user_count % @limit - if limit == 0 - limit = @limit - end - @users = scope.offset(@offset).limit(limit).all.reverse - end - - respond_to do |format| - format.html { - @groups = Group.all.sort - render :layout => @user_base_tag - } - format.api - end - end - - def show - pre_count = 10 #limit - case params[:type] - when "1" - if @user == User.current - activity = Activity.where('user_id = ?', User.current.id).order('id desc') - @activity_count = activity.count - @activity_pages = Paginator.new @activity_count, pre_count, params['page'] - @activity = activity.offset(@activity_pages.offset).limit(@activity_pages.per_page).all - @state = 1 - end - when "2" - message = [] - if @user == User.current - message = JournalsForMessage.reference_message(@user.id) - message += Journal.reference_message(@user.id) - end - @activity_count = message.size - @info_pages = Paginator.new @activity_count, pre_count, params['page'] - messages = message.sort {|x,y| y.created_on <=> x.created_on } - @message = messages[@info_pages.offset, @info_pages.per_page] - @state = 2 - else - where_condition = nil; - # where_condition = "act_type <> 'JournalsForMessage'" - if @user == User.current - watcher = User.watched_by(@user) - watcher.push(User.current) - activity = Activity.where(where_condition).where('user_id in (?)', watcher).order('id desc') - else - activity = Activity.where(where_condition).where('user_id = ?', @user.id).order('id desc') - end - @activity_count = activity.count - @activity_pages = Paginator.new @activity_count, pre_count, params['page'] - @activity = activity.offset(@activity_pages.offset).limit(@activity_pages.per_page).all - @state = 0 - end - - if params[:user].present? - - user_temp = User.find_by_sql("select id from users where concat(lastname,firstname) like '%#{params[:user]}%' or lastname like '%#{params[:user]}%'") - - if user_temp.size > 1 - activity = Activity.where('user_id in (?)', user_temp).where('user_id in (?)', watcher).order('id desc') - elsif user_temp.size == 1 - activity = Activity.where('user_id = ?', user_temp).where('user_id in (?)', watcher).order('id desc') - else - activity = Activity.where("1 = 0") - end - @offset, @limit = api_offset_and_limit({:limit => 10}) - @activity_count = activity.count - @activity_pages = Paginator.new @activity_count, @limit, params['page'] - @offset ||= @activity_pages.offset - @activity = activity.offset(@offset).limit(@limit) - @state = 0 - end - - -#Modified by nie - unless User.current.admin? - if !@user.active? #|| (@user != User.current && @memberships.empty? && events.empty?) - # redirect_to home_path - render_404 - return - end - end - - respond_to do |format| - format.html - format.api - end - end - - ##end fq - - #### added by fq - def info - - message = [] - if @user == User.current - message = JournalsForMessage.reference_message(@user.id) - message += Journal.reference_message(@user.id) - end - @offset, @limit = api_offset_and_limit({:limit => 10}) - @info_count = message.size - @info_pages = Paginator.new @info_count, @limit, params['page'] - @offset ||= @info_pages.offset - - messages = message.sort {|x,y| y.created_on <=> x.created_on } - - @message = messages[@offset, @limit] - - unless User.current.admin? - if !@user.active? - render_404 - return - end - end - - respond_to do |format| - format.html - format.api - end - end - #### end - - - def new - @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option) - @auth_sources = AuthSource.all - render :layout => "users_base" - end - - def create - @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option) - @user.safe_attributes = params[:user] - @user.admin = params[:user][:admin] || false - @user.login = params[:user][:login] - @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] unless @user.auth_source_id - - if @user.save - @user.pref.attributes = params[:pref] - @user.pref[:no_self_notified] = (params[:no_self_notified] == '1') - @user.pref.save - @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : []) - - Mailer.account_information(@user, params[:user][:password]).deliver if params[:send_information] - - respond_to do |format| - format.html { - flash[:notice] = l(:notice_user_successful_create, :id => view_context.link_to(@user.login, user_path(@user))) - if params[:continue] - redirect_to new_user_path - else - redirect_to edit_user_path(@user) - end - } - format.api { render :action => 'show', :status => :created, :location => user_url(@user) } - end - else - @auth_sources = AuthSource.all - # Clear password input - @user.password = @user.password_confirmation = nil - - respond_to do |format| - format.html { render :action => 'new',:layout => "users_base" } - format.api { render_validation_errors(@user) } - end - end - - unless @user.id.nil? - #后台注册的用户默认权限为男性开发员 - ue = UserExtensions.create(:identity => 3, - :gender => 0, - :user_id => @user.id) - ue.save - end - end - - def edit - @auth_sources = AuthSource.all - @membership ||= Member.new - end - - def watch_projects - @watch_projects = Project.joins(:watchers).where("project_type <>? and watchable_type = ? and `watchers`.user_id = ?", '1','Project', @user.id) - @state = 1 - respond_to do |format| - format.html { - render :layout => 'base_users' - } - format.api - end - end - - def update - @user.admin = params[:user][:admin] if params[:user][:admin] - @user.login = params[:user][:login] if params[:user][:login] - if params[:user][:password].present? && (@user.auth_source_id.nil? || params[:user][:auth_source_id].blank?) - @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] - end - @user.safe_attributes = params[:user] - # Was the account actived ? (do it before User#save clears the change) - was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE]) - # TODO: Similar to My#account - @user.pref.attributes = params[:pref] - @user.pref[:no_self_notified] = (params[:no_self_notified] == '1') - - if @user.save - @user.pref.save - @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : []) - - if was_activated - Mailer.account_activated(@user).deliver - elsif @user.active? && params[:send_information] && !params[:user][:password].blank? && @user.auth_source_id.nil? - Mailer.account_information(@user, params[:user][:password]).deliver - end - - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_to_referer_or edit_user_path(@user) - } - format.api { render_api_ok } - end - else - @auth_sources = AuthSource.all - @membership ||= Member.new - # Clear password input - @user.password = @user.password_confirmation = nil - - respond_to do |format| - format.html { render :action => :edit } - format.api { render_validation_errors(@user) } - end - end - end - - def destroy - @user.destroy - respond_to do |format| - format.html { redirect_back_or_default(admin_users_path) } - format.api { render_api_ok } - end - end - - def edit_membership - @membership = Member.edit_membership(params[:membership_id], params[:membership], @user) - @membership.save - respond_to do |format| - format.html { redirect_to edit_user_path(@user, :tab => 'memberships') } - format.js - end - end - - def destroy_membership - @membership = Member.find(params[:membership_id]) - if @membership.deletable? - @membership.destroy - end - respond_to do |format| - format.html { redirect_to edit_user_path(@user, :tab => 'memberships') } - format.js - end - end - - ################# added by william - def tag_save - @tags = params[:tag_for_save][:name] - @obj_id = params[:tag_for_save][:object_id] - @obj_flag = params[:tag_for_save][:object_flag] - - case @obj_flag - when '1' then - @obj = User.find_by_id(@obj_id) - when '2' then - @obj = Project.find_by_id(@obj_id) - when '3' then - @obj = Issue.find_by_id(@obj_id) - when '4' then - @obj = Bid.find_by_id(@obj_id) - when '5' then - @obj = Forum.find_by_id(@obj_id) - when '6' - @obj = Attachment.find_by_id(@obj_id) - when '7' then - @obj = Contest.find_by_id(@obj_id) - when '8' - @obj = OpenSourceProject.find_by_id(@obj_id) - when '9' - @obj = Course.find_by_id(@obj_id) - else - @obj = nil - end - unless @obj.nil? - @obj.tag_list.add(@tags.split(",")) - else - return - end - if @obj.save - logger.debug "#{__FILE__}:#{__LINE__} ===> #{@obj.to_json}" - else - logger.error "#{__FILE__}:#{__LINE__} ===> #{@obj.errors.try(:full_messages)}" - end - respond_to do |format| - format.js - format.html - end - end - - def tag_saveEx - @tags = params[:tag_name] - @obj_id = params[:obj_id] - @obj_flag = params[:obj_flag] - - case @obj_flag - when '1' then - @obj = User.find_by_id(@obj_id) - when '2' then - @obj = Project.find_by_id(@obj_id) - when '3' then - @obj = Issue.find_by_id(@obj_id) - when '4' then - @obj = Bid.find_by_id(@obj_id) - when '5' then - @obj = Forum.find_by_id(@obj_id) - when '6' - @obj = Attachment.find_by_id(@obj_id) - when '7' then - @obj = Contest.find_by_id(@obj_id) - when '8' - @obj = OpenSourceProject.find_by_id(@obj_id) - when '9' - @obj = Course.find_by_id(@obj_id) - else - @obj = nil - end - unless @obj.nil? - @obj.tag_list.add(@tags.split(",")) - else - return - end - if @obj.save - ## 执行成功的操作。 - else - #捕获异常 - end - respond_to do |format| - format.js - format.html - end - end - ###add by huang - def user_watchlist - end - ###add by huang - def user_fanslist - - end - - #william - def update_extensions(user_extensions) - user_extensions = params[:user_extensions] - unless user_extensions.nil? - user_extensions = UserExtensions.find_by_id(user_extensions.user_id) - - # user_extensions. - end - end - -# added by bai - def topic_score_index - - end - - def project_score_index - - end - - def activity_score_index - - end - - def influence_score_index - - end - - def score_index - - end -# end - def topic_new_score_index - - end - - def project_new_score_index - - end - - def activity_new_score_index - - end - - def influence_new_score_index - - end - - def score_new_index - - end - - def update_score - @user = User.find(params[:id]) - end - - private - - def find_user - if params[:id] == 'current' - require_login || return - @user = User.current - else - @user = User.find(params[:id]) - end - rescue ActiveRecord::RecordNotFound - render_404 - end - - def setting_layout(default_base='base_users') - User.current.admin? ? default_base : default_base - end - - # 必填自己的工作单位,其实就是学校 - def auth_user_extension - if @user == User.current && @user.user_extensions.school.nil? - flash[:error] = l(:error_complete_occupation) - redirect_to my_account_path - end - end - - #重置用户得分 - def rest_user_score - memo_num(@user) - messges_for_issue_num(@user) - issues_status_num(@user) - replay_for_memo_num(@user) - tread_num(@user) - praise_num(@user) - changeset_num(@user) - document_num(@user) - attachment_num(@user) - issue_done_ratio_num(@user) - post_issue_num(@user) - end - - #验证是否显示课程 - def can_show_course - @first_page = FirstPage.where("page_type = 'project'").first - if @first_page.show_course == 2 - render_404 - end - end -end +# 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 UsersController < ApplicationController + layout :setting_layout + #Added by young + menu_item :activity + menu_item :user_information, :only => :info + menu_item :user_course, :only => :user_courses + menu_item :user_homework, :only => :user_homeworks + menu_item :user_project, :only => [:user_projects, :watch_projects] + menu_item :requirement_focus, :only => :watch_bids + menu_item :requirement_focus, :only => :watch_contests + menu_item :user_newfeedback, :only => :user_newfeedback + + + #Ended by young + + before_filter :can_show_course, :only => [:user_courses,:user_homeworks] + before_filter :require_admin, :except => [:show, :index, :search, :tag_save, :tag_saveEx,:user_projects, :user_newfeedback, :user_comments, :watch_bids, :watch_contests, :info, + :user_watchlist, :user_fanslist,:update, :user_courses, :user_homeworks, :watch_projects, :show_score, :topic_score_index, :project_score_index, + :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, + :activity_new_score_index, :influence_new_score_index, :score_new_index,:update_score,:user_activities] + #edit has been deleted by huang, 2013-9-23 + before_filter :find_user, :only => [:user_fanslist, :user_watchlist, :show, :edit, :update, :destroy, :edit_membership, :user_courses, + :user_homeworks, :destroy_membership, :user_activities, :user_projects, :user_newfeedback, :user_comments, + :watch_bids, :watch_contests, :info, :watch_projects, :show_score, :topic_score_index, :project_score_index, + :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, + :activity_new_score_index, :influence_new_score_index, :score_new_index] + before_filter :auth_user_extension, only: :show + before_filter :rest_user_score, only: :show + accept_api_auth :index, :show, :create, :update, :destroy,:tag_save , :tag_saveEx + + #william + before_filter :require_login, :only => [:tag_save,:tag_saveEx] + #before_filter :refresh_changests, :only =>[:user_activities,:user_courses,:user_projects,:user_newfeedback] + + + helper :sort + include SortHelper + helper :custom_fields + include CustomFieldsHelper + include AvatarHelper + include WordsHelper + include GitlabHelper + include UserScoreHelper + helper :user_score + + # added by liuping 关注 + + helper :watchers + helper :activities + + ### added by william + include ActsAsTaggableOn::TagsHelper + + # fq + helper :words + + def refresh_changests + if !(@user.nil?) && !(@user.memberships.nil?) + @user.memberships.each do |member| + unless member.project.nil? + member.project.repository.fetch_changesets if Setting.autofetch_changesets? + end + end + end + end + + #added by young + def user_projects + + if User.current.admin? + @memberships = @user.memberships.all(conditions: "projects.project_type = #{Project::ProjectType_project}") + else + cond = Project.visible_condition(User.current) + " AND projects.project_type <> 1" + @memberships = @user.memberships.all(:conditions => cond) + end + #events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 20) + #@events_by_day = events.group_by(&:event_date) + @state = 0 + + + #add by huang + unless User.current.admin? + if !@user.active? #|| (@user != User.current && @memberships.empty? && events.empty?) + render_404 + return + end + end + #end + + respond_to do |format| + format.html + format.api + end + end + +# added by bai + def show_score + + end + + def show_new_score + render :layout => false + end +# end + + ##added by fq + def watch_bids + cond = 'bids.reward_type <> 1' + @bids = Bid.watched_by(@user).where('reward_type = ?', 1) # added by huang + @offset, @limit = api_offset_and_limit({:limit => 10}) + @bid_count = @bids.count + @bid_pages = Paginator.new @bid_count, @limit, params['page'] + @offset ||= @bid_pages.reverse_offset + unless @offset == 0 + @bid = @bids.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + @bid = @bids.offset(@offset).limit(limit).all.reverse + end + + respond_to do |format| + format.html { + render :layout => 'base_users' + } + format.api + end + end + +#new add by linchun + def watch_contests + @bids = Contest.watched_by(@user) + @offset, @limit = api_offset_and_limit({:limit => 10}) + @contest_count = @contests.count + @contest_pages = Paginator.new @contest_count, @limit, params['page'] + @offset ||= @contest_pages.reverse_offset + unless @offset == 0 + @contest = @contests.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + @contest = @contests.offset(@offset).limit(limit).all.reverse + end + + respond_to do |format| + format.html { + render :layout => 'base_users' + } + format.api + end + end + + # added by fq + def user_activities + redirect_to user_path(@user, type: params[:type], page: params[:page]) + return + # useless abort. + @watcher = User.watched_by_id(@user) + events = [] + for user in @watcher + events << Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 30) + end + + + + @events_by_day = events.group_by(&:event_date) + + unless User.current.admin? + if !@user.active? || (@user != User.current && @memberships.empty? && events.empty?) + render_404 + return + end + end + + respond_to do |format| + format.html + format.api + end + end + # end + + # added by huang + def user_homeworks + @membership = @user.memberships.all(:conditions => Project.visible_condition(User.current)) + @memberships = [] + @membership.each do |membership| + if membership.project.project_type == 1 + @memberships << membership + end + end + @bid = [] + @memberships.each do |membership| + @bid += membership.project.homeworks + end + @bid = @bid.group_by {|bid| bid.courses.first.id} + unless User.current.admin? + if !@user.active? + render_404 + return + end + end + end + + + include CoursesHelper + def user_courses + + unless User.current.admin? + if !@user.active? #|| (@user != User.current && @memberships.empty? && events.empty?) + render_404 + return + end + end + + membership = @user.coursememberships.all#@user.coursememberships.all(:conditions => Course.visible_condition(User.current)) + membership.sort! {|older, newer| newer.created_on <=> older.created_on } + @memberships = [] + membership.collect { |e| + @memberships.push(e) + } + ## 判断课程是否过期 [需封装] + @memberships_doing = [] + @memberships_done = [] + now_time = Time.now.year + @memberships.map { |e| + end_time = e.course.get_time.year + isDone = course_endTime_timeout?(e.course) + if isDone + @memberships_done.push e + else + @memberships_doing.push e + end + } + # respond_to do |format| + # format.html + # format.api + # end + end + +# modified by fq + def user_newfeedback + @jours = @user.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @jours.update_all(:is_readed => true, :status => false) + @jours.each do |journal| + fetch_user_leaveWord_reply(journal).update_all(:is_readed => true, :status => false) + end + + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @state = false + end + # end + + def user_comments + + end + + #end + def index + @status = params[:status] || 1 + sort_init 'login', 'asc' + sort_update %w(login firstname lastname mail admin created_on last_login_on) + + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit({:limit => 15}) + else + @limit = 15 + end + + # retrieve all users + # 先内连一下statuses 保证排序之后数量一致 + scope = User.visible. + joins("INNER JOIN user_statuses ON users.id = user_statuses.user_id") + + # unknow + scope = scope.in_group(params[:group_id]) if params[:group_id].present? + + # pagination + @user_count = scope.count + @user_pages = Paginator.new @user_count, @limit, params['page'] + + # users classify + case params[:user_sort_type] + when '0' + # 创建时间排序 + @s_type = 0 + @users = scope.reorder('users.created_on DESC') + when '1' + # 活跃度排序, 就是所谓的得分情况 + @s_type = 1 + @users = scope. + joins("LEFT JOIN option_numbers ON users.id = option_numbers.user_id and option_numbers.score_type = 1"). + reorder('option_numbers.total_score DESC') + when '2' + # 粉丝数排序 + @s_type = 2 + @users = scope. + #joins("INNER JOIN user_statuses ON users.id = user_statuses.user_id"). + reorder('user_statuses.watchers_count DESC') + + else + # 默认活跃度排序 + @s_type = 1 + @users = scope. + joins("LEFT JOIN option_numbers ON users.id = option_numbers.user_id and option_numbers.score_type = 1"). + reorder('option_numbers.total_score DESC') + end + + # limit and offset + @users = @users.limit(@user_pages.per_page).offset(@user_pages.offset) + + @user_base_tag = params[:id] ? 'base_users':'users_base' + respond_to do |format| + format.html { + @groups = Group.all.sort + render :layout => @user_base_tag + } + format.api + end + end + + def search + sort_init 'login', 'asc' + sort_update %w(login firstname lastname mail admin created_on last_login_on) + (redirect_to users_path, :notice => l(:label_sumbit_empty);return) if params[:name].blank? + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit({:limit => 15}) + else + @limit = 15#per_page_option + end + + @status = params[:status] || 1 + has = { + "show_changesets" => true + } + scope = User.logged.status(@status) + scope = scope.like(params[:name]) if params[:name].present? + @user_count = scope.count + @user_pages = Paginator.new @user_count, @limit, params['page'] + @user_base_tag = params[:id] ? 'base_users':'users_base' + @offset ||= @user_pages.reverse_offset + unless @offset == 0 + @users = scope.offset(@offset).limit(@limit).all.reverse + else + limit = @user_count % @limit + if limit == 0 + limit = @limit + end + @users = scope.offset(@offset).limit(limit).all.reverse + end + + respond_to do |format| + format.html { + @groups = Group.all.sort + render :layout => @user_base_tag + } + format.api + end + end + + def show + pre_count = 10 #limit + case params[:type] + when "1" + if @user == User.current + activity = Activity.where('user_id = ?', User.current.id).order('id desc') + @activity_count = activity.count + @activity_pages = Paginator.new @activity_count, pre_count, params['page'] + @activity = activity.offset(@activity_pages.offset).limit(@activity_pages.per_page).all + @state = 1 + end + when "2" + message = [] + if @user == User.current + message = JournalsForMessage.reference_message(@user.id) + message += Journal.reference_message(@user.id) + end + @activity_count = message.size + @info_pages = Paginator.new @activity_count, pre_count, params['page'] + messages = message.sort {|x,y| y.created_on <=> x.created_on } + @message = messages[@info_pages.offset, @info_pages.per_page] + @state = 2 + else + where_condition = nil; + # where_condition = "act_type <> 'JournalsForMessage'" + if @user == User.current + watcher = User.watched_by(@user) + watcher.push(User.current) + activity = Activity.where(where_condition).where('user_id in (?)', watcher).order('id desc') + else + activity = Activity.where(where_condition).where('user_id = ?', @user.id).order('id desc') + end + @activity_count = activity.count + @activity_pages = Paginator.new @activity_count, pre_count, params['page'] + @activity = activity.offset(@activity_pages.offset).limit(@activity_pages.per_page).all + @state = 0 + end + + if params[:user].present? + + user_temp = User.find_by_sql("select id from users where concat(lastname,firstname) like '%#{params[:user]}%' or lastname like '%#{params[:user]}%'") + + if user_temp.size > 1 + activity = Activity.where('user_id in (?)', user_temp).where('user_id in (?)', watcher).order('id desc') + elsif user_temp.size == 1 + activity = Activity.where('user_id = ?', user_temp).where('user_id in (?)', watcher).order('id desc') + else + activity = Activity.where("1 = 0") + end + @offset, @limit = api_offset_and_limit({:limit => 10}) + @activity_count = activity.count + @activity_pages = Paginator.new @activity_count, @limit, params['page'] + @offset ||= @activity_pages.offset + @activity = activity.offset(@offset).limit(@limit) + @state = 0 + end + + +#Modified by nie + unless User.current.admin? + if !@user.active? #|| (@user != User.current && @memberships.empty? && events.empty?) + # redirect_to home_path + render_404 + return + end + end + + respond_to do |format| + format.html + format.api + end + end + + ##end fq + + #### added by fq + def info + + message = [] + if @user == User.current + message = JournalsForMessage.reference_message(@user.id) + message += Journal.reference_message(@user.id) + end + @offset, @limit = api_offset_and_limit({:limit => 10}) + @info_count = message.size + @info_pages = Paginator.new @info_count, @limit, params['page'] + @offset ||= @info_pages.offset + + messages = message.sort {|x,y| y.created_on <=> x.created_on } + + @message = messages[@offset, @limit] + + unless User.current.admin? + if !@user.active? + render_404 + return + end + end + + respond_to do |format| + format.html + format.api + end + end + #### end + + + def new + @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option) + @auth_sources = AuthSource.all + render :layout => "users_base" + end + + def create + @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option) + @user.safe_attributes = params[:user] + @user.admin = params[:user][:admin] || false + @user.login = params[:user][:login] + @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] unless @user.auth_source_id + + if @user.save + @user.pref.attributes = params[:pref] + @user.pref[:no_self_notified] = (params[:no_self_notified] == '1') + @user.pref.save + @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : []) + + Mailer.account_information(@user, params[:user][:password]).deliver if params[:send_information] + + respond_to do |format| + format.html { + flash[:notice] = l(:notice_user_successful_create, :id => view_context.link_to(@user.login, user_path(@user))) + if params[:continue] + redirect_to new_user_path + else + redirect_to edit_user_path(@user) + end + } + format.api { render :action => 'show', :status => :created, :location => user_url(@user) } + end + else + @auth_sources = AuthSource.all + # Clear password input + @user.password = @user.password_confirmation = nil + + respond_to do |format| + format.html { render :action => 'new',:layout => "users_base" } + format.api { render_validation_errors(@user) } + end + end + + unless @user.id.nil? + #后台注册的用户默认权限为男性开发员 + ue = UserExtensions.create(:identity => 3, + :gender => 0, + :user_id => @user.id) + ue.save + end + end + + def edit + @auth_sources = AuthSource.all + @membership ||= Member.new + end + + def watch_projects + @watch_projects = Project.joins(:watchers).where("project_type <>? and watchable_type = ? and `watchers`.user_id = ?", '1','Project', @user.id) + @state = 1 + respond_to do |format| + format.html { + render :layout => 'base_users' + } + format.api + end + end + + def update + @user.admin = params[:user][:admin] if params[:user][:admin] + @user.login = params[:user][:login] if params[:user][:login] + if params[:user][:password].present? && (@user.auth_source_id.nil? || params[:user][:auth_source_id].blank?) + @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] + end + @user.safe_attributes = params[:user] + # Was the account actived ? (do it before User#save clears the change) + was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE]) + # TODO: Similar to My#account + @user.pref.attributes = params[:pref] + @user.pref[:no_self_notified] = (params[:no_self_notified] == '1') + + if @user.save + @user.pref.save + @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : []) + + if was_activated + Mailer.account_activated(@user).deliver + elsif @user.active? && params[:send_information] && !params[:user][:password].blank? && @user.auth_source_id.nil? + Mailer.account_information(@user, params[:user][:password]).deliver + end + + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_to_referer_or edit_user_path(@user) + } + format.api { render_api_ok } + end + else + @auth_sources = AuthSource.all + @membership ||= Member.new + # Clear password input + @user.password = @user.password_confirmation = nil + + respond_to do |format| + format.html { render :action => :edit } + format.api { render_validation_errors(@user) } + end + end + end + + def destroy + @user.destroy + respond_to do |format| + format.html { redirect_back_or_default(admin_users_path) } + format.api { render_api_ok } + end + end + + def edit_membership + @membership = Member.edit_membership(params[:membership_id], params[:membership], @user) + @membership.save + respond_to do |format| + format.html { redirect_to edit_user_path(@user, :tab => 'memberships') } + format.js + end + end + + def destroy_membership + @membership = Member.find(params[:membership_id]) + if @membership.deletable? + @membership.destroy + end + respond_to do |format| + format.html { redirect_to edit_user_path(@user, :tab => 'memberships') } + format.js + end + end + + ################# added by william + def tag_save + @tags = params[:tag_for_save][:name] + @obj_id = params[:tag_for_save][:object_id] + @obj_flag = params[:tag_for_save][:object_flag] + + case @obj_flag + when '1' then + @obj = User.find_by_id(@obj_id) + when '2' then + @obj = Project.find_by_id(@obj_id) + when '3' then + @obj = Issue.find_by_id(@obj_id) + when '4' then + @obj = Bid.find_by_id(@obj_id) + when '5' then + @obj = Forum.find_by_id(@obj_id) + when '6' + @obj = Attachment.find_by_id(@obj_id) + when '7' then + @obj = Contest.find_by_id(@obj_id) + when '8' + @obj = OpenSourceProject.find_by_id(@obj_id) + when '9' + @obj = Course.find_by_id(@obj_id) + else + @obj = nil + end + unless @obj.nil? + @obj.tag_list.add(@tags.split(",")) + else + return + end + if @obj.save + logger.debug "#{__FILE__}:#{__LINE__} ===> #{@obj.to_json}" + else + logger.error "#{__FILE__}:#{__LINE__} ===> #{@obj.errors.try(:full_messages)}" + end + respond_to do |format| + format.js + format.html + end + end + + def tag_saveEx + @tags = params[:tag_name] + @obj_id = params[:obj_id] + @obj_flag = params[:obj_flag] + + case @obj_flag + when '1' then + @obj = User.find_by_id(@obj_id) + when '2' then + @obj = Project.find_by_id(@obj_id) + when '3' then + @obj = Issue.find_by_id(@obj_id) + when '4' then + @obj = Bid.find_by_id(@obj_id) + when '5' then + @obj = Forum.find_by_id(@obj_id) + when '6' + @obj = Attachment.find_by_id(@obj_id) + when '7' then + @obj = Contest.find_by_id(@obj_id) + when '8' + @obj = OpenSourceProject.find_by_id(@obj_id) + when '9' + @obj = Course.find_by_id(@obj_id) + else + @obj = nil + end + unless @obj.nil? + @obj.tag_list.add(@tags.split(",")) + else + return + end + if @obj.save + ## 执行成功的操作。 + else + #捕获异常 + end + respond_to do |format| + format.js + format.html + end + end + ###add by huang + def user_watchlist + end + ###add by huang + def user_fanslist + + end + + #william + def update_extensions(user_extensions) + user_extensions = params[:user_extensions] + unless user_extensions.nil? + user_extensions = UserExtensions.find_by_id(user_extensions.user_id) + + # user_extensions. + end + end + +# added by bai + def topic_score_index + + end + + def project_score_index + + end + + def activity_score_index + + end + + def influence_score_index + + end + + def score_index + + end +# end + def topic_new_score_index + + end + + def project_new_score_index + + end + + def activity_new_score_index + + end + + def influence_new_score_index + + end + + def score_new_index + + end + + def update_score + @user = User.find(params[:id]) + end + + private + + def find_user + if params[:id] == 'current' + require_login || return + @user = User.current + else + @user = User.find(params[:id]) + end + rescue ActiveRecord::RecordNotFound + render_404 + end + + def setting_layout(default_base='base_users') + User.current.admin? ? default_base : default_base + end + + # 必填自己的工作单位,其实就是学校 + def auth_user_extension + if @user == User.current && (@user.user_extensions.nil? || @user.user_extensions.school.nil?) + flash[:error] = l(:error_complete_occupation) + redirect_to my_account_path + end + end + + #重置用户得分 + def rest_user_score + memo_num(@user) + messges_for_issue_num(@user) + issues_status_num(@user) + replay_for_memo_num(@user) + tread_num(@user) + praise_num(@user) + changeset_num(@user) + document_num(@user) + attachment_num(@user) + issue_done_ratio_num(@user) + post_issue_num(@user) + end + + #验证是否显示课程 + def can_show_course + @first_page = FirstPage.where("page_type = 'project'").first + if @first_page.show_course == 2 + render_404 + end + end +end diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index 5824848ff..c3aff06e1 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -1,200 +1,200 @@ -# 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 VersionsController < ApplicationController - layout "base_projects" - menu_item :roadmap - model_object Version - before_filter :find_model_object, :except => [:index, :new, :create, :close_completed] - #before_filter :find_model_object_contest, :except => [:index, :new, :create] - before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed] - before_filter :find_project_by_project_id, :only => [:index, :new, :create, :close_completed] - before_filter :authorize - - accept_api_auth :index, :show, :create, :update, :destroy - - helper :custom_fields - helper :projects - helper :project_score - - def index - respond_to do |format| - format.html { - @trackers = @project.trackers.sorted.all - retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?}) - @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') - project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id] - - @versions = @project.shared_versions || [] - @versions += @project.rolled_up_versions.visible if @with_subprojects - #added by young - @versions = @versions.uniq.reverse#Modified by young - unless params[:completed] - @completed_versions = @versions.select {|version| version.closed? || version.completed? } - @versions -= @completed_versions - end - @offset, @limit = api_offset_and_limit({:limit => 4}) - @versions_count = @versions.count - @versions_pages = Paginator.new @versions_count, @limit, params['page'] - @offset ||= @versions_pages.offset - @versions = @versions.slice(@offset, @limit) - #end by young - - - @issues_by_version = {} - if @selected_tracker_ids.any? && @versions.any? - issues = Issue.visible.all( - :include => [:project, :status, :tracker, :priority, :fixed_version], - :conditions => {:tracker_id => @selected_tracker_ids, :project_id => project_ids, :fixed_version_id => @versions.map(&:id)}, - :order => "#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id" - ) - @issues_by_version = issues.group_by(&:fixed_version) - end - @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?} - } - format.api { - @versions = @project.shared_versions.all - } - end - end - - def show - respond_to do |format| - format.html { - @issues = @version.fixed_issues.visible. - includes(:status, :tracker, :priority). - reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id"). - all - } - format.api - end - end - - def new - @version = @project.versions.build - @version.safe_attributes = params[:version] - - respond_to do |format| - format.html - format.js - end - end - - def create - @version = @project.versions.build - if params[:version] - attributes = params[:version].dup - attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing']) - @version.safe_attributes = attributes - end - - if request.post? - if @version.save - respond_to do |format| - format.html do - flash[:notice] = l(:notice_successful_create) - redirect_to settings_project_path(@project, :tab => 'versions') - end - format.js - format.api do - render :action => 'show', :status => :created, :location => version_url(@version) - end - end - else - respond_to do |format| - format.html { render :action => 'new' } - format.js { render :action => 'new' } - format.api { render_validation_errors(@version) } - end - end - end - end - - def edit - end - - def update - if request.put? && params[:version] - attributes = params[:version].dup - attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing']) - @version.safe_attributes = attributes - if @version.save - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_back_or_default settings_project_path(@project, :tab => 'versions') - } - format.api { render_api_ok } - end - else - respond_to do |format| - format.html { render :action => 'edit' } - format.api { render_validation_errors(@version) } - end - end - end - end - - def close_completed - if request.put? - @project.close_completed_versions - end - redirect_to settings_project_path(@project, :tab => 'versions') - end - - def close_completed_contest - if request.put? - @contest.close_completed_versions - end - redirect_to settings_contest_path(@contest, :tab => 'versions') - end - - def destroy - if @version.fixed_issues.empty? - @version.destroy - respond_to do |format| - format.html { redirect_back_or_default settings_project_path(@project, :tab => 'versions') } - format.api { render_api_ok } - end - else - respond_to do |format| - format.html { - flash[:error] = l(:notice_unable_delete_version) - redirect_to settings_project_path(@project, :tab => 'versions') - } - format.api { head :unprocessable_entity } - end - end - end - - def status_by - respond_to do |format| - format.html { render :action => 'show' } - format.js - end - end - - private - - def retrieve_selected_tracker_ids(selectable_trackers, default_trackers=nil) - if ids = params[:tracker_ids] - @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s } - else - @selected_tracker_ids = (selectable_trackers).collect {|t| t.id.to_s } - end - end -end +# 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 VersionsController < ApplicationController + layout "base_projects" + menu_item :roadmap + model_object Version + before_filter :find_model_object, :except => [:index, :new, :create, :close_completed] + #before_filter :find_model_object_contest, :except => [:index, :new, :create] + before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed] + before_filter :find_project_by_project_id, :only => [:index, :new, :create, :close_completed] + before_filter :authorize + + accept_api_auth :index, :show, :create, :update, :destroy + + helper :custom_fields + helper :projects + helper :project_score + + def index + respond_to do |format| + format.html { + @trackers = @project.trackers.sorted.all + retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?}) + @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') + project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id] + + @versions = @project.shared_versions || [] + @versions += @project.rolled_up_versions.visible if @with_subprojects + #added by young + @versions = @versions.uniq.reverse#Modified by young + unless params[:completed] + @completed_versions = @versions.select {|version| version.closed? || version.completed? } + @versions -= @completed_versions + end + @offset, @limit = api_offset_and_limit({:limit => 4}) + @versions_count = @versions.count + @versions_pages = Paginator.new @versions_count, @limit, params['page'] + @offset ||= @versions_pages.offset + @versions = @versions.slice(@offset, @limit) + #end by young + + + @issues_by_version = {} + if @selected_tracker_ids.any? && @versions.any? + issues = Issue.visible.all( + :include => [:project, :status, :tracker, :priority, :fixed_version], + :conditions => {:tracker_id => @selected_tracker_ids, :project_id => project_ids, :fixed_version_id => @versions.map(&:id)}, + :order => "#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id" + ) + @issues_by_version = issues.group_by(&:fixed_version) + end + @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?} + } + format.api { + @versions = @project.shared_versions.all + } + end + end + + def show + respond_to do |format| + format.html { + @issues = @version.fixed_issues.visible. + includes(:status, :tracker, :priority). + reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id"). + all + } + format.api + end + end + + def new + @version = @project.versions.build + @version.safe_attributes = params[:version] + + respond_to do |format| + format.html + format.js + end + end + + def create + @version = @project.versions.build + if params[:version] + attributes = params[:version].dup + attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing']) + @version.safe_attributes = attributes + end + + if request.post? + if @version.save + respond_to do |format| + format.html do + flash[:notice] = l(:notice_successful_create) + redirect_to settings_project_path(@project, :tab => 'versions') + end + format.js + format.api do + render :action => 'show', :status => :created, :location => version_url(@version) + end + end + else + respond_to do |format| + format.html { render :action => 'new' } + format.js { render :action => 'new' } + format.api { render_validation_errors(@version) } + end + end + end + end + + def edit + end + + def update + if request.put? && params[:version] + attributes = params[:version].dup + attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing']) + @version.safe_attributes = attributes + if @version.save + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_back_or_default settings_project_path(@project, :tab => 'versions') + } + format.api { render_api_ok } + end + else + respond_to do |format| + format.html { render :action => 'edit' } + format.api { render_validation_errors(@version) } + end + end + end + end + + def close_completed + if request.put? + @project.close_completed_versions + end + redirect_to settings_project_path(@project, :tab => 'versions') + end + + def close_completed_contest + if request.put? + @contest.close_completed_versions + end + redirect_to settings_contest_path(@contest, :tab => 'versions') + end + + def destroy + if @version.fixed_issues.empty? + @version.destroy + respond_to do |format| + format.html { redirect_back_or_default settings_project_path(@project, :tab => 'versions') } + format.api { render_api_ok } + end + else + respond_to do |format| + format.html { + flash[:error] = l(:notice_unable_delete_version) + redirect_to settings_project_path(@project, :tab => 'versions') + } + format.api { head :unprocessable_entity } + end + end + end + + def status_by + respond_to do |format| + format.html { render :action => 'show' } + format.js + end + end + + private + + def retrieve_selected_tracker_ids(selectable_trackers, default_trackers=nil) + if ids = params[:tracker_ids] + @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s } + else + @selected_tracker_ids = (selectable_trackers).collect {|t| t.id.to_s } + end + end +end diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index 641f02af7..ca168ccb8 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -1,200 +1,200 @@ -# 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 WelcomeController < ApplicationController - include ApplicationHelper - include WelcomeHelper - helper :project_score - caches_action :robots - before_filter :find_first_page, :only => [:index] - # before_filter :fake, :only => [:index, :course] - before_filter :entry_select, :only => [:index] - - def index - #@first_page = FirstPage.where("page_type = 'project'").first - #@show_course = @first_page.show_course - if @first_page.nil? || @first_page.sort_type.nil? - @projects = find_miracle_project(10, 3,"score desc") - else - case @first_page.sort_type - when 0 - @projects = find_miracle_project(10, 3,"created_on desc") - #@projects = @projects_all.order("created_on desc") - when 1 - @projects = find_miracle_project(10, 3,"score desc") - #@projects = @projects_all.order("grade desc") - when 2 - @projects = find_miracle_project(10, 3,"watchers_count desc") - #@projects = @projects_all.order("watchers_count desc") - - #gcm - #when '3' - #@projects=desc_sort_course_by_avtivity(@project_activity_count_array,@project_all_array) - # @projects=handle_project @projects_all,@project_activity_count - # @s_type = 3 - # @projects = @projects[@project_pages.offset, @project_pages.per_page] - - else - @projects = @projects_all.order("score desc") - end - end - - end - - def robots - @projects = Project.all_public.active - render :layout => false, :content_type => 'text/plain' - end - - def course - @course_page = FirstPage.where("page_type = 'course'").first - if params[:school_id] - @school_id = params[:school_id] - elsif User.current.logged? && User.current.user_extensions.school - @school_id = User.current.user_extensions.school.try(:id) - end - @logoLink ||= logolink() - end - - - - def logolink() - @course_page = FirstPage.where("page_type = 'course'").first - logo = get_avatar?(@course_page) - id = params[:school_id] - logo_link = "" - if id.nil? && (User.current.user_extensions.nil? || User.current.user_extensions.school.nil?) - if logo - logo_link = url_to_avatar(@course_page) - else - logo_link = '/images/transparent.png' - end - - else - if id == "0" - if logo - logo_link = url_to_avatar(@course_page) - else - logo_link = '/images/transparent.png' - end - else - if id.nil? - if School.find(User.current.user_extensions.school.id).logo_link.nil? - logo_link = '/images/transparent.png' - else - logo_link = School.find(User.current.user_extensions.school.id).logo_link - end - else - logo_link = School.find(id).logo_link - - end - end - end - return logo_link - end - - - def contest - @contest_page = FirstPage.where("page_type = 'contest'").first - @contest_notifications = ContestNotification.order("id desc") - end - - def search - search_condition = params[:q] - search_type = params[:search_type].to_sym unless search_condition.blank? - - if search_type.nil? && params[:contests_search] && params[:name] != "" - search_type = :contests - search_condition = params[:name] - end - - respond_to do |format| - format.html{ - case search_type - when :projects - redirect_to projects_search_path(:name => search_condition, - :project_type => Project::ProjectType_project) - when :courses - redirect_to courses_search_path(:name => search_condition) - when :contests - redirect_to contests_path(:name => search_condition) - when :users - redirect_to users_search_path(:name => search_condition) - when :users_teacher - redirect_to users_search_path(:name => search_condition, :role => :teacher) - when :users_student - redirect_to users_search_path(:name => search_condition, :role => :student) - else - #redirect_to home_path, :alert => l(:label_sumbit_empty) - (redirect_to home_path, :notice => l(:label_sumbit_empty);return) #if params[:name].blank? - end - } - end - end - - private - # 判断网站的入口,是课程 course 则跳过index去渲染 course 方法 - def entry_select - #@first_page = FirstPage.where("page_type = 'project'").first - url = request.original_url.gsub('/','') - if url.include?(Setting.host_course.gsub('/','')) - if @first_page.show_course == 1 - course - render :course - else - render_404 - end - - return 0 - elsif url.include?(Setting.host_contest.gsub('/','')) - if @first_page.show_contest == 1 - contest - render :contest - else - render_404 - end - - return 0 - elsif url.include?(Setting.host_user.gsub('/','')) - redirect_to(:controller => "users", :action => "index") - end - - - end - - # def render(*args) - # _fake if @fake_filter - # super - # end - - # private - - # def fake - # @fake_filter = true - # end - - # # 骗子方法 - # def _fake - # instance_variables.map { |variable| - # if variable.to_s =~ /Count$/ - # self.instance_variable_set(variable.to_sym, - # ("1" + (self.instance_variable_get(variable.to_sym).to_s)).to_i) - # end - # } - # end - -end +# 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 WelcomeController < ApplicationController + include ApplicationHelper + include WelcomeHelper + helper :project_score + caches_action :robots + before_filter :find_first_page, :only => [:index] + # before_filter :fake, :only => [:index, :course] + before_filter :entry_select, :only => [:index] + + def index + #@first_page = FirstPage.where("page_type = 'project'").first + #@show_course = @first_page.show_course + if @first_page.nil? || @first_page.sort_type.nil? + @projects = find_miracle_project(10, 3,"score desc") + else + case @first_page.sort_type + when 0 + @projects = find_miracle_project(10, 3,"created_on desc") + #@projects = @projects_all.order("created_on desc") + when 1 + @projects = find_miracle_project(10, 3,"score desc") + #@projects = @projects_all.order("grade desc") + when 2 + @projects = find_miracle_project(10, 3,"watchers_count desc") + #@projects = @projects_all.order("watchers_count desc") + + #gcm + #when '3' + #@projects=desc_sort_course_by_avtivity(@project_activity_count_array,@project_all_array) + # @projects=handle_project @projects_all,@project_activity_count + # @s_type = 3 + # @projects = @projects[@project_pages.offset, @project_pages.per_page] + + else + @projects = @projects_all.order("score desc") + end + end + + end + + def robots + @projects = Project.all_public.active + render :layout => false, :content_type => 'text/plain' + end + + def course + @course_page = FirstPage.where("page_type = 'course'").first + if params[:school_id] + @school_id = params[:school_id] + elsif User.current.logged? && User.current.user_extensions.try(:school) + @school_id = User.current.user_extensions.school.try(:id) + end + @logoLink ||= logolink() + end + + + + def logolink() + @course_page = FirstPage.where("page_type = 'course'").first + logo = get_avatar?(@course_page) + id = params[:school_id] + logo_link = "" + if id.nil? && (User.current.user_extensions.nil? || User.current.user_extensions.school.nil?) + if logo + logo_link = url_to_avatar(@course_page) + else + logo_link = '/images/transparent.png' + end + + else + if id == "0" + if logo + logo_link = url_to_avatar(@course_page) + else + logo_link = '/images/transparent.png' + end + else + if id.nil? + if School.find(User.current.user_extensions.school.id).logo_link.nil? + logo_link = '/images/transparent.png' + else + logo_link = School.find(User.current.user_extensions.school.id).logo_link + end + else + logo_link = School.find(id).logo_link + + end + end + end + return logo_link + end + + + def contest + @contest_page = FirstPage.where("page_type = 'contest'").first + @contest_notifications = ContestNotification.order("id desc") + end + + def search + search_condition = params[:q] + search_type = params[:search_type].to_sym unless search_condition.blank? + + if search_type.nil? && params[:contests_search] && params[:name] != "" + search_type = :contests + search_condition = params[:name] + end + + respond_to do |format| + format.html{ + case search_type + when :projects + redirect_to projects_search_path(:name => search_condition, + :project_type => Project::ProjectType_project) + when :courses + redirect_to courses_search_path(:name => search_condition) + when :contests + redirect_to contests_path(:name => search_condition) + when :users + redirect_to users_search_path(:name => search_condition) + when :users_teacher + redirect_to users_search_path(:name => search_condition, :role => :teacher) + when :users_student + redirect_to users_search_path(:name => search_condition, :role => :student) + else + #redirect_to home_path, :alert => l(:label_sumbit_empty) + (redirect_to home_path, :notice => l(:label_sumbit_empty);return) #if params[:name].blank? + end + } + end + end + + private + # 判断网站的入口,是课程 course 则跳过index去渲染 course 方法 + def entry_select + #@first_page = FirstPage.where("page_type = 'project'").first + url = request.original_url.gsub('/','') + if url.include?(Setting.host_course.gsub('/','')) + if @first_page.show_course == 1 + course + render :course + else + render_404 + end + + return 0 + elsif url.include?(Setting.host_contest.gsub('/','')) + if @first_page.show_contest == 1 + contest + render :contest + else + render_404 + end + + return 0 + elsif url.include?(Setting.host_user.gsub('/','')) + redirect_to(:controller => "users", :action => "index") + end + + + end + + # def render(*args) + # _fake if @fake_filter + # super + # end + + # private + + # def fake + # @fake_filter = true + # end + + # # 骗子方法 + # def _fake + # instance_variables.map { |variable| + # if variable.to_s =~ /Count$/ + # self.instance_variable_set(variable.to_sym, + # ("1" + (self.instance_variable_get(variable.to_sym).to_s)).to_i) + # end + # } + # end + +end diff --git a/app/controllers/zipdown_controller.rb b/app/controllers/zipdown_controller.rb index 10aa39df2..0393206b7 100644 --- a/app/controllers/zipdown_controller.rb +++ b/app/controllers/zipdown_controller.rb @@ -1,170 +1,175 @@ -class ZipdownController < ApplicationController - - #查找项目(课程) - before_filter :find_project_by_bid_id, :only => [:assort] - #检查权限 - #勿删 before_filter :authorize, :only => [:assort,:download_user_homework] - SAVE_FOLDER = "#{Rails.root}/files" - OUTPUT_FOLDER = "#{Rails.root}/tmp/archiveZip" - - #通过作业Id找到项目(课程) - def find_project_by_bid_id - obj_class = params[:obj_class] - obj_id = params[:obj_id] - obj = obj_class.constantize.find(obj_id) - case obj.class.to_s.to_sym - when :Bid - @project = obj.courses[0] - end - end - def assort - obj_class = params[:obj_class] - obj_id = params[:obj_id] - obj = obj_class.constantize.find(obj_id) - zipfile = nil - case obj.class.to_s.to_sym - when :Bid - zipfile = zip_bid obj - else - logger.error "[ZipDown#assort] ===> #{obj.class.to_s.to_sym} unKown !!" - end - send_file zipfile, :filename => obj.name+".zip", :type => detect_content_type(zipfile) if zipfile - - #rescue NameError, ActiveRecord::RecordNotFound => e - #logger.error "[ZipDown] ===> #{e}" - #@error = e - end - - #下载某一学生的作业的所有文件 - def download_user_homework - homework = HomeworkAttach.find params[:homework] - if User.current.admin? || User.current.member_of_course?(homework.bid.courses.first) - if homework != nil - if homework.attachments.count > 0 - zipfile = zip_homework_by_user homework - send_file zipfile, :filename => homework.name+".zip", :type => detect_content_type(zipfile) if(zipfile) - else - render_403 :message => :no_file_dowmload ,:layout => "course_base" - end - else - render_403 :message =>:notice_file_not_found ,:layout => "course_base" - end - else - render_403 :message => :notice_not_authorized ,:layout => "course_base" - end - - rescue => e - render file: 'public/file_not_found.html' , :layout => 'course_base' - end - - private - - def zip_user_bid(bid,user_id) - # Todo: User Access Controll - - homeattaches = bid.homeworks.where("user_id = ?",user_id) - # 得到每一个人所有文件打包的zip文件 - # 并将每一个人的zip打包为一个并返回路径 - user_zip_paths = homeattaches.map do |homeattach| - zip_homework_by_user homeattach - end - #zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER - user_zip_paths - end - - def zip_bid(bid) - # Todo: User Access Controll - - homeattaches = bid.homeworks - # 得到每一个人所有文件打包的zip文件 - # 并将每一个人的zip打包为一个并返回路径 - user_zip_paths = homeattaches.map do |homeattach| - if homeattach.attachments.count > 0 - zip_homework_by_user homeattach - end - end - zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER - - #@paths = homeworks_attach_path - #zipfile = ziping homeworks_attach_path - #send_file zipfile, :filename => bid.name, - # :type => detect_content_type(zipfile) - #rescue Errno::ENOENT => e - # logger.error "[Errno::ENOENT] ===> #{e}" - # @error = e - end - - def zip_homework_by_user(homeattach) - #if homeattach.attachments.count > 0 - homeworks_attach_path = [] - # 需要将所有homework.attachments遍历加入zip - # 并且返回zip路径 - user_attaches_paths = homeattach.attachments.each do |attach| - #length = attach.storage_path.length - homeworks_attach_path << attach.diskfile#.to_s.slice((length+1)..-1) - end - zipping("#{homeattach.user.name.to_s}_#{Time.now.to_i}.zip", homeworks_attach_path, OUTPUT_FOLDER, true) - #user_attaches_paths - #end - end - - - def zipping(zip_name_refer, files_paths, output_path, is_attachment=false) - # 输入待打包的文件列表,已经打包文件定位到ouput_path - ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') - input_filename = files_paths - - rename_zipfile = zip_name_refer ||= "archive_#{Time.now.to_i}.zip" - zipfile_name = "#{output_path}/#{rename_zipfile}" - - Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name)) - - Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| - input_filename.each do |filename| - rename_file = Time.now.to_i.to_s+ ic.iconv( (File.basename(filename)) ).to_s - rename_file = ic.iconv( filename_to_real( File.basename(filename))).to_s if is_attachment - - zipfile.add(rename_file, filename) - end - zipfile.get_output_stream('ReadMe') do |os| - os.write 'Homeworks' - end - end - zipfile_name - rescue Errno => e - logger.error "[zipdown#zipping] ===> #{e}" - @error = e - end - - #def ziping files_path - # ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') - # folder = SaveFolder - # input_filename = files_path - # zipfile_name = "#{OutputFolder}/archive_#{Time.now.to_i}.zip" - # - # Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name)) - # Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| - # input_filename.each do |filename| - # zipfile.add(ic.iconv(filename_to_real(File.basename(filename))), folder + '/' + filename) - # end - # zipfile.get_output_stream("ReadMe") { |os| - # os.write "Homeworks" - # } - # end - # zipfile_name - #rescue Errno => e - # logger.error "[zipdown#zipping] ===> #{e}" - # @error = e - #end - - def detect_content_type(name) - content_type = Redmine::MimeType.of(name) - content_type.to_s - end - - def filename_to_real(name) - attach = Attachment.find_by_disk_filename(name) - attach.filename - end - -end +require 'zip' +class ZipdownController < ApplicationController + #查找项目(课程) + before_filter :find_project_by_bid_id, :only => [:assort] + #检查权限 + #勿删 before_filter :authorize, :only => [:assort,:download_user_homework] + SAVE_FOLDER = "#{Rails.root}/files" + OUTPUT_FOLDER = "#{Rails.root}/tmp/archiveZip" + + #通过作业Id找到项目(课程) + def find_project_by_bid_id + obj_class = params[:obj_class] + obj_id = params[:obj_id] + obj = obj_class.constantize.find(obj_id) + case obj.class.to_s.to_sym + when :Bid + @project = obj.courses[0] + end + end + def assort + obj_class = params[:obj_class] + obj_id = params[:obj_id] + obj = obj_class.constantize.find(obj_id) + zipfile = nil + case obj.class.to_s.to_sym + when :Bid + zipfile = zip_bid obj + else + logger.error "[ZipDown#assort] ===> #{obj.class.to_s.to_sym} unKown !!" + end + send_file zipfile, :filename => obj.name+".zip", :type => detect_content_type(zipfile) if zipfile + + #rescue NameError, ActiveRecord::RecordNotFound => e + #logger.error "[ZipDown] ===> #{e}" + #@error = e + end + + #下载某一学生的作业的所有文件 + def download_user_homework + homework = HomeworkAttach.find params[:homework] + if User.current.admin? || User.current.member_of_course?(homework.bid.courses.first) + if homework != nil + if homework.attachments.count > 0 + zipfile = zip_homework_by_user homework + send_file zipfile, :filename => homework.name+".zip", :type => detect_content_type(zipfile) if(zipfile) + else + render file: 'public/no_file_found.html' , :layout => 'course_base' + end + else + render file: 'public/file_not_found.html' , :layout => 'course_base' + end + else + render_403 :message => :notice_not_authorized ,:layout => "course_base" + end + rescue => e + render file: 'public/file_not_found.html' , :layout => 'course_base' + end + + private + + def zip_user_bid(bid,user_id) + # Todo: User Access Controll + + homeattaches = bid.homeworks.where("user_id = ?",user_id) + # 得到每一个人所有文件打包的zip文件 + # 并将每一个人的zip打包为一个并返回路径 + user_zip_paths = homeattaches.map do |homeattach| + zip_homework_by_user homeattach + end + #zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER + user_zip_paths + end + + def zip_bid(bid) + # Todo: User Access Controll + + homeattaches = bid.homeworks + #记录所有作业是不是有附件,有一个附件就改为true + has_file = false + # 得到每一个人所有文件打包的zip文件 + # 并将每一个人的zip打包为一个并返回路径 + user_zip_paths = homeattaches.map do |homeattach| + if homeattach.attachments.count > 0 + zip_homework_by_user homeattach + has_file = true unless has_file + end + end + unless has_file + render file: 'public/no_file_fond.html' , :layout => 'course_base' + end + zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER + + #@paths = homeworks_attach_path + #zipfile = ziping homeworks_attach_path + #send_file zipfile, :filename => bid.name, + # :type => detect_content_type(zipfile) + #rescue Errno::ENOENT => e + # logger.error "[Errno::ENOENT] ===> #{e}" + # @error = e + end + + def zip_homework_by_user(homeattach) + #if homeattach.attachments.count > 0 + homeworks_attach_path = [] + # 需要将所有homework.attachments遍历加入zip + # 并且返回zip路径 + user_attaches_paths = homeattach.attachments.each do |attach| + #length = attach.storage_path.length + homeworks_attach_path << attach.diskfile#.to_s.slice((length+1)..-1) + end + zipping("#{homeattach.user.name.to_s}_#{Time.now.to_i}.zip", homeworks_attach_path, OUTPUT_FOLDER, true) + #user_attaches_paths + #end + end + + + def zipping(zip_name_refer, files_paths, output_path, is_attachment=false) + # 输入待打包的文件列表,已经打包文件定位到ouput_path + ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') + input_filename = files_paths + + rename_zipfile = zip_name_refer ||= "archive_#{Time.now.to_i}.zip" + zipfile_name = "#{output_path}/#{rename_zipfile}" + + Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name)) + + Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| + input_filename.each do |filename| + rename_file = Time.now.to_i.to_s+ ic.iconv( (File.basename(filename)) ).to_s + rename_file = ic.iconv( filename_to_real( File.basename(filename))).to_s if is_attachment + + zipfile.add(rename_file, filename) + end + zipfile.get_output_stream('ReadMe') do |os| + os.write 'Homeworks' + end + end + zipfile_name + rescue Errno => e + logger.error "[zipdown#zipping] ===> #{e}" + @error = e + end + + #def ziping files_path + # ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') + # folder = SaveFolder + # input_filename = files_path + # zipfile_name = "#{OutputFolder}/archive_#{Time.now.to_i}.zip" + # + # Dir.mkdir(File.dirname(zipfile_name)) unless File.exist?(File.dirname(zipfile_name)) + # Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| + # input_filename.each do |filename| + # zipfile.add(ic.iconv(filename_to_real(File.basename(filename))), folder + '/' + filename) + # end + # zipfile.get_output_stream("ReadMe") { |os| + # os.write "Homeworks" + # } + # end + # zipfile_name + #rescue Errno => e + # logger.error "[zipdown#zipping] ===> #{e}" + # @error = e + #end + + def detect_content_type(name) + content_type = Redmine::MimeType.of(name) + content_type.to_s + end + + def filename_to_real(name) + attach = Attachment.find_by_disk_filename(name) + attach.filename + end + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 807d851be..ef18793ab 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,8 +33,8 @@ module ApplicationHelper extend Forwardable def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter - #Added by young - #Define the course menu's link class + # Added by young + # Define the course menu's link class # 不是数组的转化成数组,然后判断当前menu_item是否在给定的列表 # REVIEW: 目测menu的机制,貌似不是很需要转换,再说 def link_class(label) @@ -679,15 +679,15 @@ module ApplicationHelper def textilizable(*args) options = args.last.is_a?(Hash) ? args.pop : {} case args.size - when 1 - obj = options[:object] - text = args.shift - when 2 - obj = args.shift - attr = args.shift - text = obj.send(attr).to_s - else - raise ArgumentError, 'invalid arguments to textilizable' + when 1 + obj = options[:object] + text = args.shift + when 2 + obj = args.shift + attr = args.shift + text = obj.send(attr).to_s + else + raise ArgumentError, 'invalid arguments to textilizable' end return '' if text.blank? project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) diff --git a/app/helpers/attachments_helper.rb b/app/helpers/attachments_helper.rb index ee9d2a70d..e6f20ea60 100644 --- a/app/helpers/attachments_helper.rb +++ b/app/helpers/attachments_helper.rb @@ -22,6 +22,9 @@ module AttachmentsHelper # Options: # :author -- author names are not displayed if set to false # :thumbails -- display thumbnails if enabled in settings + + include Redmine::Pagination + def link_to_attachments(container, options = {}) options.assert_valid_keys(:author, :thumbnails) @@ -171,7 +174,9 @@ module AttachmentsHelper s.html_safe end - def private_filter resultSet + # Modified by Longjun + # 有参数的方法要加() + def private_filter(resultSet) result = resultSet.to_a.dup # modify by nwb @@ -190,8 +195,12 @@ module AttachmentsHelper result end - include Redmine::Pagination - def paginateHelper obj, pre_size=10 + # Modified by Longjun + # include 应放在class/model 的开始处 + # include Redmine::Pagination + # end + + def paginateHelper (obj, pre_size=10) @obj_count = obj.count @obj_pages = Paginator.new @obj_count, pre_size, params['page'] if obj.kind_of? ActiveRecord::Base or obj.kind_of? ActiveRecord::Relation diff --git a/app/helpers/contests_helper.rb b/app/helpers/contests_helper.rb index 01c7d544f..0bc3e5e73 100644 --- a/app/helpers/contests_helper.rb +++ b/app/helpers/contests_helper.rb @@ -43,16 +43,16 @@ module ContestsHelper def sort_contest_enterprise(state, project_type) content = ''.html_safe case state - when 0 - content << content_tag('li', link_to(l(:label_sort_by_active), calls_path(:contest_sort_type => '1', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_time), calls_path(:contest_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") - - when 1 - content << content_tag('li', link_to(l(:label_sort_by_active), calls_path(:contest_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") - content << content_tag('li', link_to(l(:label_sort_by_time), calls_path(:contest_sort_type => '0', :project_type => project_type))) - end - content = content_tag('ul', content) - content_tag('div', content, :class => "tabs_enterprise") + when 0 + content << content_tag('li', link_to(l(:label_sort_by_active), calls_path(:contest_sort_type => '1', :project_type => project_type))) + content << content_tag('li', link_to(l(:label_sort_by_time), calls_path(:contest_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") + + when 1 + content << content_tag('li', link_to(l(:label_sort_by_active), calls_path(:contest_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") + content << content_tag('li', link_to(l(:label_sort_by_time), calls_path(:contest_sort_type => '0', :project_type => project_type))) + end + content = content_tag('ul', content) + content_tag('div', content, :class => "tabs_enterprise") end #end @@ -100,7 +100,10 @@ module ContestsHelper def count_contest_project contests = Contest.find(:id) @projects = [] - for contest in contests + # Modified by longjun + # for contest in contests + contests.each do |contest| + # end longjun @projects += contest.contesting_projects end @projects.count @@ -109,7 +112,10 @@ module ContestsHelper def count_contest_softapplication contests = Contest.find(:id) @softapplications = [] - for contest in contests + # Modified by alan + # for contest in contests + contests.each do |contest| + # end alan @softapplications += contest.contesting_softapplications end @projects.count @@ -119,19 +125,29 @@ module ContestsHelper def count_contest_user contests = Contest.find(:id) @users = [] - for contest in contests - for project in contest.projects + # Modified by alan + # for contest in contests + contests.each do |contest| + + contest.projects.each do |project| + @users += project.users end end + # end alan + @users.count end def count_contest_softapplication_user contests = Contest.find(:id) @users = [] - for contest in contests - for project in contest.softapplications + # Modified by alan + # for contest in contests + contests.each do |contest| + + contest.projects.each do |softapplications| + # for project in contest.softapplications @users += softapplication.users end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 9fcebe640..dfacff864 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -44,7 +44,7 @@ module ProjectsHelper content = ''.html_safe case state when 0 - + content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type))) content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type))) content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") @@ -70,19 +70,19 @@ module ProjectsHelper content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id))) # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type))) content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id))) - + when 1 content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id))) content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id), :class=>"selected"), :class=>"selected") # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type))) content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id))) - + when 2 content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id))) content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id))) # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected") content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id))) - + #gcm when 3 content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id))) @@ -101,7 +101,7 @@ module ProjectsHelper content = ''.html_safe case state when 0 - + content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type))) content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type))) content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") @@ -142,7 +142,7 @@ module ProjectsHelper # end - #Added by young + # Added by young def course_settings_tabs tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural, :course=>'1'}, #{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural, :project_type => 1}, @@ -151,7 +151,7 @@ module ProjectsHelper ] tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} end - #Ended by young + # Ended by young @@ -173,14 +173,42 @@ module ProjectsHelper # Renders the projects index def render_project_hierarchy(projects) render_project_nested_lists(projects) do |project| - if (project.try(:project_type) == Project::ProjectType_course ) - s = project.is_public == 1 ? "".html_safe : "#{l(:label_private)}".html_safe - s += link_to_project(project, {}, :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}").html_safe - else - s = project.is_public ? "".html_safe : "#{l(:label_private)}".html_safe - s += link_to_project(project, {}, :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}") - end + #Modified by young + if project.try(:project_type) == Project::ProjectType_course + + # modified by longjun + # never use unless and else + # unless project.is_public == 1 + + if project.is_public != 1 + s = "#{l(:lable_private)}".html_safe + else + s = "".html_safe + end + # end longjun + + # modified by Longjun + s += link_to_project(project, {}, + :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}").html_safe + # end longjun + else + # modified by longjun + # unless project.is_public + + if !project.is_public + # end longjun + s = "#{l(:lable_private)}".html_safe + else + s = "".html_safe + end + # modified by longjun + s += link_to_project(project, {}, + :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}") + # end longjun + end + #Ended by young if project.description.present? + #Delete by nie. # s << content_tag('td', textilizable(project.short_description, :project => project), :class => 'wiki description') end s @@ -243,9 +271,14 @@ module ProjectsHelper def is_manager?(user_id,project_id) @result = false @user_id = ProjectInfo.find_by_project_id(project_id) - if @user_id == user.id - @result = true - end + + # modified by longjun + # if @user_id == user.id + # @result = true + # end + + @result = true if @user_id = user.id + # end longjun return @result end @@ -330,9 +363,9 @@ module ProjectsHelper return true if (project.nil? && project.course_extra.nil?) courses_year = project.course_extra.time current_year = Time.now.year - if(courses_year >= current_year) + if courses_year >= current_year return false - elsif( (courses_year < current_year) && (Time.now.month < 3) ) + elsif (courses_year < current_year) && (Time.now.month < 3) return false else return true diff --git a/app/models/contest.rb b/app/models/contest.rb index f1503f593..b2c11ceac 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -72,11 +72,14 @@ class Contest < ActiveRecord::Base end end - def self.creat_contests(budget, deadline, name, description=nil) - self.create(:author_id => User.current.id, :budget => budget, - :deadline => deadline, :name => name, :description => description, :commit => 0) - end - + # modified by longjun + # 这个函数没有用到 + # def self.creat_contests(budget, deadline, name, description=nil) + # self.create(:author_id => User.current.id, :budget => budget, + # :deadline => deadline, :name => name, :description => description, :commit => 0) + # end + # end longjun + def update_contests(budget, deadline, name, description=nil) if(User.current.id == self.author_id) self.name = name diff --git a/app/models/contesting_project.rb b/app/models/contesting_project.rb index cb2a7fe39..641990b8a 100644 --- a/app/models/contesting_project.rb +++ b/app/models/contesting_project.rb @@ -14,7 +14,7 @@ class ContestingProject < ActiveRecord::Base validate :validate_project validates_uniqueness_of :contest_id, :scope => :project_id - def self.cerate_contesting(contest_id, project_id, description = nil) + def self.create_contesting(contest_id, project_id, description = nil) self.create(:user_id => User.current.id, :contest_id => contest_id, :project_id => project_id, :description => description) end diff --git a/app/models/project.rb b/app/models/project.rb index 1a2c0504d..ddb92a587 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,1152 +1,1153 @@ -# 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 Project < ActiveRecord::Base - include Redmine::SafeAttributes - ProjectType_project = 0 - ProjectType_course = 1 - - # Project statuses - STATUS_ACTIVE = 1 - STATUS_CLOSED = 5 - STATUS_ARCHIVED = 9 - - # Maximum length for project identifiers - IDENTIFIER_MAX_LENGTH = 100 - - # Specific overidden Activities - - belongs_to :homework_attach - has_many :time_entry_activities - 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 :users, :through => :members - has_many :principals, :through => :member_principals, :source => :principal - has_many :enabled_modules, :dependent => :delete_all - has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" - has_many :issues, :dependent => :destroy, :include => [:status, :tracker] - has_many :issue_changes, :through => :issues, :source => :journals - has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC" - has_many :time_entries, :dependent => :delete_all - has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all - has_many :documents, :dependent => :destroy - has_many :news, :dependent => :destroy, :include => :author - has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name" - has_many :boards, :dependent => :destroy, :order => "position ASC" - has_one :repository, :conditions => ["is_default = ?", true] - has_many :repositories, :dependent => :destroy - has_many :changesets, :through => :repository - #added by xianbo for delete biding_project - has_many :biding_projects, :dependent => :destroy - has_many :contesting_projects, :dependent => :destroy - has_many :softapplications, :through => :projecting_softapplications - #ended by xianbo - # added by fq - has_many :journals_for_messages, :as => :jour, :dependent => :destroy - #has_many :homework_for_courses, :dependent => :destroy - #has_many :homeworks, :through => :homework_for_courses, :source => :bid, :dependent => :destroy - has_many :shares, :dependent => :destroy - # has_many :students_for_courses, :dependent => :destroy - has_many :student, :through => :students_for_courses, :source => :user - has_one :course_extra, :class_name => 'Course', :foreign_key => :extra,:primary_key => :identifier, :dependent => :destroy - has_many :applied_projects - - - # end - #ADDED BY NIE - has_many :project_infos, :dependent => :destroy - has_one :project_status, :class_name => "ProjectStatus", :dependent => :destroy - has_many :user_grades, :class_name => "UserGrade", :dependent => :destroy - #end - - has_one :wiki, :dependent => :destroy - ##added by xianbo - has_one :course, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC" - accepts_nested_attributes_for :course - ##end - # Custom field for the project issues - has_and_belongs_to_many :issue_custom_fields, - :class_name => 'IssueCustomField', - :order => "#{CustomField.table_name}.position", - :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", - :association_foreign_key => 'custom_field_id' - - has_many :tags, :through => :project_tags, :class_name => 'Tag' - has_many :project_tags, :class_name => 'ProjectTags' - - # has_many :journals - - acts_as_nested_set :order => 'name', :dependent => :destroy - acts_as_attachable :view_permission => :view_files, - :delete_permission => :manage_files - - acts_as_customizable - acts_as_searchable :columns => ['name', 'identifier', 'description'], :project_key => 'id', :permission => nil - acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"}, - :url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o}}, - :author => nil - ############################added by william - acts_as_taggable - scope :by_join_date, order("created_on DESC") - ###################added by liuping 关注 - acts_as_watchable - - attr_protected :status - - validates_presence_of :name, :identifier - validates_uniqueness_of :identifier - validates_uniqueness_of :name - validates_associated :repository, :wiki - # validates_length_of :description, :maximum => 255 - validates_length_of :name, :maximum => 255 - validates_length_of :homepage, :maximum => 255 - validates_length_of :identifier, :in => 1..IDENTIFIER_MAX_LENGTH - # donwcase letters, digits, dashes but not digits only - validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? } - # reserved words - validates_exclusion_of :identifier, :in => %w( new ) - - after_save :update_position_under_parent, :if => Proc.new {|project| project.name_changed?} - after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?} - # 创建project之后默认创建一个board,之后的board去掉了board的概念 - after_create :create_board_sync - before_destroy :delete_all_members - def remove_references_before_destroy - return if self.id.nil? - Watcher.delete_all ['watchable_id = ?', id] - end - scope :has_module, lambda {|mod| - where("#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s) - } - 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(Project.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(Project.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 - } - scope :project_entities, -> { where(project_type: ProjectType_project) } - scope :course_entities, -> { where(project_type: ProjectType_course) } - - def new_course - self.where('project_type = ?', 1) - 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 validation - if !class_period.match([0-9]) - errors.add_to_base("class period can only digital") - end - end - -# 项目留言 added by fq - def self.add_jour(user, notes) - project = Project.find('trustie') - # project.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => 0) - pjfm = project.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0) - pjfm.save - pjfm - end - - def self.add_new_jour(user, notes, id, options={}) - project = Project.find(id) - if options.count == 0 - pjfm = project.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0) - else - pjfm = project.journals_for_messages.build(options) - end - pjfm.save - pjfm - end -# end - - # 管理员的邮件列表 - def manager_recipients - notified = project.project_infos.collect(&:user) - notified.collect(&:mail) - end - - def initialize(attributes=nil, *args) - super - - initialized = (attributes || {}).stringify_keys - if !initialized.key?('identifier') && Setting.sequential_project_identifiers? - self.identifier = Project.next_identifier - end - if !initialized.key?('is_public') - self.is_public = Setting.default_projects_public? - end - if !initialized.key?('enabled_module_names') - self.enabled_module_names = Setting.default_projects_modules - end - if !initialized.key?('trackers') && !initialized.key?('tracker_ids') - default = Setting.default_projects_tracker_ids - if default.is_a?(Array) - self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.all - else - self.trackers = Tracker.sorted.all - end - end - end - - def identifier=(identifier) - super unless identifier_frozen? - end - - def identifier_frozen? - errors[:identifier].blank? && !(new_record? || identifier.blank?) - end - - # returns latest created projects - # non public projects will be returned only if user is a member of those - def self.latest(user=nil, count=5) - visible(user).limit(count).order("created_on DESC").all - end - - # Returns true if the project is visible to +user+ or to the current user. - def visible?(user=User.current) - user.allowed_to?(:view_project, self) - end - - # Returns a SQL conditions string used to find all projects visible by the specified user. - # - # Examples: - # Project.visible_condition(admin) => "projects.status = 1" - # Project.visible_condition(normal_user) => "((projects.status = 1) AND (projects.is_public = 1 OR projects.id IN (1,3,4)))" - # Project.visible_condition(anonymous) => "((projects.status = 1) AND (projects.is_public = 1))" - def self.visible_condition(user, options={}) - allowed_to_condition(user, :view_project, options) - end - - # Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+ - # - # Valid options: - # * :project => limit the condition to project - # * :with_subprojects => limit the condition to project and its subprojects - # * :member => limit the condition to the user projects - def self.allowed_to_condition(user, permission, options={}) - perm = Redmine::AccessControl.permission(permission) - base_statement = (perm && perm.read? ? "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED}" : "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}") - if perm && perm.project_module - # If the permission belongs to a project module, make sure the module is enabled - base_statement << " AND #{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.project_module}')" - end - if options[:project] - project_statement = "#{Project.table_name}.id = #{options[:project].id}" - project_statement << " OR (#{Project.table_name}.lft > #{options[:project].lft} AND #{Project.table_name}.rgt < #{options[:project].rgt})" if options[:with_subprojects] - base_statement = "(#{project_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] = "#{Project.table_name}.is_public = #{connection.quoted_true}" - end - end - if user.logged? - user.projects_by_role.each do |role, projects| - if role.allowed_to?(permission) && projects.any? - statement_by_role[role] = "#{Project.table_name}.id IN (#{projects.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 - - # Returns the Systemwide and project specific activities - def activities(include_inactive=false) - if include_inactive - return all_activities - else - return active_activities - end - end - - # Will create a new Project specific Activity or update an existing one - # - # This will raise a ActiveRecord::Rollback if the TimeEntryActivity - # does not successfully save. - def update_or_create_time_entry_activity(id, activity_hash) - if activity_hash.respond_to?(:has_key?) && activity_hash.has_key?('parent_id') - self.create_time_entry_activity_if_needed(activity_hash) - else - activity = project.time_entry_activities.find_by_id(id.to_i) - activity.update_attributes(activity_hash) if activity - end - end - - # Create a new TimeEntryActivity if it overrides a system TimeEntryActivity - # - # This will raise a ActiveRecord::Rollback if the TimeEntryActivity - # does not successfully save. - def create_time_entry_activity_if_needed(activity) - if activity['parent_id'] - - parent_activity = TimeEntryActivity.find(activity['parent_id']) - activity['name'] = parent_activity.name - activity['position'] = parent_activity.position - - if Enumeration.overridding_change?(activity, parent_activity) - project_activity = self.time_entry_activities.create(activity) - - if project_activity.new_record? - raise ActiveRecord::Rollback, "Overridding TimeEntryActivity was not successfully saved" - else - self.time_entries.update_all("activity_id = #{project_activity.id}", ["activity_id = ?", parent_activity.id]) - end - end - end - end - - # Returns a :conditions SQL string that can be used to find the issues associated with this project. - # - # Examples: - # project.project_condition(true) => "(projects.id = 1 OR (projects.lft > 1 AND projects.rgt < 10))" - # project.project_condition(false) => "projects.id = 1" - def project_condition(with_subprojects) - cond = "#{Project.table_name}.id = #{id}" - cond = "(#{cond} OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt}))" if with_subprojects - cond - end - - def self.find(*args) - if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/) - project = find_by_identifier(*args) - raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil? - project - else - super - end - end - - def self.find_by_param(*args) - self.find(*args) - end - - alias :base_reload :reload - def reload(*args) - @shared_versions = nil - @rolled_up_versions = nil - @rolled_up_trackers = nil - @all_issue_custom_fields = nil - @all_time_entry_custom_fields = nil - @to_param = nil - @allowed_parents = nil - @allowed_permissions = nil - @actions_allowed = nil - @start_date = nil - @due_date = nil - base_reload(*args) - end - - # def to_param - # # id is used for projects with a numeric identifier (compatibility) - # @to_param ||= (identifier.to_s =~ %r{^\d*$} ? id.to_s : identifier) - # end - - def active? - self.status == STATUS_ACTIVE - end - - def archived? - self.status == STATUS_ARCHIVED - end - - # Archives the project and its descendants - def archive - # Check that there is no issue of a non descendant project that is assigned - # to one of the project or descendant versions - v_ids = self_and_descendants.collect {|p| p.version_ids}.flatten - if v_ids.any? && - Issue. - includes(:project). - where("#{Project.table_name}.lft < ? OR #{Project.table_name}.rgt > ?", lft, rgt). - where("#{Issue.table_name}.fixed_version_id IN (?)", v_ids). - exists? - return false - end - Project.transaction do - archive! - end - true - end - - # Unarchives the project - # All its ancestors must be active - def unarchive - return false if ancestors.detect {|a| !a.active?} - update_attribute :status, STATUS_ACTIVE - end - - def close - self_and_descendants.status(STATUS_ACTIVE).update_all :status => STATUS_CLOSED - end - - def reopen - self_and_descendants.status(STATUS_CLOSED).update_all :status => STATUS_ACTIVE - end - - # Returns an array of projects the project can be moved to - # by the current user - def allowed_parents - return @allowed_parents if @allowed_parents - @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).all - @allowed_parents = @allowed_parents - self_and_descendants - if User.current.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?) - @allowed_parents << nil - end - unless parent.nil? || @allowed_parents.empty? || @allowed_parents.include?(parent) - @allowed_parents << parent - end - @allowed_parents - end - - # Sets the parent of the project with authorization check - def set_allowed_parent!(p) - unless p.nil? || p.is_a?(Project) - if p.to_s.blank? - p = nil - else - p = Project.find_by_id(p) - return false unless p - end - end - if p.nil? - if !new_record? && allowed_parents.empty? - return false - end - elsif !allowed_parents.include?(p) - return false - end - set_parent!(p) - end - - # Sets the parent of the project - # Argument can be either a Project, a String, a Fixnum or nil - def set_parent!(p) - unless p.nil? || p.is_a?(Project) - if p.to_s.blank? - p = nil - else - p = Project.find_by_id(p) - return false unless p - end - end - if p == parent && !p.nil? - # Nothing to do - true - elsif p.nil? || (p.active? && move_possible?(p)) - set_or_update_position_under(p) - Issue.update_versions_from_hierarchy_change(self) - true - else - # Can not move to the given target - false - end - end - - # Recalculates all lft and rgt values based on project names - # Unlike Project.rebuild!, these values are recalculated even if the tree "looks" valid - # Used in BuildProjectsTree migration - def self.rebuild_tree! - transaction do - update_all "lft = NULL, rgt = NULL" - rebuild!(false) - end - end - - # Returns an array of the trackers used by the project and its active sub projects - def rolled_up_trackers - @rolled_up_trackers ||= - Tracker. - joins(:projects). - joins("JOIN #{EnabledModule.table_name} ON #{EnabledModule.table_name}.project_id = #{Project.table_name}.id AND #{EnabledModule.table_name}.name = 'issue_tracking'"). - select("DISTINCT #{Tracker.table_name}.*"). - where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt). - sorted. - all - end - - # Closes open and locked project versions that are completed - def close_completed_versions - Version.transaction do - versions.where(:status => %w(open locked)).all.each do |version| - if version.completed? - version.update_attribute(:status, 'closed') - end - end - end - end - - # Returns a scope of the Versions on subprojects - def rolled_up_versions - @rolled_up_versions ||= - Version.scoped(:include => :project, - :conditions => ["#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt]) - end - - # Returns a scope of the Versions used by the project - def shared_versions - if new_record? - Version.scoped(:include => :project, - :conditions => "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND #{Version.table_name}.sharing = 'system'") - else - @shared_versions ||= begin - r = root? ? self : root - Version.scoped(:include => :project, - :conditions => "#{Project.table_name}.id = #{id}" + - " OR (#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND (" + - " #{Version.table_name}.sharing = 'system'" + - " OR (#{Project.table_name}.lft >= #{r.lft} AND #{Project.table_name}.rgt <= #{r.rgt} AND #{Version.table_name}.sharing = 'tree')" + - " OR (#{Project.table_name}.lft < #{lft} AND #{Project.table_name}.rgt > #{rgt} AND #{Version.table_name}.sharing IN ('hierarchy', 'descendants'))" + - " OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt} AND #{Version.table_name}.sharing = 'hierarchy')" + - "))") - end - end - end - - # Returns a hash of project users grouped by role - 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 - - # Deletes all project's members - def delete_all_members - 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}.project_id = #{id})") - Member.delete_all(['project_id = ?', id]) - end - - # Users/groups issues can be assigned to - def assignable_users - assignable = Setting.issue_group_assignment? ? member_principals : members - assignable.select {|m| m.roles.detect {|role| role.assignable?}}.collect {|m| m.principal}.sort - 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 - - # Returns an array of all custom fields enabled for project issues - # (explictly associated custom fields and custom fields enabled for all projects) - def all_issue_custom_fields - @all_issue_custom_fields ||= (IssueCustomField.for_all + issue_custom_fields).uniq.sort - end - - # Returns an array of all custom fields enabled for project time entries - # (explictly associated custom fields and custom fields enabled for all projects) - def all_time_entry_custom_fields - @all_time_entry_custom_fields ||= (TimeEntryCustomField.for_all + time_entry_custom_fields).uniq.sort - end - - def project - self - end - - def <=>(project) - name.downcase <=> project.name.downcase - end - - def to_s - name - end - - # Returns a short description of the projects (first lines) - def short_description(length = 255) - #description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description - description.gsub(/<\/?.*?>/,"").html_safe if description - end - - def css_classes - s = 'project' - s << ' root' if root? - s << ' child' if child? - s << (leaf? ? ' leaf' : ' parent') - unless active? - if archived? - s << ' archived' - else - s << ' closed' - end - end - s - end - - # The earliest start date of a project, based on it's issues and versions - def start_date - @start_date ||= [ - issues.minimum('start_date'), - shared_versions.minimum('effective_date'), - Issue.fixed_version(shared_versions).minimum('start_date') - ].compact.min - end - - # The latest due date of an issue or version - def due_date - @due_date ||= [ - issues.maximum('due_date'), - shared_versions.maximum('effective_date'), - Issue.fixed_version(shared_versions).maximum('due_date') - ].compact.max - end - - def overdue? - active? && !due_date.nil? && (due_date < Date.today) - end - - # Returns the percent completed for this project, based on the - # progress on it's versions. - def completed_percent(options={:include_subprojects => false}) - if options.delete(:include_subprojects) - total = self_and_descendants.collect(&:completed_percent).sum - - total / self_and_descendants.count - else - if versions.count > 0 - total = versions.collect(&:completed_percent).sum - - total / versions.count - else - 100 - end - end - end - - # Return true if this project allows to do the specified action. - # action can be: - # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') - # * a permission Symbol (eg. :edit_project) - 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 module_enabled?(module_name) - module_name = module_name.to_s - enabled_modules.detect {|m| m.name == module_name} - end - - def enabled_module_names=(module_names) - if module_names && module_names.is_a?(Array) - module_names = module_names.collect(&:to_s).reject(&:blank?) - self.enabled_modules = module_names.collect {|name| enabled_modules.detect {|mod| mod.name == name} || EnabledModule.new(:name => name)} - else - enabled_modules.clear - end - end - - # Returns an array of the enabled modules names - def enabled_module_names - enabled_modules.collect(&:name) - end - - # Enable a specific module - # - # Examples: - # project.enable_module!(:issue_tracking) - # project.enable_module!("issue_tracking") - def enable_module!(name) - enabled_modules << EnabledModule.new(:name => name.to_s) unless module_enabled?(name) - end - - # Disable a module if it exists - # - # Examples: - # project.disable_module!(:issue_tracking) - # project.disable_module!("issue_tracking") - # project.disable_module!(project.enabled_modules.first) - def disable_module!(target) - target = enabled_modules.detect{|mod| target.to_s == mod.name} unless enabled_modules.include?(target) - target.destroy unless target.blank? - end - - safe_attributes 'name', - 'description', - 'homepage', - 'is_public', - 'hidden_repo', - 'identifier', - 'custom_field_values', - 'custom_fields', - 'tracker_ids', - 'issue_custom_field_ids', - 'project_type', - 'dts_test', - 'attachmenttype' - - - - safe_attributes 'enabled_module_names', - :if => lambda {|project, user| project.new_record? || user.allowed_to?(:select_project_modules, project) } - - safe_attributes 'inherit_members', - :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)} - - # Returns an array of projects that are in this project's hierarchy - # - # Example: parents, children, siblings - def hierarchy - parents = project.self_and_ancestors || [] - descendants = project.descendants || [] - project_hierarchy = parents | descendants # Set union - end - - # Returns an auto-generated project identifier based on the last identifier used - def self.next_identifier - p = Project.order('created_on DESC').first - p.nil? ? nil : p.identifier.to_s.succ - end - - # Copies and saves the Project instance based on the +project+. - # Duplicates the source project's: - # * Wiki - # * Versions - # * Categories - # * Issues - # * Members - # * Queries - # - # Accepts an +options+ argument to specify what to copy - # - # Examples: - # project.copy(1) # => copies everything - # project.copy(1, :only => 'members') # => copies members only - # project.copy(1, :only => ['members', 'versions']) # => copies members and versions - def copy(project, options={}) - project = project.is_a?(Project) ? project : Project.find(project) - - to_be_copied = %w(wiki versions issue_categories issues members queries boards) - to_be_copied = to_be_copied & options[:only].to_a unless options[:only].nil? - - Project.transaction do - if save - reload - to_be_copied.each do |name| - send "copy_#{name}", project - end - Redmine::Hook.call_hook(:model_project_copy_before_save, :source_project => project, :destination_project => self) - save - end - end - end - - # Returns a new unsaved Project instance with attributes copied from +project+ - def self.copy_from(project) - project = project.is_a?(Project) ? project : Project.find(project) - # clear unique attributes - attributes = project.attributes.dup.except('id', 'name', 'identifier', 'status', 'parent_id', 'lft', 'rgt') - copy = Project.new(attributes) - copy.enabled_modules = project.enabled_modules - copy.trackers = project.trackers - copy.custom_values = project.custom_values.collect {|v| v.clone} - copy.issue_custom_fields = project.issue_custom_fields - copy - end - - # Yields the given block for each project with its level in the tree - def self.project_tree(projects, &block) - ancestors = [] - projects.sort_by(&:lft).each do |project| - while (ancestors.any? && !project.is_descendant_of?(ancestors.last)) - ancestors.pop - end - yield project, ancestors.size - ancestors << project - end - end - - private - - def after_parent_changed(parent_was) - remove_inherited_member_roles - add_inherited_member_roles - end - - def update_inherited_members - if parent - if inherit_members? && !inherit_members_was - remove_inherited_member_roles - add_inherited_member_roles - elsif !inherit_members? && inherit_members_was - remove_inherited_member_roles - end - end - end - - def remove_inherited_member_roles - member_roles = memberships.map(&:member_roles).flatten - member_role_ids = member_roles.map(&:id) - member_roles.each do |member_role| - if member_role.inherited_from && !member_role_ids.include?(member_role.inherited_from) - member_role.destroy - end - end - end - - def add_inherited_member_roles - if inherit_members? && parent - parent.memberships.each do |parent_member| - member = Member.find_or_new(self.id, parent_member.user_id) - parent_member.member_roles.each do |parent_member_role| - member.member_roles << MemberRole.new(:role => parent_member_role.role, :inherited_from => parent_member_role.id) - end - member.save! - end - end - end - - # Copies wiki from +project+ - def copy_wiki(project) - # Check that the source project has a wiki first - unless project.wiki.nil? - wiki = self.wiki || Wiki.new - wiki.attributes = project.wiki.attributes.dup.except("id", "project_id") - wiki_pages_map = {} - project.wiki.pages.each do |page| - # Skip pages without content - next if page.content.nil? - new_wiki_content = WikiContent.new(page.content.attributes.dup.except("id", "page_id", "updated_on")) - new_wiki_page = WikiPage.new(page.attributes.dup.except("id", "wiki_id", "created_on", "parent_id")) - new_wiki_page.content = new_wiki_content - wiki.pages << new_wiki_page - wiki_pages_map[page.id] = new_wiki_page - end - - self.wiki = wiki - wiki.save - # Reproduce page hierarchy - project.wiki.pages.each do |page| - if page.parent_id && wiki_pages_map[page.id] - wiki_pages_map[page.id].parent = wiki_pages_map[page.parent_id] - wiki_pages_map[page.id].save - end - end - end - end - - # Copies versions from +project+ - def copy_versions(project) - project.versions.each do |version| - new_version = Version.new - new_version.attributes = version.attributes.dup.except("id", "project_id", "created_on", "updated_on") - self.versions << new_version - end - end - - # Copies issue categories from +project+ - def copy_issue_categories(project) - project.issue_categories.each do |issue_category| - new_issue_category = IssueCategory.new - new_issue_category.attributes = issue_category.attributes.dup.except("id", "project_id") - self.issue_categories << new_issue_category - end - end - - # Copies issues from +project+ - def copy_issues(project) - # Stores the source issue id as a key and the copied issues as the - # value. Used to map the two togeather for issue relations. - issues_map = {} - - # Store status and reopen locked/closed versions - version_statuses = versions.reject(&:open?).map {|version| [version, version.status]} - version_statuses.each do |version, status| - version.update_attribute :status, 'open' - end - - # Get issues sorted by root_id, lft so that parent issues - # get copied before their children - project.issues.reorder('root_id, lft').all.each do |issue| - new_issue = Issue.new - new_issue.copy_from(issue, :subtasks => false, :link => false) - new_issue.project = self - # Reassign fixed_versions by name, since names are unique per project - if issue.fixed_version && issue.fixed_version.project == project - new_issue.fixed_version = self.versions.detect {|v| v.name == issue.fixed_version.name} - end - # Reassign the category by name, since names are unique per project - if issue.category - new_issue.category = self.issue_categories.detect {|c| c.name == issue.category.name} - end - # Parent issue - if issue.parent_id - if copied_parent = issues_map[issue.parent_id] - new_issue.parent_issue_id = copied_parent.id - end - end - - self.issues << new_issue - if new_issue.new_record? - logger.info "Project#copy_issues: issue ##{issue.id} could not be copied: #{new_issue.errors.full_messages}" if logger && logger.info - else - issues_map[issue.id] = new_issue unless new_issue.new_record? - end - end - - # Restore locked/closed version statuses - version_statuses.each do |version, status| - version.update_attribute :status, status - end - - # Relations after in case issues related each other - project.issues.each do |issue| - new_issue = issues_map[issue.id] - unless new_issue - # Issue was not copied - next - end - - # Relations - issue.relations_from.each do |source_relation| - new_issue_relation = IssueRelation.new - new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id") - new_issue_relation.issue_to = issues_map[source_relation.issue_to_id] - if new_issue_relation.issue_to.nil? && Setting.cross_project_issue_relations? - new_issue_relation.issue_to = source_relation.issue_to - end - new_issue.relations_from << new_issue_relation - end - - issue.relations_to.each do |source_relation| - new_issue_relation = IssueRelation.new - new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id") - new_issue_relation.issue_from = issues_map[source_relation.issue_from_id] - if new_issue_relation.issue_from.nil? && Setting.cross_project_issue_relations? - new_issue_relation.issue_from = source_relation.issue_from - end - new_issue.relations_to << new_issue_relation - end - end - end - - # Copies members from +project+ - def copy_members(project) - # Copy users first, then groups to handle members with inherited and given roles - members_to_copy = [] - members_to_copy += project.memberships.select {|m| m.principal.is_a?(User)} - members_to_copy += project.memberships.select {|m| !m.principal.is_a?(User)} - - members_to_copy.each do |member| - new_member = Member.new - new_member.attributes = member.attributes.dup.except("id", "project_id", "created_on") - # only copy non inherited roles - # inherited roles will be added when copying the group membership - role_ids = member.member_roles.reject(&:inherited?).collect(&:role_id) - next if role_ids.empty? - new_member.role_ids = role_ids - new_member.project = self - self.members << new_member - end - end - - # Copies queries from +project+ - def copy_queries(project) - project.queries.each do |query| - new_query = IssueQuery.new - new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria") - new_query.sort_criteria = query.sort_criteria if query.sort_criteria - new_query.project = self - new_query.user_id = query.user_id - self.queries << new_query - end - end - - # Copies boards from +project+ - def copy_boards(project) - project.boards.each do |board| - new_board = Board.new - new_board.attributes = board.attributes.dup.except("id", "project_id", "topics_count", "messages_count", "last_message_id") - new_board.project = self - self.boards << new_board - 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 - - # Returns all the active Systemwide and project specific activities - def active_activities - overridden_activity_ids = self.time_entry_activities.collect(&:parent_id) - - if overridden_activity_ids.empty? - return TimeEntryActivity.shared.active - else - return system_activities_and_project_overrides - end - end - - # Returns all the Systemwide and project specific activities - # (inactive and active) - def all_activities - overridden_activity_ids = self.time_entry_activities.collect(&:parent_id) - - if overridden_activity_ids.empty? - return TimeEntryActivity.shared - else - return system_activities_and_project_overrides(true) - end - end - - # Returns the systemwide active activities merged with the project specific overrides - def system_activities_and_project_overrides(include_inactive=false) - if include_inactive - return TimeEntryActivity.shared. - where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all + - self.time_entry_activities - else - return TimeEntryActivity.shared.active. - where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all + - self.time_entry_activities.active - end - end - - # Archives subprojects recursively - def archive! - children.each do |subproject| - subproject.send :archive! - end - update_attribute :status, STATUS_ARCHIVED - end - - def update_position_under_parent - set_or_update_position_under(parent) - end - - def course - @course - end - - # Inserts/moves the project so that target's children or root projects stay alphabetically sorted - def set_or_update_position_under(target_parent) - parent_was = parent - sibs = (target_parent.nil? ? self.class.roots : target_parent.children) - to_be_inserted_before = sibs.sort_by {|c| c.name.to_s.downcase}.detect {|c| c.name.to_s.downcase > name.to_s.downcase } - - if to_be_inserted_before - move_to_left_of(to_be_inserted_before) - elsif target_parent.nil? - if sibs.empty? - # move_to_root adds the project in first (ie. left) position - move_to_root - else - move_to_right_of(sibs.last) unless self == sibs.last - end - else - # move_to_child_of adds the project in last (ie.right) position - move_to_child_of(target_parent) - end - if parent_was != target_parent - after_parent_changed(parent_was) - end - end - - # 创建项目后在项目下同步创建一个讨论区 - def create_board_sync - @board = self.boards.build - self.name=" #{l(:label_borad_project) }" - @board.name = self.name - @board.description = self.name.to_s - if @board.save - logger.debug "[Project Model] ===> #{@board.to_json}" - else - logger.error "[Project Model] ===> Auto create board when Project saved, because #{@board.full_messages}" - end - end - - -end +# 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 Project < ActiveRecord::Base + include Redmine::SafeAttributes + ProjectType_project = 0 + ProjectType_course = 1 + + # Project statuses + STATUS_ACTIVE = 1 + STATUS_CLOSED = 5 + STATUS_ARCHIVED = 9 + + # Maximum length for project identifiers + IDENTIFIER_MAX_LENGTH = 100 + + # Specific overidden Activities + + belongs_to :homework_attach + has_many :time_entry_activities + 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 :users, :through => :members + has_many :principals, :through => :member_principals, :source => :principal + has_many :enabled_modules, :dependent => :delete_all + has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" + has_many :issues, :dependent => :destroy, :include => [:status, :tracker] + has_many :issue_changes, :through => :issues, :source => :journals + has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC" + has_many :time_entries, :dependent => :delete_all + has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all + has_many :documents, :dependent => :destroy + has_many :news, :dependent => :destroy, :include => :author + has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name" + has_many :boards, :dependent => :destroy, :order => "position ASC" + has_one :repository, :conditions => ["is_default = ?", true] + has_many :repositories, :dependent => :destroy + has_many :changesets, :through => :repository + #added by xianbo for delete biding_project + has_many :biding_projects, :dependent => :destroy + has_many :contesting_projects, :dependent => :destroy + has_many :softapplications, :through => :projecting_softapplications + #ended by xianbo + # added by fq + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + #has_many :homework_for_courses, :dependent => :destroy + #has_many :homeworks, :through => :homework_for_courses, :source => :bid, :dependent => :destroy + has_many :shares, :dependent => :destroy + # has_many :students_for_courses, :dependent => :destroy + has_many :student, :through => :students_for_courses, :source => :user + has_one :course_extra, :class_name => 'Course', :foreign_key => :extra,:primary_key => :identifier, :dependent => :destroy + has_many :applied_projects + + + # end + #ADDED BY NIE + has_many :project_infos, :dependent => :destroy + has_one :project_status, :class_name => "ProjectStatus", :dependent => :destroy + has_many :user_grades, :class_name => "UserGrade", :dependent => :destroy + #end + + has_one :wiki, :dependent => :destroy + ##added by xianbo + has_one :course, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC" + accepts_nested_attributes_for :course + ##end + # Custom field for the project issues + has_and_belongs_to_many :issue_custom_fields, + :class_name => 'IssueCustomField', + :order => "#{CustomField.table_name}.position", + :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", + :association_foreign_key => 'custom_field_id' + + has_many :tags, :through => :project_tags, :class_name => 'Tag' + has_many :project_tags, :class_name => 'ProjectTags' + + # has_many :journals + + acts_as_nested_set :order => 'name', :dependent => :destroy + acts_as_attachable :view_permission => :view_files, + :delete_permission => :manage_files + + acts_as_customizable + acts_as_searchable :columns => ['name', 'identifier', 'description'], :project_key => 'id', :permission => nil + acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"}, + :url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o}}, + :author => nil + ############################added by william + acts_as_taggable + scope :by_join_date, order("created_on DESC") + ###################added by liuping 关注 + acts_as_watchable + + attr_protected :status + + validates_presence_of :name, :identifier + validates_uniqueness_of :identifier + validates_uniqueness_of :name + validates_associated :repository, :wiki + # validates_length_of :description, :maximum => 255 + validates_length_of :name, :maximum => 255 + validates_length_of :homepage, :maximum => 255 + validates_length_of :identifier, :in => 1..IDENTIFIER_MAX_LENGTH + # donwcase letters, digits, dashes but not digits only + validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? } + # reserved words + validates_exclusion_of :identifier, :in => %w( new ) + + #此代码功能:为原redmine中项目的树形结构按名称首字母排序,本系统项目非树形结构,且项目排序方式无按首字母排序,另该代码执行会使空数据库时创建项目时出异常故注释掉 + #after_save :update_position_under_parent, :if => Proc.new {|project| project.name_changed?} + after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?} + # 创建project之后默认创建一个board,之后的board去掉了board的概念 + after_create :create_board_sync + before_destroy :delete_all_members + def remove_references_before_destroy + return if self.id.nil? + Watcher.delete_all ['watchable_id = ?', id] + end + scope :has_module, lambda {|mod| + where("#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s) + } + 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(Project.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(Project.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 + } + scope :project_entities, -> { where(project_type: ProjectType_project) } + scope :course_entities, -> { where(project_type: ProjectType_course) } + + def new_course + self.where('project_type = ?', 1) + 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 validation + if !class_period.match([0-9]) + errors.add_to_base("class period can only digital") + end + end + +# 项目留言 added by fq + def self.add_jour(user, notes) + project = Project.find('trustie') + # project.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => 0) + pjfm = project.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0) + pjfm.save + pjfm + end + + def self.add_new_jour(user, notes, id, options={}) + project = Project.find(id) + if options.count == 0 + pjfm = project.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0) + else + pjfm = project.journals_for_messages.build(options) + end + pjfm.save + pjfm + end +# end + + # 管理员的邮件列表 + def manager_recipients + notified = project.project_infos.collect(&:user) + notified.collect(&:mail) + end + + def initialize(attributes=nil, *args) + super + + initialized = (attributes || {}).stringify_keys + if !initialized.key?('identifier') && Setting.sequential_project_identifiers? + self.identifier = Project.next_identifier + end + if !initialized.key?('is_public') + self.is_public = Setting.default_projects_public? + end + if !initialized.key?('enabled_module_names') + self.enabled_module_names = Setting.default_projects_modules + end + if !initialized.key?('trackers') && !initialized.key?('tracker_ids') + default = Setting.default_projects_tracker_ids + if default.is_a?(Array) + self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.all + else + self.trackers = Tracker.sorted.all + end + end + end + + def identifier=(identifier) + super unless identifier_frozen? + end + + def identifier_frozen? + errors[:identifier].blank? && !(new_record? || identifier.blank?) + end + + # returns latest created projects + # non public projects will be returned only if user is a member of those + def self.latest(user=nil, count=5) + visible(user).limit(count).order("created_on DESC").all + end + + # Returns true if the project is visible to +user+ or to the current user. + def visible?(user=User.current) + user.allowed_to?(:view_project, self) + end + + # Returns a SQL conditions string used to find all projects visible by the specified user. + # + # Examples: + # Project.visible_condition(admin) => "projects.status = 1" + # Project.visible_condition(normal_user) => "((projects.status = 1) AND (projects.is_public = 1 OR projects.id IN (1,3,4)))" + # Project.visible_condition(anonymous) => "((projects.status = 1) AND (projects.is_public = 1))" + def self.visible_condition(user, options={}) + allowed_to_condition(user, :view_project, options) + end + + # Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+ + # + # Valid options: + # * :project => limit the condition to project + # * :with_subprojects => limit the condition to project and its subprojects + # * :member => limit the condition to the user projects + def self.allowed_to_condition(user, permission, options={}) + perm = Redmine::AccessControl.permission(permission) + base_statement = (perm && perm.read? ? "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED}" : "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}") + if perm && perm.project_module + # If the permission belongs to a project module, make sure the module is enabled + base_statement << " AND #{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.project_module}')" + end + if options[:project] + project_statement = "#{Project.table_name}.id = #{options[:project].id}" + project_statement << " OR (#{Project.table_name}.lft > #{options[:project].lft} AND #{Project.table_name}.rgt < #{options[:project].rgt})" if options[:with_subprojects] + base_statement = "(#{project_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] = "#{Project.table_name}.is_public = #{connection.quoted_true}" + end + end + if user.logged? + user.projects_by_role.each do |role, projects| + if role.allowed_to?(permission) && projects.any? + statement_by_role[role] = "#{Project.table_name}.id IN (#{projects.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 + + # Returns the Systemwide and project specific activities + def activities(include_inactive=false) + if include_inactive + return all_activities + else + return active_activities + end + end + + # Will create a new Project specific Activity or update an existing one + # + # This will raise a ActiveRecord::Rollback if the TimeEntryActivity + # does not successfully save. + def update_or_create_time_entry_activity(id, activity_hash) + if activity_hash.respond_to?(:has_key?) && activity_hash.has_key?('parent_id') + self.create_time_entry_activity_if_needed(activity_hash) + else + activity = project.time_entry_activities.find_by_id(id.to_i) + activity.update_attributes(activity_hash) if activity + end + end + + # Create a new TimeEntryActivity if it overrides a system TimeEntryActivity + # + # This will raise a ActiveRecord::Rollback if the TimeEntryActivity + # does not successfully save. + def create_time_entry_activity_if_needed(activity) + if activity['parent_id'] + + parent_activity = TimeEntryActivity.find(activity['parent_id']) + activity['name'] = parent_activity.name + activity['position'] = parent_activity.position + + if Enumeration.overridding_change?(activity, parent_activity) + project_activity = self.time_entry_activities.create(activity) + + if project_activity.new_record? + raise ActiveRecord::Rollback, "Overridding TimeEntryActivity was not successfully saved" + else + self.time_entries.update_all("activity_id = #{project_activity.id}", ["activity_id = ?", parent_activity.id]) + end + end + end + end + + # Returns a :conditions SQL string that can be used to find the issues associated with this project. + # + # Examples: + # project.project_condition(true) => "(projects.id = 1 OR (projects.lft > 1 AND projects.rgt < 10))" + # project.project_condition(false) => "projects.id = 1" + def project_condition(with_subprojects) + cond = "#{Project.table_name}.id = #{id}" + cond = "(#{cond} OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt}))" if with_subprojects + cond + end + + def self.find(*args) + if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/) + project = find_by_identifier(*args) + raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil? + project + else + super + end + end + + def self.find_by_param(*args) + self.find(*args) + end + + alias :base_reload :reload + def reload(*args) + @shared_versions = nil + @rolled_up_versions = nil + @rolled_up_trackers = nil + @all_issue_custom_fields = nil + @all_time_entry_custom_fields = nil + @to_param = nil + @allowed_parents = nil + @allowed_permissions = nil + @actions_allowed = nil + @start_date = nil + @due_date = nil + base_reload(*args) + end + + # def to_param + # # id is used for projects with a numeric identifier (compatibility) + # @to_param ||= (identifier.to_s =~ %r{^\d*$} ? id.to_s : identifier) + # end + + def active? + self.status == STATUS_ACTIVE + end + + def archived? + self.status == STATUS_ARCHIVED + end + + # Archives the project and its descendants + def archive + # Check that there is no issue of a non descendant project that is assigned + # to one of the project or descendant versions + v_ids = self_and_descendants.collect {|p| p.version_ids}.flatten + if v_ids.any? && + Issue. + includes(:project). + where("#{Project.table_name}.lft < ? OR #{Project.table_name}.rgt > ?", lft, rgt). + where("#{Issue.table_name}.fixed_version_id IN (?)", v_ids). + exists? + return false + end + Project.transaction do + archive! + end + true + end + + # Unarchives the project + # All its ancestors must be active + def unarchive + return false if ancestors.detect {|a| !a.active?} + update_attribute :status, STATUS_ACTIVE + end + + def close + self_and_descendants.status(STATUS_ACTIVE).update_all :status => STATUS_CLOSED + end + + def reopen + self_and_descendants.status(STATUS_CLOSED).update_all :status => STATUS_ACTIVE + end + + # Returns an array of projects the project can be moved to + # by the current user + def allowed_parents + return @allowed_parents if @allowed_parents + @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).all + @allowed_parents = @allowed_parents - self_and_descendants + if User.current.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?) + @allowed_parents << nil + end + unless parent.nil? || @allowed_parents.empty? || @allowed_parents.include?(parent) + @allowed_parents << parent + end + @allowed_parents + end + + # Sets the parent of the project with authorization check + def set_allowed_parent!(p) + unless p.nil? || p.is_a?(Project) + if p.to_s.blank? + p = nil + else + p = Project.find_by_id(p) + return false unless p + end + end + if p.nil? + if !new_record? && allowed_parents.empty? + return false + end + elsif !allowed_parents.include?(p) + return false + end + set_parent!(p) + end + + # Sets the parent of the project + # Argument can be either a Project, a String, a Fixnum or nil + def set_parent!(p) + unless p.nil? || p.is_a?(Project) + if p.to_s.blank? + p = nil + else + p = Project.find_by_id(p) + return false unless p + end + end + if p == parent && !p.nil? + # Nothing to do + true + elsif p.nil? || (p.active? && move_possible?(p)) + set_or_update_position_under(p) + Issue.update_versions_from_hierarchy_change(self) + true + else + # Can not move to the given target + false + end + end + + # Recalculates all lft and rgt values based on project names + # Unlike Project.rebuild!, these values are recalculated even if the tree "looks" valid + # Used in BuildProjectsTree migration + def self.rebuild_tree! + transaction do + update_all "lft = NULL, rgt = NULL" + rebuild!(false) + end + end + + # Returns an array of the trackers used by the project and its active sub projects + def rolled_up_trackers + @rolled_up_trackers ||= + Tracker. + joins(:projects). + joins("JOIN #{EnabledModule.table_name} ON #{EnabledModule.table_name}.project_id = #{Project.table_name}.id AND #{EnabledModule.table_name}.name = 'issue_tracking'"). + select("DISTINCT #{Tracker.table_name}.*"). + where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt). + sorted. + all + end + + # Closes open and locked project versions that are completed + def close_completed_versions + Version.transaction do + versions.where(:status => %w(open locked)).all.each do |version| + if version.completed? + version.update_attribute(:status, 'closed') + end + end + end + end + + # Returns a scope of the Versions on subprojects + def rolled_up_versions + @rolled_up_versions ||= + Version.scoped(:include => :project, + :conditions => ["#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt]) + end + + # Returns a scope of the Versions used by the project + def shared_versions + if new_record? + Version.scoped(:include => :project, + :conditions => "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND #{Version.table_name}.sharing = 'system'") + else + @shared_versions ||= begin + r = root? ? self : root + Version.scoped(:include => :project, + :conditions => "#{Project.table_name}.id = #{id}" + + " OR (#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND (" + + " #{Version.table_name}.sharing = 'system'" + + " OR (#{Project.table_name}.lft >= #{r.lft} AND #{Project.table_name}.rgt <= #{r.rgt} AND #{Version.table_name}.sharing = 'tree')" + + " OR (#{Project.table_name}.lft < #{lft} AND #{Project.table_name}.rgt > #{rgt} AND #{Version.table_name}.sharing IN ('hierarchy', 'descendants'))" + + " OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt} AND #{Version.table_name}.sharing = 'hierarchy')" + + "))") + end + end + end + + # Returns a hash of project users grouped by role + 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 + + # Deletes all project's members + def delete_all_members + 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}.project_id = #{id})") + Member.delete_all(['project_id = ?', id]) + end + + # Users/groups issues can be assigned to + def assignable_users + assignable = Setting.issue_group_assignment? ? member_principals : members + assignable.select {|m| m.roles.detect {|role| role.assignable?}}.collect {|m| m.principal}.sort + 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 + + # Returns an array of all custom fields enabled for project issues + # (explictly associated custom fields and custom fields enabled for all projects) + def all_issue_custom_fields + @all_issue_custom_fields ||= (IssueCustomField.for_all + issue_custom_fields).uniq.sort + end + + # Returns an array of all custom fields enabled for project time entries + # (explictly associated custom fields and custom fields enabled for all projects) + def all_time_entry_custom_fields + @all_time_entry_custom_fields ||= (TimeEntryCustomField.for_all + time_entry_custom_fields).uniq.sort + end + + def project + self + end + + def <=>(project) + name.downcase <=> project.name.downcase + end + + def to_s + name + end + + # Returns a short description of the projects (first lines) + def short_description(length = 255) + #description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description + description.gsub(/<\/?.*?>/,"").html_safe if description + end + + def css_classes + s = 'project' + s << ' root' if root? + s << ' child' if child? + s << (leaf? ? ' leaf' : ' parent') + unless active? + if archived? + s << ' archived' + else + s << ' closed' + end + end + s + end + + # The earliest start date of a project, based on it's issues and versions + def start_date + @start_date ||= [ + issues.minimum('start_date'), + shared_versions.minimum('effective_date'), + Issue.fixed_version(shared_versions).minimum('start_date') + ].compact.min + end + + # The latest due date of an issue or version + def due_date + @due_date ||= [ + issues.maximum('due_date'), + shared_versions.maximum('effective_date'), + Issue.fixed_version(shared_versions).maximum('due_date') + ].compact.max + end + + def overdue? + active? && !due_date.nil? && (due_date < Date.today) + end + + # Returns the percent completed for this project, based on the + # progress on it's versions. + def completed_percent(options={:include_subprojects => false}) + if options.delete(:include_subprojects) + total = self_and_descendants.collect(&:completed_percent).sum + + total / self_and_descendants.count + else + if versions.count > 0 + total = versions.collect(&:completed_percent).sum + + total / versions.count + else + 100 + end + end + end + + # Return true if this project allows to do the specified action. + # action can be: + # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') + # * a permission Symbol (eg. :edit_project) + 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 module_enabled?(module_name) + module_name = module_name.to_s + enabled_modules.detect {|m| m.name == module_name} + end + + def enabled_module_names=(module_names) + if module_names && module_names.is_a?(Array) + module_names = module_names.collect(&:to_s).reject(&:blank?) + self.enabled_modules = module_names.collect {|name| enabled_modules.detect {|mod| mod.name == name} || EnabledModule.new(:name => name)} + else + enabled_modules.clear + end + end + + # Returns an array of the enabled modules names + def enabled_module_names + enabled_modules.collect(&:name) + end + + # Enable a specific module + # + # Examples: + # project.enable_module!(:issue_tracking) + # project.enable_module!("issue_tracking") + def enable_module!(name) + enabled_modules << EnabledModule.new(:name => name.to_s) unless module_enabled?(name) + end + + # Disable a module if it exists + # + # Examples: + # project.disable_module!(:issue_tracking) + # project.disable_module!("issue_tracking") + # project.disable_module!(project.enabled_modules.first) + def disable_module!(target) + target = enabled_modules.detect{|mod| target.to_s == mod.name} unless enabled_modules.include?(target) + target.destroy unless target.blank? + end + + safe_attributes 'name', + 'description', + 'homepage', + 'is_public', + 'hidden_repo', + 'identifier', + 'custom_field_values', + 'custom_fields', + 'tracker_ids', + 'issue_custom_field_ids', + 'project_type', + 'dts_test', + 'attachmenttype' + + + + safe_attributes 'enabled_module_names', + :if => lambda {|project, user| project.new_record? || user.allowed_to?(:select_project_modules, project) } + + safe_attributes 'inherit_members', + :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)} + + # Returns an array of projects that are in this project's hierarchy + # + # Example: parents, children, siblings + def hierarchy + parents = project.self_and_ancestors || [] + descendants = project.descendants || [] + project_hierarchy = parents | descendants # Set union + end + + # Returns an auto-generated project identifier based on the last identifier used + def self.next_identifier + p = Project.order('created_on DESC').first + p.nil? ? nil : p.identifier.to_s.succ + end + + # Copies and saves the Project instance based on the +project+. + # Duplicates the source project's: + # * Wiki + # * Versions + # * Categories + # * Issues + # * Members + # * Queries + # + # Accepts an +options+ argument to specify what to copy + # + # Examples: + # project.copy(1) # => copies everything + # project.copy(1, :only => 'members') # => copies members only + # project.copy(1, :only => ['members', 'versions']) # => copies members and versions + def copy(project, options={}) + project = project.is_a?(Project) ? project : Project.find(project) + + to_be_copied = %w(wiki versions issue_categories issues members queries boards) + to_be_copied = to_be_copied & options[:only].to_a unless options[:only].nil? + + Project.transaction do + if save + reload + to_be_copied.each do |name| + send "copy_#{name}", project + end + Redmine::Hook.call_hook(:model_project_copy_before_save, :source_project => project, :destination_project => self) + save + end + end + end + + # Returns a new unsaved Project instance with attributes copied from +project+ + def self.copy_from(project) + project = project.is_a?(Project) ? project : Project.find(project) + # clear unique attributes + attributes = project.attributes.dup.except('id', 'name', 'identifier', 'status', 'parent_id', 'lft', 'rgt') + copy = Project.new(attributes) + copy.enabled_modules = project.enabled_modules + copy.trackers = project.trackers + copy.custom_values = project.custom_values.collect {|v| v.clone} + copy.issue_custom_fields = project.issue_custom_fields + copy + end + + # Yields the given block for each project with its level in the tree + def self.project_tree(projects, &block) + ancestors = [] + projects.sort_by(&:lft).each do |project| + while (ancestors.any? && !project.is_descendant_of?(ancestors.last)) + ancestors.pop + end + yield project, ancestors.size + ancestors << project + end + end + + private + + def after_parent_changed(parent_was) + remove_inherited_member_roles + add_inherited_member_roles + end + + def update_inherited_members + if parent + if inherit_members? && !inherit_members_was + remove_inherited_member_roles + add_inherited_member_roles + elsif !inherit_members? && inherit_members_was + remove_inherited_member_roles + end + end + end + + def remove_inherited_member_roles + member_roles = memberships.map(&:member_roles).flatten + member_role_ids = member_roles.map(&:id) + member_roles.each do |member_role| + if member_role.inherited_from && !member_role_ids.include?(member_role.inherited_from) + member_role.destroy + end + end + end + + def add_inherited_member_roles + if inherit_members? && parent + parent.memberships.each do |parent_member| + member = Member.find_or_new(self.id, parent_member.user_id) + parent_member.member_roles.each do |parent_member_role| + member.member_roles << MemberRole.new(:role => parent_member_role.role, :inherited_from => parent_member_role.id) + end + member.save! + end + end + end + + # Copies wiki from +project+ + def copy_wiki(project) + # Check that the source project has a wiki first + unless project.wiki.nil? + wiki = self.wiki || Wiki.new + wiki.attributes = project.wiki.attributes.dup.except("id", "project_id") + wiki_pages_map = {} + project.wiki.pages.each do |page| + # Skip pages without content + next if page.content.nil? + new_wiki_content = WikiContent.new(page.content.attributes.dup.except("id", "page_id", "updated_on")) + new_wiki_page = WikiPage.new(page.attributes.dup.except("id", "wiki_id", "created_on", "parent_id")) + new_wiki_page.content = new_wiki_content + wiki.pages << new_wiki_page + wiki_pages_map[page.id] = new_wiki_page + end + + self.wiki = wiki + wiki.save + # Reproduce page hierarchy + project.wiki.pages.each do |page| + if page.parent_id && wiki_pages_map[page.id] + wiki_pages_map[page.id].parent = wiki_pages_map[page.parent_id] + wiki_pages_map[page.id].save + end + end + end + end + + # Copies versions from +project+ + def copy_versions(project) + project.versions.each do |version| + new_version = Version.new + new_version.attributes = version.attributes.dup.except("id", "project_id", "created_on", "updated_on") + self.versions << new_version + end + end + + # Copies issue categories from +project+ + def copy_issue_categories(project) + project.issue_categories.each do |issue_category| + new_issue_category = IssueCategory.new + new_issue_category.attributes = issue_category.attributes.dup.except("id", "project_id") + self.issue_categories << new_issue_category + end + end + + # Copies issues from +project+ + def copy_issues(project) + # Stores the source issue id as a key and the copied issues as the + # value. Used to map the two togeather for issue relations. + issues_map = {} + + # Store status and reopen locked/closed versions + version_statuses = versions.reject(&:open?).map {|version| [version, version.status]} + version_statuses.each do |version, status| + version.update_attribute :status, 'open' + end + + # Get issues sorted by root_id, lft so that parent issues + # get copied before their children + project.issues.reorder('root_id, lft').all.each do |issue| + new_issue = Issue.new + new_issue.copy_from(issue, :subtasks => false, :link => false) + new_issue.project = self + # Reassign fixed_versions by name, since names are unique per project + if issue.fixed_version && issue.fixed_version.project == project + new_issue.fixed_version = self.versions.detect {|v| v.name == issue.fixed_version.name} + end + # Reassign the category by name, since names are unique per project + if issue.category + new_issue.category = self.issue_categories.detect {|c| c.name == issue.category.name} + end + # Parent issue + if issue.parent_id + if copied_parent = issues_map[issue.parent_id] + new_issue.parent_issue_id = copied_parent.id + end + end + + self.issues << new_issue + if new_issue.new_record? + logger.info "Project#copy_issues: issue ##{issue.id} could not be copied: #{new_issue.errors.full_messages}" if logger && logger.info + else + issues_map[issue.id] = new_issue unless new_issue.new_record? + end + end + + # Restore locked/closed version statuses + version_statuses.each do |version, status| + version.update_attribute :status, status + end + + # Relations after in case issues related each other + project.issues.each do |issue| + new_issue = issues_map[issue.id] + unless new_issue + # Issue was not copied + next + end + + # Relations + issue.relations_from.each do |source_relation| + new_issue_relation = IssueRelation.new + new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id") + new_issue_relation.issue_to = issues_map[source_relation.issue_to_id] + if new_issue_relation.issue_to.nil? && Setting.cross_project_issue_relations? + new_issue_relation.issue_to = source_relation.issue_to + end + new_issue.relations_from << new_issue_relation + end + + issue.relations_to.each do |source_relation| + new_issue_relation = IssueRelation.new + new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id") + new_issue_relation.issue_from = issues_map[source_relation.issue_from_id] + if new_issue_relation.issue_from.nil? && Setting.cross_project_issue_relations? + new_issue_relation.issue_from = source_relation.issue_from + end + new_issue.relations_to << new_issue_relation + end + end + end + + # Copies members from +project+ + def copy_members(project) + # Copy users first, then groups to handle members with inherited and given roles + members_to_copy = [] + members_to_copy += project.memberships.select {|m| m.principal.is_a?(User)} + members_to_copy += project.memberships.select {|m| !m.principal.is_a?(User)} + + members_to_copy.each do |member| + new_member = Member.new + new_member.attributes = member.attributes.dup.except("id", "project_id", "created_on") + # only copy non inherited roles + # inherited roles will be added when copying the group membership + role_ids = member.member_roles.reject(&:inherited?).collect(&:role_id) + next if role_ids.empty? + new_member.role_ids = role_ids + new_member.project = self + self.members << new_member + end + end + + # Copies queries from +project+ + def copy_queries(project) + project.queries.each do |query| + new_query = IssueQuery.new + new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria") + new_query.sort_criteria = query.sort_criteria if query.sort_criteria + new_query.project = self + new_query.user_id = query.user_id + self.queries << new_query + end + end + + # Copies boards from +project+ + def copy_boards(project) + project.boards.each do |board| + new_board = Board.new + new_board.attributes = board.attributes.dup.except("id", "project_id", "topics_count", "messages_count", "last_message_id") + new_board.project = self + self.boards << new_board + 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 + + # Returns all the active Systemwide and project specific activities + def active_activities + overridden_activity_ids = self.time_entry_activities.collect(&:parent_id) + + if overridden_activity_ids.empty? + return TimeEntryActivity.shared.active + else + return system_activities_and_project_overrides + end + end + + # Returns all the Systemwide and project specific activities + # (inactive and active) + def all_activities + overridden_activity_ids = self.time_entry_activities.collect(&:parent_id) + + if overridden_activity_ids.empty? + return TimeEntryActivity.shared + else + return system_activities_and_project_overrides(true) + end + end + + # Returns the systemwide active activities merged with the project specific overrides + def system_activities_and_project_overrides(include_inactive=false) + if include_inactive + return TimeEntryActivity.shared. + where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all + + self.time_entry_activities + else + return TimeEntryActivity.shared.active. + where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all + + self.time_entry_activities.active + end + end + + # Archives subprojects recursively + def archive! + children.each do |subproject| + subproject.send :archive! + end + update_attribute :status, STATUS_ARCHIVED + end + + def update_position_under_parent + set_or_update_position_under(parent) + end + + def course + @course + end + + # Inserts/moves the project so that target's children or root projects stay alphabetically sorted + def set_or_update_position_under(target_parent) + parent_was = parent + sibs = (target_parent.nil? ? self.class.roots : target_parent.children) + to_be_inserted_before = sibs.sort_by {|c| c.name.to_s.downcase}.detect {|c| c.name.to_s.downcase > name.to_s.downcase } + + if to_be_inserted_before + move_to_left_of(to_be_inserted_before) + elsif target_parent.nil? + if sibs.empty? + # move_to_root adds the project in first (ie. left) position + move_to_root + else + move_to_right_of(sibs.last) unless self == sibs.last + end + else + # move_to_child_of adds the project in last (ie.right) position + move_to_child_of(target_parent) + end + if parent_was != target_parent + after_parent_changed(parent_was) + end + end + + # 创建项目后在项目下同步创建一个讨论区 + def create_board_sync + @board = self.boards.build + self.name=" #{l(:label_borad_project) }" + @board.name = self.name + @board.description = self.name.to_s + if @board.save + logger.debug "[Project Model] ===> #{@board.to_json}" + else + logger.error "[Project Model] ===> Auto create board when Project saved, because #{@board.full_messages}" + end + end + + +end diff --git a/app/models/project_status.rb b/app/models/project_status.rb index 7fd246234..d9e6159c3 100644 --- a/app/models/project_status.rb +++ b/app/models/project_status.rb @@ -1,21 +1,21 @@ -class ProjectStatus < ActiveRecord::Base - attr_accessible :changesets_count, :watchers_count, :project_id, :project_type,:grade - belongs_to :project - belongs_to :watchers - belongs_to :changesets - validates_presence_of :project_id - validates_uniqueness_of :project_id - - scope :visible, lambda {|*args| nil } - # 更新字段 watchers_count 加1 这里没有做用户是否存在的匹配 - # 负责这个表的聂同学 是在新建用户时就新建了该表的记录 - # 但是 如果超级用户删除其他用户的话会造成读取错误 这里是遗漏点 - # 删除用户时 此表创建人员未作相应删除动作 - def update_watchers_count(num) - if self.watchers_count||0 >= 0 - self.update_attribute(:watchers_count, self.watchers_count.to_i + num) - end - end - - -end +class ProjectStatus < ActiveRecord::Base + attr_accessible :changesets_count, :watchers_count, :project_id, :project_type,:grade + belongs_to :project + belongs_to :watchers + belongs_to :changesets + validates_presence_of :project_id + validates_uniqueness_of :project_id + + scope :visible, lambda {|*args| nil } + # 更新字段 watchers_count 加1 这里没有做用户是否存在的匹配 + # 负责这个表的聂同学 是在新建用户时就新建了该表的记录 + # 但是 如果超级用户删除其他用户的话会造成读取错误 这里是遗漏点 + # 删除用户时 此表创建人员未作相应删除动作 + def update_watchers_count(num) + if self.watchers_count||0 >= 0 + self.update_attribute(:watchers_count, self.watchers_count.to_i + num) + end + end + + +end diff --git a/app/views/account/password_recovery.html.erb b/app/views/account/password_recovery.html.erb index ff455f325..568d4d4bb 100644 --- a/app/views/account/password_recovery.html.erb +++ b/app/views/account/password_recovery.html.erb @@ -12,9 +12,9 @@

- - <%= password_field_tag 'new_password_confirmation', nil, :size => 25 %> -

+ + <%= password_field_tag 'new_password_confirmation', nil, :size => 25 %> +

<%= submit_tag l(:button_save) %>

<% end %> diff --git a/app/views/attachments/_form.html.erb b/app/views/attachments/_form.html.erb index 81dc5d939..5c22ff44c 100644 --- a/app/views/attachments/_form.html.erb +++ b/app/views/attachments/_form.html.erb @@ -1,52 +1,52 @@ - -<% if defined?(container) && container && container.saved_attachments %> - <% container.attachments.each_with_index do |attachment, i| %> - - <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%> - <%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") + - if attachment.id.nil? - else - link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') - end - %> - <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> - <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public, :class => 'is_public')%> - <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> - - <% end %> -<% end %> - - - -<%#= button_tag "浏览", :type=>"button", :onclick=>"CompatibleSend();" %> - -<%= button_tag "浏览", :type=>"button", :onclick=>"_file.click()",:onmouseover => 'this.focus()' %> -<%= file_field_tag 'attachments[dummy][file]', - :id => '_file', - :class => 'file_selector', - :multiple => true, - :onchange => 'addInputFiles(this);', - :style => 'display:none', - :data => { - :max_file_size => Setting.attachment_max_size.to_i.kilobytes, - :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)), - :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i, - :upload_path => uploads_path(:format => 'js'), - :description_placeholder => l(:label_optional_description) - } %> -<%= l(:label_no_file_uploaded)%> -(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) - - -<% content_for :header_tags do %> - <%= javascript_include_tag 'attachments' %> -<% end %> - - + +<% if defined?(container) && container && container.saved_attachments %> + <% container.attachments.each_with_index do |attachment, i| %> + + <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%> + <%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") + + if attachment.id.nil? + else + link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') + end + %> + <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> + <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public, :class => 'is_public')%> + <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> + + <% end %> +<% end %> + + + +<%#= button_tag "浏览", :type=>"button", :onclick=>"CompatibleSend();" %> + +<%= button_tag "浏览", :type=>"button", :onclick=>"_file.click()",:onmouseover => 'this.focus()' %> +<%= file_field_tag 'attachments[dummy][file]', + :id => '_file', + :class => 'file_selector', + :multiple => true, + :onchange => 'addInputFiles(this);', + :style => 'display:none', + :data => { + :max_file_size => Setting.attachment_max_size.to_i.kilobytes, + :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)), + :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i, + :upload_path => uploads_path(:format => 'js'), + :description_placeholder => l(:label_optional_description) + } %> +<%= l(:label_no_file_uploaded)%> +(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) + + +<% content_for :header_tags do %> + <%= javascript_include_tag 'attachments' %> +<% end %> + + diff --git a/app/views/attachments/file.html.erb b/app/views/attachments/file.html.erb index d4cb19880..75fa1858c 100644 --- a/app/views/attachments/file.html.erb +++ b/app/views/attachments/file.html.erb @@ -1,26 +1,26 @@ -

<%=h @attachment.filename %>

- -
-

<%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> - <%= link_to_user(@attachment.author) %>, <%= format_time(@attachment.created_on) %>

-

<%= link_to_attachment @attachment, :text => l(:button_download), :download => true -%> - (<%= number_to_human_size @attachment.filesize %>)    - - <% if @attachment!=nil &&(@attachment.container_type == 'Document' || @attachment.container_type == 'WikiPage') && - User.current.allowed_to?({:controller => 'code_review', :action => 'update_diff_view'}, @attachment.project) %> - <%= l(:review_assignments)+":" %><%= link = link_to(l(:button_add), {:controller => 'code_review', - :action => 'assign', :action_type => 'attachment', - :id=>@attachment.project, - :change_id => '', :attachment_id => @attachment.id, - }, :class => 'icon icon-add') %> - <% end %> -

-
-  -<%= render :partial => 'common/file', :locals => {:content => @content, :filename => @attachment.filename} %> - -<% html_title @attachment.filename %> - -<% content_for :header_tags do -%> - <%= stylesheet_link_tag "scm" -%> -<% end -%> +

<%=h @attachment.filename %>

+ +
+

<%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> + <%= link_to_user(@attachment.author) %>, <%= format_time(@attachment.created_on) %>

+

<%= link_to_attachment @attachment, :text => l(:button_download), :download => true -%> + (<%= number_to_human_size @attachment.filesize %>)    + + <% if @attachment!=nil &&(@attachment.container_type == 'Document' || @attachment.container_type == 'WikiPage') && + User.current.allowed_to?({:controller => 'code_review', :action => 'update_diff_view'}, @attachment.project) %> + <%= l(:review_assignments)+":" %><%= link = link_to(l(:button_add), {:controller => 'code_review', + :action => 'assign', :action_type => 'attachment', + :id=>@attachment.project, + :change_id => '', :attachment_id => @attachment.id, + }, :class => 'icon icon-add') %> + <% end %> +

+
+  +<%= render :partial => 'common/file', :locals => {:content => @content, :filename => @attachment.filename} %> + +<% html_title @attachment.filename %> + +<% content_for :header_tags do -%> + <%= stylesheet_link_tag "scm" -%> +<% end -%> diff --git a/app/views/boards/_project_show.html.erb b/app/views/boards/_project_show.html.erb index a14e32d6d..199155838 100644 --- a/app/views/boards/_project_show.html.erb +++ b/app/views/boards/_project_show.html.erb @@ -67,12 +67,15 @@ <% @topics.each do |topic| %> - +     + +    

diff --git a/app/views/contests/show_attendingcontest.html.erb b/app/views/contests/show_attendingcontest.html.erb index 799656f36..3ba3e73ba 100644 --- a/app/views/contests/show_attendingcontest.html.erb +++ b/app/views/contests/show_attendingcontest.html.erb @@ -79,18 +79,35 @@ <%= render_flash_messages %>
-
<%= l(:label_wellmeaning_intimation_contentone) %>
-
1) <%= l(:label_wellmeaning_intimation_contenttwo) %>
-
2) <%= l(:label_wellmeaning_intimation_contentthree) %>
+
+ <%= l(:label_wellmeaning_intimation_contentone) %> +
+
+ 1) <%= l(:label_wellmeaning_intimation_contenttwo) %> +
+
+ 2) <%= l(:label_wellmeaning_intimation_contentthree) %> +
<% if User.current.logged? %>
<%= l(:label_attending_contest) %>: - <%= link_to l(:label_new_attendingcontest_work), "javascript:void(0);", onclick: "$('#put-project-form').slideToggle();" %> + + <%= link_to l(:label_new_attendingcontest_work), + "javascript:void(0);", + onclick: "$('#put-project-form').slideToggle();" + %> +
+ + +
+ <%= render "new_softapplication" %> +
+ <% else %>
<%= l(:label_user_login_attending_contest) %> @@ -98,10 +115,7 @@
<% end %> - -
- <%= render "new_softapplication" %> -
+ diff --git a/app/views/contests/show_contest.html.erb b/app/views/contests/show_contest.html.erb index 121f5e690..11937d2bd 100644 --- a/app/views/contests/show_contest.html.erb +++ b/app/views/contests/show_contest.html.erb @@ -2,9 +2,18 @@
<%= image_tag(url_to_avatar(@contest.author), :class => "avatar")%> -

<%= link_to(@contest.author.lastname+@contest.author.firstname, user_path(@contest.author))%>:<%= @contest.name %>

+

+ <%= link_to(@contest.author.lastname+@contest.author.firstname, + user_path(@contest.author)) + %> + :<%= @contest.name %>

- <%= l(:label_bids_reward_method) %><%= @contest.budget%> + + <%= l(:label_bids_reward_method) %> + + <%= @contest.budget%> + +

<%= @contest.description %> @@ -15,7 +24,11 @@
<%= render :partial => "/praise_tread/praise_tread", - :locals => {:obj => @contest,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%> + :locals => {:obj => @contest, + :show_flag => true, + :user_id =>User.current.id, + :horizontal => false} + %>
@@ -23,7 +36,9 @@
- <%= render :partial => 'history', :locals => { :contest => @contest, :journals => @jour, :state => false} %> + <%= render :partial => 'history', + :locals => { :contest => @contest, :journals => @jour, :state => false} + %>
<%= link_to image_tag(url_to_avatar(topic.author), :class => "avatar"), user_path(topic.author) %> + <%= link_to image_tag(url_to_avatar(topic.author), :class => "avatar"), user_path(topic.author) %> + - - + +
<%= link_to h(topic.subject.truncate(40,ommision:'...')), board_message_path(@board, topic),title:topic.subject.to_s %> + <%= topic.locked? ? 'locked' : '' %>"> + <%= link_to h(topic.subject.truncate(40,ommision:'...')), board_message_path(@board, topic),title:topic.subject.to_s %> diff --git a/app/views/contest_notification/show.html.erb b/app/views/contest_notification/show.html.erb index 93fa1f4af..5664d5398 100644 --- a/app/views/contest_notification/show.html.erb +++ b/app/views/contest_notification/show.html.erb @@ -9,8 +9,12 @@ - - + +
contest.trustie.net<%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_contest_innovate), :controller => 'welcome', :action => 'contest' %> > 详情 + contest.trustie.net + + <%=link_to l(:field_homepage), home_path %> > + <%=link_to l(:label_contest_innovate), welcome_contest_path %> > 详情
diff --git a/app/views/contestnotifications/_form.html.erb b/app/views/contestnotifications/_form.html.erb index afcb60657..36bcd78c6 100644 --- a/app/views/contestnotifications/_form.html.erb +++ b/app/views/contestnotifications/_form.html.erb @@ -3,8 +3,23 @@ <%= l(:bale_news_notice) %>
-

<%= f.text_field :title, :required => true, :size => 60,:maxlength => 60, :style => "width:488px;" %>

-

<%= f.text_area :description, :required => true, :cols => 60, :rows => 11, :class => 'wiki-edit', :style => "width:490px;" %>

+

+ <%= f.text_field :title, + :required => true, + :size => 60, + :maxlength => 60, + :style => "width:488px;" + %> +

+

+ <%= f.text_area :description, + :required => true, + :cols => 60, + :rows => 11, + :class => 'wiki-edit', + :style => "width:490px;" + %> +

diff --git a/app/views/contestnotifications/_news.html.erb b/app/views/contestnotifications/_news.html.erb index fbac2557f..c8af85cf4 100644 --- a/app/views/contestnotifications/_news.html.erb +++ b/app/views/contestnotifications/_news.html.erb @@ -2,24 +2,47 @@ + <%# unless news.summary.blank? %>
<%#= link_to h(news.title), news_path(news) %> <%#= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %> - <%# unless news.summary.blank? %><%#=h news.summary %><% end %><%#=h news.summary %> <%#= authoring news.created_on, news.author %>

--> - + - <%= l(:label_work_name) %> - * : - - (<%= l(:label_workname_lengthlimit) %>) - -
-
-
- - - <%= l(:label_running_platform) %> - * : - - (<%= l(:label_workdescription_lengthlimit) %>) - -
-
-
- - - <%= l(:label_work_type) %> - * : - - - -
-
-
- - - <%= l(:label_work_description) %> - * : - - - -
-
-
- - - <%= l(:label_softapplication_developers) %> - * : - - (<%= l(:label_workdescription_lengthlimit) %>) - -
-
-
- - - <%= l(:label_work_deposit_project) %>: - <%= select_tag 'project', options_for_select(select_option_helper(@option)), :name => 'project', :class => 'grayline2',:style => "width:328px;" %> - <%= link_to l(:label_create_new_projects),{:controller => 'projects',:action => 'new',course: 0, project_type: 0,host: Setting.project_domain}, :target => '_blank' %> - -
-
-
- -
- - <%= l(:label_upload_softworkpacket_photo) %> - - <%#= render_flash_messages %> -

- <%= render :partial => 'attachments/form' %> -

- -

- 1、<%= l(:label_upload_softapplication_packets_mustpacketed) %>
-
- 2、<%= l(:label_upload_softapplication_photo_condition) %> -

- -
-
-
- - <%#= submit_tag l(:button_create) %> - <%= submit_tag l(:button_cancel), :name => nil, :onclick => "cancel();", - :type => 'button', :class => "enterprise", :onmouseout => "this.style.backgroundPosition = 'left top'", - :onmouseover => "this.style.backgroundPosition = 'left -30px'" %> -
+<%#= error_messages_for 'softapplication' %> + + + +<%= form_for Softapplication.new, :url => softapplications_path do |f| %> +
+ <%= hidden_field_tag 'contest_id', @contest.id %> +
+ <%= l(:label_work_name) %> + * : + + (<%= l(:label_workname_lengthlimit) %>) + +
+
+
+ + + <%= l(:label_running_platform) %> + * : + + (<%= l(:label_workdescription_lengthlimit) %>) + +
+
+
+ + + <%= l(:label_work_type) %> + * : + + + +
+
+
+ + + <%= l(:label_work_description) %> + * : + + + +
+
+
+ + + <%= l(:label_softapplication_developers) %> + * : + + + (<%= l(:label_workdescription_lengthlimit) %>) + + +
+
+
+ + + <%= l(:label_work_deposit_project) %>: + + <%= select_tag 'project', + options_for_select(select_option_helper(@option)), + :name => 'project', + :class => 'grayline2', + :style => "width:328px;" + %> + + + + + <%= link_to l(:label_create_new_projects), + new_project_path(:course => 0, :project_type => 0, :host => Setting.project_domain), + :target => '_blank' + %> + + + +
+
+
+ +
+ + <%= l(:label_upload_softworkpacket_photo) %> + + <%#= render_flash_messages %> +

+ <%= render :partial => 'attachments/form' %> +

+ +

+ 1、<%= l(:label_upload_softapplication_packets_mustpacketed) %>
+
+ 2、<%= l(:label_upload_softapplication_photo_condition) %> +

+ +
+
+
+ + <%#= submit_tag l(:button_create) %> + <%= submit_tag l(:button_cancel), + :name => nil, + :onclick => "cancel();", + :type => 'button', + :class => "enterprise", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -30px'" %> +
<% end %> \ No newline at end of file diff --git a/app/views/contests/_pre_show.html.erb b/app/views/contests/_pre_show.html.erb index fef1f16e4..67ceeb356 100644 --- a/app/views/contests/_pre_show.html.erb +++ b/app/views/contests/_pre_show.html.erb @@ -5,7 +5,12 @@ - +
+ + - - + - - + diff --git a/app/views/contestnotifications/edit.html.erb b/app/views/contestnotifications/edit.html.erb index 7b91d922c..1606d97d6 100644 --- a/app/views/contestnotifications/edit.html.erb +++ b/app/views/contestnotifications/edit.html.erb @@ -1,9 +1,15 @@

<%=l(:label_news)%>

-<%= labelled_form_for @contestnotification, url: contest_contestnotification_path, :html => { :id => 'contestnotifications-form', :multipart => true, :method => :put } do |f| %> +<%= labelled_form_for @contestnotification, + :url => contest_contestnotification_path, + :html => { :id => 'contestnotifications-form', + :multipart => true, + :method => :put } do |f| %> <%= render :partial => 'form', :locals => { :f => f } %> <%= submit_tag l(:button_save) %> -<%= preview_link preview_contestnotifications_path(id: @contestnotification), 'contestnotifications-form' %> +<%= preview_link preview_contestnotifications_path(id: @contestnotification), + 'contestnotifications-form' +%> <% end %>
diff --git a/app/views/contestnotifications/new.html.erb b/app/views/contestnotifications/new.html.erb index 30d5f0106..a5a1c7e58 100644 --- a/app/views/contestnotifications/new.html.erb +++ b/app/views/contestnotifications/new.html.erb @@ -1,5 +1,7 @@ -<%= labelled_form_for @contestnotification, :url => contest_contestnotifications_path(@contest), :html => { :id => 'contestnotifications-form', :multipart => true } do |f| %> +<%= labelled_form_for @contestnotification, + :url => contest_contestnotifications_path(@contest), + :html => { :id => 'contestnotifications-form', :multipart => true } do |f| %> <%= render :partial => 'contestnotifications/form', :locals => { :f => f } %> <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> <%= submit_tag l(:button_cancel), :class => "whiteButton m3p10 h30",:onclick => "cancel();" %> diff --git a/app/views/contestnotifications/show.html.erb b/app/views/contestnotifications/show.html.erb index b6ac88008..a44ee5909 100644 --- a/app/views/contestnotifications/show.html.erb +++ b/app/views/contestnotifications/show.html.erb @@ -1,21 +1,26 @@
<%= link_to(l(:button_edit), - edit_contest_contestnotification_path(@contest, @contestnotification), - :class => 'icon icon-edit', - :accesskey => accesskey(:edit), - :onclick => '$("#edit-contestnotifications").show(); return true;') if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?)%> + edit_contest_contestnotification_path(@contest, @contestnotification), + :class => 'icon icon-edit', + :accesskey => accesskey(:edit), + :onclick => '$("#edit-contestnotifications").show(); return true;') if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?)%> <%= delete_link contest_contestnotification_path(@contest, @contestnotification) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %>

<%=h @contestnotification.title %>

@@ -23,7 +28,9 @@
- <%= textilizable(@contestnotification, :description) %> + + <%= textilizable(@contestnotification, :description) %> +
<%#= link_to_attachments @contestnotification %>
@@ -31,16 +38,26 @@ <% if User.current.logged? %>

- <%= toggle_link l(:label_comment_add), "add_notificationcomment_form", :focus => "notificationcomment_notificationcomments" %> + <%= toggle_link l(:label_comment_add), + "add_notificationcomment_form", + :focus => "notificationcomment_notificationcomments" + %>

<% else %> <%= l(:label_user_login_notificationcomment) %> <%= link_to l(:label_user_login_new), signin_path %> <% end %> - <%= form_tag( contest_contestnotification_notificationcomments_path(@contest, @contestnotification) , :id => "add_notificationcomment_form", :style => "display:none;") do %> + <%= form_tag( contest_contestnotification_notificationcomments_path(@contest, @contestnotification) , + :id => "add_notificationcomment_form", + :style => "display:none;") do %>
- <%= text_area 'notificationcomment', 'notificationcomments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= text_area 'notificationcomment', + 'notificationcomments', + :cols => 80, + :rows => 15, + :class => 'wiki-edit' + %> <%= wikitoolbar_for 'notificationcomment_notificationcomments' %>

@@ -65,7 +82,9 @@ <% next if notificationcomment.new_record? %>

<%=link_to contestnotifications.author,contest_contestnotification_path(contestnotifications)%> - <%= l(:label_project_newshare) %> <%= link_to h(contestnotifications.title), contest_contestnotification_path(contestnotifications) %> + + + <%=link_to contestnotifications.author, + contest_contestnotification_path(contestnotifications) + %> + + + <%= l(:label_project_newshare) %> + + <%= link_to h(contestnotifications.title), + contest_contestnotification_path(contestnotifications) + %>

<%=h contestnotifications.description%>

+

+ <%=h contestnotifications.description%> +

+
<%= contestnotifications.created_at %><%= link_to l(:label_project_newother),contest_contestnotification_path(contestnotifications)%> + + + <%= contestnotifications.created_at %> + + + <%= link_to l(:label_project_newother), + contest_contestnotification_path(contestnotifications) + %> <%= "(#{l(:label_x_comments, :count => contestnotifications.notificationcomments_count)})" if contestnotifications.notificationcomments_count > 0 %>
- +
<%= image_tag(url_to_avatar(notificationcomment.author), :class => "avatar")%> + <%= image_tag(url_to_avatar(notificationcomment.author), :class => "avatar")%> + @@ -80,8 +99,9 @@ @@ -92,7 +112,11 @@

- + diff --git a/app/views/contests/_contest_list.html.erb b/app/views/contests/_contest_list.html.erb index a91978079..967d31459 100644 --- a/app/views/contests/_contest_list.html.erb +++ b/app/views/contests/_contest_list.html.erb @@ -4,7 +4,10 @@ +  <%= link_to(contest.name, + contest_contestnotifications_path(contest), + :class => 'bid_path', + :target => "_blank") %> - +
@@ -31,5 +34,7 @@ <% end %>
<% end %> - + diff --git a/app/views/contests/_new.html.erb b/app/views/contests/_new.html.erb index 7ef0e71f1..a72ff6f36 100644 --- a/app/views/contests/_new.html.erb +++ b/app/views/contests/_new.html.erb @@ -30,7 +30,18 @@ <% if User.current.logged? %>
<% if notificationcomment.author==User.current|| User.current.admin? %> - <%= link_to(l(:label_bid_respond_delete), contest_contestnotification_notificationcomment_path(@contest, @contestnotification,notificationcomment), - :method => :delete,:confirm => l(:text_are_you_sure), :title => l(:button_delete)) %> + <%= link_to(l(:label_bid_respond_delete), + contest_contestnotification_notificationcomment_path(@contest, @contestnotification,notificationcomment), + :method => :delete,:confirm => l(:text_are_you_sure), :title => l(:button_delete)) %> <% end %>
<%= format_time(notificationcomment.created_at) %> + + <%= format_time(notificationcomment.created_at) %> + + <%#= link_to_if_authorized_contest image_tag('delete.png'), {:controller => 'notificationcomments', :action => 'destroy', :id => @contestnotifications, :notificationcomment_id => notificationcomment}, :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
<% unless contest.author.nil? %> - <%= link_to(image_tag(url_to_avatar(contest.author), :class => 'avatar'), user_path(contest.author), :class => "avatar") %> + <%= link_to(image_tag(url_to_avatar(contest.author), :class => 'avatar'), + user_path(contest.author), + :class => "avatar") + %> <% end %> @@ -12,33 +15,85 @@
<% unless contest.author.nil? %> - <%= link_to(contest.author, user_path(contest.author), :class => 'bid_user') %>: + <%= link_to(contest.author, + user_path(contest.author), + :class => 'bid_user') + %>: <% end %> -  <%= link_to(contest.name, contest_contestnotifications_path(contest), :class => 'bid_path', :target => "_blank") %>
- <%= l(:label_contests_reward_method) %>:  <%= contest.budget%> + <%= l(:label_contests_reward_method) %>:   + + <%= contest.budget%> + +
- - <% if contest.id == 2 or contest.id == 3 or contest.id == 6 %> - <%= l(:label_contest_work, :count => contest.contesting_projects.count) %>(<%= link_to(contest.projects.where('is_public=1').count, show_attendingcontest_contest_path(contest), :target => "_blank") %>) + + + <% if contest.id == 2 || contest.id == 3 || contest.id == 6 %> + <%= l(:label_contest_work, + :count => contest.contesting_projects.count) + %> + ( + + <%= link_to(contest.projects.where('is_public=1').count, + show_attendingcontest_contest_path(contest), + :target => "_blank") + %> + + ) <% else %> - <%= l(:label_contest_work, :count => contest.contesting_softapplications.count) %>(<%= link_to(contest.contesting_softapplications.count, show_attendingcontest_contest_path(contest), :target => "_blank") %>) + <%= l(:label_contest_work, + :count => contest.contesting_softapplications.count) + %> + ( + + <%= link_to(contest.contesting_softapplications.count, + show_attendingcontest_contest_path(contest), + :target => "_blank") %> + + ) <% end %>
<%= l :label_create_time %>: <%= format_time contest.created_on %> + + <%= l :label_create_time %>: <%= format_time contest.created_on %> + +
@@ -58,6 +113,6 @@ diff --git a/app/views/contests/_form_contest.html.erb b/app/views/contests/_form_contest.html.erb index 79c531969..68e941a27 100644 --- a/app/views/contests/_form_contest.html.erb +++ b/app/views/contests/_form_contest.html.erb @@ -20,17 +20,55 @@ <%= error_messages_for 'contest' %> -

<%= l(:label_bids_form_contest_new_description) %>

-

<%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Contest::NAME_LENGTH_LIMIT, :placeholder => "#{l(:label_contest_name)}" %>

+

+ <%= l(:label_bids_form_contest_new_description) %> +

+

+ <%= f.text_field :name, + :required => true, + :size => 60, + :style => "width:490px;", + :maxlength => Contest::NAME_LENGTH_LIMIT, + :placeholder => "#{l(:label_contest_name)}" + %> +

-

<%= f.text_area :description, :rows => 5, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => Contest::DESCRIPTION_LENGTH_LIMIT, :placeholder => "#{l(:label_contest_description)}" %>

+

+ <%= f.text_area :description, + :rows => 5, + :class => 'wiki-edit', + :style => "font-size:small;width:490px;margin-left:10px;", + :maxlength => Contest::DESCRIPTION_LENGTH_LIMIT, + :placeholder => "#{l(:label_contest_description)}" + %> +

-

<%= f.text_field :password, :size => 60, :style => "width:488px;margin-left: 10px;" %>

+

+ <%= f.text_field :password, + :size => 60, + :style => "width:488px;margin-left: 10px;" + %> +

- <%= f.text_area :budget, :required => true, :size => 60,:rows => 4,:maxlength => Contest::DESCRIPTION_LENGTH_LIMIT, :style => "width:490px;", :placeholder => l(:label_bids_reward_what) %> + <%= f.text_area :budget, + :required => true, + :size => 60, + :rows => 4, + :maxlength => Contest::DESCRIPTION_LENGTH_LIMIT, + :style => "width:490px;", + :placeholder => l(:label_bids_reward_what) + %>

-

<%= f.text_field :deadline, :required => true, :size => 60, :style => "width:150px;", :placeholder => "#{l(:label_deadline)}" %><%= calendar_for('contest_deadline')%>

+

+ <%= f.text_field :deadline, + :required => true, + :size => 60, + :style => "width:150px;", + :placeholder => "#{l(:label_deadline)}" + %> + <%= calendar_for('contest_deadline')%> +

diff --git a/app/views/contests/_history.html.erb b/app/views/contests/_history.html.erb index 6be572c65..f59bc0fc7 100644 --- a/app/views/contests/_history.html.erb +++ b/app/views/contests/_history.html.erb @@ -11,36 +11,66 @@
    <% for journal in journals%>
  • - <%= image_tag(url_to_avatar(journal.user), :class => "avatar") %> - - <%= link_to journal.user, user_path(journal.user)%> - <% label = l(:label_contest_requirement) %> -
    <%= textilizable journal.notes%>
    - <%= l(:label_bids_published) %> <%= time_tag(journal.created_on).html_safe %> <%= l(:label_bids_published_ago) %> - - <% ids = 'project_respond_form_'+ journal.id.to_s%> - - - <% if reply_allow %> - <%#= link_to(l(:button_quote), {:controller => 'contests', :action => 'new', :id => contest, :journal_id => journal}, :remote => true, :method => 'post', :title => l(:button_quote))%> - <%= link_to(l(:button_quote), contests_path(:id => contest, :journal_id => journal), :remote => true, :method => 'post', :title => l(:button_quote))%> - <%= link_to l(:label_bid_respond_quote),'', - {:focus => 'project_respond', :onclick => "toggleAndSettingWordsVal($('##{ids}'), $('##{ids} textarea'), '#{l(:label_reply_plural)} #{journal.user.show_name}: '); $('##{ids} textarea') ;return false;"}%> - <% end %> - - <% if @user==User.current|| User.current.admin? %> - <%#= link_to(l(:label_bid_respond_delete), {:controller => 'bids', :action => 'destroy', :object_id => journal, :id => bid},:confirm => l(:label_delete_confirm), - :remote => true, :method => 'delete', :class => "delete", :confirm => l(:text_are_you_sure), :title => l(:button_delete)) %> - <%= link_to(l(:label_bid_respond_delete), {:controller => 'words', :action => 'destroy', :object_id => journal, :user_id => @user}, :remote => true, :confirm => l(:text_are_you_sure), :method => 'delete', :class => "delete", :title => l(:button_delete)) %> - <% end %> - -
    + + <%= image_tag(url_to_avatar(journal.user), :class => "avatar") %> + + + + <%= link_to journal.user, user_path(journal.user)%> + + + <% label = l(:label_contest_requirement) %> + +
    <%= textilizable journal.notes%>
    + + <%= l(:label_bids_published) %>  + <%= time_tag(journal.created_on).html_safe %>  + <%= l(:label_bids_published_ago) %> + + + <% ids = 'project_respond_form_'+ journal.id.to_s%> + + + <% if reply_allow %> + <%#= link_to(l(:button_quote), {:controller => 'contests', :action => 'new', :id => contest, :journal_id => journal}, :remote => true, :method => 'post', :title => l(:button_quote))%> + <%= link_to(l(:button_quote), + contests_path(:id => contest, + :journal_id => journal), + :remote => true, + :method => 'post', + :title => l(:button_quote)) + %> + <%= link_to l(:label_bid_respond_quote), + '', + {:focus => 'project_respond', + :onclick => "toggleAndSettingWordsVal($('##{ids}'), $('##{ids} textarea'), '#{l(:label_reply_plural)} #{journal.user.show_name}: '); $('##{ids} textarea') ;return false;" + } + %> + <% end %> + + <% if @user==User.current|| User.current.admin? %> + <%#= link_to(l(:label_bid_respond_delete), {:controller => 'bids', :action => 'destroy', :object_id => journal, :id => bid},:confirm => l(:label_delete_confirm), + :remote => true, :method => 'delete', :class => "delete", :confirm => l(:text_are_you_sure), :title => l(:button_delete)) %> + + <%= link_to(l(:label_bid_respond_delete), + + words_destroy_path(:user_id => @user, :object_id => journal), + :remote => true, + :confirm => l(:text_are_you_sure), + :method => 'delete', + :class => "delete", + :title => l(:button_delete)) %> + <% end %> + +
    <% ids = 'project_respond_form_'+ journal.id.to_s%> <% if reply_allow %>
    - <%= render :partial => 'words/new_respond', :locals => {:journal => journal, :m_reply_id => journal} %> + <%= render :partial => 'words/new_respond', + :locals => {:journal => journal, :m_reply_id => journal} + %>
    <% end %>
    diff --git a/app/views/contests/_list_projects.html.erb b/app/views/contests/_list_projects.html.erb index 10086e5a3..fec4cf24c 100644 --- a/app/views/contests/_list_projects.html.erb +++ b/app/views/contests/_list_projects.html.erb @@ -26,8 +26,9 @@
- <%= l(:label_system_grade) %>:<%= (c_project.project.project_status.nil? ? 0.0 : c_project.project.project_status.grade) unless (c_project.project.project_status.nil? && c_project.project.nil?) %> - <% if get_prize(c_project).nil? or get_prize(c_project) == "" %> + <%= l(:label_system_grade) %>: + <%= (c_project.project.project_status.nil? ? 0.0 : c_project.project.project_status.grade) unless (c_project.project.project_status.nil? && c_project.project.nil?) %> + <% if get_prize(c_project).nil? || get_prize(c_project) == "" %> <% if @contest.deadline < Date.today %> <%= l(:label_noawards)%> <% end %> diff --git a/app/views/contests/_list_softapplications.html.erb b/app/views/contests/_list_softapplications.html.erb index 89e8a3172..40a6f1cb2 100644 --- a/app/views/contests/_list_softapplications.html.erb +++ b/app/views/contests/_list_softapplications.html.erb @@ -6,7 +6,10 @@
<%=l(:label_softapplication)%>: - <%= link_to(c_softapplication.softapplication.name, softapplication_path(c_softapplication.softapplication), :target => '_blank') %> + <%= link_to(c_softapplication.softapplication.name, + softapplication_path(c_softapplication.softapplication), + :target => '_blank') + %>
- + + + +
<%= f.text_area 'message', :rows => 3, :cols => 65, :placeholder => l(:label_my_respond), :style => "resize: none;", :class => 'noline'%> + <%= f.text_area 'message', + :rows => 3, + :cols => 65, + :placeholder => l(:label_my_respond), + :style => "resize: none;", + :class => 'noline' + %> +
@@ -39,8 +50,23 @@ - + + +
<%= submit_tag l(:button_leave_meassge), :name => nil , :class => "contest_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'"%> - <%= submit_tag l(:button_clear_meassge), :name => nil, :onclick => "clearMessage('contest_message_message');", :type => 'button', :class => "bid_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'" %> + <%= submit_tag l(:button_leave_meassge), + :name => nil , + :class => "contest_btn", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -31px'" + %> + <%= submit_tag l(:button_clear_meassge), + :name => nil, + :onclick => "clearMessage('contest_message_message');", + :type => 'button', :class => "bid_btn", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -31px'" + %> +
diff --git a/app/views/contests/_new_join.html.erb b/app/views/contests/_new_join.html.erb index 3b0cff690..fc638d218 100644 --- a/app/views/contests/_new_join.html.erb +++ b/app/views/contests/_new_join.html.erb @@ -50,8 +50,17 @@ <%= text_field_tag 'contest_password', nil, :size => 45 %>

- <%= submit_tag l(:label_new_join), :name => nil, :class => "contest_btn", :onclick => "hideModal(this);" %> - <%= submit_tag l(:button_cancel), :name => nil, :class => "contest_btn", :onclick => "hideModal(this);", :type => 'button' %> + <%= submit_tag l(:label_new_join), + :name => nil, :class => "contest_btn", + :onclick => "hideModal(this);" + %> + <%= submit_tag l(:button_cancel), + :name => nil, + :class => "contest_btn", + :onclick => "hideModal(this);", + :type => 'button' + %> +

<% end %> diff --git a/app/views/contests/_new_softapplication.html.erb b/app/views/contests/_new_softapplication.html.erb index e8b0a32cd..71e5d0568 100644 --- a/app/views/contests/_new_softapplication.html.erb +++ b/app/views/contests/_new_softapplication.html.erb @@ -1,184 +1,232 @@ -<%#= error_messages_for 'softapplication' %> - - - -<%= form_for Softapplication.new, :url => softapplications_path do |f| %> -
- <%= hidden_field_tag 'contest_id', @contest.id %> -
<%= f.text_field :name, :required => true, :size => 60, :style => "width:320px;", :onblur => "regexName();" %>
- <%= f.text_field :android_min_version_available, :required => true, :size => 60, :style => "width:320px;", :onblur=>"regexWorkdescription();"%> -
- - <%#= select_tag 'app_type_name', work_type_opttion, {:name => 'app_type_name',:style => "width:358px;"} %> - - <%= f.select :app_type_name,work_type_opttion, {},{:style => "width:328px;",:onchange => "selectChange(this)"} %> - <%#= f.text_field :app_type_name, :required => true, :size => 60, :style => "width:400px;" %> -
<%= f.text_field :description, :required => true, :size => 60, :style => "width:320px;" %>
<%= f.text_field :application_developers, :required => true, :size => 60, :style => "width:320px;", :onblur => 'regexDevelopers();' %>
+ <%= f.text_field :name, + :required => true, + :size => 60, + :style => "width:320px;", + :onblur => "regexName();" + %> +
+ <%= f.text_field :android_min_version_available, + :required => true, + :size => 60, + :style => "width:320px;", + :onblur=>"regexWorkdescription();" + %> +
+ + <%#= select_tag 'app_type_name', work_type_opttion, {:name => 'app_type_name',:style => "width:358px;"} %> + + <%= f.select :app_type_name,work_type_opttion, + {}, + {:style => "width:328px;",:onchange => "selectChange(this)"} %> + <%#= f.text_field :app_type_name, :required => true, :size => 60, :style => "width:400px;" %> +
+ <%= f.text_field :description, + :required => true, + :size => 60, + :style => "width:320px;" + %> +
+ <%= f.text_field :application_developers, + :required => true, + :size => 60, + :style => "width:320px;", + :onblur => 'regexDevelopers();' + %> +
<%= textilizable content %>
<%= hidden_field_tag 'reference_content', params[:reference_content], :value => content%> + <%= hidden_field_tag 'reference_content', + params[:reference_content], + :value => content + %> +
<% end %> diff --git a/app/views/contests/_project_list.html.erb b/app/views/contests/_project_list.html.erb index 325e87105..33e884020 100644 --- a/app/views/contests/_project_list.html.erb +++ b/app/views/contests/_project_list.html.erb @@ -2,7 +2,9 @@ <%= render_flash_messages %> - + <% if User.current.logged? %>
<%= l(:label_bidding_project) %>(<%= contesting_project.count%>) + <%= l(:label_bidding_project) %>(<%= contesting_project.count%>) +
@@ -12,4 +14,6 @@ <% end %>
-<%= render :partial=> "list_projects",:locals => {:contesting_project => contesting_project,:contest => @contest }%> +<%= render :partial=> "list_projects", + :locals => {:contesting_project => contesting_project,:contest => @contest } +%> diff --git a/app/views/contests/_softapplication_list.html.erb b/app/views/contests/_softapplication_list.html.erb index e5d030123..d93923d72 100644 --- a/app/views/contests/_softapplication_list.html.erb +++ b/app/views/contests/_softapplication_list.html.erb @@ -2,14 +2,23 @@ <%= render_flash_messages %> - + <% if User.current.logged? %> <% end %>
<%= l(:label_contest_softapplication) %>(<%= @contest.contesting_softapplications.count%>) + <%= l(:label_contest_softapplication) %> + (<%= @contest.contesting_softapplications.count%>) +
- <%= link_to l(:button_contesting_as_application), "javascript:void(0);", onclick: "$('#put-bid-form').toggle();" %> + <%= link_to l(:button_contesting_as_application), + "javascript:void(0);", + onclick: "$('#put-bid-form').toggle();" + %>
-<%= render :partial=> "list_softapplications",:locals => {:contesting_softapplication => contesting_softapplication,:contest => @contest }%> +<%= render :partial=> "list_softapplications", + :locals => {:contesting_softapplication => contesting_softapplication, + :contest => @contest } +%> diff --git a/app/views/contests/index.html.erb b/app/views/contests/index.html.erb index 6f8430ca0..60608fd89 100644 --- a/app/views/contests/index.html.erb +++ b/app/views/contests/index.html.erb @@ -6,22 +6,44 @@
<%= l(:label_user_location) %> : <% if User.current.logged? %> - <% unless User.current.user_extensions.identity == 1 %> - <%= link_to(l(:label_newtype_contest), {:controller => 'contests', :action => 'new_contest'}, :class => 'icon icon-add', :target => "_blank") %> - <% end %> + <% unless User.current.user_extensions.identity == 1 %> + + <%= link_to(l(:label_newtype_contest), contest_new_contest_path, :class => 'icon icon-add', :target => "_blank") %> + + <% end %> <% end %>
<%= link_to request.host()+"/contests", :controller => 'contests', :action => 'index' %> <%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_contest_innovate), :controller => 'contests', :action => 'index' %> + + + <%= link_to request.host()+"/contests", contests_path %> + + + + <%=link_to l(:field_homepage), home_path %> > + + <%=link_to l(:label_contest_innovate), :controller => 'contests', :action => 'index' %> + +
<% end %> diff --git a/app/views/contests/new_contest.html.erb b/app/views/contests/new_contest.html.erb index 7366b4203..019c8c1db 100644 --- a/app/views/contests/new_contest.html.erb +++ b/app/views/contests/new_contest.html.erb @@ -1,10 +1,12 @@

<%=l(:label_newtype_contest)%>

-<%= labelled_form_for @contest, :url => {:controller => 'contests', :action => 'create_contest'}, method: :post do |f| %> +<%= labelled_form_for @contest, + :url => {:controller => 'contests', :action => 'create_contest'}, + method: :post do |f| %>
- <%= render :partial => 'form_contest', :locals => { :f => f } %> - <%= submit_tag l(:button_create) %> - <%= javascript_tag "$('#bid_name').focus();" %> - <% end %> + <%= render :partial => 'form_contest', :locals => { :f => f } %> + <%= submit_tag l(:button_create) %> + <%= javascript_tag "$('#bid_name').focus();" %> + <% end %>
\ No newline at end of file diff --git a/app/views/contests/set_reward_project.js.erb b/app/views/contests/set_reward_project.js.erb index c0de3e2ef..2ea06abb1 100644 --- a/app/views/contests/set_reward_project.js.erb +++ b/app/views/contests/set_reward_project.js.erb @@ -1,26 +1,27 @@ + $('#reward_result_<%= @contesting_project_id %>').html('<%= j( -if get_prize(@c_p).nil? or get_prize(@c_p) == "" +if get_prize(@c_p).nil? || get_prize(@c_p) == "" if @contest.deadline < Date.today puts '未评奖' end else case get_prize(@c_p) - when '-1' - image_tag("/images/bid/special_reward.png") - when '0' - image_tag("/images/bid/first_reward.png") - when '1' - image_tag("/images/bid/second_reward.png") - when '2' - image_tag("/images/bid/third_reward.png") - when '3' - image_tag("/images/bid/forth_reward.png") - when '4' - image_tag("/images/bid/fifth_reward.png") - when '5' - image_tag("/images/bid/qualified.png") + when '-1' + image_tag("/images/bid/special_reward.png") + when '0' + image_tag("/images/bid/first_reward.png") + when '1' + image_tag("/images/bid/second_reward.png") + when '2' + image_tag("/images/bid/third_reward.png") + when '3' + image_tag("/images/bid/forth_reward.png") + when '4' + image_tag("/images/bid/fifth_reward.png") + when '5' + image_tag("/images/bid/qualified.png") end end diff --git a/app/views/contests/set_reward_softapplication.js.erb b/app/views/contests/set_reward_softapplication.js.erb index a8cf0d486..2906d95d3 100644 --- a/app/views/contests/set_reward_softapplication.js.erb +++ b/app/views/contests/set_reward_softapplication.js.erb @@ -1,26 +1,28 @@ + $('#reward_result_<%= @contesting_softapplication_id %>').html('<%= j( -if get_prize(@c_sa).nil? or get_prize(@c_sa) == "" + +if get_prize(@c_sa).nil? || get_prize(@c_sa) == "" if @contest.deadline < Date.today puts '未评奖' end else case get_prize(@c_sa) - when '-1' - image_tag("/images/bid/special_reward.png") - when '0' - image_tag("/images/bid/first_reward.png") - when '1' - image_tag("/images/bid/second_reward.png") - when '2' - image_tag("/images/bid/third_reward.png") - when '3' - image_tag("/images/bid/forth_reward.png") - when '4' - image_tag("/images/bid/fifth_reward.png") - when '5' - image_tag("/images/bid/qualified.png") + when '-1' + image_tag("/images/bid/special_reward.png") + when '0' + image_tag("/images/bid/first_reward.png") + when '1' + image_tag("/images/bid/second_reward.png") + when '2' + image_tag("/images/bid/third_reward.png") + when '3' + image_tag("/images/bid/forth_reward.png") + when '4' + image_tag("/images/bid/fifth_reward.png") + when '5' + image_tag("/images/bid/qualified.png") end end diff --git a/app/views/contests/settings.html.erb b/app/views/contests/settings.html.erb index a2780f060..4f8b8b0f2 100644 --- a/app/views/contests/settings.html.erb +++ b/app/views/contests/settings.html.erb @@ -1,6 +1,7 @@

-

<%=l(:label_contest_settings)%><%=l(:label_contest_settings)%> <%= image_tag(url_to_avatar(user), :class => "avatar") %> - - + - <%= l(:label_work_name) %> - * : - (<%= l(:label_workname_lengthlimit) %>) -
-
-
- - - <%= l(:label_running_platform) %> - * : - (<%= l(:label_workdescription_lengthlimit) %>) - -
-
-
- - - <%= l(:label_work_type) %> - * : - - -
-
-
- - - <%= l(:label_work_description) %> - * : - - -
-
-
- - - <%= l(:label_softapplication_developers) %> - * : - (<%= l(:label_workdescription_lengthlimit) %>) - -
-
-
- - - <%= l(:label_work_deposit_project) %>: - <%= select_tag 'project', options_for_select(select_option_helper(@option),@softapplication.project_id), :name => 'project', :class => 'grayline3' %> - <%#= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target=>'_blank'%> - -
-
-
- - - -
-

- <% options = {:author => true, :deletable => true} %> - - <%= render :partial => 'attachments/links', - :locals => {:attachments => @softapplication.attachments, :options => options} %> - -

- <%=l(:label_upload_softworkpacket_photo)%> - <%= render_flash_messages %> -

- <%= render :partial => 'attachments/form' %> -

-

1、<%=l(:label_upload_softapplication_packets_mustpacketed)%>
2、<%=l(:label_upload_softapplication_photo_condition)%>

- - -
-
-
<%= submit_tag l(:button_create), :onclick => "return true" %>
-<% end %> - + +<%= form_for(softapplication) do |f| %> + + <% if softapplication.errors.any? %> +
+

<%= pluralize(softapplication.errors.count, "error") %> prohibited this softapplication from being saved:

+ +
    + <% softapplication.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+
+ <% end %> +
+ +
+ <%= l(:label_work_name) %> + * : + (<%= l(:label_workname_lengthlimit) %>) +
+
+
+ + + <%= l(:label_running_platform) %> + * : + (<%= l(:label_workdescription_lengthlimit) %>) + +
+
+
+ + + <%= l(:label_work_type) %> + * : + + +
+
+
+ + + <%= l(:label_work_description) %> + * : + + +
+
+
+ + + <%= l(:label_softapplication_developers) %> + * : + (<%= l(:label_workdescription_lengthlimit) %>) + +
+
+
+ + + <%= l(:label_work_deposit_project) %>: + <%= select_tag 'project', options_for_select(select_option_helper(@option),@softapplication.project_id), :name => 'project', :class => 'grayline3' %> + <%#= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target=>'_blank'%> + +
+
+
+ + + +
+

+ <% options = {:author => true, :deletable => true} %> + + <%= render :partial => 'attachments/links', + :locals => {:attachments => @softapplication.attachments, :options => options} %> + +

+ <%=l(:label_upload_softworkpacket_photo)%> + <%= render_flash_messages %> +

+ <%= render :partial => 'attachments/form' %> +

+

1、<%=l(:label_upload_softapplication_packets_mustpacketed)%>
2、<%=l(:label_upload_softapplication_photo_condition)%>

+ + +
+
+
<%= submit_tag l(:button_create), :onclick => "return true" %>
+<% end %> + diff --git a/app/views/tags/_show_contests.html.erb b/app/views/tags/_show_contests.html.erb index bc2682fb8..4eded773a 100644 --- a/app/views/tags/_show_contests.html.erb +++ b/app/views/tags/_show_contests.html.erb @@ -1,15 +1,15 @@ -
- <% if contests_results.try(:size).to_i > 0 %> -
- <% contests_results.each do |contest| %> -

- <%= l(:label_tags_contest) %>:<%= link_to "#{contest.name}", - :controller => "contests",:action => "show",:id => contest.id %> -
- <%= l(:label_tags_contest_description) %>:<%= contest.description %> - <%= contest.updated_on %> -

-
- <% end %> - <% end %> -
+
+ <% if contests_results.try(:size).to_i > 0 %> +
+ <% contests_results.each do |contest| %> +

+ <%= l(:label_tags_contest) %>:<%= link_to "#{contest.name}", + :controller => "contests",:action => "show_contest",:id => contest.id %> +
+ <%= l(:label_tags_contest_description) %>:<%= contest.description %> + <%= contest.updated_on %> +

+
+ <% end %> + <% end %> +
diff --git a/app/views/users/_score_new_index.html.erb b/app/views/users/_score_new_index.html.erb index 733088067..e50b240fd 100644 --- a/app/views/users/_score_new_index.html.erb +++ b/app/views/users/_score_new_index.html.erb @@ -1,14 +1,14 @@ - -<% option_num = get_option_number(@user,1) %> -
<%= l(:label_user_score) %>
-
= <%= l(:label_user_score_of_collaboration) %> + <%= l(:label_user_score_of_influence) %> + - <%= l(:label_user_score_of_skill)%> + <%= l(:label_user_score_of_active) %>
- -
= <%= format("%.2f" ,collaboration(option_num)).to_i %> + <%= format("%.2f" , influence(option_num) ).to_i %> - + <%= "(" if skill(option_num) < 0 %> <%= format("%.2f" , skill(option_num)).to_i %> <%= ")" if skill(option_num) < 0 %> + <%= format("%.2f" , active(option_num)).to_i %>
- <% if (format("%.2f" ,collaboration(option_num)).to_i + format("%.2f" , influence(option_num) ).to_i + format("%.2f" , skill(option_num)).to_i + format("%.2f" , active(option_num)).to_i) < 0 %> -
<%= l(:label_score_less_than_zero) %>
- <% else %> -
= <%= format("%.2f" ,option_num.total_score).to_i %>
- <% end %> - + +<% option_num = get_option_number(@user,1) %> +
<%= l(:label_user_score) %>
+
= <%= l(:label_user_score_of_collaboration) %> + <%= l(:label_user_score_of_influence) %> + + <%= l(:label_user_score_of_skill)%> + <%= l(:label_user_score_of_active) %>
+ +
= <%= format("%.2f" ,collaboration(option_num)).to_i %> + <%= format("%.2f" , influence(option_num) ).to_i %> + + <%= "(" if skill(option_num) < 0 %> <%= format("%.2f" , skill(option_num)).to_i %> <%= ")" if skill(option_num) < 0 %> + <%= format("%.2f" , active(option_num)).to_i %>
+ <% if (format("%.2f" ,collaboration(option_num)).to_i + format("%.2f" , influence(option_num) ).to_i + format("%.2f" , skill(option_num)).to_i + format("%.2f" , active(option_num)).to_i) < 0 %> +
<%= l(:label_score_less_than_zero) %>
+ <% else %> +
= <%= format("%.2f" ,option_num.total_score).to_i %>
+ <% end %> + diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 068390192..551f7e724 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -1,424 +1,336 @@ -<% if User.current.id == @user.id %> - - <%#= show_activity @state%> -
- - - - - - <%= form_tag(:controller => 'users', :action => "show") do %> -
<%= content_tag "div", link_to_user(user), :class => "project_avatar_name" %> + + + <%= content_tag "div", link_to_user(user), :class => "project_avatar_name" %> +

<% unless user.memberships.empty? %> diff --git a/app/views/contests/show_participator.html.erb b/app/views/contests/show_participator.html.erb index da51aef3a..9c829b9f2 100644 --- a/app/views/contests/show_participator.html.erb +++ b/app/views/contests/show_participator.html.erb @@ -1,5 +1,9 @@ -

<%=link_to l(:label_x_join_in_contest, :count => @contest.join_in_contests.count)+"("+@contest.join_in_contests(@user.id).count.to_s+")", :controller=>"contests", :action=>"show_participator"%>

+

+ <%=link_to l(:label_x_join_in_contest, :count => @contest.join_in_contests.count)+"("+@contest.join_in_contests(@user.id).count.to_s+")", + show_participator_contest_path + %> +

<% for temp in @contest.join_in_contests %> <% user = temp.user %> diff --git a/app/views/contests/show_project.html.erb b/app/views/contests/show_project.html.erb index 3e759cfc1..84dfbbbc2 100644 --- a/app/views/contests/show_project.html.erb +++ b/app/views/contests/show_project.html.erb @@ -60,15 +60,28 @@ <% end %>
- <%= render :partial => 'project_list', :locals => {:contesting_project => @contesting_project,:contest => @contest} %> + <%= render :partial => 'project_list', + :locals => {:contesting_project => @contesting_project,:contest => @contest} + %>
diff --git a/app/views/contests/show_softapplication.html.erb b/app/views/contests/show_softapplication.html.erb index d12a70e35..7bb4b0231 100644 --- a/app/views/contests/show_softapplication.html.erb +++ b/app/views/contests/show_softapplication.html.erb @@ -60,15 +60,29 @@

<%= link_to h(forum.name), forum_path(forum) %>

-

<%= forum.description%>

+

<%= textAreailizable forum.description%>

<%= authoring forum.created_at, forum.creator %>

diff --git a/app/views/forums/show.html.erb b/app/views/forums/show.html.erb index 1622bbe02..4cd6631c2 100644 --- a/app/views/forums/show.html.erb +++ b/app/views/forums/show.html.erb @@ -1,56 +1,44 @@ - - - -<% #= link_to '发布帖子', new_forum_memo_path(@forum), :class => 'icon icon-add' %> - - <%= link_to( - image_tag('edit.png')+l(:label_forum_edit), - {:action => 'edit', :id => @forum}, - :method => 'get', - :title => l(:button_edit) - ) if @forum.editable_by?(User.current) %> - <%= link_to( - image_tag('delete.png')+'删除讨论区', - {:action => 'destroy', :id => @forum}, - :method => :delete, - :data => {:confirm => l(:text_are_you_sure)}, - :title => l(:button_delete) - ) if @forum.destroyable_by?(User.current) %> - - - <%= link_to l(:label_memo_new_from_forum), new_forum_memo_path(@forum), :class => 'icon icon-add', - :onclick => 'showAndScrollTo("add-memo", "memo_subject"); return false;' if User.current.logged? %> - - - -<%= render :partial => 'forums/show_topics', :locals => {:memos => @memos} %> + + + +<% #= link_to '发布帖子', new_forum_memo_path(@forum), :class => 'icon icon-add' %> + + <%= link_to( + image_tag('edit.png')+l(:label_forum_edit), + {:action => 'edit', :id => @forum}, + :method => 'get', + :title => l(:button_edit) + ) if @forum.editable_by?(User.current) %> + <%= link_to( + image_tag('delete.png')+'删除讨论区', + {:action => 'destroy', :id => @forum}, + :method => :delete, + :data => {:confirm => l(:text_are_you_sure)}, + :title => l(:button_delete) + ) if @forum.destroyable_by?(User.current) %> + + + <%= link_to l(:label_memo_new_from_forum), new_forum_memo_path(@forum), :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-memo", "memo_subject"); return false;' if User.current.logged? %> + + + +<%= render :partial => 'forums/show_topics', :locals => {:memos => @memos} %> diff --git a/app/views/layouts/base_contest.html.erb b/app/views/layouts/base_contest.html.erb index 0f2f4cf96..740016ff8 100644 --- a/app/views/layouts/base_contest.html.erb +++ b/app/views/layouts/base_contest.html.erb @@ -1,235 +1,235 @@ -<% - @nav_dispaly_contest_label = 1 - @nav_dispaly_store_all_label = 1 -%> - - - - - <%= h html_title %> - - - <%= csrf_meta_tag %> - <%= favicon %> - <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', :media => 'all' %> - <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> - <%= javascript_heads %> - <%= heads_for_theme %> - <%= call_hook :view_layouts_base_html_head %> - - <%= yield :header_tags -%> - - -
-
-
- <%=render :partial => 'layouts/base_header'%> -
- -
-
<%= link_to (forum.memo_count), forum_path(forum) %><%= link_to (forum.topic_count), forum_path(forum) %>
- - - - - - - - - -
<%=l(:label_contest_innovate_community)%><%= l(:label_user_location) %> : - -
<%=link_to request.host()+"/contest", :controller => 'bids', :action => 'contest' %><%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_contest_innovate), :controller => 'bids', :action => 'contest' %> > - <%= link_to @bid.name, bid_path %>
-
- - - -
- <% if display_main_menu?(@bid) %> -
- <%= render_menu :bid_menu %> -
- <% end %> - - <%= yield %> - <%= call_hook :view_layouts_base_content %> -
-
- <%=render :partial => 'layouts/base_footer'%> -
- - - - - - - - <%= call_hook :view_layouts_base_body_bottom %> - - +<% + @nav_dispaly_contest_label = 1 + @nav_dispaly_store_all_label = 1 +%> + + + + + <%= h html_title %> + + + <%= csrf_meta_tag %> + <%= favicon %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', :media => 'all' %> + <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> + <%= javascript_heads %> + <%= heads_for_theme %> + <%= call_hook :view_layouts_base_html_head %> + + <%= yield :header_tags -%> + + +
+
+
+ <%=render :partial => 'layouts/base_header'%> +
+ +
+ + + + + + + + + + +
<%=l(:label_contest_innovate_community)%><%= l(:label_user_location) %> : + +
<%=link_to request.host()+"/contest", :controller => 'bids', :action => 'contest' %><%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_contest_innovate), :controller => 'bids', :action => 'contest' %> > + <%= link_to @bid.name, bid_path %>
+
+ + + +
+ <% if display_main_menu?(@bid) %> +
+ <%= render_menu :bid_menu %> +
+ <% end %> + + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
+
+ <%=render :partial => 'layouts/base_footer'%> +
+
+
+ + + + +
+ <%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base_forums.html.erb b/app/views/layouts/base_forums.html.erb index ef376c2ec..d8a0b0a69 100644 --- a/app/views/layouts/base_forums.html.erb +++ b/app/views/layouts/base_forums.html.erb @@ -1,97 +1,99 @@ -<% @nav_dispaly_home_path_label = 1 - @nav_dispaly_main_course_label = 1 - @nav_dispaly_main_project_label = 1 - @nav_dispaly_main_contest_label = 1 %> -<% @nav_dispaly_forum_label = 1%> - - - - - <%= h html_title %> - - - <%= csrf_meta_tag %> - <%= favicon %> - <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> - <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> - <%= javascript_heads %> - <%= heads_for_theme %> - <%= javascript_include_tag "ckeditor/ckeditor.js" %> - <%= call_hook :view_layouts_base_html_head %> - <%= yield :header_tags -%> - - -
-
-
- <%=render :partial => 'layouts/base_header'%> -
-
- - - - - - - - - - -
软件项目托管社区<%= l(:label_user_location) %> : - -
<%= link_to request.host()+"/forums", forums_path %>

<%=link_to l(:label_home),home_path %> > <%=link_to '公共贴吧', :controller => 'forums', :action => 'index' %> > <%=link_to @forum.name, forum_path(@forum) %>

-
- -
- - <%= render_flash_messages %> - <%= yield %> - <%= call_hook :view_layouts_base_content %> -
- -
- <%= render :partial => 'layouts/base_footer'%> -
- - -
-
-
- <%= call_hook :view_layouts_base_body_bottom %> - - - +<% @nav_dispaly_home_path_label = 1 + @nav_dispaly_main_course_label = 1 + @nav_dispaly_main_project_label = 1 + @nav_dispaly_main_contest_label = 1 %> +<% @nav_dispaly_forum_label = 1%> + + + + + <%= h html_title %> + + + <%= csrf_meta_tag %> + <%= favicon %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> + <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> + <%= javascript_heads %> + <%= heads_for_theme %> + <%= javascript_include_tag "ckeditor/ckeditor.js" %> + <%= call_hook :view_layouts_base_html_head %> + <%= yield :header_tags -%> + + +
+
+
+ <%=render :partial => 'layouts/base_header'%> +
+
+ + + + + + + + + + +
软件项目托管社区<%= l(:label_user_location) %> : + +
<%= link_to request.host()+"/forums", forums_path %>

<%=link_to l(:label_home),home_path %> > <%=link_to '公共贴吧', :controller => 'forums', :action => 'index' %> > <%=link_to @forum.name, forum_path(@forum) %>

+
+ +
+ + <%= render_flash_messages %> + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
+ +
+ <%= render :partial => 'layouts/base_footer'%> +
+ + +
+
+
+ <%= call_hook :view_layouts_base_body_bottom %> + + + diff --git a/app/views/layouts/base_memos.html.erb b/app/views/layouts/base_memos.html.erb index 875fbd4fc..fdce1cc83 100644 --- a/app/views/layouts/base_memos.html.erb +++ b/app/views/layouts/base_memos.html.erb @@ -63,11 +63,16 @@
<%= image_tag(url_to_avatar(@forum.creator), :class => 'vatar-size') %> - <%=link_to @forum.creator.name, user_path(@forum.creator) %> -
- <%= link_to l(:label_user_watcher)+"("+User.watched_by(@forum.creator.id).count.to_s+")" ,:controller=>"users", :action=>"user_watchlist", :id => @forum.creator.id %> - <%= link_to l(:label_x_user_fans, :count => User.current.watcher_users(User.current.id).count)+"("+@forum.creator.watcher_users(@forum.creator.id).count.to_s+")", :controller=>"users", :action=>"user_fanslist", :id => @forum.creator.id %>
-
+ + <% unless @forum.creator.nil? %> + <%=link_to @forum.creator.name, user_path(@forum.creator) %> +
+ <%= link_to l(:label_user_watcher)+"("+User.watched_by(@forum.creator.id).count.to_s+")" ,:controller=>"users", :action=>"user_watchlist", :id => @forum.creator.id %> + <%= link_to l(:label_x_user_fans, :count => User.current.watcher_users(User.current.id).count)+"("+@forum.creator.watcher_users(@forum.creator.id).count.to_s+")", :controller=>"users", :action=>"user_fanslist", :id => @forum.creator.id %> +
+
+ <% end %> +
<% if User.current.logged? || User.current.admin? %> diff --git a/app/views/layouts/base_newcontest.html.erb b/app/views/layouts/base_newcontest.html.erb index 9dfb4a5dd..9fef1e3e6 100644 --- a/app/views/layouts/base_newcontest.html.erb +++ b/app/views/layouts/base_newcontest.html.erb @@ -1,245 +1,240 @@ -<% - @nav_dispaly_contest_label = 1 - @nav_dispaly_store_all_label = 1 -%> - - - - - <%= h html_title %> - - - <%= csrf_meta_tag %> - <%= favicon %> - <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', :media => 'all' %> - <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> - - <%= javascript_heads %> - <%= heads_for_theme %> - <%= call_hook :view_layouts_base_html_head %> - - <%= yield :header_tags -%> - - -
-
-
- <%=render :partial => 'layouts/base_header'%> -
- -
- - - - - - - - - - -
<%=l(:label_contest_innovate_community)%><%= l(:label_user_location) %> : - -
<%=link_to request.host()+"/contests", :controller=>'contests', :action=>'index' %><%=link_to l(:field_homepage), home_path %> > - <%=link_to l(:label_contest_innovate), :controller=>'contests', :action=>'index' %> > - <%= link_to @contest.name, show_contest_contest_path(@contest) %> -
-
- - - - -
- <% if display_main_menu?(@contest) %> -
-
    -
  • <%= link_to l(:label_contest_notification), contest_contestnotifications_path(@contest), :class => link_class(:contestnotifications) %>
  • -
  • <%= link_to l(:label_contest_joincontest), show_attendingcontest_contest_path(@contest), :class => link_class(:attendingcontests) %>
  • -
  • <%= link_to l(:label_contest_userresponse), show_contest_contest_path(@contest), :class => link_class(:respond) %>
  • -
-
- <% end %> - - <%= yield %> - <%= call_hook :view_layouts_base_content %> -
-
- <%=render :partial => 'layouts/base_footer'%> -
-
-
- - - - -
- <%= call_hook :view_layouts_base_body_bottom %> - - +<% + @nav_dispaly_contest_label = 1 + @nav_dispaly_store_all_label = 1 +%> + + + + + <%= h html_title %> + + + <%= csrf_meta_tag %> + <%= favicon %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', :media => 'all' %> + <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> + + <%= javascript_heads %> + <%= heads_for_theme %> + <%= call_hook :view_layouts_base_html_head %> + + <%= yield :header_tags -%> + + +
+
+
+ <%=render :partial => 'layouts/base_header'%> +
+ +
+ + + + + + + + + + +
<%=l(:label_contest_innovate_community)%><%= l(:label_user_location) %> : + +
<%=link_to request.host()+"/contests", :controller=>'contests', :action=>'index' %><%=link_to l(:field_homepage), home_path %> > + <%=link_to l(:label_contest_innovate), :controller=>'contests', :action=>'index' %> > + <%= link_to h(truncate(@contest.name, length: 20, omission: '...')), show_contest_contest_path(@contest) %> +
+
+ + + + +
+ <% if display_main_menu?(@contest) %> +
+
    +
  • <%= link_to l(:label_contest_notification), contest_contestnotifications_path(@contest), :class => link_class(:contestnotifications) %>
  • +
  • <%= link_to l(:label_contest_joincontest), show_attendingcontest_contest_path(@contest), :class => link_class(:attendingcontests) %>
  • +
  • <%= link_to l(:label_contest_userresponse), show_contest_contest_path(@contest), :class => link_class(:respond) %>
  • +
+
+ <% end %> + + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
+
+ <%=render :partial => 'layouts/base_footer'%> +
+
+
+ + + + +
+ <%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/layouts/base_projects.html.erb b/app/views/layouts/base_projects.html.erb index a3b8e267c..8f6d86f29 100644 --- a/app/views/layouts/base_projects.html.erb +++ b/app/views/layouts/base_projects.html.erb @@ -1,165 +1,156 @@ - -<% @nav_dispaly_project_label = 1 - @nav_dispaly_forum_label = 1 %> -<% #@nav_dispaly_project_label = 1 %> - - - - - <%= h html_title %> - - - <%= csrf_meta_tag %> - <%= favicon %> - <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> - <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> - <%= javascript_heads %> - <%= heads_for_theme %> - <%= hubspot_head %> - <%= call_hook :view_layouts_base_html_head %> - - <%= yield :header_tags -%> - - - -
-
-
- <%=render :partial => 'layouts/base_header'%> -
-
- - - - - - - - - - -
软件项目托管社区<%= l(:label_user_location) %> : - -
<%= link_to request.host()+"/projects", :controller => 'projects', :action => 'index', :project_type => 0 %>

<%=link_to l(:label_home),home_path %> > <%=link_to l(:label_project_deposit),:controller => 'projects', :action => 'index', :project_type => 0 %> > <%=link_to @project, project_path(@project) %>

-
- - - - -
-
- <%= render_main_menu(@project) %> -
- <%= render_flash_messages %> - <%= yield %> - <%= call_hook :view_layouts_base_content %> -
-
- <%= render :partial => 'layouts/base_footer'%> -
- - - -
-
- <%= call_hook :view_layouts_base_body_bottom %> -
- - - + +<% @nav_dispaly_project_label = 1 + @nav_dispaly_forum_label = 1 %> +<%#@nav_dispaly_project_label = 1 %> + + + + + <%= h html_title %> + + + <%= csrf_meta_tag %> + <%= favicon %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> + <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> + <%= javascript_heads %> + <%= heads_for_theme %> + <%= hubspot_head %> + <%= call_hook :view_layouts_base_html_head %> + + <%= yield :header_tags -%> + + + +
+
+
+ <%=render :partial => 'layouts/base_header'%> +
+
+ + + + + + + + + + +
软件项目托管社区<%= l(:label_user_location) %> : + +
<%= link_to request.host()+"/projects", :controller => 'projects', :action => 'index', :project_type => 0 %>

<%=link_to l(:label_home),home_path %> > <%=link_to l(:label_project_deposit),:controller => 'projects', :action => 'index', :project_type => 0 %> > <%=link_to @project, project_path(@project) %>

+
+ +
+
+ <%= render_main_menu(@project) %> +
+ <%= render_flash_messages %> + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
+
+ <%= render :partial => 'layouts/base_footer'%> +
+ + + +
+
+ <%= call_hook :view_layouts_base_body_bottom %> +
+ + + diff --git a/app/views/layouts/users_base.html.erb b/app/views/layouts/users_base.html.erb index 97db13193..d98ef3f46 100644 --- a/app/views/layouts/users_base.html.erb +++ b/app/views/layouts/users_base.html.erb @@ -1,50 +1,50 @@ -<% @nav_dispaly_home_path_label = 1 - @nav_dispaly_main_course_label = 1 - @nav_dispaly_main_project_label = 1 - @nav_dispaly_main_contest_label = 1 %> -<% @nav_dispaly_forum_label = 1%> - - - - - <%=h html_title %> - - - <%= csrf_meta_tag %> - <%= favicon %> - <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> - <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> - <%= javascript_heads %> - <%= javascript_include_tag "jquery.leanModal.min" %> - <%= javascript_include_tag 'seems_rateable/jRating', 'seems_rateable/rateable'%> - <%= heads_for_theme %> - <%= call_hook :view_layouts_base_html_head %> - - <%= yield :header_tags -%> - - -
-
-
- <%=render :partial => 'layouts/base_header'%> -
-
- <%= render_flash_messages %> - <%= yield %> - <%= call_hook :view_layouts_base_content %> -
- <%=render :partial => 'layouts/base_footer'%> -
- -
-
- - - - - -
-
- - - +<% @nav_dispaly_home_path_label = 1 + @nav_dispaly_main_course_label = 1 + @nav_dispaly_main_project_label = 1 + @nav_dispaly_main_contest_label = 1 %> +<% @nav_dispaly_forum_label = 1%> + + + + + <%=h html_title %> + + + <%= csrf_meta_tag %> + <%= favicon %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> + <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> + <%= javascript_heads %> + <%= javascript_include_tag "jquery.leanModal.min" %> + <%= javascript_include_tag 'seems_rateable/jRating', 'seems_rateable/rateable'%> + <%= heads_for_theme %> + <%= call_hook :view_layouts_base_html_head %> + + <%= yield :header_tags -%> + + +
+
+
+ <%=render :partial => 'layouts/base_header'%> +
+
+ <%= render_flash_messages %> + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
+ <%=render :partial => 'layouts/base_footer'%> +
+ +
+
+ + + + + +
+
+ + + diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb index c6e5bd686..6581a5b11 100644 --- a/app/views/messages/_form.html.erb +++ b/app/views/messages/_form.html.erb @@ -1,51 +1,40 @@ -<%= error_messages_for 'message' %> -<% replying ||= false %> - -
- - <% unless replying %> -


- <%= f.text_field :subject, :size => 60, :style => "width: 99%;", :id => "message_subject" %> -

- <% else %> -


- <%= f.text_field :subject, :size => 60, :style => "width: 99%;", :id => "message_subject", :readonly => true %> -

- <% end %> -

-<% unless replying %> - <% if @message.safe_attribute? 'sticky' %> - <%= f.check_box :sticky %> <%= label_tag 'message_sticky', l(:label_board_sticky) %> - <% end %> - <% if @message.safe_attribute? 'locked' %> - <%= f.check_box :locked %> <%= label_tag 'message_locked', l(:label_board_locked) %> - <% end %> -<% end %> -

- -<% if !replying && !@message.new_record? && @message.safe_attribute?('board_id') %> -


- <%# modify by nwb%> - <% if @message.project %> - <%= f.select :board_id, boards_options_for_select(@message.project.boards) %> - <% elsif @message.course %> - <%= f.select :board_id, boards_options_for_select(@message.course.boards) %> - <% end %> -

-<% end %> -

-

- <%= text_area :quote,:quote,:style => 'display:none' %> -

-

-<%= label_tag "message_content", l(:description_message_content), :class => "hidden-for-sighted" %> -<%= f.text_area :content, :cols => 80, :rows => 13, :class => 'wiki-edit', :id => 'message_content' %>

- - - -

<%= l(:label_attachment_plural) %>
-<%= render :partial => 'attachments/form_course', :locals => {:container => @message,:isReply => @isReply} %>

-
- - +<%= error_messages_for 'message' %> +<% replying ||= false %> + +
+ + <% unless replying %> +


+ <%= f.text_field :subject, :size => 60, :style => "width: 99%;", :id => "message_subject" %> +

+ <% else %> +


+ <%= f.text_field :subject, :size => 60, :style => "width: 99%;", :id => "message_subject", :readonly => true %> +

+ <% end %> +

+<% unless replying %> + <% if @message.safe_attribute? 'sticky' %> + <%= f.check_box :sticky %> <%= label_tag 'message_sticky', l(:label_board_sticky) %> + <% end %> + <% if @message.safe_attribute? 'locked' %> + <%= f.check_box :locked %> <%= label_tag 'message_locked', l(:label_board_locked) %> + <% end %> +<% end %> +

+

+

+ <%= text_area :quote,:quote,:style => 'display:none' %> +

+

+<%= label_tag "message_content", l(:description_message_content), :class => "hidden-for-sighted" %> +<%= f.text_area :content, :cols => 80, :rows => 13, :class => 'wiki-edit', :id => 'message_content' %>

+ + + +

<%= l(:label_attachment_plural) %>
+<%= render :partial => 'attachments/form_course', :locals => {:container => @message,:isReply => @isReply} %>

+
+ + <%#= wikitoolbar_for 'message_content' %> \ No newline at end of file diff --git a/app/views/praise_tread/_praise_tread.html.erb b/app/views/praise_tread/_praise_tread.html.erb index 696b204f9..5bb7addb2 100644 --- a/app/views/praise_tread/_praise_tread.html.erb +++ b/app/views/praise_tread/_praise_tread.html.erb @@ -1,157 +1,156 @@ - - <% if User.current.logged? %> - <% if horizontal %> - -
- - <% @is_valuate = is_praise_or_tread(obj,user_id)%> - <% if @is_valuate.size > 0 %> - <% @flag = @is_valuate.first.praise_or_tread %> - <% if @flag == 1 %> - - - - - - -
<%= image_tag "/images/praise_tread/praise_false.png" , weight:"22px", height:"22px",:title => l(:label_issue_praise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_appraise_over) %>
- - <% elsif @flag == 0 %> - - - - - - - -
<%= image_tag "/images/praise_tread/praise_false.png",weight:"22px", height:"22px", :title => l(:label_issue_appraise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_tread_over) %>
- <% end %> - - <% else %> - - <% if user_id == obj.author_id %> - - - - - - -
<%= image_tag "/images/praise_tread/praise_true.png" , weight:"22px", height:"22px",:title => l(:label_issue_not_praise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_not_treed_over) %>
- <% else %> - - <% if OptionNumber.get_user_option_number(user_id).nil? || OptionNumber.get_user_option_number(user_id).total_score < 2 %> - - - - - - -
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), - :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issues_score_not_enough) %>
- <% else %> - - - - - - -
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), - :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %> <%= get_praise_num(obj)%> <%= link_to image_tag("/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_tread)),:controller=>"praise_tread", - :action=>"tread_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %>
- <% end %> - - <% end %> - - - <% end %> -
- - <% else %> - -
- - <% @is_valuate = is_praise_or_tread(obj,user_id)%> - <% if @is_valuate.size > 0 %> - <% @flag = @is_valuate.first.praise_or_tread %> - <% if @flag == 1 %> - - - - - - - - - - - -
<%= image_tag "/images/praise_tread/praise_false.png" , weight:"22px", height:"22px",:title => l(:label_issue_praise_over) %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_appraise_over) %>
- - <% elsif @flag == 0 %> - - - - - - - - - - - - -
<%= image_tag "/images/praise_tread/praise_false.png",weight:"22px", height:"22px", :title => l(:label_issue_appraise_over) %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_tread_over) %>
- <% end %> - - <% else %> - <% if user_id == obj.author_id %> - - - - - - - - - - - -
<%= image_tag "/images/praise_tread/praise_true.png",weight:"22px", height:"22px", :title => l(:label_issue_not_praise_over) %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_not_treed_over) %>
- <% else %> - <% if OptionNumber.get_user_option_number(user_id).nil? || OptionNumber.get_user_option_number(user_id).total_score < 2 %> - - - - - - - - - - - -
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), - :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issues_score_not_enough) %>
- <% else %> - - - - - - - - - - -
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), - :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
<%= get_praise_num(obj)%>
<%= link_to image_tag("/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_tread)),:controller=>"praise_tread", - :action=>"tread_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
- <% end %> - - <% end %> - - - <% end %> -
- <% end %> - <% end %> + + <% if User.current.logged? %> + <% if horizontal %> + +
+ + <% @is_valuate = is_praise_or_tread(obj,user_id)%> + <% if @is_valuate.size > 0 %> + <% @flag = @is_valuate.first.praise_or_tread %> + <% if @flag == 1 %> + + + + + + +
<%= image_tag "/images/praise_tread/praise_false.png" , weight:"22px", height:"22px",:title => l(:label_issue_praise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_appraise_over) %>
+ + <% elsif @flag == 0 %> + + + + + + + +
<%= image_tag "/images/praise_tread/praise_false.png",weight:"22px", height:"22px", :title => l(:label_issue_appraise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_tread_over) %>
+ <% end %> + + <% else %> + + <% if user_id == obj.author_id %> + + + + + + +
<%= image_tag "/images/praise_tread/praise_true.png" , weight:"22px", height:"22px",:title => l(:label_issue_not_praise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_not_treed_over) %>
+ <% else %> + + <% if OptionNumber.get_user_option_number(user_id).nil? || OptionNumber.get_user_option_number(user_id).total_score < 2 %> + + + + + + +
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), + :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issues_score_not_enough) %>
+ <% else %> + + + + + + +
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), + :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %> <%= get_praise_num(obj)%> <%= link_to image_tag("/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_tread)),:controller=>"praise_tread", + :action=>"tread_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %>
+ <% end %> + + <% end %> + + + <% end %> +
+ + <% else %> + +
+ <% @is_valuate = is_praise_or_tread(obj,user_id)%> + <% if @is_valuate.size > 0 %> + <% @flag = @is_valuate.first.praise_or_tread %> + <% if @flag == 1 %> + + + + + + + + + + + +
<%= image_tag "/images/praise_tread/praise_false.png" , weight:"22px", height:"22px",:title => l(:label_issue_praise_over) %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_appraise_over) %>
+ + <% elsif @flag == 0 %> + + + + + + + + + + + + +
<%= image_tag "/images/praise_tread/praise_false.png",weight:"22px", height:"22px", :title => l(:label_issue_appraise_over) %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_tread_over) %>
+ <% end %> + + <% else %> + <% if user_id == obj.author_id %> + + + + + + + + + + + +
<%= image_tag "/images/praise_tread/praise_true.png",weight:"22px", height:"22px", :title => l(:label_issue_not_praise_over) %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_not_treed_over) %>
+ <% else %> + <% if OptionNumber.get_user_option_number(user_id).nil? || OptionNumber.get_user_option_number(user_id).total_score < 2 %> + + + + + + + + + + + +
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), + :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
<%= get_praise_num(obj)%>
<%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issues_score_not_enough) %>
+ <% else %> + + + + + + + + + + +
<%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), + :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
<%= get_praise_num(obj)%>
<%= link_to image_tag("/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_tread)),:controller=>"praise_tread", + :action=>"tread_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
+ <% end %> + + <% end %> + + + <% end %> +
+ <% end %> + <% end %> diff --git a/app/views/projects/_project.html.erb b/app/views/projects/_project.html.erb index 6f2354d66..b9f45356a 100644 --- a/app/views/projects/_project.html.erb +++ b/app/views/projects/_project.html.erb @@ -1,154 +1,154 @@ - -
-
- <% if(@project.project_type==1)%> - <% if get_avatar?(project)%> - <%= image_tag(url_to_avatar(project), :class => "avatar2") %> - <% else %> - <%= image_tag('../images/avatars/Project/course.jpg', :class => "avatar2") %> - <% end %> - <% else %> - <%= image_tag(url_to_avatar(project), :class => "avatar2") %> -
-
-

- <%= textilizable(project.short_description.strip, :project => project) %> -

-
- -
-

- - - - - - - - - - - - - - - - - -
- <%= link_to @project.watcher_users.count, project_watcherlist_path(project)%> - - <%= content_tag('span', l(:label_x_follow_people,:count =>@project.watcher_users.count)) %> -
- <%= link_to "#{@project.members.count}", project_member_path(@project)%> - - <%= content_tag('span', l(:label_x_current_contributors, :count => @project.users.count)) %> -
- <%= content_tag('span', "#{(@project.repository.nil? || @project.repository.changesets[0].nil?) ? '0' : distance_of_time_in_words(Time.now, @project.repository.changesets[0].committed_on)}", :class => "info") %> - - <%= content_tag('span', l(:label_since_last_commits)) %> -
- - <%= content_tag('span', "#{get_project_score(@project).nil? ? 0:get_project_score(@project).changeset_num}", :class => "info") %> - - <%= content_tag('span', l(:label_commit_on)) %> -
-

-
- <% end %> - <% if(@project.project_type==1)%> -
-
-

- <%= textilizable(project.short_description, :project => project) %> -

-
- -
- -

- <%= content_tag('span', link_to("#{@project.homeworks.count}", homework_project_path(@project)), :class => "info") %><%= content_tag('span', l(:label_x_task, :count => @project.homeworks.count)) %> -

-

- <%= content_tag('span', link_to("#{@project.members.count}", member_project_path(@project)), :class => "info") %><%= content_tag('span', l(:label_x_member, :count => @project.members.count)) %> -

-

- <% files_count = @project.attachments.count %> - <% @project.versions.each do |version| %> - <% files_count += version.attachments.count %> - <% end %> - <%= content_tag('span', link_to(files_count, file_project_path(@project)), :class => "info") %><%= content_tag('span', l(:label_x_data,:count => files_count)) %> -

- -
-<% end %> - - -
-
- - <% if(@project.project_type==1)%> - <%= content_tag('span', "#{l(:field_tea_name)}: ") %> - <% else %> - <%= content_tag('span', "#{l(:default_role_manager)}: ") %> - <% end %> - <% @admin = @project.project_infos%> - - <% if @admin.size > Setting.show_tags_length.to_i then %> - <% i = 0 %> - <% until i>Setting.show_tags_length.to_i do %> - <%= link_to @admin[i].user.name, user_path(@admin[i].user_id) %> - <% i += 1 %> - <% end %> - <%= link_to l(:label_more_tags), member_project_path(@project) %> - <% else %> - <%= content_tag('a', @admin.collect{|u| link_to(u.user.name, user_path(u.user_id))}.join(", ").html_safe) %> - <% end %> - - <%# if @admin.size > 0 %> - <%#= content_tag('a', @admin.collect{|u| link_to(u.user.name, user_path(u.user_id))}.join(", ").html_safe) %> - <%# end %> - <% if(@project.project_type==1)%> -    <%= l(:label_course_college) %>: - <%if @admin&&@admin.first&&@admin.first.user&&@admin.first.user.user_extensions%> - <%= @admin.first.user.user_extensions.occupation %> - <% end %> - <% end %> -
-
- <%= content_tag('span', "#{l(:label_create_time)}: ") %><%= content_tag('span', format_time(@project.created_on)) %> -
- - -
- - <% if @project.project_type !=1 %> - <%= l(:label_project_grade)%>: - - <%= link_to(format("%.2f" , red_project_scores(@project) ).to_i, - {:controller => 'projects', - :action => 'show_projects_score', - :remote => true, :id => @project.id}, :style=>"color: #EC6300;") %> - - <% end %> -
- - - - - - -
-
- -
- - <%= image_tag( "/images/sidebar/tags.png") %> - - <%= render :partial => 'tags/tag_name', :locals => {:obj => @project,:object_flag => "2",:non_list_all => true }%> - -
-
+ +
+
+ <% if(@project.project_type==1)%> + <% if get_avatar?(project)%> + <%= image_tag(url_to_avatar(project), :class => "avatar2") %> + <% else %> + <%= image_tag('../images/avatars/Project/course.jpg', :class => "avatar2") %> + <% end %> + <% else %> + <%= image_tag(url_to_avatar(project), :class => "avatar2") %> +
+
+

+ <%= textilizable(project.short_description.strip, :project => project) %> +

+
+ +
+

+ + + + + + + + + + + + + + + + + +
+ <%= link_to @project.watcher_users.count, project_watcherlist_path(project)%> + + <%= content_tag('span', l(:label_x_follow_people,:count =>@project.watcher_users.count)) %> +
+ <%= link_to "#{@project.members.count}", project_member_path(@project)%> + + <%= content_tag('span', l(:label_x_current_contributors, :count => @project.users.count)) %> +
+ <%= content_tag('span', "#{(@project.repository.nil? || @project.repository.changesets[0].nil?) ? '0' : distance_of_time_in_words(Time.now, @project.repository.changesets[0].committed_on)}", :class => "info") %> + + <%= content_tag('span', l(:label_since_last_commits)) %> +
+ + <%= content_tag('span', "#{get_project_score(@project).nil? ? 0:get_project_score(@project).changeset_num}", :class => "info") %> + + <%= content_tag('span', l(:label_commit_on)) %> +
+

+
+ <% end %> + <% if(@project.project_type==1)%> +
+
+

+ <%= textilizable(project.short_description, :project => project) %> +

+
+ +
+ +

+ <%= content_tag('span', link_to("#{@project.homeworks.count}", homework_project_path(@project)), :class => "info") %><%= content_tag('span', l(:label_x_task, :count => @project.homeworks.count)) %> +

+

+ <%= content_tag('span', link_to("#{@project.members.count}", member_project_path(@project)), :class => "info") %><%= content_tag('span', l(:label_x_member, :count => @project.members.count)) %> +

+

+ <% files_count = @project.attachments.count %> + <% @project.versions.each do |version| %> + <% files_count += version.attachments.count %> + <% end %> + <%= content_tag('span', link_to(files_count, file_project_path(@project)), :class => "info") %><%= content_tag('span', l(:label_x_data,:count => files_count)) %> +

+ +
+<% end %> + + +
+
+ + <% if(@project.project_type==1)%> + <%= content_tag('span', "#{l(:field_tea_name)}: ") %> + <% else %> + <%= content_tag('span', "#{l(:default_role_manager)}: ") %> + <% end %> + <% @admin = @project.project_infos%> + + <% if @admin.size > Setting.show_tags_length.to_i then %> + <% i = 0 %> + <% until i>Setting.show_tags_length.to_i do %> + <%= link_to @admin[i].user.name, user_path(@admin[i].user_id) %> + <% i += 1 %> + <% end %> + <%= link_to l(:label_more_tags), member_project_path(@project) %> + <% else %> + <%= content_tag('a', @admin.collect{|u| link_to(u.user.name, user_path(u.user_id))}.join(", ").html_safe) %> + <% end %> + + <%# if @admin.size > 0 %> + <%#= content_tag('a', @admin.collect{|u| link_to(u.user.name, user_path(u.user_id))}.join(", ").html_safe) %> + <%# end %> + <% if(@project.project_type==1)%> +    <%= l(:label_course_college) %>: + <%if @admin&&@admin.first&&@admin.first.user&&@admin.first.user.user_extensions%> + <%= @admin.first.user.user_extensions.occupation %> + <% end %> + <% end %> +
+
+ <%= content_tag('span', "#{l(:label_create_time)}: ") %><%= content_tag('span', format_time(@project.created_on)) %> +
+ + +
+ + <% if @project.project_type !=1 %> + <%= l(:label_project_grade)%>: + + <%= link_to(format("%.2f" , red_project_scores(@project) ).to_i, + {:controller => 'projects', + :action => 'show_projects_score', + :remote => true, :id => @project.id}, :style=>"color: #EC6300;") %> + + <% end %> +
+ + + + + + +
+
+ +
+ + <%= image_tag( "/images/sidebar/tags.png") %> + + <%= render :partial => 'tags/tag_name', :locals => {:obj => @project,:object_flag => "2",:non_list_all => true }%> + +
+
diff --git a/app/views/projects/settings/_members.html.erb b/app/views/projects/settings/_members.html.erb index c1d63d03b..25f02da0d 100644 --- a/app/views/projects/settings/_members.html.erb +++ b/app/views/projects/settings/_members.html.erb @@ -1,146 +1,147 @@ -<%= error_messages_for 'member' %> -<% - roles = Role.givable.all - if @project.project_type == Project::ProjectType_course - roles = roles[3..5] - else - roles = roles[0..2] - end - members = @project.member_principals.includes(:roles, :principal).all.sort -%> - -
- <% if members.any? %> - - - - - - - <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> - - - - <% members.each do |member| %> - <% next if member.new_record? %> - - - - - <% if @project.project_type == 1 %> - <% if member.roles.first.to_s == "Manager" %> - - <% else %> - - <% end %> - <% else %> - - <% end %> - - <%= call_hook(:view_projects_settings_members_table_row, {:project => @project, :member => member}) %> - - <% end; reset_cycle %> - -
<%= l(:label_user) %><%= l(:label_role_plural) %>
<%= link_to_user member.principal %> - - <%= h member.roles.sort.collect(&:to_s).join(', ') %> - - <%= form_for(member, {:as => :membership, :remote => true, :url => membership_path(member), - :method => :put, - :html => {:id => "member-#{member.id}-roles-form", :class => 'hol'}} - ) do |f| %> - -

- <% roles.each do |role| %> -
- <% end %>

- <%= hidden_field_tag 'membership[role_ids][]', '' %> -

<%= submit_tag l(:button_change), :class => "small" %> - <%= link_to_function l(:button_cancel), - "$('#member-#{member.id}-roles').show(); $('#member-#{member.id}-roles-form').hide(); return false;" - %>

- <% end %> -
- <%= link_to_function l(:button_edit), - "$('#member-#{member.id}-roles').hide(); $('#member-#{member.id}-roles-form').show(); return false;", - :class => 'icon icon-edit' %> - <%= delete_link membership_path(member), - :remote => true, - :data => (!User.current.admin? && member.include?(User.current) ? {:confirm => l(:text_own_membership_delete_confirmation)} : {}) if member.deletable? %> - - <%= link_to_function l(:button_edit), - "$('#member-#{member.id}-roles').hide(); $('#member-#{member.id}-roles-form').show(); return false;", - :class => 'icon icon-edit' %> - <%= delete_link membership_path(member), - :remote => true, - :data => (!User.current.admin? && member.include?(User.current) ? {:confirm => l(:text_own_membership_delete_confirmation)} : {}) if member.deletable? %> -
- <% else %> -

<%= l(:label_no_data) %>

- <% end %> -
- -
- <% if roles.any? %> - <% if @project.applied_projects.any? %> -
- <%= form_for(@applied_members, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %> -
- <%= l(:label_apply_project) %> - -
- <%= render_principals_for_applied_members(@project) %> -
-
- -

<%= l(:label_role_plural) %>: - <% roles.each do |role| %> - - - <% end %>

- -

<%= submit_tag l(:label_approve), :id => 'member-add-submit' %> - <%= submit_tag l(:label_refusal), :name => "refusal_button", :id => 'member-refusal-submit' %> -

-
- <% end %> -
- <% end %> - - <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %> -
- <%= l(:label_member_new) %> - -

<%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %>

- <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %> - -
- <%= render_principals_for_new_members(@project) %> -
- -

<%= l(:label_role_plural) %>: - <% roles.each do |role| %> - - - <% end %>

- -

<%= submit_tag l(:button_add), :id => 'member-add-submit' %>

-
- <% end %> - <% end %> -
- \ No newline at end of file diff --git a/app/views/projects/show_projects_score.html.erb b/app/views/projects/show_projects_score.html.erb index b16f46f91..7f3f05cce 100644 --- a/app/views/projects/show_projects_score.html.erb +++ b/app/views/projects/show_projects_score.html.erb @@ -1,71 +1,71 @@ - - - - <%= h html_title %> - - - <%= csrf_meta_tag %> - <%= favicon %> - <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> - <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> - <%= javascript_heads %> - <%= heads_for_theme %> - <%= hubspot_head %> - <%= call_hook :view_layouts_base_html_head %> - - <%= yield :header_tags -%> - -<% if @project %> -

<%= l(:label_projects_score) %>

-
- - - - - - -
<%= image_tag(url_to_avatar(@project), :class => 'avatar2') %> - - - -
<%= @project.name %>
-
- - - -
<%= l(:label_projects_score) %>
<%= format("%.2f" , project_scores(@project) ).to_i %>
-
-
- -
-
    -
  • - <%= link_to l(:label_projects_score), {:controller => 'projects', :action => 'show_projects_score', :remote => true}%> : - <%= format("%.2f" , project_scores(@project) ).to_i %> -
  • -
  • - <%= link_to l(:label_issue_score), {:controller => 'projects', :action => 'issue_score_index', :remote => true}%> : - <%= format("%.2f" , issue_score(@project)).to_i %> -
  • -
  • - <%= link_to l(:label_news_score), {:controller => 'projects', :action => 'news_score_index', :remote => true}%> : - <%= format("%.2f" , news_score(@project)).to_i %> -
  • -
  • - <%= link_to l(:label_file_score), {:controller => 'projects', :action => 'file_score_index', :remote => true}%> : - <%= format("%.2f" , documents_score(@project)).to_i %> -
  • -
  • - <%= link_to l(:label_code_submit_score), {:controller => 'projects', :action => 'code_submit_score_index', :remote => true}%> : - <%= format("%.2f" , changesets_score(@project)).to_i %> -
  • -
  • - <%= link_to l(:label_topic_score), {:controller => 'projects', :action => 'projects_topic_score_index', :remote => true}%> : - <%= format("%.2f" , board_message_score(@project)).to_i %> -
  • -
-
-
- <%= render :partial => 'projects/project_score_index', :locals => {:index => 0 } %> -
+ + + + <%= h html_title %> + + + <%= csrf_meta_tag %> + <%= favicon %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> + <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> + <%= javascript_heads %> + <%= heads_for_theme %> + <%= hubspot_head %> + <%= call_hook :view_layouts_base_html_head %> + + <%= yield :header_tags -%> + +<% if @project %> +

<%= l(:label_projects_score) %>

+
+ + + + + + +
<%= image_tag(url_to_avatar(@project), :class => 'avatar2') %> + + + +
<%= @project.name %>
+
+ + + +
<%= l(:label_projects_score) %>
<%= format("%.2f" , project_scores(@project) ).to_i %>
+
+
+ +
+
    +
  • + <%= link_to l(:label_projects_score), {:controller => 'projects', :action => 'show_projects_score', :remote => true}%> : + <%= format("%.2f" , project_scores(@project) ).to_i %> +
  • +
  • + <%= link_to l(:label_issue_score), {:controller => 'projects', :action => 'issue_score_index', :remote => true}%> : + <%= format("%.2f" , issue_score(@project)).to_i %> +
  • +
  • + <%= link_to l(:label_news_score), {:controller => 'projects', :action => 'news_score_index', :remote => true}%> : + <%= format("%.2f" , news_score(@project)).to_i %> +
  • +
  • + <%= link_to l(:label_file_score), {:controller => 'projects', :action => 'file_score_index', :remote => true}%> : + <%= format("%.2f" , documents_score(@project)).to_i %> +
  • +
  • + <%= link_to l(:label_code_submit_score), {:controller => 'projects', :action => 'code_submit_score_index', :remote => true}%> : + <%= format("%.2f" , changesets_score(@project)).to_i %> +
  • +
  • + <%= link_to l(:label_topic_score), {:controller => 'projects', :action => 'projects_topic_score_index', :remote => true}%> : + <%= format("%.2f" , board_message_score(@project)).to_i %> +
  • +
+
+
+ <%= render :partial => 'projects/project_score_index', :locals => {:index => 0 } %> +
<% end %> \ No newline at end of file diff --git a/app/views/repositories/revision.html.erb b/app/views/repositories/revision.html.erb index 7b4934bfa..82b881f7d 100644 --- a/app/views/repositories/revision.html.erb +++ b/app/views/repositories/revision.html.erb @@ -1,97 +1,97 @@ -
- « - <% unless @changeset.previous.nil? -%> - <%= link_to_revision(@changeset.previous, @repository, :text => l(:label_previous)) %> - <% else -%> - <%= l(:label_previous) %> - <% end -%> -| - <% unless @changeset.next.nil? -%> - <%= link_to_revision(@changeset.next, @repository, :text => l(:label_next)) %> - <% else -%> - <%= l(:label_next) %> - <% end -%> - »  - - <%= form_tag({:controller => 'repositories', - :action => 'revision', - :id => @project, - :repository_id => @repository.identifier_param, - :rev => nil}, - :method => :get) do %> - <%= text_field_tag 'rev', @rev, :size => 8 %> - <%= submit_tag l(:label_button_ok), :name => nil %> - <% end %> -
- -

<%= avatar(@changeset.user, :size => "24") %><%= l(:label_revision) %> <%= format_revision(@changeset) %>

- -<% if @changeset.scmid.present? || @changeset.parents.present? || @changeset.children.present? %> - - <% if @changeset.scmid.present? %> - - - - <% end %> - <% if @changeset.parents.present? %> - - - - - <% end %> - <% if @changeset.children.present? %> - - - - - <% end %> -
ID<%= h(@changeset.scmid) %>
<%= l(:label_parent_revision) %> - <%= @changeset.parents.collect{ - |p| link_to_revision(p, @repository, :text => format_revision(p)) - }.join(", ").html_safe %> -
<%= l(:label_child_revision) %> - <%= @changeset.children.collect{ - |p| link_to_revision(p, @repository, :text => format_revision(p)) - }.join(", ").html_safe %> -
-<% end %> - -

- -<%= authoring(@changeset.committed_on, @changeset.author) %> - -

- -<%= textilizable @changeset.comments %> - -<% if @changeset.issues.visible.any? || User.current.allowed_to?(:manage_related_issues, @repository.project) %> - <%= render :partial => 'related_issues' %> -<% end %> - -<% if User.current.allowed_to?(:browse_repository, @project) %> -

<%= l(:label_attachment_plural) %>

-
    -
  • <%= l(:label_added) %>
  • -
  • <%= l(:label_modified) %>
  • -
  • <%= l(:label_copied) %>
  • -
  • <%= l(:label_renamed) %>
  • -
  • <%= l(:label_deleted) %>
  • -
- -

<%= link_to(l(:label_view_diff), - :action => 'diff', - :id => @project, - :repository_id => @repository.identifier_param, - :path => "", - :rev => @changeset.identifier) if @changeset.filechanges.any? %>

- -
-<%= render_changeset_changes %> -
-<% end %> - -<% content_for :header_tags do %> -<%= stylesheet_link_tag "scm" %> -<% end %> - -<% html_title("#{l(:label_revision)} #{format_revision(@changeset)}") -%> +
+ « + <% unless @changeset.previous.nil? -%> + <%= link_to_revision(@changeset.previous, @repository, :text => l(:label_previous)) %> + <% else -%> + <%= l(:label_previous) %> + <% end -%> +| + <% unless @changeset.next.nil? -%> + <%= link_to_revision(@changeset.next, @repository, :text => l(:label_next)) %> + <% else -%> + <%= l(:label_next) %> + <% end -%> + »  + + <%= form_tag({:controller => 'repositories', + :action => 'revision', + :id => @project, + :repository_id => @repository.identifier_param, + :rev => nil}, + :method => :get) do %> + <%= text_field_tag 'rev', @rev, :size => 8 %> + <%= submit_tag l(:label_button_ok), :name => nil %> + <% end %> +
+ +

<%= avatar(@changeset.user, :size => "24") %><%= l(:label_revision) %> <%= format_revision(@changeset) %>

+ +<% if @changeset.scmid.present? || @changeset.parents.present? || @changeset.children.present? %> + + <% if @changeset.scmid.present? %> + + + + <% end %> + <% if @changeset.parents.present? %> + + + + + <% end %> + <% if @changeset.children.present? %> + + + + + <% end %> +
ID<%= h(@changeset.scmid) %>
<%= l(:label_parent_revision) %> + <%= @changeset.parents.collect{ + |p| link_to_revision(p, @repository, :text => format_revision(p)) + }.join(", ").html_safe %> +
<%= l(:label_child_revision) %> + <%= @changeset.children.collect{ + |p| link_to_revision(p, @repository, :text => format_revision(p)) + }.join(", ").html_safe %> +
+<% end %> + +

+ +<%= authoring(@changeset.committed_on, @changeset.author) %> + +

+ +<%= textilizable @changeset.comments %> + +<% if @changeset.issues.visible.any? || User.current.allowed_to?(:manage_related_issues, @repository.project) %> + <%= render :partial => 'related_issues' %> +<% end %> + +<% if User.current.allowed_to?(:browse_repository, @project) %> +

<%= l(:label_attachment_plural) %>

+
    +
  • <%= l(:label_added) %>
  • +
  • <%= l(:label_modified) %>
  • +
  • <%= l(:label_copied) %>
  • +
  • <%= l(:label_renamed) %>
  • +
  • <%= l(:label_deleted) %>
  • +
+ +

<%= link_to(l(:label_view_diff), + :action => 'diff', + :id => @project, + :repository_id => @repository.identifier_param, + :path => "", + :rev => @changeset.identifier) if @changeset.filechanges.any? %>

+ +
+<%= render_changeset_changes %> +
+<% end %> + +<% content_for :header_tags do %> +<%= stylesheet_link_tag "scm" %> +<% end %> + +<% html_title("#{l(:label_revision)} #{format_revision(@changeset)}") -%> diff --git a/app/views/repositories/revisions.html.erb b/app/views/repositories/revisions.html.erb index 321ff72b2..4efc4992a 100644 --- a/app/views/repositories/revisions.html.erb +++ b/app/views/repositories/revisions.html.erb @@ -1,34 +1,34 @@ -
-<%= form_tag( - {:controller => 'repositories', :action => 'revision', :id => @project, - :repository_id => @repository.identifier_param}, - :method => :get - ) do %> - <%= l(:label_revision) %>: <%= text_field_tag 'rev', nil, :size => 8 %> - <%= submit_tag l(:label_button_ok) %> -<% end %> -
- -

<%= l(:label_revision_plural) %>

- -<%= render :partial => 'revisions', - :locals => {:project => @project, - :path => '', - :revisions => @changesets, - :entry => nil } %> - - - -<% content_for :header_tags do %> - <%= stylesheet_link_tag "scm" %> - <%= auto_discovery_link_tag( - :atom, - params.merge( - {:format => 'atom', :page => nil, :key => User.current.rss_key})) %> -<% end %> - -<% other_formats_links do |f| %> - <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> -<% end %> - -<% html_title(l(:label_revision_plural)) -%> +
+<%= form_tag( + {:controller => 'repositories', :action => 'revision', :id => @project, + :repository_id => @repository.identifier_param}, + :method => :get + ) do %> + <%= l(:label_revision) %>: <%= text_field_tag 'rev', nil, :size => 8 %> + <%= submit_tag l(:label_button_ok) %> +<% end %> +
+ +

<%= l(:label_revision_plural) %>

+ +<%= render :partial => 'revisions', + :locals => {:project => @project, + :path => '', + :revisions => @changesets, + :entry => nil } %> + + + +<% content_for :header_tags do %> + <%= stylesheet_link_tag "scm" %> + <%= auto_discovery_link_tag( + :atom, + params.merge( + {:format => 'atom', :page => nil, :key => User.current.rss_key})) %> +<% end %> + +<% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<% end %> + +<% html_title(l(:label_revision_plural)) -%> diff --git a/app/views/school/index.html.erb b/app/views/school/index.html.erb index 6c1eafd6d..02b934581 100644 --- a/app/views/school/index.html.erb +++ b/app/views/school/index.html.erb @@ -3,10 +3,6 @@ @@ -55,7 +51,7 @@ //alert(value); if(value == "") { - alert("搜索条件不能为空"); + alert("<%= l(:label_search_conditions_not_null) %>"); return; } //alert(province); @@ -82,17 +78,17 @@

- <%= link_to "全部学校",school_index_path %>      + <%= link_to l(:label_all_schol),school_index_path %>      <% if User.current.logged? %> - 我的学校 + <%= l(:label_my_school) %> <% end %>

    -
  • 请选择省份: +
  • <%= l(:label_select_province) %>:
  • -
  • +
diff --git a/app/views/softapplications/_form.html.erb b/app/views/softapplications/_form.html.erb index 95c61ae27..916b085a0 100644 --- a/app/views/softapplications/_form.html.erb +++ b/app/views/softapplications/_form.html.erb @@ -1,122 +1,122 @@ - -<%= form_for(softapplication) do |f| %> - - <% if softapplication.errors.any? %> -
-

<%= pluralize(softapplication.errors.count, "error") %> prohibited this softapplication from being saved:

- -
    - <% softapplication.errors.full_messages.each do |msg| %> -
  • <%= msg %>
  • - <% end %> -
-
- <% end %> -
- -
<%= f.text_field :name, :required => true, :size => 60, :style => "width:400px;" %>
<%= f.text_field :android_min_version_available, :required => true, :size => 60, :style => "width:400px;" %>
- <%#= f.text_field :app_type_name, :required => true, :size => 60, :style => "width:400px;" %> - <% if work_type_opttion.include?([@softapplication.app_type_name,@softapplication.app_type_name]) %> - <%= f.select :app_type_name,options_for_select(work_type_opttion,@softapplication.app_type_name), {},{:style => "width:410px;",:onchange => "selectChange(this)"} %> - - <% else %> - <%= f.select :app_type_name,options_for_select(work_type_opttion,"其他"), {},{:style => "width:410px;",:onchange => "selectChange(this)"} %> - - <%#= f.text_field :other_input, :required => true, :size => 60, :style => "width:100px;" %> - - - <% end %> -
<%= f.text_field :description, :required => true, :size => 60, :style => "width:400px;" %>
<%= f.text_field :application_developers, :required => true, :size => 60, :style => "width:400px;" %>
<%= f.text_field :name, :required => true, :size => 60, :style => "width:400px;" %>
<%= f.text_field :android_min_version_available, :required => true, :size => 60, :style => "width:400px;" %>
+ <%#= f.text_field :app_type_name, :required => true, :size => 60, :style => "width:400px;" %> + <% if work_type_opttion.include?([@softapplication.app_type_name,@softapplication.app_type_name]) %> + <%= f.select :app_type_name,options_for_select(work_type_opttion,@softapplication.app_type_name), {},{:style => "width:410px;",:onchange => "selectChange(this)"} %> + + <% else %> + <%= f.select :app_type_name,options_for_select(work_type_opttion,"其他"), {},{:style => "width:410px;",:onchange => "selectChange(this)"} %> + + <%#= f.text_field :other_input, :required => true, :size => 60, :style => "width:100px;" %> + + + <% end %> +
<%= f.text_field :description, :required => true, :size => 60, :style => "width:400px;" %>
<%= f.text_field :application_developers, :required => true, :size => 60, :style => "width:400px;" %>
- - - -
- -
- - <% end %> -<% end %> - -<% unless @state == 2 %> - <% unless @activity.empty? %> -
- <% @activity.each do |e| %> - <%# 以下一行代码解决有未知的活动无法转换成Model报错%> - <% (Rails.logger.error "[Error] =========================================================> NameError: uninitialized constant " + e.act_type.to_s; next;) if e.act_type.safe_constantize.nil? %> - <% act = e.act %> - <% unless act.nil? %> - <% if e.act_type == 'JournalsForMessage' || e.act_type == 'Bid' || e.act_type == 'Journal'|| e.act_type == 'Changeset' || e.act_type == 'Message' || e.act_type == 'Principal' || e.act_type == 'News' || e.act_type == 'Issue' || e.act_type == 'Contest'%> - - - - - - -
<%= image_tag(url_to_avatar(e.user), :class => "avatar") %> - - <% case e.act_type %> - <% when 'JournalsForMessage' %> - <% if User.current.login == e.user.try(:login) %> - <%# if e.user_id == act.jour.id %> - - - - <%# else %> - - <%# end %> - <% else %> - - - - <% end %> - - - - - - - - <% when 'Bid' %> - - <% if act.reward_type == 3 && @show_course == 1%> - <% if e.user == User.current %> - - <% else %> - - <% end %> - <% else %> - <% if e.user == User.current %> - - <% else %> - - <% end %> - <% end %> - - - - - - - - <% when 'Journal' %> - - <% if e.user == User.current %> - - <% else %> - - <% end %> - - - <% if act.notes.nil? %> - <% desStr = '' %> - <% else %> - <% desStr= textAreailizable(act, :notes) %> - <% end %> - - - - - - <% when 'Changeset' %> - - <% if e.user == User.current %> - - <% else %> - - <% end %> - - - - - - - - <% when 'Message' %> - - <% if e.user == User.current %> - - <% else %> - - <% end %> - - - - - - - - <% when 'Principal' %> - - <% if e.user == User.current %> - - <% else %> - - <% end %> - - - - - - - - <% when 'News' %> - - <% if e.user == User.current %> - - <% else %> - - <% end %> - - - - - - - - <% when 'Issue' %> - - <% if e.user == User.current %> - - <% else %> - - <% end %> - - - - - - - - <% when 'Contest' %> - - <% if e.user == User.current && @show_contest == 1%> - - <% else %> - - <% end %> - - - - - - - <% else %> - <%# f=1 %> - <% end %> -
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_have_feedback) %> - <%= link_to("#{e.act.user.name}", user_path(e.act.user.id)) %><%= l(:label_of_feedback) + l(:label_layouts_feedback) %> -
- <%= link_to("#{e.user.name}", user_path(e.user_id)) %> <%= l(:label_have_feedback) %><%= - link_to("#{e.act.user.name}", user_path(e.act.user.id)) %><%= l(:label_of_feedback) + l(:label_layouts_feedback) %> -
-

<%= textAreailizable act.notes %>

- -
<%= link_to(l(:label_goto), user_newfeedback_user_path(e.user_id)) %> -
-
-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
-
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %><%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_active_homework)}##{act.id}:#{act.name}"), respond_path(e.act_id) %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_activity) %>  <%= link_to format_activity_title("#{l(:label_active_homework)}##{act.id}:#{act.name}"), respond_path(e.act_id) %> - - <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %><%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_active_call)}##{act.id}:#{act.name}"), respond_path(e.act_id) %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_activity) %>  <%= link_to format_activity_title("#{l(:label_active_call)}##{act.id}:#{act.name}"), respond_path(e.act_id) %> -
-

<%=textAreailizable act, :description %>

-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
- <%= link_to l(:label_find_all_comments), respond_path(e.act_id) %><%= l(:label_comments_count, :count => e.act.commit) %> -
-
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to(l(:label_activity_project)+act.issue.project.name, project_path(act.issue.project.id)) %> <%= link_to format_activity_title("#{act.issue.tracker} ##{act.issue.id}: #{act.issue.subject}"), {:controller => 'issues', :action => 'show', :id => act.issue.id, :anchor => "change-#{act.id}"} %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_activity) %> <%= link_to(l(:label_activity_project)+act.issue.project.name, project_path(act.issue.project.identifier)) %> <%= link_to format_activity_title("#{act.issue.tracker} ##{act.issue.id}: #{act.issue.subject}"), {:controller => 'issues', :action => 'show', :id => act.issue.id, :anchor => "change-#{act.id}"} %> -

<%= desStr %>

-
-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
-
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title(act.title), {:controller => 'repositories', :action => 'revision', :id => act.repository.project, :repository_id => act.repository.identifier_param, :rev => act.identifier} %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_activity) %> <%= link_to format_activity_title(act.title), {:controller => 'repositories', :action => 'revision', :id => act.repository.project, :repository_id => act.repository.identifier_param, :rev => act.identifier} %> -
-

<%= textAreailizable act,:long_comments %>

-
- <%= format_time(e.act.committed_on) %> -
-
- <%= link_to l(:label_find_all_comments), {:controller => 'repositories', :action => 'revision', :id => act.repository.project, :repository_id => act.repository.identifier_param, :rev => act.identifier} %><%= l(:label_comments_count, :count => e.act.count) %> -
-
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{act.board.name}: #{act.subject}"), {:controller => 'messages', :action => 'show', :board_id => act.board_id}.merge(act.parent_id.nil? ? {:id => act.id} : {:id => act.parent_id, :r => act.id, :anchor => "message-#{act.id}"}) %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_activity) %> <%= link_to format_activity_title("#{act.board.name}: #{act.subject}"), {:controller => 'messages', :action => 'show', :board_id => act.board_id}.merge(act.parent_id.nil? ? {:id => act.id} : {:id => act.parent_id, :r => act.id, :anchor => "message-#{act.id}"}) %> -
-

<%= textAreailizable(act,:content) %>

-
-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
-
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_new_user) %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_user) %> -

-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
-
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_news)}: #{act.title}"), {:controller => 'news', :action => 'show', :id => act.id} %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_activity) %> <%= link_to format_activity_title("#{l(:label_news)}: #{act.title}"), {:controller => 'news', :action => 'show', :id => act.id} %> -
-

<%= textAreailizable act,:description %>

-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
- <%= link_to l(:label_find_all_comments), {:controller => 'news', :action => 'show', :id => act.id} %><%= l(:label_comments_count, :count => e.act.comments_count) %> -
-
- - <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> -   - - <%= l(:label_i_new_activity) %> -   - <%= link_to format_activity_title("#{act.source_from} (#{act.status}): #{act.tracker.name} #{act.subject}"), {:controller => 'issues', :action => 'show', :id => act.id} %> - - - <%= link_to(h(e.user), user_path(e.user_id)) %> -   - - <%= l(:label_new_activity) %> -   - <%= link_to format_activity_title("#{act.source_from} (#{act.status}): #{act.tracker.name} #{act.subject}"), {:controller => 'issues', :action => 'show', :id => act.id} %> -
- - <%= textAreailizable act, :description %> - -
-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
- <%= link_to l(:label_find_all_comments), {:controller => 'issues', :action => 'show', :id => act.id} %><%= l(:label_comments_count, :count => e.act.journals.count) %> -
-
- <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_contest)}: #{act.name}"), {:controller => 'contests', :action => 'show_contest', :id => act.id} %> - - <%= link_to(h(e.user), user_path(e.user_id)) %> <%= l(:label_new_activity) %> <%= link_to format_activity_title("#{l(:label_contest)}: #{act.name}"), {:controller => 'contests', :action => 'show_contest', :id => act.id} %> -

<%= textAreailizable act, :description %>

-
-
- <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> -
-
-
- <% end %> - <% end %> - - <% end %> -
- - <% else %> - <% if @user == User.current %> - <%= l(:label_user_activities) %> - <% else %> -

- <%= l(:label_user_activities_other) %> -

- <% end %> - <% end %> - -<% else %> - <% unless @message.empty? %> -
- <% @message.each do |e| -%> - - - - - -
<%= image_tag(url_to_avatar(e.user), :class => "avatar") %> - - - - - - - - - - - -
- <%= link_to(h(e.user), user_path(e.user)) %> - <% if e.instance_of?(JournalsForMessage) %> - <% if e.reply_id == User.current.id %> - <% if e.jour_type == 'Bid' %> - <%= l(:label_in_bids) %><%= link_to(e.jour.name, respond_path(e.jour)) %> <%= l(:label_quote_my_words) %> - <% elsif e.jour_type == 'User' %> - <%= l(:label_in_users) %><%= link_to(e.jour.firstname, feedback_path(e.jour)) %> <%= l(:label_quote_my_words) %> - <% elsif e.jour_type == 'Project' %> - <%= '在'<<%= link_to(e.jour.name, feedback_path(e.jour)) %> <%= l(:label_reply_plural) %> - <% end %> - <% else %> - <%= l(:label_about_requirement) %><%= link_to(e.jour.name, respond_path(e.jour_id)) %> <%= l(:label_have_respond) %> - <% end %> - <% else %> - <% if e.journal_reply.nil? || e.journal_reply.reply_id != User.current.id %> - <%= l(:label_about_issue) %><%= link_to(e.issue.subject, issue_path(e.journalized_id)) %><%= l(:label_have_respond) %> - - <% else %> - <%= l(:label_in_issues) %><%= link_to(e.issue.subject, issue_path(e.issue)) %><%= l(:label_quote_my_words) %> - <% end %> - <% end %> -

<%= textAreailizable e.notes %>

- <%= format_time e.created_on %>
-
- <% end %> -
- - - - <% else %> -

<%= l(:label_no_user_respond_you) %>

- <% end %> - - -<% end %> - + <% if User.current.id == @user.id %> + +
+ <%= form_tag(:controller => 'users', :action => "show") do %> + + <% end %> + <% end %> + + <% unless @state == 2 %> + <% unless @activity.empty? %> +
+ <% @activity.each do |e| %> + <%# 以下一行代码解决有未知的活动无法转换成Model报错%> + <% (Rails.logger.error "[Error] =========================================================> NameError: uninitialized constant " + e.act_type.to_s; next;) if e.act_type.safe_constantize.nil? %> + <% act = e.act %> + <% unless act.nil? %> + <% if e.act_type == 'JournalsForMessage' || e.act_type == 'Bid' || e.act_type == 'Journal'|| e.act_type == 'Changeset' || e.act_type == 'Message' || e.act_type == 'Principal' || e.act_type == 'News' || e.act_type == 'Issue' || e.act_type == 'Contest'%> + + + + + + +
<%= image_tag(url_to_avatar(e.user), :class => "avatar") %> + + <% case e.act_type %> + <% when 'JournalsForMessage' %> + + + + + + + + + + <% when 'Bid' %> + + <% if act.reward_type == 3 && @show_course == 1%> + + <% else %> + + <% end %> + + + + + + + + <% when 'Journal' %> + + + + + <% if act.notes.nil? %> + <% desStr = '' %> + <% else %> + <% desStr= textAreailizable(act, :notes) %> + <% end %> + + + + + + <% when 'Changeset' %> + + + + + + + + + + <% when 'Message' %> + + + + + + + + + + <% when 'Principal' %> + + + + + + + + + + <% when 'News' %> + + + + + + + + + + <% when 'Issue' %> + + + + + + + + + + <% when 'Contest' %> + + + + + + + + + <% else %> + <%# f=1 %> + <% end %> +
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_have_feedback) %> + <%= link_to("#{e.act.user.name}", user_path(e.act.user.id)) %><%= l(:label_of_feedback) + l(:label_layouts_feedback) %> +
+

<%= textAreailizable act.notes %>

+
+ <%= link_to(l(:label_goto), user_newfeedback_user_path(e.user_id)) %> +
+
+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %><%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_active_homework)}##{act.id}:#{act.name}"), respond_path(e.act_id) %> + + <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %><%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_active_call)}##{act.id}:#{act.name}"), respond_path(e.act_id) %> +
+

<%=textAreailizable act, :description %>

+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+ <%= link_to l(:label_find_all_comments), respond_path(e.act_id) %><%= l(:label_comments_count, :count => e.act.commit) %> +
+
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to(l(:label_activity_project)+act.issue.project.name, project_path(act.issue.project.id)) %> <%= link_to format_activity_title("#{act.issue.tracker} ##{act.issue.id}: #{act.issue.subject}"), {:controller => 'issues', :action => 'show', :id => act.issue.id, :anchor => "change-#{act.id}"} %> +

<%= desStr %>

+
+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title(act.title), {:controller => 'repositories', :action => 'revision', :id => act.repository.project, :repository_id => act.repository.identifier_param, :rev => act.identifier} %> +
+

<%= textAreailizable act,:long_comments %>

+
+ <%= format_time(e.act.committed_on) %> +
+
+ <%= link_to l(:label_find_all_comments), {:controller => 'repositories', :action => 'revision', :id => act.repository.project, :repository_id => act.repository.identifier_param, :rev => act.identifier} %><%= l(:label_comments_count, :count => e.act.count) %> +
+
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{act.board.name}: #{act.subject}"), {:controller => 'messages', :action => 'show', :board_id => act.board_id}.merge(act.parent_id.nil? ? {:id => act.id} : {:id => act.parent_id, :r => act.id, :anchor => "message-#{act.id}"}) %> +
+

<%= textAreailizable(act,:content) %>

+
+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_new_user) %> +

+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_news)}: #{act.title}"), {:controller => 'news', :action => 'show', :id => act.id} %> +
+

<%= textAreailizable act,:description %>

+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+ <%= link_to l(:label_find_all_comments), {:controller => 'news', :action => 'show', :id => act.id} %><%= l(:label_comments_count, :count => e.act.comments_count) %> +
+
+ + <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> +   + + <%= l(:label_i_new_activity) %> +   + <%= link_to format_activity_title("#{act.source_from} (#{act.status}): #{act.tracker.name} #{act.subject}"), {:controller => 'issues', :action => 'show', :id => act.id} %> +
+ <%= textAreailizable act, :description %> +
+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+ <%= link_to l(:label_find_all_comments), {:controller => 'issues', :action => 'show', :id => act.id} %><%= l(:label_comments_count, :count => e.act.journals.count) %> +
+
+ <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> <%= l(:label_i_new_activity) %> <%= link_to format_activity_title("#{l(:label_contest)}: #{act.name}"), {:controller => 'contests', :action => 'show_contest', :id => act.id} %> +

<%= textAreailizable act, :description %>

+
+
+ <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> +
+
+
+ <% end %> + <% end %> + + <% end %> +
+ + <% else %> + <% if @user == User.current %> + <%= l(:label_user_activities) %> + <% else %> +

+ <%= l(:label_user_activities_other) %> +

+ <% end %> + <% end %> + + <% else %> + <% unless @message.empty? %> +
+ <% @message.each do |e| -%> + + + + + +
<%= image_tag(url_to_avatar(e.user), :class => "avatar") %> + + + + + + + + + + + +
+ <%= link_to(h(e.user), user_path(e.user)) %> + <% if e.instance_of?(JournalsForMessage) %> + <% if e.reply_id == User.current.id %> + <% if e.jour_type == 'Bid' %> + <%= l(:label_in_bids) %><%= link_to(e.jour.name, respond_path(e.jour)) %> <%= l(:label_quote_my_words) %> + <% elsif e.jour_type == 'User' %> + <%= l(:label_in_users) %><%= link_to(e.jour.firstname, feedback_path(e.jour)) %> <%= l(:label_quote_my_words) %> + <% elsif e.jour_type == 'Project' %> + <%= '在'<<%= link_to(e.jour.name, feedback_path(e.jour)) %> <%= l(:label_reply_plural) %> + <% end %> + <% else %> + <%= l(:label_about_requirement) %><%= link_to(e.jour.name, respond_path(e.jour_id)) %> <%= l(:label_have_respond) %> + <% end %> + <% else %> + <% if e.journal_reply.nil? || e.journal_reply.reply_id != User.current.id %> + <%= l(:label_about_issue) %><%= link_to(e.issue.subject, issue_path(e.journalized_id)) %><%= l(:label_have_respond) %> + + <% else %> + <%= l(:label_in_issues) %><%= link_to(e.issue.subject, issue_path(e.issue)) %><%= l(:label_quote_my_words) %> + <% end %> + <% end %> +

<%= textAreailizable e.notes %>

+ <%= format_time e.created_on %>
+
+ <% end %> +
+ + + + <% else %> +

<%= l(:label_no_user_respond_you) %>

+ <% end %> + + + <% end %> + diff --git a/app/views/welcome/_course_list.html.erb b/app/views/welcome/_course_list.html.erb index b6dac9022..5fdd8cf3d 100644 --- a/app/views/welcome/_course_list.html.erb +++ b/app/views/welcome/_course_list.html.erb @@ -1,32 +1,32 @@ -<% course_list.map do |course| %> -
  • /,"") %>> -
    - <%= image_tag(get_course_avatar(course), :class => "avatar-4") %> -
    - -
    - - <% unless course.is_public == 1 %> - <%= l(:label_private) %> - <% end %> - <%= link_to(course.name.truncate(30, omission: '...')+":", course_path(course.id), :class => "d-g-blue d-p-project-name", :title => "#{course.name}") %> - - - - <%= link_to(course.try(:teacher).try(:realname), user_path(course.teacher)) %> - <%#=course.try(:teacher).try(:name)%> - -
    -
    - [<%= get_course_term course %>] - <% if (course.school == nil) %> -               - <% else %> - <%= link_to course.school.name.try(:gsub, /(.+)$/, '\1'), options={:action => 'course', :school_id => course.school.id}, html_options={:method => 'get'} %> - <% end %> - (<%= course.members.count %>人) - <%# files_count = course.attachments.count.to_s %> - (<%= link_to "#{course.attachments.count.to_s}份", course_files_path(course) %>资料) -
    -
  • -<% end %> +<% course_list.map do |course| %> +
  • /,"") %>> +
    + <%= image_tag(get_course_avatar(course), :class => "avatar-4") %> +
    + +
    + + <% unless course.is_public == 1 %> + <%= l(:label_private) %> + <% end %> + <%= link_to(course.name.truncate(30, omission: '...')+":", course_path(course.id), :class => "d-g-blue d-p-project-name", :title => "#{course.name}") %> + + + + <%= link_to(course.try(:teacher).try(:realname), user_path(course.teacher)) %> + <%#=course.try(:teacher).try(:name)%> + +
    +
    + [<%= get_course_term course %>] + <% if (course.school == nil) %> +               + <% else %> + <%= link_to course.school.name.try(:gsub, /(.+)$/, '\1'), options={:action => 'course', :school_id => course.school.id}, html_options={:method => 'get'} %> + <% end %> + (<%= course.members.count %>人) + <%# files_count = course.attachments.count.to_s %> + (<%= link_to "#{course.attachments.count.to_s}份", course_files_path(course) %>资料) +
    +
  • +<% end %> diff --git a/app/views/welcome/_more_course.html.erb b/app/views/welcome/_more_course.html.erb new file mode 100644 index 000000000..54d8ec6ef --- /dev/null +++ b/app/views/welcome/_more_course.html.erb @@ -0,0 +1,8 @@ +<% if User.current.logged?%> + <% if User.current.user_extensions.identity == 0 %> + <%= link_to(l(:label_course_new), {:controller => 'courses', :action => 'new'}, + :class => 'icon icon-add') if User.current.allowed_to?(:add_course,nil, :global => true) %> + <% end %> +<% end %> +     +<%= link_to "更多>>", {:controller => 'courses', :action => 'index', :school_id => school_id} %> \ No newline at end of file diff --git a/app/views/welcome/contest.html.erb b/app/views/welcome/contest.html.erb index a3cc9f6e9..4f8350fa2 100644 --- a/app/views/welcome/contest.html.erb +++ b/app/views/welcome/contest.html.erb @@ -196,7 +196,7 @@
    -

    +

    <%=l(:label_notification)%>

    diff --git a/app/views/welcome/course.html.erb b/app/views/welcome/course.html.erb index e25ef5665..9ec745f87 100644 --- a/app/views/welcome/course.html.erb +++ b/app/views/welcome/course.html.erb @@ -85,7 +85,7 @@ <%school_course=[]%> <% end %> <% if (school_course.count == 0) %> - <%= link_to "更多>>", {:controller => 'courses', :action => 'index', :school_id => nil} %> + <%= render :partial => 'more_course', :locals => {:school_id => nil}%>
      @@ -103,11 +103,11 @@ <% else %> <% if school_course.count < 10 %> - <%= link_to "更多>>", {:controller => 'courses', :action => 'index', :school_id => nil} %> + <%= render :partial => 'more_course', :locals => {:school_id => nil}%> <% else %> - <%= link_to "更多>>", {:controller => 'courses', :action => 'index', :school_id => @school_id} %> + <%= render :partial => 'more_course', :locals => {:school_id => @school_id}%> <% end %>
      diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 4fd01d319..b73f0970f 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -29,8 +29,7 @@
      - -