From e9124c62ceb6d779b8f78cf9e11de46eb6bc3098 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 23 Oct 2014 09:22:41 +0800 Subject: [PATCH 1/7] =?UTF-8?q?#1250=E4=BF=AE=E6=94=B9=E5=B8=90=E5=8F=B7?= =?UTF-8?q?=E5=90=8E=E5=B0=86=E5=B8=90=E5=8F=B7=E6=9B=B4=E6=96=B0=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E6=94=BE=E5=9C=A8=E4=B8=80=E4=B8=AA=E6=98=BE=E7=9C=BC?= =?UTF-8?q?=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/my_controller.rb | 2 +- app/views/layouts/base_users.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 4e23fc41b..00c843045 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -130,7 +130,7 @@ class MyController < ApplicationController @user.pref.save @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : []) set_language_if_valid @user.language - flash.now[:notice] = l(:notice_account_updated) + flash[:notice] = l(:notice_account_updated) redirect_to user_url(@user) return else diff --git a/app/views/layouts/base_users.html.erb b/app/views/layouts/base_users.html.erb index c1c0eaf7b..97d5fc47f 100644 --- a/app/views/layouts/base_users.html.erb +++ b/app/views/layouts/base_users.html.erb @@ -281,7 +281,7 @@ <%= yield %> <%= call_hook :view_layouts_base_content %>
- <%= render_flash_messages %> + <%#= render_flash_messages %> From 91d08d5b9ac027ed26ce2b1b02f9e3ba4cab5f9a Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 23 Oct 2014 09:44:06 +0800 Subject: [PATCH 2/7] =?UTF-8?q?#1233=E4=BF=AE=E5=A4=8D=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E4=B8=BB=E9=A1=B5--=E5=8A=A8=E6=80=81=EF=BC=9A=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E9=A1=B9=E7=9B=AE=E9=93=BE=E6=8E=A5=E6=8A=A5500?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84BUG=20=E4=BC=98=E5=8C=96=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/users/show.html.erb | 825 ++++++++++++++++++++-------------- 1 file changed, 484 insertions(+), 341 deletions(-) diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index fd0195833..7d13e404e 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -48,353 +48,485 @@ <% 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'%> - + @@ -451,12 +583,19 @@ - + + + <%= format_time e.created_on %> + +
<%= image_tag(url_to_avatar(e.user), :class => "avatar") %> + <%= 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%> - <% if e.user == User.current %> + <% when 'JournalsForMessage' %> + - <% else %> - + + - <% end %> - <% else %> - <% if e.user == User.current %> - + + - <% else %> - + <% 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 %> + + + + + + - <% 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 %> - <% 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 %> + <% end %>
- <% if User.current.login == e.user.try(:login) %> - - <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> - -   - <% else %> - <%= link_to("#{e.user.name}", user_path(e.user_id)) %> - <% end %> - - <%= 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)) %> - + <% if User.current.login == e.user.try(:login) %> + + <%= link_to("#{l(:label_i)}", user_path(e.user_id)) %> + +   + <% else %> + + <%= link_to("#{e.user.name}", user_path(e.user_id)) %> + + <% end %> - <%= l(:label_i_new_activity) %> + <%= 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 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) %> +
+

+ <%= textAreailizable act.notes %> +

+
+ + <%= link_to(l(:label_goto), user_newfeedback_user_path(e.user_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) %> +
+
+ + <%= (l(:label_update_time).to_s << ':' << format_time(e.act.created_on)).to_s %> + +
+
- <%= 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) %> +
+ + <%= 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) %> + +
-

<%=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 %> -
-
+ + <%= 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.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} %> + + + <%= 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 %> + +
+

<%= textAreailizable e.notes %>

+

+ <%= textAreailizable e.notes %> +

+
- <%= format_time e.created_on %>
@@ -466,11 +605,15 @@ <% else %> -

<%= l(:label_no_user_respond_you) %>

+

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

<% end %> From 923a33add544ba0c018e5ccb2ee08f44de0ab391 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 23 Oct 2014 10:44:06 +0800 Subject: [PATCH 3/7] =?UTF-8?q?#1397=E3=80=81#1396=E6=96=B0=E5=BB=BA?= =?UTF-8?q?=E7=AB=9E=E8=B5=9B=E9=80=9A=E7=9F=A5=E5=A2=9E=E5=8A=A0js?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/contestnotifications/_form.html.erb | 39 +++++------ app/views/contestnotifications/index.html.erb | 64 ++++++++++++++++++- config/locales/zh.yml | 4 ++ 3 files changed, 86 insertions(+), 21 deletions(-) diff --git a/app/views/contestnotifications/_form.html.erb b/app/views/contestnotifications/_form.html.erb index 36bcd78c6..908d1138d 100644 --- a/app/views/contestnotifications/_form.html.erb +++ b/app/views/contestnotifications/_form.html.erb @@ -3,24 +3,27 @@ <%= 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;", + :onblur => "regexTitle();" + %> +

+ +

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

+
<%= wikitoolbar_for 'news_description' %> diff --git a/app/views/contestnotifications/index.html.erb b/app/views/contestnotifications/index.html.erb index 8a4278551..a678d87e8 100644 --- a/app/views/contestnotifications/index.html.erb +++ b/app/views/contestnotifications/index.html.erb @@ -1,3 +1,62 @@ + + <%= l(:label_notification) %> @@ -12,10 +71,9 @@ <%= 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', :name => nil %> - <%#= preview_link preview_contestnotifications_path(:contest_id => @contest), 'contestnotifications-form', target='preview', {:class => 'whiteButton m3p10'} %> + | - <%= link_to l(:button_cancel), "#", :onclick => '$("#add-contestnotifications").hide(); return false;', :class => 'whiteButton m3p10' %> + <% end if @contest %>
diff --git a/config/locales/zh.yml b/config/locales/zh.yml index d20bb6e6d..2eb44a0a6 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -2165,3 +2165,7 @@ zh: lable_course_teacher: 主讲老师 lable_course_end: 课程学期已结束 lable_file_sharingarea: 资源共享区 + label_no_contest_news_description: 竞赛描述不能为空 + label_contest_news_condition: 竞赛描述超过5000个汉字 + label_no_contest_news_title: 竞赛标题不能为空 + label_contest_news_title_condition: 竞赛标题超过255个汉字 From 943df643aa80be6a42f5fba4584d6819121b2087 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 23 Oct 2014 10:45:25 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=AB=9E=E8=B5=9B?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E9=A1=B5=E9=9D=A2=E5=8F=96=E6=B6=88=E6=8C=89?= =?UTF-8?q?=E9=92=AEjs=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/contestnotifications/new.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/contestnotifications/new.html.erb b/app/views/contestnotifications/new.html.erb index a5a1c7e58..5008a61d7 100644 --- a/app/views/contestnotifications/new.html.erb +++ b/app/views/contestnotifications/new.html.erb @@ -4,7 +4,7 @@ :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();" %> + <% end %> From d2f4b38eb6fd68a67940b8ffe735d8f7437acde1 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 23 Oct 2014 10:57:23 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AB=9E=E8=B5=9B?= =?UTF-8?q?=E9=80=9A=E7=9F=A5new=E9=A1=B5=E9=9D=A2=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=9A=201.=E5=A2=9E=E5=8A=A0js=E9=AA=8C=E8=AF=81=EF=BC=8C?= =?UTF-8?q?=202.=E4=BF=AE=E5=A4=8D=E7=82=B9=E5=87=BB=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E5=8D=B4=E6=8F=90=E4=BA=A4=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/contestnotifications/_form.html.erb | 51 +++++++++++++++++ app/views/contestnotifications/index.html.erb | 55 +------------------ app/views/contestnotifications/new.html.erb | 16 ++++-- 3 files changed, 65 insertions(+), 57 deletions(-) diff --git a/app/views/contestnotifications/_form.html.erb b/app/views/contestnotifications/_form.html.erb index 908d1138d..f3861f034 100644 --- a/app/views/contestnotifications/_form.html.erb +++ b/app/views/contestnotifications/_form.html.erb @@ -1,4 +1,55 @@ <%= error_messages_for @contestnotifications %> +
<%= l(:bale_news_notice) %>
diff --git a/app/views/contestnotifications/index.html.erb b/app/views/contestnotifications/index.html.erb index a678d87e8..50de15698 100644 --- a/app/views/contestnotifications/index.html.erb +++ b/app/views/contestnotifications/index.html.erb @@ -1,60 +1,11 @@ diff --git a/app/views/contestnotifications/new.html.erb b/app/views/contestnotifications/new.html.erb index 5008a61d7..310a68d77 100644 --- a/app/views/contestnotifications/new.html.erb +++ b/app/views/contestnotifications/new.html.erb @@ -1,11 +1,17 @@ - + <%= 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" %> - - - + + <%= link_to l(:button_cancel), contest_contestnotifications_path(@contest.id) %> <% end %>
From e044f5b615a4b686bba9369cc2c33ccd3eb92594 Mon Sep 17 00:00:00 2001 From: alan <547533434@qq.com> Date: Thu, 23 Oct 2014 11:30:34 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E4=BF=AE=E6=94=B9contest=E4=B8=AD=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E9=80=BB=E8=BE=91=E9=94=99=E8=AF=AF=20Signed?= =?UTF-8?q?-off-by:=20alan=20<547533434@qq.com>?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 268 +- Gemfile.lock | 562 +-- app/controllers/account_controller.rb | 814 ++-- app/controllers/admin_controller.rb | 572 +-- app/controllers/auth_sources_controller.rb | 192 +- app/controllers/bids_controller.rb | 2062 ++++----- app/controllers/boards_controller.rb | 304 +- app/controllers/comments_controller.rb | 110 +- .../contest_notification_controller.rb | 12 +- .../contestnotifications_controller.rb | 374 +- app/controllers/contests_controller.rb | 1466 +++---- app/controllers/custom_fields_controller.rb | 162 +- app/controllers/documents_controller.rb | 240 +- app/controllers/enumerations_controller.rb | 196 +- app/controllers/files_controller.rb | 560 +-- app/controllers/forums_controller.rb | 458 +- app/controllers/groups_controller.rb | 282 +- app/controllers/homework_attach_controller.rb | 730 ++-- .../issue_categories_controller.rb | 264 +- app/controllers/issue_relations_controller.rb | 176 +- app/controllers/issue_statuses_controller.rb | 162 +- app/controllers/issues_controller.rb | 962 ++--- app/controllers/journals_controller.rb | 234 +- app/controllers/members_controller.rb | 652 +-- app/controllers/memos_controller.rb | 414 +- app/controllers/my_controller.rb | 564 +-- app/controllers/news_controller.rb | 352 +- .../notificationcomments_controller.rb | 72 +- .../open_source_projects_controller.rb | 524 +-- .../project_enumerations_controller.rb | 84 +- app/controllers/queries_controller.rb | 212 +- app/controllers/roles_controller.rb | 216 +- app/controllers/search_controller.rb | 222 +- app/controllers/settings_controller.rb | 146 +- .../softapplications_controller.rb | 712 ++-- app/controllers/timelog_controller.rb | 630 +-- app/controllers/trackers_controller.rb | 216 +- .../web_footer_companies_controller.rb | 104 +- app/controllers/wiki_controller.rb | 716 ++-- app/controllers/wikis_controller.rb | 72 +- app/controllers/words_controller.rb | 566 +-- app/controllers/workflows_controller.rb | 256 +- app/helpers/application_helper.rb | 3796 ++++++++--------- app/helpers/attachments_helper.rb | 438 +- app/helpers/logger_helper.rb | 54 +- app/helpers/projects_helper.rb | 756 ++-- app/helpers/watchers_helper.rb | 4 +- app/helpers/welcome_helper.rb | 1024 ++--- app/models/activity.rb | 16 +- app/models/attachment.rb | 1064 ++--- app/models/auth_source.rb | 180 +- app/models/auth_source_ldap.rb | 412 +- app/models/biding_project.rb | 118 +- app/models/board.rb | 180 +- app/models/bug_to_osp.rb | 22 +- app/models/change.rb | 78 +- app/models/changeset.rb | 664 +-- app/models/comment.rb | 48 +- app/models/contest.rb | 268 +- app/models/contest_notification.rb | 8 +- app/models/contesting_project.rb | 106 +- app/models/course.rb | 620 +-- app/models/course_status.rb | 10 +- app/models/enabled_module.rb | 78 +- app/models/softapplication.rb | 78 +- app/models/web_footer_company.rb | 16 +- app/models/web_footer_oranizer.rb | 6 +- app/views/admin/_tab_partial.html.erb | 14 +- app/views/admin/contest_page_made.html.erb | 80 +- app/views/admin/course_page_made.html.erb | 76 +- app/views/admin/first_page_made.html.erb | 118 +- app/views/admin/users.html.erb | 138 +- app/views/admin/web_footer_made.html.erb | 54 +- app/views/attachments/_app_link.html.erb | 34 +- app/views/attachments/_form_course.html.erb | 126 +- app/views/attachments/_links.html.erb | 106 +- app/views/bids/_form.html.erb | 70 +- app/views/bids/_form_contest.html.erb | 72 +- app/views/bids/_history.html.erb | 132 +- app/views/bids/_homework_form.html.erb | 110 +- app/views/bids/_new_bid.html.erb | 162 +- app/views/bids/edit.html.erb | 118 +- app/views/bids/show.html.erb | 72 +- app/views/calendars/show.html.erb | 80 +- app/views/common/403.html | 82 +- app/views/common/404.html | 82 +- app/views/common/_calendar.html.erb | 76 +- app/views/common/_preview.html.erb | 6 +- app/views/contestnotifications/edit.html.erb | 34 +- app/views/contestnotifications/index.html.erb | 244 +- app/views/contests/_form_contest.html.erb | 150 +- app/views/contests/_history.html.erb | 158 +- app/views/contests/new_contest.html.erb | 24 +- .../contests/show_attendingcontest.html.erb | 630 +-- app/views/contests/show_contest.html.erb | 30 +- app/views/contests/show_participator.html.erb | 83 - app/views/contests/show_project.html.erb | 123 - app/views/contests/watcherlist.html.erb | 34 + app/views/courses/_homework_form.html.erb | 118 +- .../courses/_join_private_course.html.erb | 150 +- app/views/courses/_set_join.js.erb | 40 +- app/views/courses/homework.html.erb | 118 +- app/views/courses/join_private_courses.js.erb | 6 +- app/views/courses/search.html.erb | 132 +- app/views/files/index.html.erb | 496 +-- app/views/forums/new.html.erb | 2 +- app/views/homework_attach/_app_link.html.erb | 30 +- .../_comprehensive_evaluation.html.erb | 60 +- .../homework_attach/_evaluation.html.erb | 6 +- .../_evaluation_add_jour.html.erb | 194 +- .../_teacher_evaluation.html.erb | 14 +- app/views/homework_attach/edit.html.erb | 182 +- app/views/homework_attach/new.html.erb | 124 +- app/views/homework_attach/show.html.erb | 350 +- app/views/issues/_list.html.erb | 132 +- app/views/issues/_sidebar.html.erb | 32 +- app/views/issues/bulk_edit.html.erb | 300 +- app/views/issues/index.html.erb | 270 +- app/views/journals/diff.html.erb | 20 +- app/views/layouts/_base_footer.html.erb | 78 +- app/views/layouts/_base_header.html.erb | 256 +- app/views/layouts/_user_courses_list.html.erb | 26 +- app/views/layouts/_user_project_list.html.erb | 22 +- app/views/layouts/base_admin.html.erb | 120 +- app/views/layouts/base_homework.html.erb | 590 +-- app/views/layouts/base_newcontest.html.erb | 2 +- app/views/members/autocomplete.js.erb | 42 +- app/views/my/account.html.erb | 1122 ++--- app/views/news/edit.html.erb | 24 +- app/views/news/new.html.erb | 34 +- app/views/projects/_new_homework.html.erb | 160 +- app/views/projects/_new_join.html.erb | 124 +- app/views/projects/new.html.erb | 32 +- .../projects/settings/_repositories.html.erb | 130 +- app/views/projects/watcherlist.html.erb | 66 +- app/views/repositories/diff.html.erb | 54 +- app/views/settings/_display.html.erb | 52 +- app/views/softapplications/_list.html.erb | 68 +- app/views/softapplications/show.html.erb | 286 +- app/views/stores/index.html.erb | 142 +- app/views/tags/_show_attachments.html.erb | 68 +- app/views/tags/_show_bids.html.erb | 30 +- app/views/tags/_show_courses.html.erb | 28 +- app/views/tags/_show_forums.html.erb | 30 +- app/views/tags/_show_issues.html.erb | 30 +- .../tags/_show_open_source_projects.html.erb | 30 +- app/views/tags/_show_projects.html.erb | 30 +- app/views/tags/_tag.html.erb | 168 +- app/views/tags/_tag_search_results.html.erb | 92 +- app/views/tags/index.html.erb | 96 +- app/views/timelog/_form.html.erb | 64 +- app/views/timelog/bulk_edit.html.erb | 100 +- app/views/users/tag_save.js.erb | 36 +- app/views/users/user_newfeedback.html.erb | 34 +- app/views/users/user_projects.html.erb | 130 +- app/views/versions/_form.html.erb | 82 +- app/views/web_footer_companies/edit.html.erb | 36 +- app/views/web_footer_companies/index.html.erb | 20 +- app/views/web_footer_companies/new.html.erb | 24 +- app/views/welcome/_wei_xin.html.erb | 6 +- app/views/welcome/contest.html.erb | 600 +-- app/views/welcome/index.html.erb | 384 +- app/views/wiki/edit.html.erb | 124 +- app/views/wiki/history.html.erb | 116 +- app/views/wiki/show.html.erb | 140 +- app/views/words/_feedback.html.erb | 98 +- config/environment.rb | 56 +- config/locales/zh.yml | 4 +- config/routes.rb | 1 + config/settings.yml | 540 +-- .../20140916005319_update_works_categories.rb | 52 +- ...140930072719_add_open_student_to_course.rb | 10 +- .../20141009010934_update_bids_proportion.rb | 24 +- ...55029_update_homeworkattach_description.rb | 10 +- ...41013014908_create_web_footer_oranizers.rb | 20 +- ...41013023400_create_web_footer_companies.rb | 22 +- .../lib/acts_as_attachable.rb | 340 +- lib/redmine/menu_manager.rb | 916 ++-- lib/tasks/user_new_score.rake | 46 +- .../app/views/code_review/index.html.erb | 220 +- plugins/redmine_code_review/init.rb | 186 +- public/404.html | 82 +- public/javascripts/attachments.js | 466 +- public/javascripts/welcome.js | 136 +- .../stylesheets/window_js/mac_os_x_dialog.css | 320 +- .../stylesheets/window_js/nuncio.css | 328 +- .../stylesheets/window_js/spread.css | 216 +- test/fixtures/web_footer_companies.yml | 22 +- test/fixtures/web_footer_oranizers.yml | 18 +- .../web_footer_companies_controller_test.rb | 14 +- .../web_footer_companies_helper_test.rb | 8 +- test/unit/web_footer_company_test.rb | 14 +- test/unit/web_footer_oranizer_test.rb | 14 +- 193 files changed, 21986 insertions(+), 22155 deletions(-) delete mode 100644 app/views/contests/show_participator.html.erb delete mode 100644 app/views/contests/show_project.html.erb create mode 100644 app/views/contests/watcherlist.html.erb diff --git a/Gemfile b/Gemfile index 867c0fb75..91e72a745 100644 --- a/Gemfile +++ b/Gemfile @@ -1,134 +1,134 @@ -source 'http://ruby.taobao.org' -#source 'http://ruby.sdutlinux.org/' - -unless RUBY_PLATFORM =~ /w32/ - # unix-like only - gem 'iconv' - gem 'rubyzip' - gem 'zip-zip' -end - -gem 'seems_rateable', path: 'lib/seems_rateable' -gem "rails", "3.2.13" -gem "jquery-rails", "~> 2.0.2" -gem "i18n", "~> 0.6.0" -gem "coderay", "~> 1.0.6" -gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] -gem "builder", "3.0.0" -gem 'acts-as-taggable-on', '2.4.1' - -group :development do - gem 'better_errors', path: 'lib/better_errors' - gem 'rack-mini-profiler', path: 'lib/rack-mini-profiler' -end - -group :test do - gem "shoulda", "~> 3.5.0" - gem "mocha", "~> 1.1.0" - gem 'capybara', '~> 2.4.1' - gem 'nokogiri', '~> 1.6.3' - gem 'factory_girl', '~> 4.4.0' - gem 'selenium-webdriver', '~> 2.42.0' - - - platforms :mri, :mingw do - group :rmagick do - # RMagick 2 supports ruby 1.9 - # RMagick 1 would be fine for ruby 1.8 but Bundler does not support - # different requirements for the same gem on different platforms - gem "rmagick", ">= 2.0.0" - end - end -end - -group :development, :test do - gem "guard-rails", '~> 0.5.3' - gem 'spork-testunit', '~> 0.0.8' - gem 'guard-spork', '~> 1.5.1' - gem 'guard-test', '~> 1.0.0' - gem 'ruby-prof', '~> 0.15.1' unless RUBY_PLATFORM =~ /w32/ - gem 'pry' - gem 'pry-nav' - -end - - -# Gems used only for assets and not required -# in production environments by default. -group :assets do - gem 'sass-rails', '~> 3.2.3' - gem 'coffee-rails', '~> 3.2.1' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - gem 'therubyracer', :platforms => :ruby - - gem 'uglifier', '>= 1.0.3' -end - -# Optional gem for LDAP authentication -group :ldap do - gem "net-ldap", "~> 0.3.1" -end - - -# Optional gem for OpenID authentication -group :openid do - gem "ruby-openid", "~> 2.1.4", :require => "openid" - gem "rack-openid" -end - -# Optional gem for exporting the gantt to a PNG file, not supported with jruby -platforms :jruby do - # jruby-openssl is bundled with JRuby 1.7.0 - gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0' - gem "activerecord-jdbc-adapter", "1.2.5" -end - -# Include database gems for the adapters found in the database -# configuration file -require 'erb' -require 'yaml' -database_file = File.join(File.dirname(__FILE__), "config/database.yml") -if File.exist?(database_file) - database_config = YAML::load(ERB.new(IO.read(database_file)).result) - adapters = database_config.values.map {|c| c['adapter']}.compact.uniq - if adapters.any? - adapters.each do |adapter| - case adapter - when 'mysql2' - gem "mysql2", "= 0.3.11", :platforms => [:mri, :mingw] - gem "activerecord-jdbcmysql-adapter", :platforms => :jruby - when 'mysql' - gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw] - gem "activerecord-jdbcmysql-adapter", :platforms => :jruby - when /postgresql/ - gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw] - gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby - when /sqlite3/ - gem "sqlite3", :platforms => [:mri, :mingw] - gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby - when /sqlserver/ - gem "tiny_tds", "~> 0.5.1", :platforms => [:mri, :mingw] - gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw] - else - warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems") - end - end - else - warn("No adapter found in config/database.yml, please configure it first") - end -else - warn("Please configure your config/database.yml first") -end - -local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") -if File.exists?(local_gemfile) - puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v` - instance_eval File.read(local_gemfile) -end - -# Load plugins' Gemfiles -Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file| - puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v` - instance_eval File.read(file) -end +source 'http://ruby.taobao.org' +#source 'http://ruby.sdutlinux.org/' + +unless RUBY_PLATFORM =~ /w32/ + # unix-like only + gem 'iconv' + gem 'rubyzip' + gem 'zip-zip' +end + +gem 'seems_rateable', path: 'lib/seems_rateable' +gem "rails", "3.2.13" +gem "jquery-rails", "~> 2.0.2" +gem "i18n", "~> 0.6.0" +gem "coderay", "~> 1.0.6" +gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] +gem "builder", "3.0.0" +gem 'acts-as-taggable-on', '2.4.1' + +group :development do + gem 'better_errors', path: 'lib/better_errors' + gem 'rack-mini-profiler', path: 'lib/rack-mini-profiler' +end + +group :test do + gem "shoulda", "~> 3.5.0" + gem "mocha", "~> 1.1.0" + gem 'capybara', '~> 2.4.1' + gem 'nokogiri', '~> 1.6.3' + gem 'factory_girl', '~> 4.4.0' + gem 'selenium-webdriver', '~> 2.42.0' + + + platforms :mri, :mingw do + group :rmagick do + # RMagick 2 supports ruby 1.9 + # RMagick 1 would be fine for ruby 1.8 but Bundler does not support + # different requirements for the same gem on different platforms + gem "rmagick", ">= 2.0.0" + end + end +end + +group :development, :test do + gem "guard-rails", '~> 0.5.3' + gem 'spork-testunit', '~> 0.0.8' + gem 'guard-spork', '~> 1.5.1' + gem 'guard-test', '~> 1.0.0' + gem 'ruby-prof', '~> 0.15.1' unless RUBY_PLATFORM =~ /w32/ + gem 'pry' + gem 'pry-nav' + +end + + +# Gems used only for assets and not required +# in production environments by default. +group :assets do + gem 'sass-rails', '~> 3.2.3' + gem 'coffee-rails', '~> 3.2.1' + + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + gem 'therubyracer', :platforms => :ruby + + gem 'uglifier', '>= 1.0.3' +end + +# Optional gem for LDAP authentication +group :ldap do + gem "net-ldap", "~> 0.3.1" +end + + +# Optional gem for OpenID authentication +group :openid do + gem "ruby-openid", "~> 2.1.4", :require => "openid" + gem "rack-openid" +end + +# Optional gem for exporting the gantt to a PNG file, not supported with jruby +platforms :jruby do + # jruby-openssl is bundled with JRuby 1.7.0 + gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0' + gem "activerecord-jdbc-adapter", "1.2.5" +end + +# Include database gems for the adapters found in the database +# configuration file +require 'erb' +require 'yaml' +database_file = File.join(File.dirname(__FILE__), "config/database.yml") +if File.exist?(database_file) + database_config = YAML::load(ERB.new(IO.read(database_file)).result) + adapters = database_config.values.map {|c| c['adapter']}.compact.uniq + if adapters.any? + adapters.each do |adapter| + case adapter + when 'mysql2' + gem "mysql2", "= 0.3.11", :platforms => [:mri, :mingw] + gem "activerecord-jdbcmysql-adapter", :platforms => :jruby + when 'mysql' + gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw] + gem "activerecord-jdbcmysql-adapter", :platforms => :jruby + when /postgresql/ + gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw] + gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby + when /sqlite3/ + gem "sqlite3", :platforms => [:mri, :mingw] + gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby + when /sqlserver/ + gem "tiny_tds", "~> 0.5.1", :platforms => [:mri, :mingw] + gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw] + else + warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems") + end + end + else + warn("No adapter found in config/database.yml, please configure it first") + end +else + warn("Please configure your config/database.yml first") +end + +local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") +if File.exists?(local_gemfile) + puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v` + instance_eval File.read(local_gemfile) +end + +# Load plugins' Gemfiles +Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file| + puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v` + instance_eval File.read(file) +end diff --git a/Gemfile.lock b/Gemfile.lock index 0ecb19aff..4ba8ecf6c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,281 +1,281 @@ -PATH - remote: lib/better_errors - specs: - better_errors (1.1.0) - coderay (>= 1.0.0) - erubis (>= 2.6.6) - -PATH - remote: lib/rack-mini-profiler - specs: - rack-mini-profiler (0.9.1) - rack (>= 1.1.3) - -PATH - remote: lib/seems_rateable - specs: - seems_rateable (1.0.13) - jquery-rails - rails - -GEM - remote: http://ruby.taobao.org/ - remote: https://rubygems.org/ - specs: - actionmailer (3.2.13) - actionpack (= 3.2.13) - mail (~> 2.5.3) - actionpack (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - builder (~> 3.0.0) - erubis (~> 2.7.0) - journey (~> 1.0.4) - rack (~> 1.4.5) - rack-cache (~> 1.2) - rack-test (~> 0.6.1) - sprockets (~> 2.2.1) - activemodel (3.2.13) - activesupport (= 3.2.13) - builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activeresource (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - activesupport (3.2.13) - i18n (= 0.6.1) - multi_json (~> 1.0) - acts-as-taggable-on (2.4.1) - rails (>= 3, < 5) - arel (3.0.3) - builder (3.0.0) - capybara (2.4.1) - mime-types (>= 1.16) - nokogiri (>= 1.3.3) - rack (>= 1.0.0) - rack-test (>= 0.5.4) - xpath (~> 2.0) - celluloid (0.15.2) - timers (~> 1.1.0) - childprocess (0.5.3) - ffi (~> 1.0, >= 1.0.11) - climate_control (0.0.3) - activesupport (>= 3.0) - cocaine (0.5.4) - climate_control (>= 0.0.3, < 1.0) - coderay (1.0.9) - coffee-rails (3.2.2) - coffee-script (>= 2.2.0) - railties (~> 3.2.0) - coffee-script (2.3.0) - coffee-script-source - execjs - coffee-script-source (1.7.1) - erubis (2.7.0) - execjs (2.2.1) - factory_girl (4.4.0) - activesupport (>= 3.0.0) - fastercsv (1.5.5) - ffi (1.9.3) - ffi (1.9.3-x86-mingw32) - formatador (0.2.5) - guard (2.6.1) - formatador (>= 0.2.4) - listen (~> 2.7) - lumberjack (~> 1.0) - pry (>= 0.9.12) - thor (>= 0.18.1) - guard-rails (0.5.3) - guard (~> 2.0) - guard-spork (1.5.1) - childprocess (>= 0.2.3) - guard (>= 1.1) - spork (>= 0.8.4) - guard-test (1.0.0) - guard (>= 1.8) - test-unit (~> 2.2) - hike (1.2.3) - htmlentities (4.3.2) - i18n (0.6.1) - journey (1.0.4) - jquery-rails (2.0.3) - railties (>= 3.1.0, < 5.0) - thor (~> 0.14) - json (1.8.1) - kaminari (0.16.1) - actionpack (>= 3.0.0) - activesupport (>= 3.0.0) - libv8 (3.16.14.3) - listen (2.7.9) - celluloid (>= 0.15.2) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) - lumberjack (1.0.9) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) - metaclass (0.0.4) - method_source (0.8.2) - mime-types (1.25.1) - mini_portile (0.6.0) - mocha (1.1.0) - metaclass (~> 0.0.1) - multi_json (1.10.1) - mysql2 (0.3.11-x86-mingw32) - net-ldap (0.3.1) - nokogiri (1.6.3) - mini_portile (= 0.6.0) - nokogiri (1.6.3-x86-mingw32) - mini_portile (= 0.6.0) - paperclip (3.5.4) - activemodel (>= 3.0.0) - activesupport (>= 3.0.0) - cocaine (~> 0.5.3) - mime-types - polyglot (0.3.5) - pry (0.9.12.6) - coderay (~> 1.0) - method_source (~> 0.8) - slop (~> 3.4) - pry (0.9.12.6-x86-mingw32) - coderay (~> 1.0) - method_source (~> 0.8) - slop (~> 3.4) - win32console (~> 1.3) - pry-nav (0.2.3) - pry (~> 0.9.10) - rack (1.4.5) - rack-cache (1.2) - rack (>= 0.4) - rack-openid (1.4.2) - rack (>= 1.1.0) - ruby-openid (>= 2.1.8) - rack-raw-upload (1.1.1) - multi_json - rack-ssl (1.3.4) - rack - rack-test (0.6.2) - rack (>= 1.0) - rails (3.2.13) - actionmailer (= 3.2.13) - actionpack (= 3.2.13) - activerecord (= 3.2.13) - activeresource (= 3.2.13) - activesupport (= 3.2.13) - bundler (~> 1.0) - railties (= 3.2.13) - railties (3.2.13) - actionpack (= 3.2.13) - activesupport (= 3.2.13) - rack-ssl (~> 1.3.2) - rake (>= 0.8.7) - rdoc (~> 3.4) - thor (>= 0.14.6, < 2.0) - rake (10.3.2) - rb-fsevent (0.9.4) - rb-inotify (0.9.5) - ffi (>= 0.5.0) - rdoc (3.12.2) - json (~> 1.4) - ref (1.0.5) - rich (1.4.6) - jquery-rails - kaminari - mime-types - paperclip - rack-raw-upload - rails (>= 3.2.0) - sass-rails - rmagick (2.13.2) - ruby-openid (2.1.8) - rubyzip (1.1.6) - sass (3.3.10) - sass-rails (3.2.6) - railties (~> 3.2.0) - sass (>= 3.1.10) - tilt (~> 1.3) - selenium-webdriver (2.42.0) - childprocess (>= 0.5.0) - multi_json (~> 1.0) - rubyzip (~> 1.0) - websocket (~> 1.0.4) - shoulda (3.5.0) - shoulda-context (~> 1.0, >= 1.0.1) - shoulda-matchers (>= 1.4.1, < 3.0) - shoulda-context (1.2.1) - shoulda-matchers (2.6.1) - activesupport (>= 3.0.0) - slop (3.5.0) - spork (0.9.2) - spork-testunit (0.0.8) - spork (>= 0.6.0) - sprockets (2.2.2) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - test-unit (2.5.5) - therubyracer (0.12.1) - libv8 (~> 3.16.14.0) - ref - thor (0.19.1) - tilt (1.4.1) - timers (1.1.0) - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) - tzinfo (0.3.40) - uglifier (2.5.1) - execjs (>= 0.3.0) - json (>= 1.8.0) - websocket (1.0.7) - win32console (1.3.2-x86-mingw32) - xpath (2.0.0) - nokogiri (~> 1.3) - -PLATFORMS - ruby - x86-mingw32 - -DEPENDENCIES - activerecord-jdbc-adapter (= 1.2.5) - activerecord-jdbcmysql-adapter - acts-as-taggable-on (= 2.4.1) - better_errors! - builder (= 3.0.0) - capybara (~> 2.4.1) - coderay (~> 1.0.6) - coffee-rails (~> 3.2.1) - factory_girl (~> 4.4.0) - fastercsv (~> 1.5.0) - guard-rails (~> 0.5.3) - guard-spork (~> 1.5.1) - guard-test (~> 1.0.0) - htmlentities - i18n (~> 0.6.0) - jquery-rails (~> 2.0.2) - kaminari - mocha (~> 1.1.0) - mysql2 (= 0.3.11) - net-ldap (~> 0.3.1) - nokogiri (~> 1.6.3) - paperclip (~> 3.5.4) - pry - pry-nav - rack-mini-profiler! - rack-openid - rails (= 3.2.13) - rich (= 1.4.6) - rmagick (>= 2.0.0) - ruby-openid (~> 2.1.4) - sass-rails (~> 3.2.3) - seems_rateable! - selenium-webdriver (~> 2.42.0) - shoulda (~> 3.5.0) - spork-testunit (~> 0.0.8) - therubyracer - uglifier (>= 1.0.3) +PATH + remote: lib/better_errors + specs: + better_errors (1.1.0) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + +PATH + remote: lib/rack-mini-profiler + specs: + rack-mini-profiler (0.9.1) + rack (>= 1.1.3) + +PATH + remote: lib/seems_rateable + specs: + seems_rateable (1.0.13) + jquery-rails + rails + +GEM + remote: http://ruby.taobao.org/ + remote: https://rubygems.org/ + specs: + actionmailer (3.2.13) + actionpack (= 3.2.13) + mail (~> 2.5.3) + actionpack (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + erubis (~> 2.7.0) + journey (~> 1.0.4) + rack (~> 1.4.5) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.2.1) + activemodel (3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + activerecord (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activeresource (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + activesupport (3.2.13) + i18n (= 0.6.1) + multi_json (~> 1.0) + acts-as-taggable-on (2.4.1) + rails (>= 3, < 5) + arel (3.0.3) + builder (3.0.0) + capybara (2.4.1) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + celluloid (0.15.2) + timers (~> 1.1.0) + childprocess (0.5.3) + ffi (~> 1.0, >= 1.0.11) + climate_control (0.0.3) + activesupport (>= 3.0) + cocaine (0.5.4) + climate_control (>= 0.0.3, < 1.0) + coderay (1.0.9) + coffee-rails (3.2.2) + coffee-script (>= 2.2.0) + railties (~> 3.2.0) + coffee-script (2.3.0) + coffee-script-source + execjs + coffee-script-source (1.7.1) + erubis (2.7.0) + execjs (2.2.1) + factory_girl (4.4.0) + activesupport (>= 3.0.0) + fastercsv (1.5.5) + ffi (1.9.3) + ffi (1.9.3-x86-mingw32) + formatador (0.2.5) + guard (2.6.1) + formatador (>= 0.2.4) + listen (~> 2.7) + lumberjack (~> 1.0) + pry (>= 0.9.12) + thor (>= 0.18.1) + guard-rails (0.5.3) + guard (~> 2.0) + guard-spork (1.5.1) + childprocess (>= 0.2.3) + guard (>= 1.1) + spork (>= 0.8.4) + guard-test (1.0.0) + guard (>= 1.8) + test-unit (~> 2.2) + hike (1.2.3) + htmlentities (4.3.2) + i18n (0.6.1) + journey (1.0.4) + jquery-rails (2.0.3) + railties (>= 3.1.0, < 5.0) + thor (~> 0.14) + json (1.8.1) + kaminari (0.16.1) + actionpack (>= 3.0.0) + activesupport (>= 3.0.0) + libv8 (3.16.14.3) + listen (2.7.9) + celluloid (>= 0.15.2) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + lumberjack (1.0.9) + mail (2.5.4) + mime-types (~> 1.16) + treetop (~> 1.4.8) + metaclass (0.0.4) + method_source (0.8.2) + mime-types (1.25.1) + mini_portile (0.6.0) + mocha (1.1.0) + metaclass (~> 0.0.1) + multi_json (1.10.1) + mysql2 (0.3.11-x86-mingw32) + net-ldap (0.3.1) + nokogiri (1.6.3) + mini_portile (= 0.6.0) + nokogiri (1.6.3-x86-mingw32) + mini_portile (= 0.6.0) + paperclip (3.5.4) + activemodel (>= 3.0.0) + activesupport (>= 3.0.0) + cocaine (~> 0.5.3) + mime-types + polyglot (0.3.5) + pry (0.9.12.6) + coderay (~> 1.0) + method_source (~> 0.8) + slop (~> 3.4) + pry (0.9.12.6-x86-mingw32) + coderay (~> 1.0) + method_source (~> 0.8) + slop (~> 3.4) + win32console (~> 1.3) + pry-nav (0.2.3) + pry (~> 0.9.10) + rack (1.4.5) + rack-cache (1.2) + rack (>= 0.4) + rack-openid (1.4.2) + rack (>= 1.1.0) + ruby-openid (>= 2.1.8) + rack-raw-upload (1.1.1) + multi_json + rack-ssl (1.3.4) + rack + rack-test (0.6.2) + rack (>= 1.0) + rails (3.2.13) + actionmailer (= 3.2.13) + actionpack (= 3.2.13) + activerecord (= 3.2.13) + activeresource (= 3.2.13) + activesupport (= 3.2.13) + bundler (~> 1.0) + railties (= 3.2.13) + railties (3.2.13) + actionpack (= 3.2.13) + activesupport (= 3.2.13) + rack-ssl (~> 1.3.2) + rake (>= 0.8.7) + rdoc (~> 3.4) + thor (>= 0.14.6, < 2.0) + rake (10.3.2) + rb-fsevent (0.9.4) + rb-inotify (0.9.5) + ffi (>= 0.5.0) + rdoc (3.12.2) + json (~> 1.4) + ref (1.0.5) + rich (1.4.6) + jquery-rails + kaminari + mime-types + paperclip + rack-raw-upload + rails (>= 3.2.0) + sass-rails + rmagick (2.13.2) + ruby-openid (2.1.8) + rubyzip (1.1.6) + sass (3.3.10) + sass-rails (3.2.6) + railties (~> 3.2.0) + sass (>= 3.1.10) + tilt (~> 1.3) + selenium-webdriver (2.42.0) + childprocess (>= 0.5.0) + multi_json (~> 1.0) + rubyzip (~> 1.0) + websocket (~> 1.0.4) + shoulda (3.5.0) + shoulda-context (~> 1.0, >= 1.0.1) + shoulda-matchers (>= 1.4.1, < 3.0) + shoulda-context (1.2.1) + shoulda-matchers (2.6.1) + activesupport (>= 3.0.0) + slop (3.5.0) + spork (0.9.2) + spork-testunit (0.0.8) + spork (>= 0.6.0) + sprockets (2.2.2) + hike (~> 1.2) + multi_json (~> 1.0) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + test-unit (2.5.5) + therubyracer (0.12.1) + libv8 (~> 3.16.14.0) + ref + thor (0.19.1) + tilt (1.4.1) + timers (1.1.0) + treetop (1.4.15) + polyglot + polyglot (>= 0.3.1) + tzinfo (0.3.40) + uglifier (2.5.1) + execjs (>= 0.3.0) + json (>= 1.8.0) + websocket (1.0.7) + win32console (1.3.2-x86-mingw32) + xpath (2.0.0) + nokogiri (~> 1.3) + +PLATFORMS + ruby + x86-mingw32 + +DEPENDENCIES + activerecord-jdbc-adapter (= 1.2.5) + activerecord-jdbcmysql-adapter + acts-as-taggable-on (= 2.4.1) + better_errors! + builder (= 3.0.0) + capybara (~> 2.4.1) + coderay (~> 1.0.6) + coffee-rails (~> 3.2.1) + factory_girl (~> 4.4.0) + fastercsv (~> 1.5.0) + guard-rails (~> 0.5.3) + guard-spork (~> 1.5.1) + guard-test (~> 1.0.0) + htmlentities + i18n (~> 0.6.0) + jquery-rails (~> 2.0.2) + kaminari + mocha (~> 1.1.0) + mysql2 (= 0.3.11) + net-ldap (~> 0.3.1) + nokogiri (~> 1.6.3) + paperclip (~> 3.5.4) + pry + pry-nav + rack-mini-profiler! + rack-openid + rails (= 3.2.13) + rich (= 1.4.6) + rmagick (>= 2.0.0) + ruby-openid (~> 2.1.4) + sass-rails (~> 3.2.3) + seems_rateable! + selenium-webdriver (~> 2.42.0) + shoulda (~> 3.5.0) + spork-testunit (~> 0.0.8) + therubyracer + uglifier (>= 1.0.3) diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index 36b6435c8..74c988781 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -1,407 +1,407 @@ -# 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 AccountController < ApplicationController - helper :custom_fields - include CustomFieldsHelper - - # prevents login action to be filtered by check_if_login_required application scope filter - skip_before_filter :check_if_login_required - - # Login request and validation - def login - if request.get? - if User.current.logged? - redirect_to home_url - end - else - authenticate_user - end - rescue AuthSourceException => e - logger.error "An error occured when authenticating #{params[:username]}: #{e.message}" - render_error :message => e.message - end - - # Log out current user and redirect to welcome page - def logout - if User.current.anonymous? - redirect_to home_url - elsif request.post? - logout_user - redirect_to home_url - end - # display the logout form - end - - # Lets user choose a new password - def lost_password - (redirect_to(home_url); return) unless Setting.lost_password? - if params[:token] - @token = Token.find_token("recovery", params[:token].to_s) - if @token.nil? || @token.expired? - redirect_to home_url - return - end - @user = @token.user - unless @user && @user.active? - redirect_to home_url - return - end - if request.post? - @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] - if @user.save - @token.destroy - flash[:notice] = l(:notice_account_password_updated) - redirect_to signin_url - return - end - end - render :template => "account/password_recovery" - return - else - if request.post? - user = User.find_by_mail(params[:mail].to_s) - # user not found or not active - unless user && user.active? - flash.now[:error] = l(:notice_account_unknown_email) - return - end - # user cannot change its password - unless user.change_password_allowed? - flash.now[:error] = l(:notice_can_t_change_password) - return - end - # create a new token for password recovery - token = Token.new(:user => user, :action => "recovery") - if token.save - Thread.new do - Mailer.lost_password(token).deliver - end - flash[:notice] = l(:notice_account_lost_email_sent) - redirect_to signin_url - return - end - end - end - end - - # User self-registration - def register - # @root_path="/home/pdl/redmine-2.3.2-0/apache2/" -# - @cache_identityy = params[:identity]||"" #身份 - @cache_no = params[:no]||"" #学号 - @cache_technical_title = params[:technical_title]||"" #教师职称 - @cache_province = params[:province]||"" #省份 - @cache_city = params[:city]||"" #城市 - @cache_enterprise_name = params[:enterprise_name]||"" #企业 - - firstname_code = "" - lastname_code = "" - (redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration] - if request.get? - session[:auth_source_registration] = nil - @user = User.new(:language => current_language.to_s) - else - user_params = params[:user] || {} - @user = User.new - @user.safe_attributes = user_params - if params[:identity] == "2" # 2 企业 - firstname_code = @user.firstname - lastname_code = @user.lastname - @user.firstname = params[:enterprise_name] - @user.lastname = l(:field_enterprise) - end - @user.admin = false - @user.register - if session[:auth_source_registration] - @user.activate - @user.login = session[:auth_source_registration][:login] - @user.auth_source_id = session[:auth_source_registration][:auth_source_id] - if @user.save - session[:auth_source_registration] = nil - self.logged_user = @user - flash[:notice] = l(:notice_account_activated) - redirect_to my_account_url - end - else - @user.login = params[:user][:login] - unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank? - @user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation] - end - - if(@cache_identityy == "") - if params[:identity] == "2" - @user.firstname = firstname_code - @user.lastname = lastname_code - end - flash.now[:error]= l(:label_identity)+l(:'activerecord.errors.messages.empty') - return - end - if(@cache_city == "") - if params[:identity] == "2" - @user.firstname = firstname_code - @user.lastname = lastname_code - end - flash.now[:error]= l(:label_location)+l(:'activerecord.errors.messages.empty') - return - end - - case Setting.self_registration - when '1' - register_by_email_activation(@user) - when '3' - register_automatically(@user) - else - register_manually_by_administrator(@user) - end - - #added by bai - if @user.id != nil - ue = @user.user_extensions ||= UserExtensions.new - #ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => ) - ue.identity = params[:identity].to_i - ue.technical_title = params[:technical_title] - ue.gender = params[:gender].to_i - ue.user_id = @user.id - ue.student_id = params[:no] - ue.location = params[:province] if params[:province] != nil - ue.location_city = params[:city] if params[:city] != nil - ue.save - end - - end - end - if params[:identity] == "2" - @user.firstname = firstname_code - @user.lastname = lastname_code - end - end - - # Token based account activation - def activate - (redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present? - token = Token.find_token('register', params[:token].to_s) - (redirect_to(home_url); return) unless token and !token.expired? - user = token.user - (redirect_to(home_url); return) unless user.registered? - user.activate - if user.save - token.destroy - flash[:notice] = l(:notice_account_activated) - end - redirect_to signin_url - end - - def valid_ajax - req = Hash.new(false) - req[:message] = '' - - valid_attr = params[:valid] - valid_value = params[:value] - - faker = User.new - - if valid_attr.eql?('login') - faker.login = valid_value - faker.valid? - req[:valid] = faker.errors[:login].blank? - req[:message] = faker.errors[:login] - end - - if valid_attr.eql?('mail') - faker.mail = valid_value - faker.valid? - req[:valid] = faker.errors[:mail].blank? - req[:message] = faker.errors[:mail] - end - - req[:message] = l(:modal_valid_passing) if req[:message].blank? - render :json => req - end - - private - - def authenticate_user - if Setting.openid? && using_open_id? - open_id_authenticate(params[:openid_url]) - else - password_authentication - end - end - - def password_authentication - user = User.try_to_login(params[:username], params[:password]) - - if user.nil? - invalid_credentials - elsif user.status == 2 - invalid_credentials_new - elsif user.new_record? - onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id }) - else - # Valid user - successful_authentication(user) - end - end - - def open_id_authenticate(openid_url) - back_url = signin_url(:autologin => params[:autologin]) - - authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => back_url, :method => :post) do |result, identity_url, registration| - if result.successful? - user = User.find_or_initialize_by_identity_url(identity_url) - if user.new_record? - # Self-registration off - (redirect_to(home_url); return) unless Setting.self_registration? - - # Create on the fly - user.login = registration['nickname'] unless registration['nickname'].nil? - user.mail = registration['email'] unless registration['email'].nil? - user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil? - user.random_password - user.register - - case Setting.self_registration - when '1' - register_by_email_activation(user) do - onthefly_creation_failed(user) - end - when '3' - register_automatically(user) do - onthefly_creation_failed(user) - end - else - register_manually_by_administrator(user) do - onthefly_creation_failed(user) - end - end - else - # Existing record - if user.active? - successful_authentication(user) - else - account_pending - end - end - end - end - end - - def successful_authentication(user) - logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}" - # Valid user - self.logged_user = user - # generate a key and set cookie if autologin - if params[:autologin] && Setting.autologin? - set_autologin_cookie(user) - end - call_hook(:controller_account_success_authentication_after, {:user => user }) - - code = /\d*/ - #根据home_url生产正则表达式 - eval("code = " + "/^" + home_url.gsub(/\//,"\\\/") + "\\\/*(welcome)?\\\/*(\\\/index\\\/*.*)?\$/") - if code=~params[:back_url] - redirect_to user_activities_path(user) - else - #by young - #redirect_back_or_default my_page_path - redirect_back_or_default User.current - #redirect_to User.current - end - end - - def set_autologin_cookie(user) - token = Token.create(:user => user, :action => 'autologin') - cookie_options = { - :value => token.value, - :expires => 1.year.from_now, - :path => (Redmine::Configuration['autologin_cookie_path'] || '/'), - :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false), - :httponly => true - } - cookies[autologin_cookie_name] = cookie_options - end - - # Onthefly creation failed, display the registration form to fill/fix attributes - def onthefly_creation_failed(user, auth_source_options = { }) - @user = user - session[:auth_source_registration] = auth_source_options unless auth_source_options.empty? - render :action => 'register' - end - - def invalid_credentials - logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}" - flash.now[:error] = l(:notice_account_invalid_creditentials) - end - - def invalid_credentials_new - logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}" - flash.now[:error] = l(:notice_account_invalid_creditentials_new) - end - - # Register a user for email activation. - # - # Pass a block for behavior when a user fails to save - def register_by_email_activation(user, &block) - token = Token.new(:user => user, :action => "register") - if user.save and token.save - UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0) - Mailer.register(token).deliver - flash[:notice] = l(:notice_account_register_done) - redirect_to signin_url - else - yield if block_given? - end - end - - # Automatically register a user - # - # Pass a block for behavior when a user fails to save - def register_automatically(user, &block) - # Automatic activation - user.activate - user.last_login_on = Time.now - if user.save - UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0) - self.logged_user = user - flash[:notice] = l(:notice_account_activated) - redirect_to my_account_url - else - yield if block_given? - end - end - - # Manual activation by the administrator - # - # Pass a block for behavior when a user fails to save - def register_manually_by_administrator(user, &block) - if user.save - UserStatus.create(:user_id => user.id ,:changsets_count => 0, :watchers_count => 0) - # Sends an email to the administrators - Mailer.account_activation_request(user).deliver - account_pending - else - yield if block_given? - end - end - - def account_pending - flash[:notice] = l(:notice_account_pending) - redirect_to signin_url - 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 AccountController < ApplicationController + helper :custom_fields + include CustomFieldsHelper + + # prevents login action to be filtered by check_if_login_required application scope filter + skip_before_filter :check_if_login_required + + # Login request and validation + def login + if request.get? + if User.current.logged? + redirect_to home_url + end + else + authenticate_user + end + rescue AuthSourceException => e + logger.error "An error occured when authenticating #{params[:username]}: #{e.message}" + render_error :message => e.message + end + + # Log out current user and redirect to welcome page + def logout + if User.current.anonymous? + redirect_to home_url + elsif request.post? + logout_user + redirect_to home_url + end + # display the logout form + end + + # Lets user choose a new password + def lost_password + (redirect_to(home_url); return) unless Setting.lost_password? + if params[:token] + @token = Token.find_token("recovery", params[:token].to_s) + if @token.nil? || @token.expired? + redirect_to home_url + return + end + @user = @token.user + unless @user && @user.active? + redirect_to home_url + return + end + if request.post? + @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] + if @user.save + @token.destroy + flash[:notice] = l(:notice_account_password_updated) + redirect_to signin_url + return + end + end + render :template => "account/password_recovery" + return + else + if request.post? + user = User.find_by_mail(params[:mail].to_s) + # user not found or not active + unless user && user.active? + flash.now[:error] = l(:notice_account_unknown_email) + return + end + # user cannot change its password + unless user.change_password_allowed? + flash.now[:error] = l(:notice_can_t_change_password) + return + end + # create a new token for password recovery + token = Token.new(:user => user, :action => "recovery") + if token.save + Thread.new do + Mailer.lost_password(token).deliver + end + flash[:notice] = l(:notice_account_lost_email_sent) + redirect_to signin_url + return + end + end + end + end + + # User self-registration + def register + # @root_path="/home/pdl/redmine-2.3.2-0/apache2/" +# + @cache_identityy = params[:identity]||"" #身份 + @cache_no = params[:no]||"" #学号 + @cache_technical_title = params[:technical_title]||"" #教师职称 + @cache_province = params[:province]||"" #省份 + @cache_city = params[:city]||"" #城市 + @cache_enterprise_name = params[:enterprise_name]||"" #企业 + + firstname_code = "" + lastname_code = "" + (redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration] + if request.get? + session[:auth_source_registration] = nil + @user = User.new(:language => current_language.to_s) + else + user_params = params[:user] || {} + @user = User.new + @user.safe_attributes = user_params + if params[:identity] == "2" # 2 企业 + firstname_code = @user.firstname + lastname_code = @user.lastname + @user.firstname = params[:enterprise_name] + @user.lastname = l(:field_enterprise) + end + @user.admin = false + @user.register + if session[:auth_source_registration] + @user.activate + @user.login = session[:auth_source_registration][:login] + @user.auth_source_id = session[:auth_source_registration][:auth_source_id] + if @user.save + session[:auth_source_registration] = nil + self.logged_user = @user + flash[:notice] = l(:notice_account_activated) + redirect_to my_account_url + end + else + @user.login = params[:user][:login] + unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank? + @user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation] + end + + if(@cache_identityy == "") + if params[:identity] == "2" + @user.firstname = firstname_code + @user.lastname = lastname_code + end + flash.now[:error]= l(:label_identity)+l(:'activerecord.errors.messages.empty') + return + end + if(@cache_city == "") + if params[:identity] == "2" + @user.firstname = firstname_code + @user.lastname = lastname_code + end + flash.now[:error]= l(:label_location)+l(:'activerecord.errors.messages.empty') + return + end + + case Setting.self_registration + when '1' + register_by_email_activation(@user) + when '3' + register_automatically(@user) + else + register_manually_by_administrator(@user) + end + + #added by bai + if @user.id != nil + ue = @user.user_extensions ||= UserExtensions.new + #ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => ) + ue.identity = params[:identity].to_i + ue.technical_title = params[:technical_title] + ue.gender = params[:gender].to_i + ue.user_id = @user.id + ue.student_id = params[:no] + ue.location = params[:province] if params[:province] != nil + ue.location_city = params[:city] if params[:city] != nil + ue.save + end + + end + end + if params[:identity] == "2" + @user.firstname = firstname_code + @user.lastname = lastname_code + end + end + + # Token based account activation + def activate + (redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present? + token = Token.find_token('register', params[:token].to_s) + (redirect_to(home_url); return) unless token and !token.expired? + user = token.user + (redirect_to(home_url); return) unless user.registered? + user.activate + if user.save + token.destroy + flash[:notice] = l(:notice_account_activated) + end + redirect_to signin_url + end + + def valid_ajax + req = Hash.new(false) + req[:message] = '' + + valid_attr = params[:valid] + valid_value = params[:value] + + faker = User.new + + if valid_attr.eql?('login') + faker.login = valid_value + faker.valid? + req[:valid] = faker.errors[:login].blank? + req[:message] = faker.errors[:login] + end + + if valid_attr.eql?('mail') + faker.mail = valid_value + faker.valid? + req[:valid] = faker.errors[:mail].blank? + req[:message] = faker.errors[:mail] + end + + req[:message] = l(:modal_valid_passing) if req[:message].blank? + render :json => req + end + + private + + def authenticate_user + if Setting.openid? && using_open_id? + open_id_authenticate(params[:openid_url]) + else + password_authentication + end + end + + def password_authentication + user = User.try_to_login(params[:username], params[:password]) + + if user.nil? + invalid_credentials + elsif user.status == 2 + invalid_credentials_new + elsif user.new_record? + onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id }) + else + # Valid user + successful_authentication(user) + end + end + + def open_id_authenticate(openid_url) + back_url = signin_url(:autologin => params[:autologin]) + + authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => back_url, :method => :post) do |result, identity_url, registration| + if result.successful? + user = User.find_or_initialize_by_identity_url(identity_url) + if user.new_record? + # Self-registration off + (redirect_to(home_url); return) unless Setting.self_registration? + + # Create on the fly + user.login = registration['nickname'] unless registration['nickname'].nil? + user.mail = registration['email'] unless registration['email'].nil? + user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil? + user.random_password + user.register + + case Setting.self_registration + when '1' + register_by_email_activation(user) do + onthefly_creation_failed(user) + end + when '3' + register_automatically(user) do + onthefly_creation_failed(user) + end + else + register_manually_by_administrator(user) do + onthefly_creation_failed(user) + end + end + else + # Existing record + if user.active? + successful_authentication(user) + else + account_pending + end + end + end + end + end + + def successful_authentication(user) + logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}" + # Valid user + self.logged_user = user + # generate a key and set cookie if autologin + if params[:autologin] && Setting.autologin? + set_autologin_cookie(user) + end + call_hook(:controller_account_success_authentication_after, {:user => user }) + + code = /\d*/ + #根据home_url生产正则表达式 + eval("code = " + "/^" + home_url.gsub(/\//,"\\\/") + "\\\/*(welcome)?\\\/*(\\\/index\\\/*.*)?\$/") + if code=~params[:back_url] + redirect_to user_activities_path(user) + else + #by young + #redirect_back_or_default my_page_path + redirect_back_or_default User.current + #redirect_to User.current + end + end + + def set_autologin_cookie(user) + token = Token.create(:user => user, :action => 'autologin') + cookie_options = { + :value => token.value, + :expires => 1.year.from_now, + :path => (Redmine::Configuration['autologin_cookie_path'] || '/'), + :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false), + :httponly => true + } + cookies[autologin_cookie_name] = cookie_options + end + + # Onthefly creation failed, display the registration form to fill/fix attributes + def onthefly_creation_failed(user, auth_source_options = { }) + @user = user + session[:auth_source_registration] = auth_source_options unless auth_source_options.empty? + render :action => 'register' + end + + def invalid_credentials + logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}" + flash.now[:error] = l(:notice_account_invalid_creditentials) + end + + def invalid_credentials_new + logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}" + flash.now[:error] = l(:notice_account_invalid_creditentials_new) + end + + # Register a user for email activation. + # + # Pass a block for behavior when a user fails to save + def register_by_email_activation(user, &block) + token = Token.new(:user => user, :action => "register") + if user.save and token.save + UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0) + Mailer.register(token).deliver + flash[:notice] = l(:notice_account_register_done) + redirect_to signin_url + else + yield if block_given? + end + end + + # Automatically register a user + # + # Pass a block for behavior when a user fails to save + def register_automatically(user, &block) + # Automatic activation + user.activate + user.last_login_on = Time.now + if user.save + UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0) + self.logged_user = user + flash[:notice] = l(:notice_account_activated) + redirect_to my_account_url + else + yield if block_given? + end + end + + # Manual activation by the administrator + # + # Pass a block for behavior when a user fails to save + def register_manually_by_administrator(user, &block) + if user.save + UserStatus.create(:user_id => user.id ,:changsets_count => 0, :watchers_count => 0) + # Sends an email to the administrators + Mailer.account_activation_request(user).deliver + account_pending + else + yield if block_given? + end + end + + def account_pending + flash[:notice] = l(:notice_account_pending) + redirect_to signin_url + end +end diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index fb6c2e8fe..3326d0b1a 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -1,286 +1,286 @@ -# 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 AdminController < ApplicationController - layout 'admin' - menu_item :projects, :only => :projects - menu_item :plugins, :only => :plugins - menu_item :info, :only => :info - - before_filter :require_admin - helper :sort - helper :Users - helper :Settings - include SortHelper - - def index - @no_configuration_data = Redmine::DefaultData::Loader::no_data? - end - - def projects - @status = params[:status] || 1 - - scope = Project.status(@status).order('lft') - scope = scope.like(params[:name]) if params[:name].present? - @projects = scope.where(project_type: Project::ProjectType_project).all - - render :action => "projects", :layout => false if request.xhr? - end - - def users - 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#per_page_option - end - - @status = params[:status] || 1 - scope = User.logged.status(@status) - scope = User.like(params[:name]) if params[:name].present? - scope = scope.in_group(params[:group_id]) if params[:group_id].present? - - @user_count = scope.count - @user_pages = Paginator.new @user_count, @limit, params['page'] - @offset ||= @user_pages.offset - @users = scope.order(sort_clause).limit(@limit).offset(@offset).all - - - respond_to do |format| - format.html { - @groups = Group.all.sort - } - format.api - end - end - - def plugins - @plugins = Redmine::Plugin.all - end - - # Loads the default configuration - # (roles, trackers, statuses, workflow, enumerations) - def default_configuration - if request.post? - begin - Redmine::DefaultData::Loader::load(params[:lang]) - flash[:notice] = l(:notice_default_data_loaded) - rescue Exception => e - flash[:error] = l(:error_can_t_load_default_data, e.message) - end - end - redirect_to admin_url - end - - def test_email - raise_delivery_errors = ActionMailer::Base.raise_delivery_errors - # Force ActionMailer to raise delivery errors so we can catch it - ActionMailer::Base.raise_delivery_errors = true - begin - @test = Mailer.test_email(User.current).deliver - flash[:notice] = l(:notice_email_sent, User.current.mail) - rescue Exception => e - flash[:error] = l(:notice_email_error, e.message) - end - ActionMailer::Base.raise_delivery_errors = raise_delivery_errors - redirect_to settings_url(:tab => 'notifications') - end - - def info - @db_adapter_name = ActiveRecord::Base.connection.adapter_name - @checklist = [ - [:text_default_administrator_account_changed, User.default_admin_account_changed?], - [:text_file_repository_writable, File.writable?(Attachment.storage_path)], - [:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)], - [:text_rmagick_available, Object.const_defined?(:Magick)] - ] - end - #管理功能用户列表的搜索 - def search - 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#per_page_option - end - - @status = params[:status] || 1 - 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':'base' - - @users = scope.offset(@user_pages.offset).limit(@user_pages.per_page) - - respond_to do |format| - format.html { - @groups = Group.all.sort - } - format.api - end - end - - #首页定制 - def first_page_made - if request.get? - @first_page = FirstPage.find_by_page_type('project') - elsif request.post? - @first_page = FirstPage.find_by_page_type('project') - @first_page.web_title = params[:web_title] - @first_page.description = params[:first_page][:description] - #@first_page.title = params[:title] - @first_page.image_width = params[:image_width] - @first_page.image_height = params[:image_height] - @first_page.sort_type = params[:sort_type] - @first_page.show_course = params[:show_course] - @first_page.show_contest = params[:show_contest] - if @first_page.save - respond_to do |format| - flash[:notice] = l(:notice_successful_update) - format.html { - redirect_to first_page_made_url - } - format.api { render_api_ok } - #format.json { render json: @first_page, status: :created, location: @first_page } - end - else - respond_to do |format| - flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}" - format.html { - render :action => 'first_page_made' - } - format.api { render_validation_errors(@first_page) } - #format.json { render json: @first_page.errors, status: :unprocessable_entity } - end - end - end - end - - def course_page_made - if request.get? - @course_page = FirstPage.find_by_page_type('course') - @first_page = FirstPage.find_by_page_type('project') - elsif request.post? - @first_page = FirstPage.find_by_page_type('project') - @course_page = FirstPage.find_by_page_type('course') - @first_page.web_title = params[:web_title] - @course_page.web_title = params[:web_title] - @course_page.title = params[:course_title] - @course_page.image_width = params[:image_width] - @course_page.image_height = params[:image_height] - @course_page.description = params[:course_description] - if @first_page.save && @course_page.save - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_to course_page_made_url - } - format.api { render_api_ok } - end - else - respond_to do |format| - flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@course_page.errors.full_messages[0]}" - #flash.now[:error] = "#{l :label_first_page_create_fail}: #{@course_page.errors.full_messages[0]}" - format.html { - - render :action => 'course_page_made' - } - format.api { render_validation_errors(@first_page) } - format.api { render_validation_errors(@course_page) } - end - end - end - end - - def contest_page_made - if request.get? - @contest_page = FirstPage.find_by_page_type('contest') - @first_page = FirstPage.find_by_page_type('project') - elsif request.post? - @first_page = FirstPage.find_by_page_type('project') - @contest_page = FirstPage.find_by_page_type('contest') - @first_page.web_title = params[:web_title] - @contest_page.web_title = params[:web_title] - @contest_page.title = params[:contest_title] - @contest_page.image_width = params[:image_width] - @contest_page.image_height = params[:image_height] - @contest_page.description = params[:contest_description] - - if @first_page.save && @contest_page.save - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_to contest_page_made_url - } - format.api { render_api_ok } - end - else - respond_to do |format| - flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@contest_page.errors.full_messages[0]}\n\t#{@notification.errors.full_messages[0]}" - format.html { - render :action => 'contest_page_made' - } - format.api { render_validation_errors(@first_page) } - format.api { render_validation_errors(@contest_page) } - end - end - end - end - - def web_footer_made - if request.get? - @organizer = WebFooterOranizer.first - @first_page = FirstPage.find_by_page_type('project') - #@notification = ContestNotification.all.first; - elsif request.post? - @first_page = FirstPage.find_by_page_type('project') - @first_page.web_title = params[:web_title] - @organizer = WebFooterOranizer.first - if @organizer.nil? - @organizer = WebFooterOranizer.new - end - @organizer.name = params[:organizer_name] - @organizer.description = params[:web_footer_oranizer][:description] - if @first_page.save && @organizer.save - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_to web_footer_made_url - } - format.api { render_api_ok } - end - else - respond_to do |format| - flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@organizer.errors.full_messages[0]}}" - format.html { - render :action => 'web_footer_made' - } - format.api { render_validation_errors(@first_page) } - format.api { render_validation_errors(@contest_page) } - end - end - 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 AdminController < ApplicationController + layout 'admin' + menu_item :projects, :only => :projects + menu_item :plugins, :only => :plugins + menu_item :info, :only => :info + + before_filter :require_admin + helper :sort + helper :Users + helper :Settings + include SortHelper + + def index + @no_configuration_data = Redmine::DefaultData::Loader::no_data? + end + + def projects + @status = params[:status] || 1 + + scope = Project.status(@status).order('lft') + scope = scope.like(params[:name]) if params[:name].present? + @projects = scope.where(project_type: Project::ProjectType_project).all + + render :action => "projects", :layout => false if request.xhr? + end + + def users + 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#per_page_option + end + + @status = params[:status] || 1 + scope = User.logged.status(@status) + scope = User.like(params[:name]) if params[:name].present? + scope = scope.in_group(params[:group_id]) if params[:group_id].present? + + @user_count = scope.count + @user_pages = Paginator.new @user_count, @limit, params['page'] + @offset ||= @user_pages.offset + @users = scope.order(sort_clause).limit(@limit).offset(@offset).all + + + respond_to do |format| + format.html { + @groups = Group.all.sort + } + format.api + end + end + + def plugins + @plugins = Redmine::Plugin.all + end + + # Loads the default configuration + # (roles, trackers, statuses, workflow, enumerations) + def default_configuration + if request.post? + begin + Redmine::DefaultData::Loader::load(params[:lang]) + flash[:notice] = l(:notice_default_data_loaded) + rescue Exception => e + flash[:error] = l(:error_can_t_load_default_data, e.message) + end + end + redirect_to admin_url + end + + def test_email + raise_delivery_errors = ActionMailer::Base.raise_delivery_errors + # Force ActionMailer to raise delivery errors so we can catch it + ActionMailer::Base.raise_delivery_errors = true + begin + @test = Mailer.test_email(User.current).deliver + flash[:notice] = l(:notice_email_sent, User.current.mail) + rescue Exception => e + flash[:error] = l(:notice_email_error, e.message) + end + ActionMailer::Base.raise_delivery_errors = raise_delivery_errors + redirect_to settings_url(:tab => 'notifications') + end + + def info + @db_adapter_name = ActiveRecord::Base.connection.adapter_name + @checklist = [ + [:text_default_administrator_account_changed, User.default_admin_account_changed?], + [:text_file_repository_writable, File.writable?(Attachment.storage_path)], + [:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)], + [:text_rmagick_available, Object.const_defined?(:Magick)] + ] + end + #管理功能用户列表的搜索 + def search + 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#per_page_option + end + + @status = params[:status] || 1 + 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':'base' + + @users = scope.offset(@user_pages.offset).limit(@user_pages.per_page) + + respond_to do |format| + format.html { + @groups = Group.all.sort + } + format.api + end + end + + #首页定制 + def first_page_made + if request.get? + @first_page = FirstPage.find_by_page_type('project') + elsif request.post? + @first_page = FirstPage.find_by_page_type('project') + @first_page.web_title = params[:web_title] + @first_page.description = params[:first_page][:description] + #@first_page.title = params[:title] + @first_page.image_width = params[:image_width] + @first_page.image_height = params[:image_height] + @first_page.sort_type = params[:sort_type] + @first_page.show_course = params[:show_course] + @first_page.show_contest = params[:show_contest] + if @first_page.save + respond_to do |format| + flash[:notice] = l(:notice_successful_update) + format.html { + redirect_to first_page_made_url + } + format.api { render_api_ok } + #format.json { render json: @first_page, status: :created, location: @first_page } + end + else + respond_to do |format| + flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}" + format.html { + render :action => 'first_page_made' + } + format.api { render_validation_errors(@first_page) } + #format.json { render json: @first_page.errors, status: :unprocessable_entity } + end + end + end + end + + def course_page_made + if request.get? + @course_page = FirstPage.find_by_page_type('course') + @first_page = FirstPage.find_by_page_type('project') + elsif request.post? + @first_page = FirstPage.find_by_page_type('project') + @course_page = FirstPage.find_by_page_type('course') + @first_page.web_title = params[:web_title] + @course_page.web_title = params[:web_title] + @course_page.title = params[:course_title] + @course_page.image_width = params[:image_width] + @course_page.image_height = params[:image_height] + @course_page.description = params[:course_description] + if @first_page.save && @course_page.save + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_to course_page_made_url + } + format.api { render_api_ok } + end + else + respond_to do |format| + flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@course_page.errors.full_messages[0]}" + #flash.now[:error] = "#{l :label_first_page_create_fail}: #{@course_page.errors.full_messages[0]}" + format.html { + + render :action => 'course_page_made' + } + format.api { render_validation_errors(@first_page) } + format.api { render_validation_errors(@course_page) } + end + end + end + end + + def contest_page_made + if request.get? + @contest_page = FirstPage.find_by_page_type('contest') + @first_page = FirstPage.find_by_page_type('project') + elsif request.post? + @first_page = FirstPage.find_by_page_type('project') + @contest_page = FirstPage.find_by_page_type('contest') + @first_page.web_title = params[:web_title] + @contest_page.web_title = params[:web_title] + @contest_page.title = params[:contest_title] + @contest_page.image_width = params[:image_width] + @contest_page.image_height = params[:image_height] + @contest_page.description = params[:contest_description] + + if @first_page.save && @contest_page.save + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_to contest_page_made_url + } + format.api { render_api_ok } + end + else + respond_to do |format| + flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@contest_page.errors.full_messages[0]}\n\t#{@notification.errors.full_messages[0]}" + format.html { + render :action => 'contest_page_made' + } + format.api { render_validation_errors(@first_page) } + format.api { render_validation_errors(@contest_page) } + end + end + end + end + + def web_footer_made + if request.get? + @organizer = WebFooterOranizer.first + @first_page = FirstPage.find_by_page_type('project') + #@notification = ContestNotification.all.first; + elsif request.post? + @first_page = FirstPage.find_by_page_type('project') + @first_page.web_title = params[:web_title] + @organizer = WebFooterOranizer.first + if @organizer.nil? + @organizer = WebFooterOranizer.new + end + @organizer.name = params[:organizer_name] + @organizer.description = params[:web_footer_oranizer][:description] + if @first_page.save && @organizer.save + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_to web_footer_made_url + } + format.api { render_api_ok } + end + else + respond_to do |format| + flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@organizer.errors.full_messages[0]}}" + format.html { + render :action => 'web_footer_made' + } + format.api { render_validation_errors(@first_page) } + format.api { render_validation_errors(@contest_page) } + end + end + end + end + +end diff --git a/app/controllers/auth_sources_controller.rb b/app/controllers/auth_sources_controller.rb index 81542cf47..b298a789f 100644 --- a/app/controllers/auth_sources_controller.rb +++ b/app/controllers/auth_sources_controller.rb @@ -1,96 +1,96 @@ -# 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 AuthSourcesController < ApplicationController - layout 'admin' - menu_item :ldap_authentication - - before_filter :require_admin - before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy] - - def index - @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25 - end - - def new - klass_name = params[:type] || 'AuthSourceLdap' - @auth_source = AuthSource.new_subclass_instance(klass_name, params[:auth_source]) - render_404 unless @auth_source - end - - def create - @auth_source = AuthSource.new_subclass_instance(params[:type], params[:auth_source]) - if @auth_source.save - flash[:notice] = l(:notice_successful_create) - redirect_to auth_sources_url - else - render :action => 'new' - end - end - - def edit - end - - def update - if @auth_source.update_attributes(params[:auth_source]) - flash[:notice] = l(:notice_successful_update) - redirect_to auth_sources_url - else - render :action => 'edit' - end - end - - def test_connection - begin - @auth_source.test_connection - flash[:notice] = l(:notice_successful_connection) - rescue Exception => e - flash[:error] = l(:error_unable_to_connect, e.message) - end - redirect_to auth_sources_url - end - - def destroy - unless @auth_source.users.exists? - @auth_source.destroy - flash[:notice] = l(:notice_successful_delete) - end - redirect_to auth_sources_url - end - - def autocomplete_for_new_user - results = AuthSource.search(params[:term]) - - render :json => results.map {|result| { - 'value' => result[:login], - 'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})", - 'login' => result[:login].to_s, - 'firstname' => result[:firstname].to_s, - 'lastname' => result[:lastname].to_s, - 'mail' => result[:mail].to_s, - 'auth_source_id' => result[:auth_source_id].to_s - }} - end - - private - - def find_auth_source - @auth_source = AuthSource.find(params[:id]) - 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. + +class AuthSourcesController < ApplicationController + layout 'admin' + menu_item :ldap_authentication + + before_filter :require_admin + before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy] + + def index + @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25 + end + + def new + klass_name = params[:type] || 'AuthSourceLdap' + @auth_source = AuthSource.new_subclass_instance(klass_name, params[:auth_source]) + render_404 unless @auth_source + end + + def create + @auth_source = AuthSource.new_subclass_instance(params[:type], params[:auth_source]) + if @auth_source.save + flash[:notice] = l(:notice_successful_create) + redirect_to auth_sources_url + else + render :action => 'new' + end + end + + def edit + end + + def update + if @auth_source.update_attributes(params[:auth_source]) + flash[:notice] = l(:notice_successful_update) + redirect_to auth_sources_url + else + render :action => 'edit' + end + end + + def test_connection + begin + @auth_source.test_connection + flash[:notice] = l(:notice_successful_connection) + rescue Exception => e + flash[:error] = l(:error_unable_to_connect, e.message) + end + redirect_to auth_sources_url + end + + def destroy + unless @auth_source.users.exists? + @auth_source.destroy + flash[:notice] = l(:notice_successful_delete) + end + redirect_to auth_sources_url + end + + def autocomplete_for_new_user + results = AuthSource.search(params[:term]) + + render :json => results.map {|result| { + 'value' => result[:login], + 'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})", + 'login' => result[:login].to_s, + 'firstname' => result[:firstname].to_s, + 'lastname' => result[:lastname].to_s, + 'mail' => result[:mail].to_s, + 'auth_source_id' => result[:auth_source_id].to_s + }} + end + + private + + def find_auth_source + @auth_source = AuthSource.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/bids_controller.rb b/app/controllers/bids_controller.rb index d9b28c08a..a45b64c8c 100644 --- a/app/controllers/bids_controller.rb +++ b/app/controllers/bids_controller.rb @@ -1,1031 +1,1031 @@ -# fq -class BidsController < ApplicationController - #Added by young - menu_item l(:label_homework), :only => [:edit, :udpate] - menu_item :respond - menu_item :course, :only => :show_courseEx - menu_item :project, :only => [:show_project,:show_results, :new_submit_homework] - menu_item :homework_respond, :only => :homework_respond - menu_item :homework_statistics, :only => :homework_statistics - - before_filter :can_show_course,only: [] - before_filter :can_show_contest,only: [] - #Ended by young - before_filter :find_bid, :only => [:show, :show_project, :create,:destroy,:more,:back,:add,:delete,:new,:show_results,:set_reward, :add_homework, :fork, :create_fork, - :show_course, :show_courseEx,:show_bid_project, :show_bid_user, :join_in_contest, :unjoin_in_contest, :new_join,:show_participator, :settings] - # 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 :memberAccess, only: :show_project - - helper :watchers - helper :attachments - include AttachmentsHelper - include ApplicationHelper - include BidsHelper - - helper :projects - helper :words - helper :welcome - helper :project_score - - def find_project_by_bid_id - @bid = Bid.find(params[:id]) - @project = @bid.courses[0] - rescue ActiveRecord::RecordNotFound - render_404 - end - - def homework_ajax_modal - @bid = Bid.find_by_id(params[:id]) - # find_bid - respond_to do |format| - format.js - end - end - - - def index - @project_type = params[:project_type] - # Modified by nie - # @requirement_title = "4" - @offset, @limit = api_offset_and_limit({:limit => 10}) - if @project_type == '1' - @bids = Bid.visible.where('reward_type = ?', 3) - # elsif - # @bids = Bid.visible.where('reward_type = ? or reward_type = ?', 4) - else - @bids = Bid.visible.where('reward_type = ?', 1) - end - - @bids = @bids.like(params[:name]) if params[:name].present? - @bid_count = @bids.count - @bid_pages = Paginator.new @bid_count, @limit, params['page'] - - @offset ||= @bid_pages.reverse_offset - #added by nie - if params[:bid_sort_type].present? - case params[:bid_sort_type] - when '0' - unless @offset == 0 - @bids = @bids.offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.offset(@offset).limit(limit).all.reverse - end - @s_state = 0 - when '1' - unless @offset == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse - end - @s_state = 1 - when '2' - unless @offset == 0 - @bids = @bids.offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.offset(@offset).limit(@limit).all.reverse - end - @s_state = 0 - end - else - unless @offset == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse - end - @s_state = 1 - end - #end - end - #huang - def contest - - # Modified by nie - # @requirement_title = "4" - @offset, @limit = api_offset_and_limit({:limit => 10}) - - @bids = Bid.visible.where('reward_type = ?', 2) - - # elsif - # @bids = Bid.visible.where('reward_type = ? or reward_type = ?', 4) - @bids = @bids.like(params[:name]) if params[:name].present? - @bid_count = @bids.count - @bid_pages = Paginator.new @bid_count, @limit, params['page'] - - @offset ||= @bid_pages.reverse_offset - #added by nie - if params[:contest_sort_type].present? - case params[:contest_sort_type] - when '0' - unless @offset == 0 - @bids = @bids.offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.offset(@offset).limit(limit).all.reverse - end - @s_state = 0 - when '1' - unless @offset == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse - end - @s_state = 1 - when '2' - unless @offset == 0 - @bids = @bids.offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.offset(@offset).limit(@limit).all.reverse - end - @s_state = 0 - end - else - unless @offset == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - limit = @limit if limit == 0 - @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse - end - @s_state = 1 - end - #end - end - - def fork - @courses = [] - @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) - @membership.each do |membership| - if membership.project.project_type == 1 - @courses << membership.project - end - end - end - - def create_fork - @homework = Bid.new - @homework.name = params[:bid][:name] - @homework.description = params[:bid][:description] - @homework.reward_type = 3 - # @bid.budget = params[:bid][:budget] - @homework.deadline = params[:bid][:deadline] - @homework.budget = 0 - @homework.author_id = User.current.id - @homework.commit = 0 - @homework.homework_type = 1 - @homework.is_evaluation = params[:bid][:is_evaluation] - @homework.parent_id = @bid.id - @homework.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) - # @bid. - if @homework.save - HomeworkForCourse.create(:course_id => params[:course], :bid_id => @homework.id) - unless @bid.watched_by?(User.current) - if @bid.add_watcher(User.current) - flash[:notice] = l(:label_bid_succeed) - end - end - redirect_to respond_path(@homework) - else - @bid.safe_attributes = params[:bid] - @courses = [] - @membership = User.current.coursememberships.all#(:conditions => Project.visible_condition(User.current)) - @membership.each do |membership| - @courses << membership.course - end - render :action => 'fork' - end - end - - def show - @user = @bid.author - @jours = @bid.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - @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 - - respond_to do |format| - layout_file = '' - case @bid.reward_type - when 3 - html_title(l(:label_question_student)) - layout_file = 'base_homework' - when 1 - layout_file = 'base_bids' - else - layout_file = 'base_contest' - end - format.html { - render :layout => layout_file - } - format.api - end - end - - def join_in_contest - if @bid.reward_type == 2 && params[:course_password] == @bid.password - JoinInContest.create(:user_id => User.current.id, :bid_id => @bid.id) - @state = 0 - else - @state = 1 - end - - respond_to do |format| - # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} - # TO_DO - format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } - end - end - - def unjoin_in_contest - - joined = JoinInContest.where('bid_id = ? and user_id = ?', @bid.id, User.current.id) - - joined.each do |join| - join.delete - end - - respond_to do |format| - # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} - format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } - end - end - - def new_join - # added by fq - - - end - - # added by bai 增加了参与者和竞赛设置 - def show_participator - render :layout => 'base_contest' - - end - - def settings - if @bid.author.id == User.current.id - if @bid.reward_type == 2 - @contest = Bid.find_by_reward_type(@bid.reward_type) - render :layout => 'base_contest' - end - else - render_403 :message => :notice_not_contest_setting_authorized - end - end - #end - - # 显示课程 - def show_course - bids = Bid.where('parent_id = ?', @bid.id) - @courses = [] - for bid in bids - @courses << bid.courses.first - end - - respond_to do |format| - if @bid.reward_type == 3 - format.html { - render :layout => 'base_homework' - } - elsif @bid.reward_type == 1 - format.html { - render :layout => 'base_bids' - } - else - format.html { - render :layout => 'base_contest' - } - end - format.api - - end - end - - def show_bid_project - bids = Bid.where('parent_id = ?', @bid.id) - @projects = [] - for bid in bids - @projects += bid.biding_projects - end - - respond_to do |format| - if @bid.reward_type == 3 - format.html { - render :layout => 'base_homework' - } - elsif @bid.reward_type == 1 - format.html { - render :layout => 'base_bids' - } - else - format.html { - render :layout => 'base_contest' - } - end - format.api - - end - end - - def show_bid_user - bids = Bid.where('parent_id = ?', @bid.id) - @users = [] - for bid in bids - for project in bid.projects - @users += project.users - end - end - - respond_to do |format| - if @bid.reward_type == 3 - format.html { - render :layout => 'base_homework' - } - elsif @bid.reward_type == 1 - format.html { - render :layout => 'base_bids' - } - else - format.html { - render :layout => 'base_contest' - } - end - format.api - - end - end - - def show_project - # flash[:notice] = "" - @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) - @option = [] - @membership.each do |membership| - unless(membership.project.project_type==1) - if membership.user.allowed_to?(:quote_project,membership.project) - @option << membership.project - end - end - end - - # a = [1] - # @project = Project.where("id in []", a) - @user = @bid.author - @bidding_project = @bid.biding_projects.all - if params[:student_id].present? - @temp = [] - @bidding_project.each do |pro| - if pro.project && pro.project.project_status - if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id - @temp << pro - end - end - @temp - end - @bidding_project = @temp - else - #added by nie - @temp = [] - @bidding_project.each do |pro| - if pro.project && pro.project.project_status - @temp << pro - end - @temp - end - if @temp.size > 0 - @bidding_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} - end - #ended - end - - if @bid.homework_type == 1 - @homework = HomeworkAttach.new - #@homework_list = @bid.homeworks - #增加作业按评分排序, - @homework_list = @bid.homeworks.eager_load(:rate_averages, :user, :attachments).order('seems_rateable_cached_ratings.avg DESC').order("#{HomeworkAttach.table_name}.created_at ASC") - if params[:student_id].present? - @temp = [] - @homework_list.each do |pro| - if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id - @temp << pro - end - @temp - end - @homework_list = @temp - end - end - - respond_to do |format| - if @bid.reward_type == 3 - format.html { - render :layout => 'base_homework' - } - elsif @bid.reward_type == 1 - format.html { - render :layout => 'base_bids' - } - else - format.html { - render :layout => 'base_contest' - } - end - format.api - end - end - - # 显示作业课程 - # add by nwb - def show_courseEx - if (User.current.logged? && (User.current.member_of_course?(@bid.courses.first) || User.current.admin?)) - # flash[:notice] = "" - @membership = User.current.coursememberships.all(:conditions => Course.visible_condition(User.current)) - - @user = @bid.author - @bidding_project = @bid.biding_projects.all - - if params[:student_id].present? - @temp = [] - @bidding_project.each do |pro| - if pro.project && pro.project.project_status - if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id - @temp << pro - end - end - @temp - end - @bidding_project = @temp - else - #added by nie - @temp = [] - @bidding_project.each do |pro| - if pro.project && pro.project.project_status - @temp << pro - end - @temp - end - if @temp.size > 0 - @bidding_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} - end - #ended - end - - if @bid.homework_type - @homework = HomeworkAttach.new - if @bid.proportion - teacher_proportion = @bid.proportion * 1.0 / 100 - else - teacher_proportion = 1.0 - end - #@homework_list = @bid.homeworks - #增加作业按评分排序, - #@homework_list = @bid.homeworks.eager_load(:rate_averages, :user, :attachments).order('seems_rateable_cached_ratings.avg DESC').order("#{HomeworkAttach.table_name}.created_at ASC") - all_homework_list = HomeworkAttach.eager_load(:attachments,:user,:rate_averages).find_by_sql("SELECT homework_attaches.*, - (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id = #{@bid.author_id}) AS t_score, - (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id <> #{@bid.author_id}) AS s_score - FROM homework_attaches WHERE bid_id = #{@bid.id} ORDER BY - (CASE WHEN t_score IS NULL THEN 0 ELSE t_score * #{teacher_proportion} END + CASE WHEN s_score IS NULL THEN 0 ELSE s_score * #{1 - teacher_proportion} END) DESC,created_at ASC") - - limit = 10 - feedback_count = all_homework_list.count - @feedback_pages = Paginator.new feedback_count, limit, params['page'] - offset ||= @feedback_pages.offset - @homework_list = all_homework_list[offset, limit] - - if params[:student_id].present? - @temp = [] - @homework_list.each do |pro| - if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id - @temp << pro - end - @temp - end - @homework_list = @temp - end - end - - respond_to do |format| - if @bid.reward_type == 3 - format.html { - html_title(l(:label_homework_info)) - render :layout => 'base_homework' - } - elsif @bid.reward_type == 1 - format.html { - render :layout => 'base_bids' - } - else - format.html { - render :layout => 'base_contest' - } - end - format.api - end - else - render_403 :message => :notice_not_authorized - end - end - - ##### by huang - def show_project_homework - # flash[:notice] = "" - @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) - @option = [] - @membership.each do |membership| - end - # a = [1] - # @project = Project.where("id in []", a) - @user = @bid.author - @bidding_project = @bid.biding_projects - respond_to do |format| - if @bid.reward_type == 3 - format.html { - render :layout => 'base_homework' - } - elsif @bid.reward_type == 1 - format.html { - render :layout => 'base_bids' - } - else - format.html { - render :layout => 'base_contest' - } - end - format.api - end - end - - ###添加应标项目 - def add - project = Project.find(params[:bid]) - bid_message = params[:bid_for_save][:bid_message] - if BidingProject.where("project_id = ? and bid_id = ?", project.id, @bid.id).size == 0 - if BidingProject.cerate_bidding(@bid.id, project.id, bid_message) - - # added by bai type ==1 需求,type==2 竞赛, type==3 作业 - if @bid.reward_type == 1 - flash.now[:notice] = l(:label_bidding_succeed) - - elsif @bid.reward_type == 2 - flash.now[:notice] = l(:label_bidding_contest_succeed) - - else @bid.reward_type == 3 - flash.now[:notice] = l(:label_bidding_homework_succeed) - end - # end - - end - else - if @bid.reward_type == 3 - flash.now[:error] = l(:label_bidding_homework_fail) - else - flash.now[:error] = l(:label_bidding_fail) - end - end - @bidding_project = @bid.biding_projects - respond_to do |format| - # format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}} - # format.html - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - #删除已提交的项目作业(不删项目) - def delete - binding_project = params[:binding_project] - if can_delete_project_homework(BidingProject.find(binding_project),User.current) - if BidingProject.delete(binding_project) - redirect_to project_for_bid_url - else - render_403; - end - end - end - ## 新建留言 - def create - - if params[:bid_message][:message].size>0 - if params[:reference_content] - message = params[:bid_message][:message] + "\n" + params[:reference_content] - else - message = params[:bid_message][:message] - @m = message - end - refer_user_id = params[:bid_message][:reference_user_id].to_i - @bid.add_jour(User.current, message, refer_user_id) - end - @user = @bid.author - @jours = @bid.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - @bid.set_commit(@feedback_count) - - respond_to do |format| - format.js - #format.api { render_api_ok } - end - - end - - ##删除留言 - def destroy - @user = @bid.author - if User.current.admin? || User.current.id == @user.id - JournalsForMessage.delete_message(params[:object_id]) - end - @jours = @bid.journals_for_messages.reverse - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - - @bid.set_commit(@feedback_count) - # if a_message.size > 5 - # @message = a_message[-5, 5] - # else - # @message = a_message - # end - # @message_count = a_message.count - - respond_to do |format| - # format.html - format.js - #format.api { render_api_ok } - end - end - - #删除作业 - #by xianbo - def homework_destroy - @bid_to_destroy = Bid.find params[:course_id] - (render_403; return false) unless User.current.admin?||User.current.id==@bid_to_destroy.author_id - @bid_to_destroy.destroy - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - #end by xianbo - ##引用 - def new - @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] - if @jour - user = @jour.user - text = @jour.notes - else - user = @bid.author - text = @bid.description - end - # Replaces pre blocks with [...] - text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') - @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " - @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - @id = user.id - rescue ActiveRecord::RecordNotFound - render_404 - end - - ##新建需求 - def new_bid - @bid = Bid.new - @bid.safe_attributes = params[:bid] - end - - #huang - def create_contest - @bid = Bid.new - @bid.name = params[:bid][:name] - @bid.description = params[:bid][:description] - @bid.reward_type = 2 - @bid.budget = params[:bid][:budget] - @bid.deadline = params[:bid][:deadline] - @bid.password = params[:bid][:password] #added by bai - @bid.author_id = User.current.id - @bid.commit = 0 - if @bid.save - unless @bid.watched_by?(User.current) - if @bid.add_watcher(User.current) - flash[:notice] = l(:label_bid_succeed) - end - end - redirect_to respond_url(@bid) - else - @bid.safe_attributes = params[:bid] - render :action => 'new_bid' - end - end - -# added by bai - def update_contest - @bid = Bid.find(params[:id]) - @bid.name = params[:bid][:name] - @bid.description = params[:bid][:description] - @bid.reward_type = 2 - @bid.budget = params[:bid][:budget] - @bid.deadline = params[:bid][:deadline] - @bid.password = params[:bid][:password] - @bid.author_id = User.current.id - @bid.commit = 0 - if @bid.save - unless @bid.watched_by?(User.current) - if @bid.add_watcher(User.current) - flash[:notice] = l(:label_bid_succeed) - end - end - redirect_to respond_url(@bid) - else - @bid.safe_attributes = params[:bid] - render :action => 'new_bid' - end - end - #huang - def new_contest - @bid = Bid.new - @bid.safe_attributes = params[:bid] - end - - def create_bid - @bid = Bid.new - @bid.name = params[:bid][:name] - @bid.description = params[:bid][:description] - @bid.reward_type = 1 - @bid.budget = params[:bid][:budget] - @bid.deadline = params[:bid][:deadline] - @bid.author_id = User.current.id - @bid.commit = 0 - if @bid.save - unless @bid.watched_by?(User.current) - if @bid.add_watcher(User.current) - flash[:notice] = l(:label_bid_succeed) - end - end - redirect_to respond_url(@bid) - else - @bid.safe_attributes = params[:bid] - render :action => 'new_bid' - end - end - - def create_homework - @bid = Bid.new - @bid.name = params[:bid][:name] - @bid.description = params[:bid][:description] - @bid.is_evaluation = params[:bid][:is_evaluation] - @bid.proportion = params[:bid][:proportion] - @bid.reward_type = 3 - # @bid.budget = params[:bid][:budget] - @bid.deadline = params[:bid][:deadline] - @bid.budget = 0 - @bid.author_id = User.current.id - @bid.commit = 0 - @bid.homework_type = 1 - @bid.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) - # @bid. - if @bid.save - HomeworkForCourse.create(:course_id => params[:course_id], :bid_id => @bid.id) - unless @bid.watched_by?(User.current) - if @bid.add_watcher(User.current) - flash[:notice] = l(:label_bid_succeed) - end - end - redirect_to respond_url(@bid) - else - @bid.safe_attributes = params[:bid] - @homework = @bid - @course = Course.find_by_id(params[:course_id]) - @course_id = @course.id - #respond_to do |format| - # format.html { redirect_to new_homework_course_path(params[:course_id]),:layout => 'base_courses'} - # format.api { render_validation_errors(@bid) } - #end - render file: 'courses/new_homework', layout: 'base_courses' - end - end - - # modify by nwb\ - # 编辑作业 - def edit - @bid = Bid.find(params[:bid_id]) - if (User.current.admin?||User.current.id==@bid.author_id) - @course_id = params[:course_id] - respond_to do |format| - format.html { - @course = Course.find(params[:course_id]) - @user= User.find(User.current.id) - render :layout => 'base_courses' - } - end - else - render_403 - end - end - - def update - @bid = Bid.find(params[:id]) - @course = @bid.courses.first#Project.find(params[:course_id]) - @bid.name = params[:bid][:name] - @bid.description = params[:bid][:description] - @bid.is_evaluation = params[:bid][:is_evaluation] - @bid.proportion = params[:bid][:proportion] - @bid.reward_type = 3 - @bid.deadline = params[:bid][:deadline] - @bid.budget = 0 - @bid.author_id = User.current.id - @bid.commit = 0 - @bid.homework_type = 1 - @bid.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) - if @bid.save - flash[:notice] = l(:label_update_homework_succeed) - redirect_to course_homework_url(@course) - else - @bid.safe_attributes = params[:bid] - render :action => 'edit', :layout =>'base_courses' - end - end - - def new_submit_homework - #render html to prepare create submit homework - find_bid - render :layout => 'base_homework' - end - - def add_homework - if User.current.logged? && (!Member.where('user_id = ? and project_id = ?', User.current.id, @bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, @bid.courses.first.id).first.roles&Role.where('id = ? or id = ? or id =?',5, 10, 7)).size >0) - # homework = HomeworkAttach.create(:bid_id => @bid.id, :user_id => User.current.id) - # homework.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) - - if hadcommittedhomework(User.current.id, @bid.id) == true - @homework_flag = l(:label_bidding_homework_committed) - else - @homework = HomeworkAttach.new - @homework.safe_attributes = params[:homeworkattach] - @homework.bid_id = @bid.id - @homework.user_id = User.current.id - @homework.save_attachments(params[:attachments]) - - render_attachment_warning_if_needed(@homework) - - @homework_flag = if @homework.save - l(:label_bidding_homework_succeed) - else - l(:label_bidding_homework_failed) - end - - if @homework.attachments.empty? - @homework.delete - #flash[:error] = l(:no_attachmens_allowed) - @homework_flag = l(:no_attachmens_allowed) - # else - end - end - end - - @homework_list = @bid.homeworks - respond_to do |format| - format.html{ - #redirect_to project_for_bid_path, notice: @homework_flag.to_s - flash[:notice] = @homework_flag.to_s - redirect_back_or_default(project_for_bid_path) - } - format.js - end - - end - - # 作业统计 - def homework_statistics - @course = @bid.courses.first - @member = [] - @course.memberships.each do |member| - unless (member.roles && Role.where('id = ? ', 3)).empty? - @member.push member - end - end - if @bid.homework_type = 1 - @student = User.where("id in (select DISTINCT user_id from #{HomeworkAttach.table_name} where bid_id = ? )", @bid.id) - @homework_type = true - else - - @homework_type = false - end - @user = @bid.author - render :layout => 'base_homework' - end - - def homework_respond - @user = @bid.author - render :layout => 'base_homework' - end - - def more - @jour = @bid.journals_for_messages - @jour.each_with_index {|j,i| j.indice = i+1} - @state = true - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - def back - @jour = @bid.journals_for_messages - @jour.each_with_index {|j,i| j.indice = i+1} - @state = false - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - #added by william - #used to set the bidding project reward - def set_reward - @b_p = nil - @biding_project_id = nil - - if params[:set_reward][:reward]&&((User.current.id==@bid.author_id)||User.current.admin) - # @bid_id = params[:id] - @biding_project_id = params[:set_reward][:b_id] - @b_p = BidingProject.find_by_id(@biding_project_id) - - # 把字段存进表中 - @b_p.update_reward(params[:set_reward][:reward].to_s) - end - - respond_to do |format| - format.js - end - end - - # added by william - # used to manage the bid and end the bid - def manage - - end - - private - - def find_bid - if params[:id] - @bid = Bid.find(params[:id], :include => [{:homeworks => :user}]) - @user = @bid.author - end - rescue - render_404 - end - - def memberAccess - # 是课程,则判断当前用户是否参加了课程 - return true if current_user.admin? - #return 0 if @bid.courses.first.project_type == Project::ProjectType_project - currentUser = User.current - render_403 unless currentUser.member_of_course?(@bid.courses.first) - end - - #验证是否显示课程 - def can_show_course - @first_page = FirstPage.find_by_page_type('project') - if @first_page.show_course == 2 - render_404 - end - end - - #验证是否显示竞赛 - def can_show_contest - @first_page = FirstPage.find_by_page_type('project') - if @first_page.show_contest == 2 - render_404 - end - end - -end - +# fq +class BidsController < ApplicationController + #Added by young + menu_item l(:label_homework), :only => [:edit, :udpate] + menu_item :respond + menu_item :course, :only => :show_courseEx + menu_item :project, :only => [:show_project,:show_results, :new_submit_homework] + menu_item :homework_respond, :only => :homework_respond + menu_item :homework_statistics, :only => :homework_statistics + + before_filter :can_show_course,only: [] + before_filter :can_show_contest,only: [] + #Ended by young + before_filter :find_bid, :only => [:show, :show_project, :create,:destroy,:more,:back,:add,:delete,:new,:show_results,:set_reward, :add_homework, :fork, :create_fork, + :show_course, :show_courseEx,:show_bid_project, :show_bid_user, :join_in_contest, :unjoin_in_contest, :new_join,:show_participator, :settings] + # 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 :memberAccess, only: :show_project + + helper :watchers + helper :attachments + include AttachmentsHelper + include ApplicationHelper + include BidsHelper + + helper :projects + helper :words + helper :welcome + helper :project_score + + def find_project_by_bid_id + @bid = Bid.find(params[:id]) + @project = @bid.courses[0] + rescue ActiveRecord::RecordNotFound + render_404 + end + + def homework_ajax_modal + @bid = Bid.find_by_id(params[:id]) + # find_bid + respond_to do |format| + format.js + end + end + + + def index + @project_type = params[:project_type] + # Modified by nie + # @requirement_title = "4" + @offset, @limit = api_offset_and_limit({:limit => 10}) + if @project_type == '1' + @bids = Bid.visible.where('reward_type = ?', 3) + # elsif + # @bids = Bid.visible.where('reward_type = ? or reward_type = ?', 4) + else + @bids = Bid.visible.where('reward_type = ?', 1) + end + + @bids = @bids.like(params[:name]) if params[:name].present? + @bid_count = @bids.count + @bid_pages = Paginator.new @bid_count, @limit, params['page'] + + @offset ||= @bid_pages.reverse_offset + #added by nie + if params[:bid_sort_type].present? + case params[:bid_sort_type] + when '0' + unless @offset == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.offset(@offset).limit(limit).all.reverse + end + @s_state = 0 + when '1' + unless @offset == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse + end + @s_state = 1 + when '2' + unless @offset == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + end + @s_state = 0 + end + else + unless @offset == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse + end + @s_state = 1 + end + #end + end + #huang + def contest + + # Modified by nie + # @requirement_title = "4" + @offset, @limit = api_offset_and_limit({:limit => 10}) + + @bids = Bid.visible.where('reward_type = ?', 2) + + # elsif + # @bids = Bid.visible.where('reward_type = ? or reward_type = ?', 4) + @bids = @bids.like(params[:name]) if params[:name].present? + @bid_count = @bids.count + @bid_pages = Paginator.new @bid_count, @limit, params['page'] + + @offset ||= @bid_pages.reverse_offset + #added by nie + if params[:contest_sort_type].present? + case params[:contest_sort_type] + when '0' + unless @offset == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.offset(@offset).limit(limit).all.reverse + end + @s_state = 0 + when '1' + unless @offset == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse + end + @s_state = 1 + when '2' + unless @offset == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + end + @s_state = 0 + end + else + unless @offset == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + limit = @limit if limit == 0 + @bids = @bids.reorder('bids.commit').offset(@offset).limit(limit).all.reverse + end + @s_state = 1 + end + #end + end + + def fork + @courses = [] + @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + @membership.each do |membership| + if membership.project.project_type == 1 + @courses << membership.project + end + end + end + + def create_fork + @homework = Bid.new + @homework.name = params[:bid][:name] + @homework.description = params[:bid][:description] + @homework.reward_type = 3 + # @bid.budget = params[:bid][:budget] + @homework.deadline = params[:bid][:deadline] + @homework.budget = 0 + @homework.author_id = User.current.id + @homework.commit = 0 + @homework.homework_type = 1 + @homework.is_evaluation = params[:bid][:is_evaluation] + @homework.parent_id = @bid.id + @homework.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) + # @bid. + if @homework.save + HomeworkForCourse.create(:course_id => params[:course], :bid_id => @homework.id) + unless @bid.watched_by?(User.current) + if @bid.add_watcher(User.current) + flash[:notice] = l(:label_bid_succeed) + end + end + redirect_to respond_path(@homework) + else + @bid.safe_attributes = params[:bid] + @courses = [] + @membership = User.current.coursememberships.all#(:conditions => Project.visible_condition(User.current)) + @membership.each do |membership| + @courses << membership.course + end + render :action => 'fork' + end + end + + def show + @user = @bid.author + @jours = @bid.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @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 + + respond_to do |format| + layout_file = '' + case @bid.reward_type + when 3 + html_title(l(:label_question_student)) + layout_file = 'base_homework' + when 1 + layout_file = 'base_bids' + else + layout_file = 'base_contest' + end + format.html { + render :layout => layout_file + } + format.api + end + end + + def join_in_contest + if @bid.reward_type == 2 && params[:course_password] == @bid.password + JoinInContest.create(:user_id => User.current.id, :bid_id => @bid.id) + @state = 0 + else + @state = 1 + end + + respond_to do |format| + # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} + # TO_DO + format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } + end + end + + def unjoin_in_contest + + joined = JoinInContest.where('bid_id = ? and user_id = ?', @bid.id, User.current.id) + + joined.each do |join| + join.delete + end + + respond_to do |format| + # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} + format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } + end + end + + def new_join + # added by fq + + + end + + # added by bai 增加了参与者和竞赛设置 + def show_participator + render :layout => 'base_contest' + + end + + def settings + if @bid.author.id == User.current.id + if @bid.reward_type == 2 + @contest = Bid.find_by_reward_type(@bid.reward_type) + render :layout => 'base_contest' + end + else + render_403 :message => :notice_not_contest_setting_authorized + end + end + #end + + # 显示课程 + def show_course + bids = Bid.where('parent_id = ?', @bid.id) + @courses = [] + for bid in bids + @courses << bid.courses.first + end + + respond_to do |format| + if @bid.reward_type == 3 + format.html { + render :layout => 'base_homework' + } + elsif @bid.reward_type == 1 + format.html { + render :layout => 'base_bids' + } + else + format.html { + render :layout => 'base_contest' + } + end + format.api + + end + end + + def show_bid_project + bids = Bid.where('parent_id = ?', @bid.id) + @projects = [] + for bid in bids + @projects += bid.biding_projects + end + + respond_to do |format| + if @bid.reward_type == 3 + format.html { + render :layout => 'base_homework' + } + elsif @bid.reward_type == 1 + format.html { + render :layout => 'base_bids' + } + else + format.html { + render :layout => 'base_contest' + } + end + format.api + + end + end + + def show_bid_user + bids = Bid.where('parent_id = ?', @bid.id) + @users = [] + for bid in bids + for project in bid.projects + @users += project.users + end + end + + respond_to do |format| + if @bid.reward_type == 3 + format.html { + render :layout => 'base_homework' + } + elsif @bid.reward_type == 1 + format.html { + render :layout => 'base_bids' + } + else + format.html { + render :layout => 'base_contest' + } + end + format.api + + end + end + + def show_project + # flash[:notice] = "" + @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + @option = [] + @membership.each do |membership| + unless(membership.project.project_type==1) + if membership.user.allowed_to?(:quote_project,membership.project) + @option << membership.project + end + end + end + + # a = [1] + # @project = Project.where("id in []", a) + @user = @bid.author + @bidding_project = @bid.biding_projects.all + if params[:student_id].present? + @temp = [] + @bidding_project.each do |pro| + if pro.project && pro.project.project_status + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + end + @temp + end + @bidding_project = @temp + else + #added by nie + @temp = [] + @bidding_project.each do |pro| + if pro.project && pro.project.project_status + @temp << pro + end + @temp + end + if @temp.size > 0 + @bidding_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} + end + #ended + end + + if @bid.homework_type == 1 + @homework = HomeworkAttach.new + #@homework_list = @bid.homeworks + #增加作业按评分排序, + @homework_list = @bid.homeworks.eager_load(:rate_averages, :user, :attachments).order('seems_rateable_cached_ratings.avg DESC').order("#{HomeworkAttach.table_name}.created_at ASC") + if params[:student_id].present? + @temp = [] + @homework_list.each do |pro| + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + @temp + end + @homework_list = @temp + end + end + + respond_to do |format| + if @bid.reward_type == 3 + format.html { + render :layout => 'base_homework' + } + elsif @bid.reward_type == 1 + format.html { + render :layout => 'base_bids' + } + else + format.html { + render :layout => 'base_contest' + } + end + format.api + end + end + + # 显示作业课程 + # add by nwb + def show_courseEx + if (User.current.logged? && (User.current.member_of_course?(@bid.courses.first) || User.current.admin?)) + # flash[:notice] = "" + @membership = User.current.coursememberships.all(:conditions => Course.visible_condition(User.current)) + + @user = @bid.author + @bidding_project = @bid.biding_projects.all + + if params[:student_id].present? + @temp = [] + @bidding_project.each do |pro| + if pro.project && pro.project.project_status + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + end + @temp + end + @bidding_project = @temp + else + #added by nie + @temp = [] + @bidding_project.each do |pro| + if pro.project && pro.project.project_status + @temp << pro + end + @temp + end + if @temp.size > 0 + @bidding_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} + end + #ended + end + + if @bid.homework_type + @homework = HomeworkAttach.new + if @bid.proportion + teacher_proportion = @bid.proportion * 1.0 / 100 + else + teacher_proportion = 1.0 + end + #@homework_list = @bid.homeworks + #增加作业按评分排序, + #@homework_list = @bid.homeworks.eager_load(:rate_averages, :user, :attachments).order('seems_rateable_cached_ratings.avg DESC').order("#{HomeworkAttach.table_name}.created_at ASC") + all_homework_list = HomeworkAttach.eager_load(:attachments,:user,:rate_averages).find_by_sql("SELECT homework_attaches.*, + (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id = #{@bid.author_id}) AS t_score, + (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id <> #{@bid.author_id}) AS s_score + FROM homework_attaches WHERE bid_id = #{@bid.id} ORDER BY + (CASE WHEN t_score IS NULL THEN 0 ELSE t_score * #{teacher_proportion} END + CASE WHEN s_score IS NULL THEN 0 ELSE s_score * #{1 - teacher_proportion} END) DESC,created_at ASC") + + limit = 10 + feedback_count = all_homework_list.count + @feedback_pages = Paginator.new feedback_count, limit, params['page'] + offset ||= @feedback_pages.offset + @homework_list = all_homework_list[offset, limit] + + if params[:student_id].present? + @temp = [] + @homework_list.each do |pro| + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + @temp + end + @homework_list = @temp + end + end + + respond_to do |format| + if @bid.reward_type == 3 + format.html { + html_title(l(:label_homework_info)) + render :layout => 'base_homework' + } + elsif @bid.reward_type == 1 + format.html { + render :layout => 'base_bids' + } + else + format.html { + render :layout => 'base_contest' + } + end + format.api + end + else + render_403 :message => :notice_not_authorized + end + end + + ##### by huang + def show_project_homework + # flash[:notice] = "" + @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + @option = [] + @membership.each do |membership| + end + # a = [1] + # @project = Project.where("id in []", a) + @user = @bid.author + @bidding_project = @bid.biding_projects + respond_to do |format| + if @bid.reward_type == 3 + format.html { + render :layout => 'base_homework' + } + elsif @bid.reward_type == 1 + format.html { + render :layout => 'base_bids' + } + else + format.html { + render :layout => 'base_contest' + } + end + format.api + end + end + + ###添加应标项目 + def add + project = Project.find(params[:bid]) + bid_message = params[:bid_for_save][:bid_message] + if BidingProject.where("project_id = ? and bid_id = ?", project.id, @bid.id).size == 0 + if BidingProject.cerate_bidding(@bid.id, project.id, bid_message) + + # added by bai type ==1 需求,type==2 竞赛, type==3 作业 + if @bid.reward_type == 1 + flash.now[:notice] = l(:label_bidding_succeed) + + elsif @bid.reward_type == 2 + flash.now[:notice] = l(:label_bidding_contest_succeed) + + else @bid.reward_type == 3 + flash.now[:notice] = l(:label_bidding_homework_succeed) + end + # end + + end + else + if @bid.reward_type == 3 + flash.now[:error] = l(:label_bidding_homework_fail) + else + flash.now[:error] = l(:label_bidding_fail) + end + end + @bidding_project = @bid.biding_projects + respond_to do |format| + # format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}} + # format.html + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + #删除已提交的项目作业(不删项目) + def delete + binding_project = params[:binding_project] + if can_delete_project_homework(BidingProject.find(binding_project),User.current) + if BidingProject.delete(binding_project) + redirect_to project_for_bid_url + else + render_403; + end + end + end + ## 新建留言 + def create + + if params[:bid_message][:message].size>0 + if params[:reference_content] + message = params[:bid_message][:message] + "\n" + params[:reference_content] + else + message = params[:bid_message][:message] + @m = message + end + refer_user_id = params[:bid_message][:reference_user_id].to_i + @bid.add_jour(User.current, message, refer_user_id) + end + @user = @bid.author + @jours = @bid.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @bid.set_commit(@feedback_count) + + respond_to do |format| + format.js + #format.api { render_api_ok } + end + + end + + ##删除留言 + def destroy + @user = @bid.author + if User.current.admin? || User.current.id == @user.id + JournalsForMessage.delete_message(params[:object_id]) + end + @jours = @bid.journals_for_messages.reverse + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + + @bid.set_commit(@feedback_count) + # if a_message.size > 5 + # @message = a_message[-5, 5] + # else + # @message = a_message + # end + # @message_count = a_message.count + + respond_to do |format| + # format.html + format.js + #format.api { render_api_ok } + end + end + + #删除作业 + #by xianbo + def homework_destroy + @bid_to_destroy = Bid.find params[:course_id] + (render_403; return false) unless User.current.admin?||User.current.id==@bid_to_destroy.author_id + @bid_to_destroy.destroy + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + #end by xianbo + ##引用 + def new + @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] + if @jour + user = @jour.user + text = @jour.notes + else + user = @bid.author + text = @bid.description + end + # Replaces pre blocks with [...] + text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') + @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " + @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + @id = user.id + rescue ActiveRecord::RecordNotFound + render_404 + end + + ##新建需求 + def new_bid + @bid = Bid.new + @bid.safe_attributes = params[:bid] + end + + #huang + def create_contest + @bid = Bid.new + @bid.name = params[:bid][:name] + @bid.description = params[:bid][:description] + @bid.reward_type = 2 + @bid.budget = params[:bid][:budget] + @bid.deadline = params[:bid][:deadline] + @bid.password = params[:bid][:password] #added by bai + @bid.author_id = User.current.id + @bid.commit = 0 + if @bid.save + unless @bid.watched_by?(User.current) + if @bid.add_watcher(User.current) + flash[:notice] = l(:label_bid_succeed) + end + end + redirect_to respond_url(@bid) + else + @bid.safe_attributes = params[:bid] + render :action => 'new_bid' + end + end + +# added by bai + def update_contest + @bid = Bid.find(params[:id]) + @bid.name = params[:bid][:name] + @bid.description = params[:bid][:description] + @bid.reward_type = 2 + @bid.budget = params[:bid][:budget] + @bid.deadline = params[:bid][:deadline] + @bid.password = params[:bid][:password] + @bid.author_id = User.current.id + @bid.commit = 0 + if @bid.save + unless @bid.watched_by?(User.current) + if @bid.add_watcher(User.current) + flash[:notice] = l(:label_bid_succeed) + end + end + redirect_to respond_url(@bid) + else + @bid.safe_attributes = params[:bid] + render :action => 'new_bid' + end + end + #huang + def new_contest + @bid = Bid.new + @bid.safe_attributes = params[:bid] + end + + def create_bid + @bid = Bid.new + @bid.name = params[:bid][:name] + @bid.description = params[:bid][:description] + @bid.reward_type = 1 + @bid.budget = params[:bid][:budget] + @bid.deadline = params[:bid][:deadline] + @bid.author_id = User.current.id + @bid.commit = 0 + if @bid.save + unless @bid.watched_by?(User.current) + if @bid.add_watcher(User.current) + flash[:notice] = l(:label_bid_succeed) + end + end + redirect_to respond_url(@bid) + else + @bid.safe_attributes = params[:bid] + render :action => 'new_bid' + end + end + + def create_homework + @bid = Bid.new + @bid.name = params[:bid][:name] + @bid.description = params[:bid][:description] + @bid.is_evaluation = params[:bid][:is_evaluation] + @bid.proportion = params[:bid][:proportion] + @bid.reward_type = 3 + # @bid.budget = params[:bid][:budget] + @bid.deadline = params[:bid][:deadline] + @bid.budget = 0 + @bid.author_id = User.current.id + @bid.commit = 0 + @bid.homework_type = 1 + @bid.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) + # @bid. + if @bid.save + HomeworkForCourse.create(:course_id => params[:course_id], :bid_id => @bid.id) + unless @bid.watched_by?(User.current) + if @bid.add_watcher(User.current) + flash[:notice] = l(:label_bid_succeed) + end + end + redirect_to respond_url(@bid) + else + @bid.safe_attributes = params[:bid] + @homework = @bid + @course = Course.find_by_id(params[:course_id]) + @course_id = @course.id + #respond_to do |format| + # format.html { redirect_to new_homework_course_path(params[:course_id]),:layout => 'base_courses'} + # format.api { render_validation_errors(@bid) } + #end + render file: 'courses/new_homework', layout: 'base_courses' + end + end + + # modify by nwb\ + # 编辑作业 + def edit + @bid = Bid.find(params[:bid_id]) + if (User.current.admin?||User.current.id==@bid.author_id) + @course_id = params[:course_id] + respond_to do |format| + format.html { + @course = Course.find(params[:course_id]) + @user= User.find(User.current.id) + render :layout => 'base_courses' + } + end + else + render_403 + end + end + + def update + @bid = Bid.find(params[:id]) + @course = @bid.courses.first#Project.find(params[:course_id]) + @bid.name = params[:bid][:name] + @bid.description = params[:bid][:description] + @bid.is_evaluation = params[:bid][:is_evaluation] + @bid.proportion = params[:bid][:proportion] + @bid.reward_type = 3 + @bid.deadline = params[:bid][:deadline] + @bid.budget = 0 + @bid.author_id = User.current.id + @bid.commit = 0 + @bid.homework_type = 1 + @bid.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) + if @bid.save + flash[:notice] = l(:label_update_homework_succeed) + redirect_to course_homework_url(@course) + else + @bid.safe_attributes = params[:bid] + render :action => 'edit', :layout =>'base_courses' + end + end + + def new_submit_homework + #render html to prepare create submit homework + find_bid + render :layout => 'base_homework' + end + + def add_homework + if User.current.logged? && (!Member.where('user_id = ? and project_id = ?', User.current.id, @bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, @bid.courses.first.id).first.roles&Role.where('id = ? or id = ? or id =?',5, 10, 7)).size >0) + # homework = HomeworkAttach.create(:bid_id => @bid.id, :user_id => User.current.id) + # homework.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) + + if hadcommittedhomework(User.current.id, @bid.id) == true + @homework_flag = l(:label_bidding_homework_committed) + else + @homework = HomeworkAttach.new + @homework.safe_attributes = params[:homeworkattach] + @homework.bid_id = @bid.id + @homework.user_id = User.current.id + @homework.save_attachments(params[:attachments]) + + render_attachment_warning_if_needed(@homework) + + @homework_flag = if @homework.save + l(:label_bidding_homework_succeed) + else + l(:label_bidding_homework_failed) + end + + if @homework.attachments.empty? + @homework.delete + #flash[:error] = l(:no_attachmens_allowed) + @homework_flag = l(:no_attachmens_allowed) + # else + end + end + end + + @homework_list = @bid.homeworks + respond_to do |format| + format.html{ + #redirect_to project_for_bid_path, notice: @homework_flag.to_s + flash[:notice] = @homework_flag.to_s + redirect_back_or_default(project_for_bid_path) + } + format.js + end + + end + + # 作业统计 + def homework_statistics + @course = @bid.courses.first + @member = [] + @course.memberships.each do |member| + unless (member.roles && Role.where('id = ? ', 3)).empty? + @member.push member + end + end + if @bid.homework_type = 1 + @student = User.where("id in (select DISTINCT user_id from #{HomeworkAttach.table_name} where bid_id = ? )", @bid.id) + @homework_type = true + else + + @homework_type = false + end + @user = @bid.author + render :layout => 'base_homework' + end + + def homework_respond + @user = @bid.author + render :layout => 'base_homework' + end + + def more + @jour = @bid.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = true + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def back + @jour = @bid.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = false + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + #added by william + #used to set the bidding project reward + def set_reward + @b_p = nil + @biding_project_id = nil + + if params[:set_reward][:reward]&&((User.current.id==@bid.author_id)||User.current.admin) + # @bid_id = params[:id] + @biding_project_id = params[:set_reward][:b_id] + @b_p = BidingProject.find_by_id(@biding_project_id) + + # 把字段存进表中 + @b_p.update_reward(params[:set_reward][:reward].to_s) + end + + respond_to do |format| + format.js + end + end + + # added by william + # used to manage the bid and end the bid + def manage + + end + + private + + def find_bid + if params[:id] + @bid = Bid.find(params[:id], :include => [{:homeworks => :user}]) + @user = @bid.author + end + rescue + render_404 + end + + def memberAccess + # 是课程,则判断当前用户是否参加了课程 + return true if current_user.admin? + #return 0 if @bid.courses.first.project_type == Project::ProjectType_project + currentUser = User.current + render_403 unless currentUser.member_of_course?(@bid.courses.first) + end + + #验证是否显示课程 + def can_show_course + @first_page = FirstPage.find_by_page_type('project') + if @first_page.show_course == 2 + render_404 + end + end + + #验证是否显示竞赛 + def can_show_contest + @first_page = FirstPage.find_by_page_type('project') + if @first_page.show_contest == 2 + render_404 + end + end + +end + diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index ed9fcd52f..56ed69c49 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -1,152 +1,152 @@ -# 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 BoardsController < ApplicationController - layout 'base_projects'#by young - default_search_scope :messages - before_filter :find_project_by_project_id, :find_board_if_available - before_filter :authorize, :except => [:new, :show, :create, :index] - accept_rss_auth :index, :show - - - helper :sort - include SortHelper - helper :watchers - helper :project_score - - def index - #modify by nwb - if @project - @boards = @project.boards.includes(:last_message => :author).all - @boards = [] << @boards[0] if @boards.any? - if @boards.size == 1 - @board = @boards.first - show and return - end - render :layout => false if request.xhr? - elsif @course - @boards = @course.boards.includes(:last_message => :author).all - @boards = [] << @boards[0] if @boards.any? - if @boards.size == 1 - @board = @boards.first - show and return - end - render :layout => 'base_courses' - end - - end - - def show - respond_to do |format| - format.html { - sort_init 'updated_on', 'desc' - sort_update 'created_on' => "#{Message.table_name}.created_on", - 'replies' => "#{Message.table_name}.replies_count", - 'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)" - - @topic_count = @board.topics.count - @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] - @topics = @board.topics. - reorder("#{Message.table_name}.sticky DESC"). - includes(:last_reply). - limit(@topic_pages.per_page). - offset(@topic_pages.offset). - order(sort_clause). - preload(:author, {:last_reply => :author}). - all - @message = Message.new(:board => @board) - #modify by nwb - if @project - render :action => 'show', :layout => 'base_projects' - elsif @course - render :action => 'show', :layout => 'base_courses' - end - } - format.atom { - @messages = @board.messages. - reorder('created_on DESC'). - includes(:author, :board). - limit(Setting.feeds_limit.to_i). - all - if @project - render_feed(@messages, :title => "#{@project}: #{@board}") - elsif @course - render_feed(@messages, :title => "#{@course}: #{@board}") - end - - } - end - end - - def new - @board = @project.boards.build - @board.safe_attributes = params[:board] - if @project.project_type == 1 - render :layout => 'base_courses' - end - end - - def create - @board = @project.boards.build - @board.safe_attributes = params[:board] - - if @board.save - flash[:notice] = l(:notice_successful_create) - #Modified by young - #redirect_to_settings_in_projects - redirect_to project_board_url(@project, @board) - #Ended by young - else - render :action => 'new' - end - end - - def edit - if @project.project_type == 1 - render :layout => 'base_courses' - end - end - - def update - @board.safe_attributes = params[:board] - if @board.save - redirect_to_settings_in_projects - else - render :action => 'edit' - end - end - - def destroy - @board.destroy - redirect_to_settings_in_projects - end - -private - def redirect_to_settings_in_projects - redirect_to settings_project_url(@project, :tab => 'boards') - end - - def find_board_if_available - if @project - @board = @project.boards.find(params[:id]) if params[:id] - elsif @course - @board = @course.boards.find(params[:id]) if params[:id] - 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. + +class BoardsController < ApplicationController + layout 'base_projects'#by young + default_search_scope :messages + before_filter :find_project_by_project_id, :find_board_if_available + before_filter :authorize, :except => [:new, :show, :create, :index] + accept_rss_auth :index, :show + + + helper :sort + include SortHelper + helper :watchers + helper :project_score + + def index + #modify by nwb + if @project + @boards = @project.boards.includes(:last_message => :author).all + @boards = [] << @boards[0] if @boards.any? + if @boards.size == 1 + @board = @boards.first + show and return + end + render :layout => false if request.xhr? + elsif @course + @boards = @course.boards.includes(:last_message => :author).all + @boards = [] << @boards[0] if @boards.any? + if @boards.size == 1 + @board = @boards.first + show and return + end + render :layout => 'base_courses' + end + + end + + def show + respond_to do |format| + format.html { + sort_init 'updated_on', 'desc' + sort_update 'created_on' => "#{Message.table_name}.created_on", + 'replies' => "#{Message.table_name}.replies_count", + 'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)" + + @topic_count = @board.topics.count + @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + @topics = @board.topics. + reorder("#{Message.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + preload(:author, {:last_reply => :author}). + all + @message = Message.new(:board => @board) + #modify by nwb + if @project + render :action => 'show', :layout => 'base_projects' + elsif @course + render :action => 'show', :layout => 'base_courses' + end + } + format.atom { + @messages = @board.messages. + reorder('created_on DESC'). + includes(:author, :board). + limit(Setting.feeds_limit.to_i). + all + if @project + render_feed(@messages, :title => "#{@project}: #{@board}") + elsif @course + render_feed(@messages, :title => "#{@course}: #{@board}") + end + + } + end + end + + def new + @board = @project.boards.build + @board.safe_attributes = params[:board] + if @project.project_type == 1 + render :layout => 'base_courses' + end + end + + def create + @board = @project.boards.build + @board.safe_attributes = params[:board] + + if @board.save + flash[:notice] = l(:notice_successful_create) + #Modified by young + #redirect_to_settings_in_projects + redirect_to project_board_url(@project, @board) + #Ended by young + else + render :action => 'new' + end + end + + def edit + if @project.project_type == 1 + render :layout => 'base_courses' + end + end + + def update + @board.safe_attributes = params[:board] + if @board.save + redirect_to_settings_in_projects + else + render :action => 'edit' + end + end + + def destroy + @board.destroy + redirect_to_settings_in_projects + end + +private + def redirect_to_settings_in_projects + redirect_to settings_project_url(@project, :tab => 'boards') + end + + def find_board_if_available + if @project + @board = @project.boards.find(params[:id]) if params[:id] + elsif @course + @board = @course.boards.find(params[:id]) if params[:id] + end + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 72d9ebbe5..9f61306ab 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,55 +1,55 @@ -# 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 CommentsController < ApplicationController - default_search_scope :news - model_object News - before_filter :find_model_object - before_filter :find_project_from_association - before_filter :authorize - - def create - raise Unauthorized unless @news.commentable? - - @comment = Comment.new - @comment.safe_attributes = params[:comment] - @comment.author = User.current - if @news.comments << @comment - flash[:notice] = l(:label_comment_added) - end - - redirect_to news_url(@news) - end - - def destroy - @news.comments.find(params[:comment_id]).destroy - redirect_to news_url(@news) - end - - private - - # ApplicationController's find_model_object sets it based on the controller - # name so it needs to be overriden and set to @news instead - def find_model_object - super - @news = @object - @comment = nil - @news - 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 CommentsController < ApplicationController + default_search_scope :news + model_object News + before_filter :find_model_object + before_filter :find_project_from_association + before_filter :authorize + + def create + raise Unauthorized unless @news.commentable? + + @comment = Comment.new + @comment.safe_attributes = params[:comment] + @comment.author = User.current + if @news.comments << @comment + flash[:notice] = l(:label_comment_added) + end + + redirect_to news_url(@news) + end + + def destroy + @news.comments.find(params[:comment_id]).destroy + redirect_to news_url(@news) + end + + private + + # ApplicationController's find_model_object sets it based on the controller + # name so it needs to be overriden and set to @news instead + def find_model_object + super + @news = @object + @comment = nil + @news + end + + +end diff --git a/app/controllers/contest_notification_controller.rb b/app/controllers/contest_notification_controller.rb index 461b62457..2ae841ed0 100644 --- a/app/controllers/contest_notification_controller.rb +++ b/app/controllers/contest_notification_controller.rb @@ -1,6 +1,6 @@ -class ContestNotificationController < ApplicationController - layout 'contest_base' - def show - @notification = ContestNotification.find(params[:id]) - end -end +class ContestNotificationController < ApplicationController + layout 'contest_base' + def show + @notification = ContestNotification.find(params[:id]) + end +end diff --git a/app/controllers/contestnotifications_controller.rb b/app/controllers/contestnotifications_controller.rb index f9c7e80c2..54ba33262 100644 --- a/app/controllers/contestnotifications_controller.rb +++ b/app/controllers/contestnotifications_controller.rb @@ -1,187 +1,187 @@ -class ContestnotificationsController < ApplicationController - # GET /contestnotifications - # GET /contestnotifications.json - layout 'base_newcontest' - default_search_scope :contestnotifications - model_object Contestnotification - # before_filter :find_model_object, :except => [:new, :create, :index] - # before_filter :find_contest_from_association, :except => [:new, :create, :index] - before_filter :find_contest_by_contest_id, :only => [:new, :create] - before_filter :find_contest - before_filter :find_author - # before_filter :authorize, :except => [:index] - before_filter :find_optional_contest, :only => [:index] - accept_rss_auth :index - accept_api_auth :index - - before_filter :access_edit_destroy, only: [:edit ,:update, :destroy] - - def find_author - @user = @contest.author - render_404 if @user.nil? - end - def find_contest - @contest = Contest.find(params[:contest_id]) - render_404 if @contest.nil? - end - - - def index - - # @contestnotifications = Contestnotification.all - # - # respond_to do |format| - # format.html # index.html.erb - # format.json { render json: @contestnotifications } - # end - - ### begin ### - case params[:format] - when 'xml', 'json' - @offset, @limit = api_offset_and_limit - else - @limit = 10 - end - - scope = @contest ? @contest.contestnotifications.visible : Contestnotifications.visible - - @contestnotifications_count = scope.count - @contestnotifications_pages = Paginator.new @contestnotifications_count, @limit, params['page'] - @offset ||= @contestnotifications_pages.offset - @contestnotificationss = scope.all(:include => [:author, :contest], - :order => "#{Contestnotification.table_name}.created_at DESC", - :offset => @offset, - :limit => @limit) - - respond_to do |format| - format.html { - @contestnotification = Contestnotification.new # for adding news inline - render :layout => 'base_newcontest' - } - format.api - format.atom { render_feed(@contestnotificationss, :title => (@contest ? @contest.name : Setting.app_title) + ": #{l(:label_contest_notification)}") } - end - ### end ### - end - - # GET /contestnotifications/1 - # GET /contestnotifications/1.json - def show - @contestnotification = Contestnotification.find(params[:id]) - - # - # respond_to do |format| - # format.html # show.html.erb - # format.json { render json: @contestnotification } - # end - @notificationcomments = @contestnotification.notificationcomments - @notificationcomments.reverse! if User.current.wants_notificationcomments_in_reverse_order? - render :layout => 'base_newcontest' - - end - - # GET /contestnotifications/new - # GET /contestnotifications/new.json - def new - # @contestnotification = Contestnotification.new -# - # respond_to do |format| - # format.html # new.html.erb - # format.json { render json: @contestnotification } - # end - @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) - render :layout => 'base_newcontest' - end - - # GET /contestnotifications/1/edit - def edit - @contestnotification = Contestnotification.find(params[:id]) - end - - # POST /contestnotifications - # POST /contestnotifications.json - def create - # @contestnotification = Contestnotification.new(params[:contestnotification]) - # - # respond_to do |format| - # if @contestnotification.save - # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully created.' } - # format.json { render json: @contestnotification, status: :created, location: @contestnotification } - # else - # format.html { render action: "new" } - # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } - # end - # end - @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) - @contestnotification.safe_attributes = params[:contestnotification] - @contestnotification.save_attachments(params[:attachments]) - if @contestnotification.save - render_attachment_warning_if_needed(@contestnotification) - flash[:notice] = l(:notice_successful_create) - redirect_to contest_contestnotifications_url(@contest) - else - layout_file = 'base_newcontest' - render :action => 'new', :layout => layout_file - end - end - - # PUT /contestnotifications/1 - # PUT /contestnotifications/1.json - def update - # @contestnotification = Contestnotification.find(params[:id]) - # - # respond_to do |format| - # if @contestnotification.update_attributes(params[:contestnotification]) - # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully updated.' } - # format.json { head :no_content } - # else - # format.html { render action: "edit" } - # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } - # end - # end - @contestnotification = Contestnotification.find(params[:id]) - @contestnotification.safe_attributes = params[:contestnotification] - @contestnotification.save_attachments(params[:attachments]) - if @contestnotification.save - render_attachment_warning_if_needed(@contestnotification) - flash[:notice] = l(:notice_successful_update) - redirect_to contest_contestnotification_url(@contestnotification.contest, @contestnotification) - else - render :action => 'edit' - end - end - - # DELETE /contestnotifications/1 - # DELETE /contestnotifications/1.json - def destroy - # @contestnotification = Contestnotification.find(params[:id]) - # @contestnotification.destroy - # - # respond_to do |format| - # format.html { redirect_to contestnotifications_url } - # format.json { head :no_content } - # end - @contestnotification = Contestnotification.find(params[:id]) - @contestnotification.destroy - redirect_to contest_contestnotifications_url(@contest) - end - - private - - def find_optional_contest - return true unless params[:id] - @contest = Contest.find(params[:id]) - # authorize - rescue ActiveRecord::RecordNotFound - render_404 - end - - def access_edit_destroy - if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) - return true - else - render_403 - end - end - -end +class ContestnotificationsController < ApplicationController + # GET /contestnotifications + # GET /contestnotifications.json + layout 'base_newcontest' + default_search_scope :contestnotifications + model_object Contestnotification + # before_filter :find_model_object, :except => [:new, :create, :index] + # before_filter :find_contest_from_association, :except => [:new, :create, :index] + before_filter :find_contest_by_contest_id, :only => [:new, :create] + before_filter :find_contest + before_filter :find_author + # before_filter :authorize, :except => [:index] + before_filter :find_optional_contest, :only => [:index] + accept_rss_auth :index + accept_api_auth :index + + before_filter :access_edit_destroy, only: [:edit ,:update, :destroy] + + def find_author + @user = @contest.author + render_404 if @user.nil? + end + def find_contest + @contest = Contest.find(params[:contest_id]) + render_404 if @contest.nil? + end + + + def index + + # @contestnotifications = Contestnotification.all + # + # respond_to do |format| + # format.html # index.html.erb + # format.json { render json: @contestnotifications } + # end + + ### begin ### + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit + else + @limit = 10 + end + + scope = @contest ? @contest.contestnotifications.visible : Contestnotifications.visible + + @contestnotifications_count = scope.count + @contestnotifications_pages = Paginator.new @contestnotifications_count, @limit, params['page'] + @offset ||= @contestnotifications_pages.offset + @contestnotificationss = scope.all(:include => [:author, :contest], + :order => "#{Contestnotification.table_name}.created_at DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @contestnotification = Contestnotification.new # for adding news inline + render :layout => 'base_newcontest' + } + format.api + format.atom { render_feed(@contestnotificationss, :title => (@contest ? @contest.name : Setting.app_title) + ": #{l(:label_contest_notification)}") } + end + ### end ### + end + + # GET /contestnotifications/1 + # GET /contestnotifications/1.json + def show + @contestnotification = Contestnotification.find(params[:id]) + + # + # respond_to do |format| + # format.html # show.html.erb + # format.json { render json: @contestnotification } + # end + @notificationcomments = @contestnotification.notificationcomments + @notificationcomments.reverse! if User.current.wants_notificationcomments_in_reverse_order? + render :layout => 'base_newcontest' + + end + + # GET /contestnotifications/new + # GET /contestnotifications/new.json + def new + # @contestnotification = Contestnotification.new +# + # respond_to do |format| + # format.html # new.html.erb + # format.json { render json: @contestnotification } + # end + @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) + render :layout => 'base_newcontest' + end + + # GET /contestnotifications/1/edit + def edit + @contestnotification = Contestnotification.find(params[:id]) + end + + # POST /contestnotifications + # POST /contestnotifications.json + def create + # @contestnotification = Contestnotification.new(params[:contestnotification]) + # + # respond_to do |format| + # if @contestnotification.save + # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully created.' } + # format.json { render json: @contestnotification, status: :created, location: @contestnotification } + # else + # format.html { render action: "new" } + # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } + # end + # end + @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) + @contestnotification.safe_attributes = params[:contestnotification] + @contestnotification.save_attachments(params[:attachments]) + if @contestnotification.save + render_attachment_warning_if_needed(@contestnotification) + flash[:notice] = l(:notice_successful_create) + redirect_to contest_contestnotifications_url(@contest) + else + layout_file = 'base_newcontest' + render :action => 'new', :layout => layout_file + end + end + + # PUT /contestnotifications/1 + # PUT /contestnotifications/1.json + def update + # @contestnotification = Contestnotification.find(params[:id]) + # + # respond_to do |format| + # if @contestnotification.update_attributes(params[:contestnotification]) + # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully updated.' } + # format.json { head :no_content } + # else + # format.html { render action: "edit" } + # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } + # end + # end + @contestnotification = Contestnotification.find(params[:id]) + @contestnotification.safe_attributes = params[:contestnotification] + @contestnotification.save_attachments(params[:attachments]) + if @contestnotification.save + render_attachment_warning_if_needed(@contestnotification) + flash[:notice] = l(:notice_successful_update) + redirect_to contest_contestnotification_url(@contestnotification.contest, @contestnotification) + else + render :action => 'edit' + end + end + + # DELETE /contestnotifications/1 + # DELETE /contestnotifications/1.json + def destroy + # @contestnotification = Contestnotification.find(params[:id]) + # @contestnotification.destroy + # + # respond_to do |format| + # format.html { redirect_to contestnotifications_url } + # format.json { head :no_content } + # end + @contestnotification = Contestnotification.find(params[:id]) + @contestnotification.destroy + redirect_to contest_contestnotifications_url(@contest) + end + + private + + def find_optional_contest + return true unless params[:id] + @contest = Contest.find(params[:id]) + # authorize + rescue ActiveRecord::RecordNotFound + render_404 + end + + def access_edit_destroy + if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) + return true + else + render_403 + end + end + +end diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index 204dcc201..5cdbda5a7 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -1,732 +1,734 @@ -# fq -# 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 => [] # 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 ] - - helper :watchers - helper :attachments - helper :projects - helper :words - - include AttachmentsHelper - include ApplicationHelper - - - def index - # @contests = Contest.visible - # @contests ||= [] - @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]}%'") - if params[:contests_search] - (redirect_to contests_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank? - end - @contest_count = @contests.count - @contest_pages = Paginator.new @contest_count, @limit, params['page'] - - @offset ||= @contest_pages.reverse_offset - if params[:contest_sort_type].present? - case params[:contest_sort_type] - when '0' - # modified by longjun - # never use unless and else, 将下面重复操作模块化,放在private下 - # 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 - - @contests = index_page_sort(@offset, @limit, @contest_count, @contests, 'contests.commit') - # end - @s_state = 0 - when '1' - - @contests = index_page_sort(@offset, @limit, @contest_count, @contests, 'contests.created_on') - @s_state = 1 - # modified by longjun - # 目前只有 0, 1 两个sort_type - # when '2' - else - # end longjun - - @contests = index_page_sort(@offset, @limit, @contest_count, @contests, '') - @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 - - def search - redirect_to action: 'index',name:params[:name] - end - - def homework - @offset, @limit = api_offset_and_limit({:limit => 10}) - @bids = @course.homeworks.order('deadline DESC') - @bids = @bids.like(params[:name]) if params[:name].present? - @bid_count = @bids.count - @bid_pages = Paginator.new @bid_count, @limit, params['page'] - - @offset ||= @bid_pages.reverse_offset - # 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 - @bids = @bids.offset(@offset).limit(limit).all.reverse - end - render :layout => 'base_courses' - - end - - - def show_contest - @user = @contest.author - @jours = @contest.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - @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 - - respond_to do |format| - layout_file = 'base_newcontest' - format.html { - render :layout => layout_file - } - format.api - end - end - - def join_in_contest - if params[:contest_password] == @contest.password - JoinInCompetition.create(:user_id => User.current.id, :competition_id => @contest.id) - @state = 0 - else - @state = 1 - end - - respond_to do |format| - format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } - end - end - - def unjoin_in_contest - - joined = JoinInCompetition.where('competition_id = ? and user_id = ?', @contest.id, User.current.id) - - joined.each do |join| - join.delete - end - - respond_to do |format| - format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } - end - end - - - - def show_participator - render :layout => 'base_newcontest' - - end - - - def settings - if @contest.author.id == User.current.id - @contest = Contest.find(params[:id]) - render :layout => 'base_newcontest' - else - render_403 :message => :notice_not_contest_setting_authorized - end - end - - # Added by Longjun - def destroy_contest - @contest = Contest.find(params[:id]) - if @contest.author_id == User.current.id - - @contest.destroy - redirect_to action: 'index' - else - render_403 :message => :notice_not_contest_delete_authorized - end - - end - # end - - def show_contest_project - contests = Contest.where('parent_id = ?', @contest.id) - @projects = [] - - # 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 = [] - - # 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' - } - format.api - - end - end - - def show_contest_user - contests = Contest.find(:all) - @users = [] - - # 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| - @users += project.users - end - end - # end - - respond_to do |format| - format.html { - render :layout => 'base_newcontest' - } - format.api - - end - end - #显示参赛的项目 - def show_project - @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) - @option = [] - # @contesting_project_count = @contesting_project_all.count - # @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page'] - @membership.each do |membership| - - # 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 - @user = @contest.author - @contesting_project = @contest.contesting_projects.all - if params[:student_id].present? - @temp = [] - @contesting_project.each do |pro| - if pro.project && pro.project.project_status - if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id - @temp << pro - end - end - @temp - end - @contesting_project = @temp - else - - @temp = [] - @contesting_project.each do |pro| - # 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) - respond_to do |format| - format.html { - render :layout => 'base_newcontest' - } - format.api - end - end - ############ - ##显示参赛的应用 - def show_softapplication - - # @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) - # @option = [] - - # @user = @contest.user - @softapplication = Softapplication.all - @contesting_softapplication = @contest.contesting_softapplications - - @contesting_softapplication = paginateHelper(@contesting_softapplication, 10) - - # @temp = [] - # @softapplicationt.each do |pro| - # if pro.project && pro.project.project_status - # @temp << pro - # end - # @temp - - # if @temp.size > 0 - # @contesting_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} - # end - # end - # respond_to do |format| - # format.html { - # render :layout => 'base_newcontest' - # } - # format.api - # end -########################## - @contest = Contest.find_by_id(params[:id]) - respond_to do |format| - format.html { - render :layout => 'base_newcontest' - } - format.api - end - end - - - ###我要参赛 - def show_attendingcontest -##取出参赛项目--项目列表 - @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) - @option = [] - # @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) - @option << membership.project - end - end - end - @user = @contest.author - @contesting_project = @contest.contesting_projects.all - if params[:student_id].present? - @temp = [] - @contesting_project.each do |pro| - if pro.project && pro.project.project_status - if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id - @temp << pro - end - end - @temp - end - @contesting_project = @temp - else - - @temp = [] - @contesting_project.each do |pro| - # 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"). - order("cached.avg").reverse_order - @contesting_softapplication = paginateHelper @contesting_softapplication, 10 - - - #引用base_newcontest整体样式 - @contest = Contest.find_by_id(params[:id]) - respond_to do |format| - format.html { - render :layout => 'base_newcontest' - } - format.api - end - 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 - @c_p = nil - @contesting_project_id = nil - - if params[:set_reward_project][:reward]&&((User.current.id==@contest.author_id)||User.current.admin) - # @bid_id = params[:id] - @contesting_project_id = params[:set_reward_project][:c_id] - @c_p = ContestingProject.find_by_id(@contesting_project_id) - - # 把字段存进表中 - @c_p.update_reward(params[:set_reward_project][:reward].to_s) - end - - respond_to do |format| - format.js - end - end - - def set_reward_softapplication - @c_sa = nil - @contesting_softapplication_id = nil - - if params[:set_reward_softapplication][:reward]&&((User.current.id==@contest.author_id)||User.current.admin) - # @bid_id = params[:id] - @contesting_softapplication_id = params[:set_reward_softapplication][:c_id] - @c_sa = ContestingSoftapplication.find_by_id(@contesting_softapplication_id) - - # 把字段存进表中 - @c_sa.update_reward(params[:set_reward_softapplication][:reward].to_s) - end - - respond_to do |format| - format.js - end - end - - - ###添加已创建的参赛项目 - def add - 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 - # 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 - flash.now[:error] = l(:label_bidding_fail) - end - - @contesting_project = paginateHelper @contest.contesting_projects - - respond_to do |format| - - format.html { redirect_to :back } - format.js - end - end - ###添加已发布的参赛应用 - def add_softapplication - softapplication = Softapplication.find(params[:contest]) - contest_message = params[:contest_for_save][:contest_message] - if ContestingSoftapplication.where("softapplication_id = ? and contest_id = ?", softapplication.id, @contest.id).size == 0 - if ContestingSoftapplication.create_softapplication_contesting(@contest.id, softapplication.id, contest_message) - flash.now[:notice] = l(:label_release_add_contest_succeed) - end - else - flash.now[:error] = l(:label_add_contest_succeed_fail) - end - - @contesting_softapplication = paginateHelper @contest.contesting_softapplications - - respond_to do |format| - - format.html { redirect_to :back } - format.js - end - end - ## 新建留言 - def create - - if params[:contest_message][:message].size>0 - if params[:reference_content] - message = params[:contest_message][:message] + "\n" + params[:reference_content] - else - message = params[:contest_message][:message] - end - refer_user_id = params[:contest_message][:reference_user_id].to_i - @contest.add_jour(User.current, message, refer_user_id) - end - @user = @contest.author - @jours = @contest.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - @contest.set_commit(@feedback_count) - - respond_to do |format| - format.js - end - - end - - ##删除留言 - def destroy - @user = @contest.author - if User.current.admin? || User.current.id == @user.id - JournalsForMessage.delete_message(params[:object_id]) - end - @jours = @contest.journals_for_messages.reverse - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - - @contest.set_commit(@feedback_count) - respond_to do |format| - format.js - end - end - - ##引用留言 - def new - @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] - if @jour - user = @jour.user - text = @jour.notes - else - user = @contest.author - text = @contest.description - end - text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') - @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " - @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - @id = user.id - rescue ActiveRecord::RecordNotFound - render_404 - end - - ##新建竞赛 - def new_contest - @contest = Contest.new - @contest.safe_attributes = params[:contest] - end - - ##提交创建的竞赛 - def create_contest - @contest = Contest.new - @contest.name = params[:contest][:name] - @contest.description = params[:contest][:description] - @contest.budget = params[:contest][:budget] - @contest.deadline = params[:contest][:deadline] - @contest.password = params[:contest][:password] - @contest.author_id = User.current.id - @contest.commit = 0 - if @contest.save - unless @contest.watched_by?(User.current) - if @contest.add_watcher(User.current) - flash[:notice] = l(:label_contesting_created_succeed) - end - end - redirect_to show_contest_contest_url(@contest) - else - @contest.safe_attributes = params[:contest] - render :action => 'new_contest' - end - end - - ##更新竞赛配置信息 - def update_contest - @contest = Contest.find(params[:id]) - @contest.name = params[:contest][:name] - @contest.description = params[:contest][:description] - - @contest.budget = params[:contest][:budget] - @contest.deadline = params[:contest][:deadline] - @contest.password = params[:contest][:password] - @contest.author_id = User.current.id - @contest.commit = 0 - if @contest.save - unless @contest.watched_by?(User.current) - if @contest.add_watcher(User.current) - flash[:notice] = l(:label_contesting_updated_succeed) - end - end - redirect_to show_contest_contest_url(@contest) - - else - @contest.safe_attributes = params[:contest] - render :action => 'new_contest' - end - end - - def more - @jour = @contest.journals_for_messages - @jour.each_with_index {|j,i| j.indice = i+1} - @state = true - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - def back - @jour = @contest.journals_for_messages - @jour.each_with_index {|j,i| j.indice = i+1} - @state = false - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - def set_reward - @b_p = nil - @contesting_project_id = nil - - if params[:set_reward][:reward]&&((User.current.id==@contest.author_id)||User.current.admin) - # @contest_id = params[:id] - @contesting_project_id = params[:set_reward][:b_id] #[:b_id]??? - @b_p = ContestingProject.find_by_id(@contesting_project_id) - - # 把字段存进表中 - @b_p.update_reward(params[:set_reward][:reward].to_s) - end - - respond_to do |format| - format.js - end - end - - - - - private - - def find_contest - if params[:id] - @contest = Contest.find(params[:id]) - @user = @contest.author - end - rescue - render_404 - end - - #验证是否显示竞赛 - def can_show_contest - @first_page = FirstPage.find_by_page_type('project') - if @first_page.show_contest == 2 - render_404 - end - end - - # added by longjun - # 将index页面中分页排序的方法抽离出来 - def index_page_sort(offset, limit, contest_count, contests, contest_sort_by) - # modified by longjun - # never use unless and else - # unless @offset == 0 - if offset != 0 - contests = contests.reorder(contest_sort_by).offset(offset).limit(limit).all.reverse - else - limit = contest_count % limit - limit = limit if limit == 0 - contests = contests.reorder(contest_sort_by).offset(offset).limit(limit).all.reverse - end - contests - end -end - +# fq +# 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 => [] # 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, :watcherlist, + :join_in_contest, :unjoin_in_contest, :new_join, :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 ] + + helper :watchers + helper :attachments + helper :projects + helper :words + + include AttachmentsHelper + include ApplicationHelper + + + def index + # @contests = Contest.visible + # @contests ||= [] + @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]}%'") + if params[:contests_search] + (redirect_to contests_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank? + end + @contest_count = @contests.count + @contest_pages = Paginator.new @contest_count, @limit, params['page'] + + @offset ||= @contest_pages.reverse_offset + if params[:contest_sort_type].present? + case params[:contest_sort_type] + when '0' + # modified by longjun + # never use unless and else, 将下面重复操作模块化,放在private下 + # 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 + + @contests = index_page_sort(@offset, @limit, @contest_count, @contests, 'contests.commit') + # end + @s_state = 0 + when '1' + + @contests = index_page_sort(@offset, @limit, @contest_count, @contests, 'contests.created_on') + @s_state = 1 + # modified by longjun + # 目前只有 0, 1 两个sort_type + # when '2' + else + # end longjun + + @contests = index_page_sort(@offset, @limit, @contest_count, @contests, '') + @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 + + def search + redirect_to action: 'index',name:params[:name] + end + + def homework + @offset, @limit = api_offset_and_limit({:limit => 10}) + @bids = @course.homeworks.order('deadline DESC') + @bids = @bids.like(params[:name]) if params[:name].present? + @bid_count = @bids.count + @bid_pages = Paginator.new @bid_count, @limit, params['page'] + + @offset ||= @bid_pages.reverse_offset + # 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 + @bids = @bids.offset(@offset).limit(limit).all.reverse + end + render :layout => 'base_courses' + + end + + + def show_contest + @user = @contest.author + @jours = @contest.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @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 + + respond_to do |format| + layout_file = 'base_newcontest' + format.html { + render :layout => layout_file + } + format.api + end + end + + def join_in_contest + if params[:contest_password] == @contest.password + JoinInCompetition.create(:user_id => User.current.id, :competition_id => @contest.id) + @state = 0 + else + @state = 1 + end + + respond_to do |format| + format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } + end + end + + def unjoin_in_contest + + joined = JoinInCompetition.where('competition_id = ? and user_id = ?', @contest.id, User.current.id) + + joined.each do |join| + join.delete + end + + respond_to do |format| + format.js { render :partial => 'set_join', :locals => {:user => User.current, :object_id => params[:id]} } + end + end + + + + def show_participator + render :layout => 'base_newcontest' + + end + + + def settings + if @contest.author.id == User.current.id + @contest = Contest.find(params[:id]) + render :layout => 'base_newcontest' + else + render_403 :message => :notice_not_contest_setting_authorized + end + end + + # Added by Longjun + def destroy_contest + @contest = Contest.find(params[:id]) + if @contest.author_id == User.current.id + + @contest.destroy + redirect_to action: 'index' + else + render_403 :message => :notice_not_contest_delete_authorized + end + + end + # end + + def show_contest_project + contests = Contest.where('parent_id = ?', @contest.id) + @projects = [] + + # 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 = [] + + # 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' + } + format.api + + end + end + + def show_contest_user + contests = Contest.find(:all) + @users = [] + + # 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| + @users += project.users + end + end + # end + + respond_to do |format| + format.html { + render :layout => 'base_newcontest' + } + format.api + + end + end + #显示参赛的项目 + def show_project + @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + @option = [] + # @contesting_project_count = @contesting_project_all.count + # @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page'] + @membership.each do |membership| + + # 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 + @user = @contest.author + @contesting_project = @contest.contesting_projects.all + if params[:student_id].present? + @temp = [] + @contesting_project.each do |pro| + if pro.project && pro.project.project_status + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + end + @temp + end + @contesting_project = @temp + else + + @temp = [] + @contesting_project.each do |pro| + # 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) + respond_to do |format| + format.html { + render :layout => 'base_newcontest' + } + format.api + end + end + ############ + ##显示参赛的应用 + def show_softapplication + + # @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + # @option = [] + + # @user = @contest.user + @softapplication = Softapplication.all + @contesting_softapplication = @contest.contesting_softapplications + + @contesting_softapplication = paginateHelper(@contesting_softapplication, 10) + + # @temp = [] + # @softapplicationt.each do |pro| + # if pro.project && pro.project.project_status + # @temp << pro + # end + # @temp + + # if @temp.size > 0 + # @contesting_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} + # end + # end + # respond_to do |format| + # format.html { + # render :layout => 'base_newcontest' + # } + # format.api + # end +########################## + @contest = Contest.find_by_id(params[:id]) + respond_to do |format| + format.html { + render :layout => 'base_newcontest' + } + format.api + end + end + + + ###我要参赛 + def show_attendingcontest +##取出参赛项目--项目列表 + @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + @option = [] + # @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) + @option << membership.project + end + end + end + @user = @contest.author + @contesting_project = @contest.contesting_projects.all + if params[:student_id].present? + @temp = [] + @contesting_project.each do |pro| + if pro.project && pro.project.project_status + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + end + @temp + end + @contesting_project = @temp + else + + @temp = [] + @contesting_project.each do |pro| + # 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"). + order("cached.avg").reverse_order + @contesting_softapplication = paginateHelper @contesting_softapplication, 10 + + + #引用base_newcontest整体样式 + @contest = Contest.find_by_id(params[:id]) + respond_to do |format| + format.html { + render :layout => 'base_newcontest' + } + format.api + end + 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 + @c_p = nil + @contesting_project_id = nil + + if params[:set_reward_project][:reward]&&((User.current.id==@contest.author_id)||User.current.admin) + # @bid_id = params[:id] + @contesting_project_id = params[:set_reward_project][:c_id] + @c_p = ContestingProject.find_by_id(@contesting_project_id) + + # 把字段存进表中 + @c_p.update_reward(params[:set_reward_project][:reward].to_s) + end + + respond_to do |format| + format.js + end + end + + def set_reward_softapplication + @c_sa = nil + @contesting_softapplication_id = nil + + if params[:set_reward_softapplication][:reward]&&((User.current.id==@contest.author_id)||User.current.admin) + # @bid_id = params[:id] + @contesting_softapplication_id = params[:set_reward_softapplication][:c_id] + @c_sa = ContestingSoftapplication.find_by_id(@contesting_softapplication_id) + + # 把字段存进表中 + @c_sa.update_reward(params[:set_reward_softapplication][:reward].to_s) + end + + respond_to do |format| + format.js + end + end + + + ###添加已创建的参赛项目 + def add + 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 + # 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 + flash.now[:error] = l(:label_bidding_fail) + end + + @contesting_project = paginateHelper @contest.contesting_projects + + respond_to do |format| + + format.html { redirect_to :back } + format.js + end + end + ###添加已发布的参赛应用 + def add_softapplication + softapplication = Softapplication.find(params[:contest]) + contest_message = params[:contest_for_save][:contest_message] + if ContestingSoftapplication.where("softapplication_id = ? and contest_id = ?", softapplication.id, @contest.id).size == 0 + if ContestingSoftapplication.create_softapplication_contesting(@contest.id, softapplication.id, contest_message) + flash.now[:notice] = l(:label_release_add_contest_succeed) + end + else + flash.now[:error] = l(:label_add_contest_succeed_fail) + end + + @contesting_softapplication = paginateHelper @contest.contesting_softapplications + + respond_to do |format| + + format.html { redirect_to :back } + format.js + end + end + ## 新建留言 + def create + + if params[:contest_message][:message].size>0 + if params[:reference_content] + message = params[:contest_message][:message] + "\n" + params[:reference_content] + else + message = params[:contest_message][:message] + end + refer_user_id = params[:contest_message][:reference_user_id].to_i + @contest.add_jour(User.current, message, refer_user_id) + end + @user = @contest.author + @jours = @contest.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @contest.set_commit(@feedback_count) + + respond_to do |format| + format.js + end + + end + + ##删除留言 + def destroy + @user = @contest.author + if User.current.admin? || User.current.id == @user.id + JournalsForMessage.delete_message(params[:object_id]) + end + @jours = @contest.journals_for_messages.reverse + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + + @contest.set_commit(@feedback_count) + respond_to do |format| + format.js + end + end + + ##引用留言 + def new + @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] + if @jour + user = @jour.user + text = @jour.notes + else + user = @contest.author + text = @contest.description + end + text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') + @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " + @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + @id = user.id + rescue ActiveRecord::RecordNotFound + render_404 + end + + ##新建竞赛 + def new_contest + @contest = Contest.new + @contest.safe_attributes = params[:contest] + end + + ##提交创建的竞赛 + def create_contest + @contest = Contest.new + @contest.name = params[:contest][:name] + @contest.description = params[:contest][:description] + @contest.budget = params[:contest][:budget] + @contest.deadline = params[:contest][:deadline] + @contest.password = params[:contest][:password] + @contest.author_id = User.current.id + @contest.commit = 0 + if @contest.save + unless @contest.watched_by?(User.current) + if @contest.add_watcher(User.current) + flash[:notice] = l(:label_contesting_created_succeed) + end + end + redirect_to show_contest_contest_url(@contest) + else + @contest.safe_attributes = params[:contest] + render :action => 'new_contest' + end + end + + ##更新竞赛配置信息 + def update_contest + @contest = Contest.find(params[:id]) + @contest.name = params[:contest][:name] + @contest.description = params[:contest][:description] + + @contest.budget = params[:contest][:budget] + @contest.deadline = params[:contest][:deadline] + @contest.password = params[:contest][:password] + @contest.author_id = User.current.id + @contest.commit = 0 + if @contest.save + unless @contest.watched_by?(User.current) + if @contest.add_watcher(User.current) + flash[:notice] = l(:label_contesting_updated_succeed) + end + end + redirect_to show_contest_contest_url(@contest) + + else + @contest.safe_attributes = params[:contest] + render :action => 'new_contest' + end + end + + def more + @jour = @contest.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = true + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def back + @jour = @contest.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = false + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def set_reward + @b_p = nil + @contesting_project_id = nil + + if params[:set_reward][:reward]&&((User.current.id==@contest.author_id)||User.current.admin) + # @contest_id = params[:id] + @contesting_project_id = params[:set_reward][:b_id] #[:b_id]??? + @b_p = ContestingProject.find_by_id(@contesting_project_id) + + # 把字段存进表中 + @b_p.update_reward(params[:set_reward][:reward].to_s) + end + + respond_to do |format| + format.js + end + end + def watcherlist + render :layout => 'base_newcontest' + end + + + + private + + def find_contest + if params[:id] + @contest = Contest.find(params[:id]) + @user = @contest.author + end + rescue + render_404 + end + + #验证是否显示竞赛 + def can_show_contest + @first_page = FirstPage.find_by_page_type('project') + if @first_page.show_contest == 2 + render_404 + end + end + + # added by longjun + # 将index页面中分页排序的方法抽离出来 + def index_page_sort(offset, limit, contest_count, contests, contest_sort_by) + # modified by longjun + # never use unless and else + # unless @offset == 0 + if offset != 0 + contests = contests.reorder(contest_sort_by).offset(offset).limit(limit).all.reverse + else + limit = contest_count % limit + limit = limit if limit == 0 + contests = contests.reorder(contest_sort_by).offset(offset).limit(limit).all.reverse + end + contests + end +end + diff --git a/app/controllers/custom_fields_controller.rb b/app/controllers/custom_fields_controller.rb index d017de5ca..2d06af9ba 100644 --- a/app/controllers/custom_fields_controller.rb +++ b/app/controllers/custom_fields_controller.rb @@ -1,81 +1,81 @@ -# 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 CustomFieldsController < ApplicationController - layout 'admin' - - before_filter :require_admin - before_filter :build_new_custom_field, :only => [:new, :create] - before_filter :find_custom_field, :only => [:edit, :update, :destroy] - - def index - @custom_fields_by_type = CustomField.all.group_by {|f| f.class.name } - @tab = params[:tab] || 'IssueCustomField' - end - - def new - end - - def create - if @custom_field.save - flash[:notice] = l(:notice_successful_create) - call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field) - redirect_to custom_fields_url(:tab => @custom_field.class.name) - else - render :action => 'new' - end - end - - def edit - end - - def update - if @custom_field.update_attributes(params[:custom_field]) - flash[:notice] = l(:notice_successful_update) - call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field) - redirect_to custom_fields_url(:tab => @custom_field.class.name) - else - render :action => 'edit' - end - end - - def destroy - begin - @custom_field.destroy - rescue - flash[:error] = l(:error_can_not_delete_custom_field) - end - redirect_to custom_fields_url(:tab => @custom_field.class.name) - end - - private - - def build_new_custom_field - @custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field]) - if @custom_field.nil? - render_404 - else - @custom_field.default_value = nil - end - end - - def find_custom_field - @custom_field = CustomField.find(params[:id]) - 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. + +class CustomFieldsController < ApplicationController + layout 'admin' + + before_filter :require_admin + before_filter :build_new_custom_field, :only => [:new, :create] + before_filter :find_custom_field, :only => [:edit, :update, :destroy] + + def index + @custom_fields_by_type = CustomField.all.group_by {|f| f.class.name } + @tab = params[:tab] || 'IssueCustomField' + end + + def new + end + + def create + if @custom_field.save + flash[:notice] = l(:notice_successful_create) + call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field) + redirect_to custom_fields_url(:tab => @custom_field.class.name) + else + render :action => 'new' + end + end + + def edit + end + + def update + if @custom_field.update_attributes(params[:custom_field]) + flash[:notice] = l(:notice_successful_update) + call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field) + redirect_to custom_fields_url(:tab => @custom_field.class.name) + else + render :action => 'edit' + end + end + + def destroy + begin + @custom_field.destroy + rescue + flash[:error] = l(:error_can_not_delete_custom_field) + end + redirect_to custom_fields_url(:tab => @custom_field.class.name) + end + + private + + def build_new_custom_field + @custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field]) + if @custom_field.nil? + render_404 + else + @custom_field.default_value = nil + end + end + + def find_custom_field + @custom_field = CustomField.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index bf2a7b303..2fcc2e89b 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -1,120 +1,120 @@ -# 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 DocumentsController < ApplicationController - layout 'base_projects'#by young - default_search_scope :documents - model_object Document - before_filter :find_project_by_project_id, :only => [:index, :new, :create] - before_filter :find_model_object, :except => [:index, :new, :create] - before_filter :find_project_from_association, :except => [:index, :new, :create] - before_filter :authorize , :except => [:index]#Added by young - before_filter :authorize_document - - helper :attachments - helper :project_score - - def index - @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' - temp = @project.documents.includes(:attachments, :category).all - documents = [] - temp.each do |doc| - if doc.has_right?(@project) - documents << doc - end - end - case @sort_by - when 'date' - @grouped = documents.group_by {|d| d.updated_on.to_date } - when 'title' - @grouped = documents.group_by {|d| d.title.first.upcase} - when 'author' - # @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author} - @grouped = documents.group_by {|d| d.user.name } - else - @grouped = documents.group_by(&:category) - end - @document = @project.documents.build - if @project.project_type == 1 - render :layout => 'base_courses' - else - render :layout => false if request.xhr? - end - end - - def show - @attachments = @document.attachments.all - if @project.project_type ==1 - render :action => 'show', :layout => 'base_courses' - end - end - - def new - @document = @project.documents.build - @document.safe_attributes = params[:document] - end - - def create - @document = @project.documents.build - @document.safe_attributes = params[:document] - @document.user = User.current - @document.save_attachments(params[:attachments]) - if @document.save - render_attachment_warning_if_needed(@document) - flash[:notice] = l(:notice_successful_create) - redirect_to project_documents_url(@project) - else - render :action => 'new' - end - end - - def edit - end - - def update - @document.safe_attributes = params[:document] - if request.put? and @document.save - flash[:notice] = l(:notice_successful_update) - redirect_to document_url(@document) - else - render :action => 'edit' - end - end - - def destroy - @document.destroy if request.delete? - redirect_to project_documents_url(@project) - end - - def add_attachment - attachments = Attachment.attach_files(@document, params[:attachments]) - render_attachment_warning_if_needed(@document) - - if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added') - Mailer.attachments_added(attachments[:files]).deliver - end - redirect_to document_url(@document) - end - - # 权限判断 - # add by nwb - def authorize_document - if !(User.current.admin? || User.current.member_of?(@project) || @document == nil || (@document != nil && @document.is_public==1)) - render_403 :message => :notice_not_authorized - 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 DocumentsController < ApplicationController + layout 'base_projects'#by young + default_search_scope :documents + model_object Document + before_filter :find_project_by_project_id, :only => [:index, :new, :create] + before_filter :find_model_object, :except => [:index, :new, :create] + before_filter :find_project_from_association, :except => [:index, :new, :create] + before_filter :authorize , :except => [:index]#Added by young + before_filter :authorize_document + + helper :attachments + helper :project_score + + def index + @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' + temp = @project.documents.includes(:attachments, :category).all + documents = [] + temp.each do |doc| + if doc.has_right?(@project) + documents << doc + end + end + case @sort_by + when 'date' + @grouped = documents.group_by {|d| d.updated_on.to_date } + when 'title' + @grouped = documents.group_by {|d| d.title.first.upcase} + when 'author' + # @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author} + @grouped = documents.group_by {|d| d.user.name } + else + @grouped = documents.group_by(&:category) + end + @document = @project.documents.build + if @project.project_type == 1 + render :layout => 'base_courses' + else + render :layout => false if request.xhr? + end + end + + def show + @attachments = @document.attachments.all + if @project.project_type ==1 + render :action => 'show', :layout => 'base_courses' + end + end + + def new + @document = @project.documents.build + @document.safe_attributes = params[:document] + end + + def create + @document = @project.documents.build + @document.safe_attributes = params[:document] + @document.user = User.current + @document.save_attachments(params[:attachments]) + if @document.save + render_attachment_warning_if_needed(@document) + flash[:notice] = l(:notice_successful_create) + redirect_to project_documents_url(@project) + else + render :action => 'new' + end + end + + def edit + end + + def update + @document.safe_attributes = params[:document] + if request.put? and @document.save + flash[:notice] = l(:notice_successful_update) + redirect_to document_url(@document) + else + render :action => 'edit' + end + end + + def destroy + @document.destroy if request.delete? + redirect_to project_documents_url(@project) + end + + def add_attachment + attachments = Attachment.attach_files(@document, params[:attachments]) + render_attachment_warning_if_needed(@document) + + if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added') + Mailer.attachments_added(attachments[:files]).deliver + end + redirect_to document_url(@document) + end + + # 权限判断 + # add by nwb + def authorize_document + if !(User.current.admin? || User.current.member_of?(@project) || @document == nil || (@document != nil && @document.is_public==1)) + render_403 :message => :notice_not_authorized + end + end +end diff --git a/app/controllers/enumerations_controller.rb b/app/controllers/enumerations_controller.rb index 58e76ed4a..de9414de5 100644 --- a/app/controllers/enumerations_controller.rb +++ b/app/controllers/enumerations_controller.rb @@ -1,98 +1,98 @@ -# 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 EnumerationsController < ApplicationController - layout 'admin' - - before_filter :require_admin, :except => :index - before_filter :require_admin_or_api_request, :only => :index - before_filter :build_new_enumeration, :only => [:new, :create] - before_filter :find_enumeration, :only => [:edit, :update, :destroy] - accept_api_auth :index - - helper :custom_fields - - def index - respond_to do |format| - format.html - format.api { - @klass = Enumeration.get_subclass(params[:type]) - if @klass - @enumerations = @klass.shared.sorted.all - else - render_404 - end - } - end - end - - def new - end - - def create - if request.post? && @enumeration.save - flash[:notice] = l(:notice_successful_create) - redirect_to enumerations_url - else - render :action => 'new' - end - end - - def edit - end - - def update - if request.put? && @enumeration.update_attributes(params[:enumeration]) - flash[:notice] = l(:notice_successful_update) - redirect_to enumerations_url - else - render :action => 'edit' - end - end - - def destroy - if !@enumeration.in_use? - # No associated objects - @enumeration.destroy - redirect_to enumerations_url - return - elsif params[:reassign_to_id] - if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id]) - @enumeration.destroy(reassign_to) - redirect_to enumerations_url - return - end - end - @enumerations = @enumeration.class.all - [@enumeration] - end - - private - - def build_new_enumeration - class_name = params[:enumeration] && params[:enumeration][:type] || params[:type] - @enumeration = Enumeration.new_subclass_instance(class_name, params[:enumeration]) - if @enumeration.nil? - render_404 - end - end - - def find_enumeration - @enumeration = Enumeration.find(params[:id]) - 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. + +class EnumerationsController < ApplicationController + layout 'admin' + + before_filter :require_admin, :except => :index + before_filter :require_admin_or_api_request, :only => :index + before_filter :build_new_enumeration, :only => [:new, :create] + before_filter :find_enumeration, :only => [:edit, :update, :destroy] + accept_api_auth :index + + helper :custom_fields + + def index + respond_to do |format| + format.html + format.api { + @klass = Enumeration.get_subclass(params[:type]) + if @klass + @enumerations = @klass.shared.sorted.all + else + render_404 + end + } + end + end + + def new + end + + def create + if request.post? && @enumeration.save + flash[:notice] = l(:notice_successful_create) + redirect_to enumerations_url + else + render :action => 'new' + end + end + + def edit + end + + def update + if request.put? && @enumeration.update_attributes(params[:enumeration]) + flash[:notice] = l(:notice_successful_update) + redirect_to enumerations_url + else + render :action => 'edit' + end + end + + def destroy + if !@enumeration.in_use? + # No associated objects + @enumeration.destroy + redirect_to enumerations_url + return + elsif params[:reassign_to_id] + if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id]) + @enumeration.destroy(reassign_to) + redirect_to enumerations_url + return + end + end + @enumerations = @enumeration.class.all - [@enumeration] + end + + private + + def build_new_enumeration + class_name = params[:enumeration] && params[:enumeration][:type] || params[:type] + @enumeration = Enumeration.new_subclass_instance(class_name, params[:enumeration]) + if @enumeration.nil? + render_404 + end + end + + def find_enumeration + @enumeration = Enumeration.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 313afa1c7..234d09d1c 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -1,280 +1,280 @@ -# 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 FilesController < ApplicationController - layout 'base_projects'#by young - menu_item :files - - before_filter :find_project_by_project_id#, :except => [:getattachtype] - before_filter :authorize, :except => [:getattachtype] - - helper :sort - include SortHelper - helper :project_score - - def show_attachments obj - all_attachments = [] - obj.each do |container| - all_attachments += container.attachments - end - @limit = 10 - @feedback_count = all_attachments.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @curse_attachments = all_attachments[@offset, @limit] - end - - def index - #sort_init 'filename', 'asc' - sort_init 'created_on', 'desc' - sort_update 'created_on' => "#{Attachment.table_name}.created_on", - 'filename' => "#{Attachment.table_name}.filename", - 'size' => "#{Attachment.table_name}.filesize", - 'downloads' => "#{Attachment.table_name}.downloads" - sort = "" - - if params[:project_id] - @isproject = true - - if params[:sort] - params[:sort].split(",").each do |sort_type| - order_by = sort_type.split(":") - - case order_by[0] - when "filename" - attribute = "filename" - when "size" - attribute = "filesize" - when "attach_type" - attribute = "attachtype" - when "content_type" - attribute = "created_on" - when "field_file_dense" - attribute = "is_public" - when "downloads" - attribute = "downloads" - when "created_on" - attribute = "created_on" - end - - if order_by.count == 1 - sort += "#{Attachment.table_name}.#{attribute} desc " - elsif order_by.count == 2 - sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} " - end - if sort_type != params[:sort].split(",").last - sort += "," - end - end - end - - @containers = [ Project.includes(:attachments).reorder(sort).find(@project.id)] - @containers += @project.versions.includes(:attachments).reorder(sort).all.sort - - show_attachments @containers - - render :layout => !request.xhr? - elsif params[:course_id] - @isproject = false - - if params[:sort] - params[:sort].split(",").each do |sort_type| - order_by = sort_type.split(":") - - case order_by[0] - when "filename" - attribute = "filename" - when "size" - attribute = "filesize" - when "attach_type" - attribute = "attachtype" - when "content_type" - attribute = "created_on" - when "field_file_dense" - attribute = "is_public" - when "downloads" - attribute = "downloads" - when "created_on" - attribute = "created_on" - end - - if order_by.count == 1 - sort += "#{Attachment.table_name}.#{attribute} asc " - elsif order_by.count == 2 - sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} " - end - if sort_type != params[:sort].split(",").last - sort += "," - end - end - end - @containers = [ Course.includes(:attachments).reorder(sort).find(@course.id)] - - show_attachments @containers - - render :layout => 'base_courses' - end - - end - - def new - @versions = @project.versions.sort - @course_tag = @project.project_type - if @project.project_type == 1 - render :layout => 'base_courses' - end - end - - def create - if params[:add_tag] - @addTag=true - #render :back - tag_saveEx - #render :text =>"success" - respond_to do |format| - format.js - end - else - #modify by nwb - if @project - @addTag=false - container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) - attachments = Attachment.attach_filesex(container, params[:attachments], params[:attachment_type]) - render_attachment_warning_if_needed(container) - - if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') - Mailer.attachments_added(attachments[:files]).deliver - end - - # TODO: 临时用 nyan - sort_init 'created_on', 'desc' - sort_update 'created_on' => "#{Attachment.table_name}.created_on", - 'filename' => "#{Attachment.table_name}.filename", - 'size' => "#{Attachment.table_name}.filesize", - 'downloads' => "#{Attachment.table_name}.downloads" - - @containers = [Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - - show_attachments @containers - - @attachtype = 0 - @contenttype = 0 - - respond_to do |format| - format.js - format.html { - redirect_to project_files_url(@project) - } - end - elsif @course - @addTag=false - attachments = Attachment.attach_filesex(@course, params[:attachments], params[:attachment_type]) - - if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') - Mailer.attachments_added(attachments[:files]).deliver - end - - # TODO: 临时用 nyan - sort_init 'created_on', 'desc' - sort_update 'created_on' => "#{Attachment.table_name}.created_on", - 'filename' => "#{Attachment.table_name}.filename", - 'size' => "#{Attachment.table_name}.filesize", - 'downloads' => "#{Attachment.table_name}.downloads" - - @containers = [Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] - - show_attachments @containers - - @attachtype = 0 - @contenttype = 0 - - respond_to do |format| - format.js - format.html { - redirect_to course_files_url(@course) - } - end - end - - end - end - - def tag_saveEx - @tags = params[:tag_name][:name] - @obj_id = params[:object_id] - @obj_flag = params[: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 - ## 执行成功的操作。 - else - #捕获异常 - end - end - - # 返回指定资源类型的资源列表 - # added by nwb - def getattachtype - sort_init 'created_on', 'desc' - sort_update 'created_on' => "#{Attachment.table_name}.created_on", - 'filename' => "#{Attachment.table_name}.filename", - 'size' => "#{Attachment.table_name}.filesize", - 'downloads' => "#{Attachment.table_name}.downloads" - - if @project - @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - elsif @course - @containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] - end - show_attachments @containers - - @attachtype = params[:type].to_i - @contenttype = params[:contentType].to_s - - 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 FilesController < ApplicationController + layout 'base_projects'#by young + menu_item :files + + before_filter :find_project_by_project_id#, :except => [:getattachtype] + before_filter :authorize, :except => [:getattachtype] + + helper :sort + include SortHelper + helper :project_score + + def show_attachments obj + all_attachments = [] + obj.each do |container| + all_attachments += container.attachments + end + @limit = 10 + @feedback_count = all_attachments.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @curse_attachments = all_attachments[@offset, @limit] + end + + def index + #sort_init 'filename', 'asc' + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" + sort = "" + + if params[:project_id] + @isproject = true + + if params[:sort] + params[:sort].split(",").each do |sort_type| + order_by = sort_type.split(":") + + case order_by[0] + when "filename" + attribute = "filename" + when "size" + attribute = "filesize" + when "attach_type" + attribute = "attachtype" + when "content_type" + attribute = "created_on" + when "field_file_dense" + attribute = "is_public" + when "downloads" + attribute = "downloads" + when "created_on" + attribute = "created_on" + end + + if order_by.count == 1 + sort += "#{Attachment.table_name}.#{attribute} desc " + elsif order_by.count == 2 + sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} " + end + if sort_type != params[:sort].split(",").last + sort += "," + end + end + end + + @containers = [ Project.includes(:attachments).reorder(sort).find(@project.id)] + @containers += @project.versions.includes(:attachments).reorder(sort).all.sort + + show_attachments @containers + + render :layout => !request.xhr? + elsif params[:course_id] + @isproject = false + + if params[:sort] + params[:sort].split(",").each do |sort_type| + order_by = sort_type.split(":") + + case order_by[0] + when "filename" + attribute = "filename" + when "size" + attribute = "filesize" + when "attach_type" + attribute = "attachtype" + when "content_type" + attribute = "created_on" + when "field_file_dense" + attribute = "is_public" + when "downloads" + attribute = "downloads" + when "created_on" + attribute = "created_on" + end + + if order_by.count == 1 + sort += "#{Attachment.table_name}.#{attribute} asc " + elsif order_by.count == 2 + sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} " + end + if sort_type != params[:sort].split(",").last + sort += "," + end + end + end + @containers = [ Course.includes(:attachments).reorder(sort).find(@course.id)] + + show_attachments @containers + + render :layout => 'base_courses' + end + + end + + def new + @versions = @project.versions.sort + @course_tag = @project.project_type + if @project.project_type == 1 + render :layout => 'base_courses' + end + end + + def create + if params[:add_tag] + @addTag=true + #render :back + tag_saveEx + #render :text =>"success" + respond_to do |format| + format.js + end + else + #modify by nwb + if @project + @addTag=false + container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) + attachments = Attachment.attach_filesex(container, params[:attachments], params[:attachment_type]) + render_attachment_warning_if_needed(container) + + if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') + Mailer.attachments_added(attachments[:files]).deliver + end + + # TODO: 临时用 nyan + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" + + @containers = [Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + + show_attachments @containers + + @attachtype = 0 + @contenttype = 0 + + respond_to do |format| + format.js + format.html { + redirect_to project_files_url(@project) + } + end + elsif @course + @addTag=false + attachments = Attachment.attach_filesex(@course, params[:attachments], params[:attachment_type]) + + if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') + Mailer.attachments_added(attachments[:files]).deliver + end + + # TODO: 临时用 nyan + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" + + @containers = [Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] + + show_attachments @containers + + @attachtype = 0 + @contenttype = 0 + + respond_to do |format| + format.js + format.html { + redirect_to course_files_url(@course) + } + end + end + + end + end + + def tag_saveEx + @tags = params[:tag_name][:name] + @obj_id = params[:object_id] + @obj_flag = params[: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 + ## 执行成功的操作。 + else + #捕获异常 + end + end + + # 返回指定资源类型的资源列表 + # added by nwb + def getattachtype + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" + + if @project + @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + elsif @course + @containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] + end + show_attachments @containers + + @attachtype = params[:type].to_i + @contenttype = params[:contentType].to_s + + respond_to do |format| + format.js + end + end +end diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index 88bec0f2a..d5fc1770c 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -1,230 +1,230 @@ -# added by fq -class ForumsController < ApplicationController - layout "users_base" - - # GET /forums - # GET /forums.json - before_filter :find_forum_if_available - before_filter :authenticate_user_edit, :only => [:edit, :update] - before_filter :authenticate_user_destroy, :only => [:destroy] - before_filter :require_login, :only => [:new, :create] - - helper :sort - include SortHelper - - PageLimit = 20 - - def create_memo - @memo = Memo.new(params[:memo]) - @memo.forum_id = @forum.id - @memo.author_id = User.current.id - - @memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads])) - - respond_to do |format| - if @memo.save - format.html { redirect_to (forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))), notice: "#{l :label_memo_create_succ}" } - format.json { render json: @memo, status: :created, location: @memo } - else - sort_init 'updated_at', 'desc' - sort_update 'created_at' => "#{Memo.table_name}.created_at", - 'replies' => "#{Memo.table_name}.replies_count", - 'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)" - - @topic_count = @forum.topics.count - @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] - @memos = @forum.topics. - reorder("#{Memo.table_name}.sticky DESC"). - includes(:last_reply). - limit(@topic_pages.per_page). - offset(@topic_pages.offset). - order(sort_clause). - preload(:author, {:last_reply => :author}). - all - - flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" - # back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id) - format.html { render action: :show, layout: 'base_forums' }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } - format.json { render json: @memo.errors, status: :unprocessable_entity } - end - end - end - - def index - @offset, @limit = api_offset_and_limit({:limit => 10}) - @forums_all = Forum.where('1=1') - @forums_count = @forums_all.count - @forums_pages = Paginator.new @forums_count, @limit, params['page'] - - - @offset ||= @forums_pages.offset - @forums = @forums_all.offset(@offset).limit(@limit).all - #@forums = Forum.all - respond_to do |format| - format.html # index.html.erb - format.json { render json: @forums } - end - end - - # GET /forums/1 - # GET /forums/1.json - def show - sort_init 'updated_at', 'desc' - sort_update 'created_at' => "#{Memo.table_name}.created_at", - 'replies' => "#{Memo.table_name}.replies_count", - 'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)" - - @memo = Memo.new(:forum => @forum) - @topic_count = @forum.topics.count - @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] - @memos = @forum.topics. - reorder("#{Memo.table_name}.sticky DESC"). - includes(:last_reply). - limit(@topic_pages.per_page). - offset(@topic_pages.offset). - order(sort_clause). - preload(:author, {:last_reply => :author}). - all - - - - # @offset, @limit = api_offset_and_limit({:limit => 10}) - # @forum = Forum.find(params[:id]) - # @memos_all = @forum.topics - # @topic_count = @memos_all.count - # @topic_pages = Paginator.new @topic_count, @limit, params['page'] - - # @offset ||= @topic_pages.offset - # @memos = @memos_all.offset(@offset).limit(@limit).all - respond_to do |format| - format.html { - render :layout => 'base_forums' - }# show.html.erb - format.json { render json: @forum } - end - end - - # GET /forums/new - # GET /forums/new.json - def new - @forum = Forum.new - - respond_to do |format| - format.html # new.html.erb - format.json { render json: @forum } - end - end - - # GET /forums/1/edit - def edit - @forum = Forum.find(params[:id]) - end - - # POST /forums - # POST /forums.json - def create - @forum = Forum.new(params[:forum]) - @forum.creator_id = User.current.id - - respond_to do |format| - if @forum.save - format.html { redirect_to @forum, notice: l(:label_forum_create_succ) } - format.json { render json: @forum, status: :created, location: @forum } - else - flash.now[:error] = "#{l :label_forum_create_fail}: #{@forum.errors.full_messages[0]}" - format.html { render action: "new" } - format.json { render json: @forum.errors, status: :unprocessable_entity } - end - end - end - - # PUT /forums/1 - # PUT /forums/1.json - def update - @forum = Forum.find(params[:id]) - - respond_to do |format| - if @forum.update_attributes(params[:forum]) - format.html { redirect_to @forum, notice: l(:label_forum_update_succ) } - format.json { head :no_content } - else - flash.now[:error] = "#{l :label_forum_update_fail}: #{@forum.errors.full_messages[0]}" - format.html { render action: "edit" } - format.json { render json: @forum.errors, status: :unprocessable_entity } - end - end - end - - # DELETE /forums/1 - # DELETE /forums/1.json - def destroy - @forum = Forum.find(params[:id]) - @forum.destroy - - respond_to do |format| - format.html { redirect_to forums_url } - format.json { head :no_content } - end - end - - def search_forum - # @forums = paginateHelper Forum.where("name LIKE '%#{params[:name]}%'") - q = "%#{params[:name].strip}%" - (redirect_to forums_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank? - @offset, @limit = api_offset_and_limit({:limit => 10}) - @forums_all = Forum.where("name LIKE ?", q) - @forums_count = @forums_all.count - @forums_pages = Paginator.new @forums_count, @limit, params['page'] - - - @offset ||= @forums_pages.offset - @forums = @forums_all.offset(@offset).limit(@limit).all - respond_to do |format| - format.html { - render 'index' - } - format.json { render json: @forums } - end - end - - def search_memo - q = "%#{params[:name].strip}%" - - limit = PageLimit - @memo = Memo.new - @offset, @limit = api_offset_and_limit({:limit => limit}) - @forum = Forum.find(params[:id]) - @memos_all = @forum.topics.where("subject LIKE ?", q) - @topic_count = @memos_all.count - @topic_pages = Paginator.new @topic_count, @limit, params['page'] - - @offset ||= @topic_pages.offset - @memos = @memos_all.offset(@offset).limit(@limit).all - respond_to do |format| - format.html { - render 'show', :layout => 'base_forums' - } - format.json { render json: @forum } - end - end - - private - - - def find_forum_if_available - @forum = Forum.find(params[:id]) if params[:id] - rescue ActiveRecord::RecordNotFound - render_404 - nil - end - - def authenticate_user_edit - find_forum_if_available - render_403 unless @forum.editable_by? User.current - end - - def authenticate_user_destroy - find_forum_if_available - render_403 unless @forum.destroyable_by? User.current - end +# added by fq +class ForumsController < ApplicationController + layout "users_base" + + # GET /forums + # GET /forums.json + before_filter :find_forum_if_available + before_filter :authenticate_user_edit, :only => [:edit, :update] + before_filter :authenticate_user_destroy, :only => [:destroy] + before_filter :require_login, :only => [:new, :create] + + helper :sort + include SortHelper + + PageLimit = 20 + + def create_memo + @memo = Memo.new(params[:memo]) + @memo.forum_id = @forum.id + @memo.author_id = User.current.id + + @memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads])) + + respond_to do |format| + if @memo.save + format.html { redirect_to (forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))), notice: "#{l :label_memo_create_succ}" } + format.json { render json: @memo, status: :created, location: @memo } + else + sort_init 'updated_at', 'desc' + sort_update 'created_at' => "#{Memo.table_name}.created_at", + 'replies' => "#{Memo.table_name}.replies_count", + 'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)" + + @topic_count = @forum.topics.count + @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + @memos = @forum.topics. + reorder("#{Memo.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + preload(:author, {:last_reply => :author}). + all + + flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" + # back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id) + format.html { render action: :show, layout: 'base_forums' }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } + format.json { render json: @memo.errors, status: :unprocessable_entity } + end + end + end + + def index + @offset, @limit = api_offset_and_limit({:limit => 10}) + @forums_all = Forum.where('1=1') + @forums_count = @forums_all.count + @forums_pages = Paginator.new @forums_count, @limit, params['page'] + + + @offset ||= @forums_pages.offset + @forums = @forums_all.offset(@offset).limit(@limit).all + #@forums = Forum.all + respond_to do |format| + format.html # index.html.erb + format.json { render json: @forums } + end + end + + # GET /forums/1 + # GET /forums/1.json + def show + sort_init 'updated_at', 'desc' + sort_update 'created_at' => "#{Memo.table_name}.created_at", + 'replies' => "#{Memo.table_name}.replies_count", + 'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)" + + @memo = Memo.new(:forum => @forum) + @topic_count = @forum.topics.count + @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + @memos = @forum.topics. + reorder("#{Memo.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + preload(:author, {:last_reply => :author}). + all + + + + # @offset, @limit = api_offset_and_limit({:limit => 10}) + # @forum = Forum.find(params[:id]) + # @memos_all = @forum.topics + # @topic_count = @memos_all.count + # @topic_pages = Paginator.new @topic_count, @limit, params['page'] + + # @offset ||= @topic_pages.offset + # @memos = @memos_all.offset(@offset).limit(@limit).all + respond_to do |format| + format.html { + render :layout => 'base_forums' + }# show.html.erb + format.json { render json: @forum } + end + end + + # GET /forums/new + # GET /forums/new.json + def new + @forum = Forum.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @forum } + end + end + + # GET /forums/1/edit + def edit + @forum = Forum.find(params[:id]) + end + + # POST /forums + # POST /forums.json + def create + @forum = Forum.new(params[:forum]) + @forum.creator_id = User.current.id + + respond_to do |format| + if @forum.save + format.html { redirect_to @forum, notice: l(:label_forum_create_succ) } + format.json { render json: @forum, status: :created, location: @forum } + else + flash.now[:error] = "#{l :label_forum_create_fail}: #{@forum.errors.full_messages[0]}" + format.html { render action: "new" } + format.json { render json: @forum.errors, status: :unprocessable_entity } + end + end + end + + # PUT /forums/1 + # PUT /forums/1.json + def update + @forum = Forum.find(params[:id]) + + respond_to do |format| + if @forum.update_attributes(params[:forum]) + format.html { redirect_to @forum, notice: l(:label_forum_update_succ) } + format.json { head :no_content } + else + flash.now[:error] = "#{l :label_forum_update_fail}: #{@forum.errors.full_messages[0]}" + format.html { render action: "edit" } + format.json { render json: @forum.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /forums/1 + # DELETE /forums/1.json + def destroy + @forum = Forum.find(params[:id]) + @forum.destroy + + respond_to do |format| + format.html { redirect_to forums_url } + format.json { head :no_content } + end + end + + def search_forum + # @forums = paginateHelper Forum.where("name LIKE '%#{params[:name]}%'") + q = "%#{params[:name].strip}%" + (redirect_to forums_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank? + @offset, @limit = api_offset_and_limit({:limit => 10}) + @forums_all = Forum.where("name LIKE ?", q) + @forums_count = @forums_all.count + @forums_pages = Paginator.new @forums_count, @limit, params['page'] + + + @offset ||= @forums_pages.offset + @forums = @forums_all.offset(@offset).limit(@limit).all + respond_to do |format| + format.html { + render 'index' + } + format.json { render json: @forums } + end + end + + def search_memo + q = "%#{params[:name].strip}%" + + limit = PageLimit + @memo = Memo.new + @offset, @limit = api_offset_and_limit({:limit => limit}) + @forum = Forum.find(params[:id]) + @memos_all = @forum.topics.where("subject LIKE ?", q) + @topic_count = @memos_all.count + @topic_pages = Paginator.new @topic_count, @limit, params['page'] + + @offset ||= @topic_pages.offset + @memos = @memos_all.offset(@offset).limit(@limit).all + respond_to do |format| + format.html { + render 'show', :layout => 'base_forums' + } + format.json { render json: @forum } + end + end + + private + + + def find_forum_if_available + @forum = Forum.find(params[:id]) if params[:id] + rescue ActiveRecord::RecordNotFound + render_404 + nil + end + + def authenticate_user_edit + find_forum_if_available + render_403 unless @forum.editable_by? User.current + end + + def authenticate_user_destroy + find_forum_if_available + render_403 unless @forum.destroyable_by? User.current + end end \ No newline at end of file diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 0b7eeacfb..cd2ae11b9 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,141 +1,141 @@ -# 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 GroupsController < ApplicationController - layout 'admin' - - before_filter :require_admin - before_filter :find_group, :except => [:index, :new, :create] - accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user - - helper :custom_fields - - def index - @groups = Group.sorted.all - - respond_to do |format| - format.html - format.api - end - end - - def show - respond_to do |format| - format.html - format.api - end - end - - def new - @group = Group.new - end - - def create - @group = Group.new - @group.safe_attributes = params[:group] - - respond_to do |format| - if @group.save - format.html { - flash[:notice] = l(:notice_successful_create) - redirect_to(params[:continue] ? new_group_url : groups_url) - } - format.api { render :action => 'show', :status => :created, :location => group_url(@group) } - else - format.html { render :action => "new" } - format.api { render_validation_errors(@group) } - end - end - end - - def edit - end - - def update - @group.safe_attributes = params[:group] - - respond_to do |format| - if @group.save - flash[:notice] = l(:notice_successful_update) - format.html { redirect_to(groups_url) } - format.api { render_api_ok } - else - format.html { render :action => "edit" } - format.api { render_validation_errors(@group) } - end - end - end - - def destroy - @group.destroy - - respond_to do |format| - format.html { redirect_to(groups_url) } - format.api { render_api_ok } - end - end - - def add_users - @users = User.find_all_by_id(params[:user_id] || params[:user_ids]) - @group.users << @users if request.post? - respond_to do |format| - format.html { redirect_to edit_group_url(@group, :tab => 'users') } - format.js - format.api { render_api_ok } - end - end - - def remove_user - @group.users.delete(User.find(params[:user_id])) if request.delete? - respond_to do |format| - format.html { redirect_to edit_group_url(@group, :tab => 'users') } - format.js - format.api { render_api_ok } - end - end - - def autocomplete_for_user - respond_to do |format| - format.js - end - end - - def edit_membership - @membership = Member.edit_membership(params[:membership_id], params[:membership], @group) - @membership.save if request.post? - respond_to do |format| - format.html { redirect_to edit_group_url(@group, :tab => 'memberships') } - format.js - end - end - - def destroy_membership - Member.find(params[:membership_id]).destroy if request.post? - respond_to do |format| - format.html { redirect_to edit_group_url(@group, :tab => 'memberships') } - format.js - end - end - - private - - def find_group - @group = Group.find(params[:id]) - 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. + +class GroupsController < ApplicationController + layout 'admin' + + before_filter :require_admin + before_filter :find_group, :except => [:index, :new, :create] + accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user + + helper :custom_fields + + def index + @groups = Group.sorted.all + + respond_to do |format| + format.html + format.api + end + end + + def show + respond_to do |format| + format.html + format.api + end + end + + def new + @group = Group.new + end + + def create + @group = Group.new + @group.safe_attributes = params[:group] + + respond_to do |format| + if @group.save + format.html { + flash[:notice] = l(:notice_successful_create) + redirect_to(params[:continue] ? new_group_url : groups_url) + } + format.api { render :action => 'show', :status => :created, :location => group_url(@group) } + else + format.html { render :action => "new" } + format.api { render_validation_errors(@group) } + end + end + end + + def edit + end + + def update + @group.safe_attributes = params[:group] + + respond_to do |format| + if @group.save + flash[:notice] = l(:notice_successful_update) + format.html { redirect_to(groups_url) } + format.api { render_api_ok } + else + format.html { render :action => "edit" } + format.api { render_validation_errors(@group) } + end + end + end + + def destroy + @group.destroy + + respond_to do |format| + format.html { redirect_to(groups_url) } + format.api { render_api_ok } + end + end + + def add_users + @users = User.find_all_by_id(params[:user_id] || params[:user_ids]) + @group.users << @users if request.post? + respond_to do |format| + format.html { redirect_to edit_group_url(@group, :tab => 'users') } + format.js + format.api { render_api_ok } + end + end + + def remove_user + @group.users.delete(User.find(params[:user_id])) if request.delete? + respond_to do |format| + format.html { redirect_to edit_group_url(@group, :tab => 'users') } + format.js + format.api { render_api_ok } + end + end + + def autocomplete_for_user + respond_to do |format| + format.js + end + end + + def edit_membership + @membership = Member.edit_membership(params[:membership_id], params[:membership], @group) + @membership.save if request.post? + respond_to do |format| + format.html { redirect_to edit_group_url(@group, :tab => 'memberships') } + format.js + end + end + + def destroy_membership + Member.find(params[:membership_id]).destroy if request.post? + respond_to do |format| + format.html { redirect_to edit_group_url(@group, :tab => 'memberships') } + format.js + end + end + + private + + def find_group + @group = Group.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/homework_attach_controller.rb b/app/controllers/homework_attach_controller.rb index 27a221266..1841c90ea 100644 --- a/app/controllers/homework_attach_controller.rb +++ b/app/controllers/homework_attach_controller.rb @@ -1,365 +1,365 @@ -class HomeworkAttachController < ApplicationController - layout "course_base" - include CoursesHelper - ############################### - before_filter :can_show_course,except: [] - #判断当前角色权限时需先找到当前操作的project - before_filter :find_course_by_bid_id, :only => [:new] - before_filter :find_course_by_hoemwork_id, :only => [:edit,:update,:destroy,:show,:add_homework_users,:destory_homework_users] - #判断当前角色是否有操作权限 - #勿删 before_filter :authorize, :only => [:new,:edit,:update,:destroy] - - def find_course_by_bid_id - @bid = Bid.find(params[:id]) - @course = @bid.courses[0] - rescue ActiveRecord::RecordNotFound - render_404 - end - - def find_course_by_hoemwork_id - @homework = HomeworkAttach.find(params[:id]) - @course = @homework.bid.courses[0] - end - - #获取作业的成员 - def get_homework_member homework - @hoemwork_users = users_for_homework(@homework) - @members = members_for_homework(@homework,@hoemwork_users,params[:q]) - @members = paginateHelper @members,10 - end - - def index - @homeworks = HomeworkAttach.all - respond_to do |format| - format.html # index.html.erb - format.json { render json: @homeworks } - end - end - - #作业添加成员(参与人员) - def add_homework_users - if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) - #@homework = HomeworkAttach.find(params[:id]) - if params[:membership] - if params[:membership][:user_ids] - attrs = params[:membership].dup - user_ids = attrs.delete(:user_ids) - user_ids.each do |user_id| - @homework.homework_users.build(:user_id => user_id) - end - end - end - @homework.save - get_homework_member @homework - respond_to do |format| - format.js - end - else - render_403 :message => :notice_not_authorized - end - end - - #作业删除成员(参与人员) - def destory_homework_users - #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) - homework_user = @homework.homework_users.where("user_id = #{params[:user_id]}").first - homework_user.destroy - get_homework_member @homework - respond_to do |format| - format.js - end - else - render_403 :message => :notice_not_authorized - end - end - - def create - bid = Bid.find params[:bid_id] - if User.current.admin? || User.current.member_of_course?(bid.courses.first) # modify by nwb - if bid.homeworks.where("user_id = ?",User.current).count == 0 - user_id = params[:user_id] - bid_id = params[:bid_id] - if params[:homework_attach] - if params[:homework_attach][:project_id] - project_id = params[:homework_attach][:project_id] - else - project_id = 0 - end - else - project_id = 0 - end - sta = 0 - name = params[:new_form][:name] - description = params[:new_form][:description] - options = { - :user_id => user_id, - :state => sta, - :name => name, - :description => description, - :bid_id => bid_id, - :project_id => project_id - } - - - #@homework_list = @bid.homeworks - - @homework = HomeworkAttach.new(options) - @homework.save_attachments(params[:attachments]) - render_attachment_warning_if_needed(@homework) - - if @homework.save - respond_to do |format| - format.html { redirect_to course_for_bid_url @homework.bid } - format.json { head :no_content } - end - else - render_403 :message => :notice_not_authorized - end - else - render_403 :message => :notice_has_homework - end - else - render_403 :message => :notice_not_authorized - end - end - - def new - @bid = Bid.find(params[:id]) - if User.current.admin? || User.current.member_of_course?(@bid.courses.first) #nwb - #该课程的学生的集合(新建不实现功能:添加成员) - #@members = @bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id <> #{User.current.id}", {:role_id => [5, 10]}) - - #@members = paginateHelper @members,10 - #@all_user = [] - #@bid.courses.first.members.each do |member| - # @all_user << member.user - #end - @homework = HomeworkAttach.new - #@homework_user = members_for_homework(@homework) + User.current - #@members = @all_user - @homework_user - respond_to do |format| - format.html # new.html.erb - format.json { render json: @homework } - end - else - render_403 :message => :notice_not_authorized - end - end - - #获取作业成员的集合 - def get_homework_member_list - @homework = HomeworkAttach.find(params[:bid_id]) - course = @homework.bid.courses.first - if User.current.admin? || User.current.member_of_course?(course) - get_homework_member @homework - else - raise "error" - end - respond_to do |format| - format.js - end - end - - #获取指定作业的所有成员 - def users_for_homework homework - homework.nil? ? [] : (homework.users + [homework.user]) - end - - #获取可选成员列表 - #homework:作业 - #users:该作业所有成员 - #q:模糊匹配的用户的昵称 - def members_for_homework homework,users,q - #homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id not in (:users)", {:role_id => [5, 10],:users => users}).joins(:user).where("users.login like '%#{q}%'") - unpartin_users = homework.bid.courses.first.members.where("user_id not in (:users)", {:users => users}).joins(:user).where("users.login like '%#{q}%'") - canpartin_users = [] - unpartin_users.each do |m| - if m.user.allowed_to?(:paret_in_homework,homework.bid.courses.first) - canpartin_users << m - end - end - canpartin_users - end - - def edit - #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) - #@members = @homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id)", {:role_id => [5, 10]}) - get_homework_member @homework - else - render_403 :message => :notice_not_authorized - end - end - - def update - #@homework = HomeworkAttach.find(params[:id]) - course = @homework.bid.courses.first - if User.current.admin? || User.current.member_of_course?(course) - name = params[:homework_name] - description = params[:homework_description] - if params[:homework_attach] - if params[:homework_attach][:project_id] - project_id = params[:homework_attach][:project_id] - else - project_id = 0 - end - else - project_id = 0 - end - @homework.name = name - @homework.description = description - @homework.project_id = project_id - if params[:attachments] - @homework.save_attachments(params[:attachments]) - end - if @homework.save - respond_to do |format| - format.html { redirect_to course_for_bid_url @homework.bid } - format.json { head :no_content } - end - else - end - else - render_403 :message => :notice_not_authorized - end - end - - def destroy - #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current == @homework.user - if @homework.destroy - respond_to do |format| - format.html { redirect_to course_for_bid_url @homework.bid } - format.json { head :no_content } - end - else - end - else - render_403 :message => :notice_not_authorized - end - end - - #显示作业信息 - def show - #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) - # 打分统计 - stars_reates = @homework. - rates(:quality) - stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count - stars_status = stars_reates.select("stars, count(*) as scount"). - group("stars") - @stars_status_map = Hash.new(0.0) - stars_status.each do |star_status| - percent = (star_status.scount * 1.0/ stars_reates_count) * 100.to_f - percent_m = format("%.2f", percent) - @stars_status_map["star#{star_status.stars.to_i}".to_sym] = - percent_m.to_s + "%" - end - #是否已经进行过评价 - @has_evaluation = stars_reates.where("rater_id = ?",User.current).count > 0 - #是否开启互评功能 - @is_evaluation = @homework.bid.is_evaluation == 1 || @homework.bid.is_evaluation == nil - @limit = 10 - @jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC") - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - @comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC") - - @totle_score = score_for_homework @homework - @teaher_score = teacher_score_for_homework @homework - else - render_403 :message => :notice_not_authorized - end - end - - #删除留言 - def destroy_jour - @journal_destroyed = JournalsForMessage.delete_message(params[:object_id]) - #@homework = HomeworkAttach.find(params[:id]) - #@jours = @homework.journals_for_messages.order("created_on DESC") - #@limit = 10 - #@feedback_count = @jours.count - #@feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - #@offset ||= @feedback_pages.offset - #@jour = @jours[@offset, @limit] - respond_to do |format| - format.js - end - end - - #添加留言 - def addjours - @homework = HomeworkAttach.find(params[:jour_id]) - @add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation] - @jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC") - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - @comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC") - - @totle_score = score_for_homework @homework - @teaher_score = teacher_score_for_homework @homework - respond_to do |format| - format.js - end - end - - #教师综评 - def comprehensive_evaluation_jour - @homework = HomeworkAttach.find(params[:jour_id]) - @add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation] - respond_to do |format| - format.html { redirect_to homework_attach_url @homework } - format.json { head :no_content } - end - end - - #获取指定作业的平均得分 - def score - #stars_reates = @homework.rates(:quality) - #percent = 0 - #stars_reates.each do |star_reates| - # percent = percent + star_reates.stars - #end - #stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count - #result = percent * 1.0 / stars_reates_count - #result - end - - #添加回复 - def add_jour_reply - parent_id = params[:reference_id] - author_id = User.current.id - reply_user_id = params[:reference_user_id] - reply_id = params[:reference_message_id] # 暂时不实现 - content = params[:user_notes] - options = {:user_id => author_id, - :m_parent_id => parent_id, - :m_reply_id => reply_id, - :reply_id => reply_user_id, - :notes => content, - :is_readed => false} - @jfm = JournalsForMessage.new(options) - @jfm.save - respond_to do |format| - format.js{ - @save_succ = true if @jfm.errors.empty? - } - end - end - - #验证是否显示课程 - def can_show_course - @first_page = FirstPage.find_by_page_type('project') - if @first_page.show_course == 2 - render_404 - end - end -end - +class HomeworkAttachController < ApplicationController + layout "course_base" + include CoursesHelper + ############################### + before_filter :can_show_course,except: [] + #判断当前角色权限时需先找到当前操作的project + before_filter :find_course_by_bid_id, :only => [:new] + before_filter :find_course_by_hoemwork_id, :only => [:edit,:update,:destroy,:show,:add_homework_users,:destory_homework_users] + #判断当前角色是否有操作权限 + #勿删 before_filter :authorize, :only => [:new,:edit,:update,:destroy] + + def find_course_by_bid_id + @bid = Bid.find(params[:id]) + @course = @bid.courses[0] + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_course_by_hoemwork_id + @homework = HomeworkAttach.find(params[:id]) + @course = @homework.bid.courses[0] + end + + #获取作业的成员 + def get_homework_member homework + @hoemwork_users = users_for_homework(@homework) + @members = members_for_homework(@homework,@hoemwork_users,params[:q]) + @members = paginateHelper @members,10 + end + + def index + @homeworks = HomeworkAttach.all + respond_to do |format| + format.html # index.html.erb + format.json { render json: @homeworks } + end + end + + #作业添加成员(参与人员) + def add_homework_users + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) + #@homework = HomeworkAttach.find(params[:id]) + if params[:membership] + if params[:membership][:user_ids] + attrs = params[:membership].dup + user_ids = attrs.delete(:user_ids) + user_ids.each do |user_id| + @homework.homework_users.build(:user_id => user_id) + end + end + end + @homework.save + get_homework_member @homework + respond_to do |format| + format.js + end + else + render_403 :message => :notice_not_authorized + end + end + + #作业删除成员(参与人员) + def destory_homework_users + #@homework = HomeworkAttach.find(params[:id]) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) + homework_user = @homework.homework_users.where("user_id = #{params[:user_id]}").first + homework_user.destroy + get_homework_member @homework + respond_to do |format| + format.js + end + else + render_403 :message => :notice_not_authorized + end + end + + def create + bid = Bid.find params[:bid_id] + if User.current.admin? || User.current.member_of_course?(bid.courses.first) # modify by nwb + if bid.homeworks.where("user_id = ?",User.current).count == 0 + user_id = params[:user_id] + bid_id = params[:bid_id] + if params[:homework_attach] + if params[:homework_attach][:project_id] + project_id = params[:homework_attach][:project_id] + else + project_id = 0 + end + else + project_id = 0 + end + sta = 0 + name = params[:new_form][:name] + description = params[:new_form][:description] + options = { + :user_id => user_id, + :state => sta, + :name => name, + :description => description, + :bid_id => bid_id, + :project_id => project_id + } + + + #@homework_list = @bid.homeworks + + @homework = HomeworkAttach.new(options) + @homework.save_attachments(params[:attachments]) + render_attachment_warning_if_needed(@homework) + + if @homework.save + respond_to do |format| + format.html { redirect_to course_for_bid_url @homework.bid } + format.json { head :no_content } + end + else + render_403 :message => :notice_not_authorized + end + else + render_403 :message => :notice_has_homework + end + else + render_403 :message => :notice_not_authorized + end + end + + def new + @bid = Bid.find(params[:id]) + if User.current.admin? || User.current.member_of_course?(@bid.courses.first) #nwb + #该课程的学生的集合(新建不实现功能:添加成员) + #@members = @bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id <> #{User.current.id}", {:role_id => [5, 10]}) + + #@members = paginateHelper @members,10 + #@all_user = [] + #@bid.courses.first.members.each do |member| + # @all_user << member.user + #end + @homework = HomeworkAttach.new + #@homework_user = members_for_homework(@homework) + User.current + #@members = @all_user - @homework_user + respond_to do |format| + format.html # new.html.erb + format.json { render json: @homework } + end + else + render_403 :message => :notice_not_authorized + end + end + + #获取作业成员的集合 + def get_homework_member_list + @homework = HomeworkAttach.find(params[:bid_id]) + course = @homework.bid.courses.first + if User.current.admin? || User.current.member_of_course?(course) + get_homework_member @homework + else + raise "error" + end + respond_to do |format| + format.js + end + end + + #获取指定作业的所有成员 + def users_for_homework homework + homework.nil? ? [] : (homework.users + [homework.user]) + end + + #获取可选成员列表 + #homework:作业 + #users:该作业所有成员 + #q:模糊匹配的用户的昵称 + def members_for_homework homework,users,q + #homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id not in (:users)", {:role_id => [5, 10],:users => users}).joins(:user).where("users.login like '%#{q}%'") + unpartin_users = homework.bid.courses.first.members.where("user_id not in (:users)", {:users => users}).joins(:user).where("users.login like '%#{q}%'") + canpartin_users = [] + unpartin_users.each do |m| + if m.user.allowed_to?(:paret_in_homework,homework.bid.courses.first) + canpartin_users << m + end + end + canpartin_users + end + + def edit + #@homework = HomeworkAttach.find(params[:id]) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) + #@members = @homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id)", {:role_id => [5, 10]}) + get_homework_member @homework + else + render_403 :message => :notice_not_authorized + end + end + + def update + #@homework = HomeworkAttach.find(params[:id]) + course = @homework.bid.courses.first + if User.current.admin? || User.current.member_of_course?(course) + name = params[:homework_name] + description = params[:homework_description] + if params[:homework_attach] + if params[:homework_attach][:project_id] + project_id = params[:homework_attach][:project_id] + else + project_id = 0 + end + else + project_id = 0 + end + @homework.name = name + @homework.description = description + @homework.project_id = project_id + if params[:attachments] + @homework.save_attachments(params[:attachments]) + end + if @homework.save + respond_to do |format| + format.html { redirect_to course_for_bid_url @homework.bid } + format.json { head :no_content } + end + else + end + else + render_403 :message => :notice_not_authorized + end + end + + def destroy + #@homework = HomeworkAttach.find(params[:id]) + if User.current.admin? || User.current == @homework.user + if @homework.destroy + respond_to do |format| + format.html { redirect_to course_for_bid_url @homework.bid } + format.json { head :no_content } + end + else + end + else + render_403 :message => :notice_not_authorized + end + end + + #显示作业信息 + def show + #@homework = HomeworkAttach.find(params[:id]) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) + # 打分统计 + stars_reates = @homework. + rates(:quality) + stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count + stars_status = stars_reates.select("stars, count(*) as scount"). + group("stars") + @stars_status_map = Hash.new(0.0) + stars_status.each do |star_status| + percent = (star_status.scount * 1.0/ stars_reates_count) * 100.to_f + percent_m = format("%.2f", percent) + @stars_status_map["star#{star_status.stars.to_i}".to_sym] = + percent_m.to_s + "%" + end + #是否已经进行过评价 + @has_evaluation = stars_reates.where("rater_id = ?",User.current).count > 0 + #是否开启互评功能 + @is_evaluation = @homework.bid.is_evaluation == 1 || @homework.bid.is_evaluation == nil + @limit = 10 + @jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC") + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC") + + @totle_score = score_for_homework @homework + @teaher_score = teacher_score_for_homework @homework + else + render_403 :message => :notice_not_authorized + end + end + + #删除留言 + def destroy_jour + @journal_destroyed = JournalsForMessage.delete_message(params[:object_id]) + #@homework = HomeworkAttach.find(params[:id]) + #@jours = @homework.journals_for_messages.order("created_on DESC") + #@limit = 10 + #@feedback_count = @jours.count + #@feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + #@offset ||= @feedback_pages.offset + #@jour = @jours[@offset, @limit] + respond_to do |format| + format.js + end + end + + #添加留言 + def addjours + @homework = HomeworkAttach.find(params[:jour_id]) + @add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation] + @jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC") + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC") + + @totle_score = score_for_homework @homework + @teaher_score = teacher_score_for_homework @homework + respond_to do |format| + format.js + end + end + + #教师综评 + def comprehensive_evaluation_jour + @homework = HomeworkAttach.find(params[:jour_id]) + @add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation] + respond_to do |format| + format.html { redirect_to homework_attach_url @homework } + format.json { head :no_content } + end + end + + #获取指定作业的平均得分 + def score + #stars_reates = @homework.rates(:quality) + #percent = 0 + #stars_reates.each do |star_reates| + # percent = percent + star_reates.stars + #end + #stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count + #result = percent * 1.0 / stars_reates_count + #result + end + + #添加回复 + def add_jour_reply + parent_id = params[:reference_id] + author_id = User.current.id + reply_user_id = params[:reference_user_id] + reply_id = params[:reference_message_id] # 暂时不实现 + content = params[:user_notes] + options = {:user_id => author_id, + :m_parent_id => parent_id, + :m_reply_id => reply_id, + :reply_id => reply_user_id, + :notes => content, + :is_readed => false} + @jfm = JournalsForMessage.new(options) + @jfm.save + respond_to do |format| + format.js{ + @save_succ = true if @jfm.errors.empty? + } + end + end + + #验证是否显示课程 + def can_show_course + @first_page = FirstPage.find_by_page_type('project') + if @first_page.show_course == 2 + render_404 + end + end +end + diff --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb index 8b7a8d5ce..fb62821d8 100644 --- a/app/controllers/issue_categories_controller.rb +++ b/app/controllers/issue_categories_controller.rb @@ -1,132 +1,132 @@ -# 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 IssueCategoriesController < ApplicationController - layout "project_base" - menu_item :settings - model_object IssueCategory - before_filter :find_model_object, :except => [:index, :new, :create] - #before_filter :find_model_object_contest, :except => [:index, :new, :create] - before_filter :find_project_from_association, :except => [:index, :new, :create] - before_filter :find_project_by_project_id, :only => [:index, :new, :create] - before_filter :authorize - accept_api_auth :index, :show, :create, :update, :destroy - - helper :project_score - - def index - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.api { @categories = @project.issue_categories.all } - end - end - - def show - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.api - end - end - - def new - @category = @project.issue_categories.build - @category.safe_attributes = params[:issue_category] - - respond_to do |format| - format.html{render :layout => 'base_projects'}# by young - format.js - end - end - - def create - @category = @project.issue_categories.build - @category.safe_attributes = params[:issue_category] - if @category.save - respond_to do |format| - format.html do - flash[:notice] = l(:notice_successful_create) - redirect_to_settings_in_projects - end - format.js - format.api { render :action => 'show', :status => :created, :location => issue_category_path(@category) } - end - else - respond_to do |format| - format.html { render :action => 'new'} - format.js { render :action => 'new'} - format.api { render_validation_errors(@category) } - end - end - end - - def edit - end - - def update - @category.safe_attributes = params[:issue_category] - if @category.save - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_to_settings_in_projects - } - format.api { render_api_ok } - end - else - respond_to do |format| - format.html { render :action => 'edit' } - format.api { render_validation_errors(@category) } - end - end - end - - def destroy - @issue_count = @category.issues.size - if @issue_count == 0 || params[:todo] || api_request? - reassign_to = nil - if params[:reassign_to_id] && (params[:todo] == 'reassign' || params[:todo].blank?) - reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id]) - end - @category.destroy(reassign_to) - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.api { render_api_ok } - end - return - end - @categories = @project.issue_categories - [@category] - end - - private - - def redirect_to_settings_in_projects - redirect_to settings_project_url(@project, :tab => 'categories') - end - - # Wrap ApplicationController's find_model_object method to set - # @category instead of just @issue_category - def find_model_object - super - @category = @object - end - - def find_model_object_contest - super - @category = @object - 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 IssueCategoriesController < ApplicationController + layout "project_base" + menu_item :settings + model_object IssueCategory + before_filter :find_model_object, :except => [:index, :new, :create] + #before_filter :find_model_object_contest, :except => [:index, :new, :create] + before_filter :find_project_from_association, :except => [:index, :new, :create] + before_filter :find_project_by_project_id, :only => [:index, :new, :create] + before_filter :authorize + accept_api_auth :index, :show, :create, :update, :destroy + + helper :project_score + + def index + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.api { @categories = @project.issue_categories.all } + end + end + + def show + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.api + end + end + + def new + @category = @project.issue_categories.build + @category.safe_attributes = params[:issue_category] + + respond_to do |format| + format.html{render :layout => 'base_projects'}# by young + format.js + end + end + + def create + @category = @project.issue_categories.build + @category.safe_attributes = params[:issue_category] + if @category.save + respond_to do |format| + format.html do + flash[:notice] = l(:notice_successful_create) + redirect_to_settings_in_projects + end + format.js + format.api { render :action => 'show', :status => :created, :location => issue_category_path(@category) } + end + else + respond_to do |format| + format.html { render :action => 'new'} + format.js { render :action => 'new'} + format.api { render_validation_errors(@category) } + end + end + end + + def edit + end + + def update + @category.safe_attributes = params[:issue_category] + if @category.save + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_to_settings_in_projects + } + format.api { render_api_ok } + end + else + respond_to do |format| + format.html { render :action => 'edit' } + format.api { render_validation_errors(@category) } + end + end + end + + def destroy + @issue_count = @category.issues.size + if @issue_count == 0 || params[:todo] || api_request? + reassign_to = nil + if params[:reassign_to_id] && (params[:todo] == 'reassign' || params[:todo].blank?) + reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id]) + end + @category.destroy(reassign_to) + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.api { render_api_ok } + end + return + end + @categories = @project.issue_categories - [@category] + end + + private + + def redirect_to_settings_in_projects + redirect_to settings_project_url(@project, :tab => 'categories') + end + + # Wrap ApplicationController's find_model_object method to set + # @category instead of just @issue_category + def find_model_object + super + @category = @object + end + + def find_model_object_contest + super + @category = @object + end + +end diff --git a/app/controllers/issue_relations_controller.rb b/app/controllers/issue_relations_controller.rb index f3689044b..d5c8e04ca 100644 --- a/app/controllers/issue_relations_controller.rb +++ b/app/controllers/issue_relations_controller.rb @@ -1,88 +1,88 @@ -# 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 IssueRelationsController < ApplicationController - before_filter :find_issue, :find_project_from_association, :authorize, :only => [:index, :create] - before_filter :find_relation, :except => [:index, :create] - - accept_api_auth :index, :show, :create, :destroy - - def index - @relations = @issue.relations - - respond_to do |format| - format.html { render :nothing => true } - format.api - end - end - - def show - raise Unauthorized unless @relation.visible? - - respond_to do |format| - format.html { render :nothing => true } - format.api - end - end - - def create - @relation = IssueRelation.new(params[:relation]) - @relation.issue_from = @issue - if params[:relation] && m = params[:relation][:issue_to_id].to_s.strip.match(/^#?(\d+)$/) - @relation.issue_to = Issue.visible.find_by_id(m[1].to_i) - end - saved = @relation.save - - respond_to do |format| - format.html { redirect_to issue_url(@issue) } - format.js { - @relations = @issue.reload.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? } - } - format.api { - if saved - render :action => 'show', :status => :created, :location => relation_url(@relation) - else - render_validation_errors(@relation) - end - } - end - end - - def destroy - raise Unauthorized unless @relation.deletable? - @relation.destroy - - respond_to do |format| - format.html { redirect_to issue_url(@relation.issue_from) } - format.js - format.api { render_api_ok } - end - end - -private - def find_issue - @issue = @object = Issue.find(params[:issue_id]) - rescue ActiveRecord::RecordNotFound - render_404 - end - - def find_relation - @relation = IssueRelation.find(params[:id]) - 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. + +class IssueRelationsController < ApplicationController + before_filter :find_issue, :find_project_from_association, :authorize, :only => [:index, :create] + before_filter :find_relation, :except => [:index, :create] + + accept_api_auth :index, :show, :create, :destroy + + def index + @relations = @issue.relations + + respond_to do |format| + format.html { render :nothing => true } + format.api + end + end + + def show + raise Unauthorized unless @relation.visible? + + respond_to do |format| + format.html { render :nothing => true } + format.api + end + end + + def create + @relation = IssueRelation.new(params[:relation]) + @relation.issue_from = @issue + if params[:relation] && m = params[:relation][:issue_to_id].to_s.strip.match(/^#?(\d+)$/) + @relation.issue_to = Issue.visible.find_by_id(m[1].to_i) + end + saved = @relation.save + + respond_to do |format| + format.html { redirect_to issue_url(@issue) } + format.js { + @relations = @issue.reload.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? } + } + format.api { + if saved + render :action => 'show', :status => :created, :location => relation_url(@relation) + else + render_validation_errors(@relation) + end + } + end + end + + def destroy + raise Unauthorized unless @relation.deletable? + @relation.destroy + + respond_to do |format| + format.html { redirect_to issue_url(@relation.issue_from) } + format.js + format.api { render_api_ok } + end + end + +private + def find_issue + @issue = @object = Issue.find(params[:issue_id]) + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_relation + @relation = IssueRelation.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/issue_statuses_controller.rb b/app/controllers/issue_statuses_controller.rb index 376eb5b8b..d79df35f4 100644 --- a/app/controllers/issue_statuses_controller.rb +++ b/app/controllers/issue_statuses_controller.rb @@ -1,81 +1,81 @@ -# 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 IssueStatusesController < ApplicationController - layout 'admin' - - before_filter :require_admin, :except => :index - before_filter :require_admin_or_api_request, :only => :index - accept_api_auth :index - - def index - respond_to do |format| - format.html { - @issue_status_pages, @issue_statuses = paginate IssueStatus.sorted, :per_page => 25 - render :action => "index", :layout => false if request.xhr? - } - format.api { - @issue_statuses = IssueStatus.all(:order => 'position') - } - end - end - - def new - @issue_status = IssueStatus.new - end - - def create - @issue_status = IssueStatus.new(params[:issue_status]) - if request.post? && @issue_status.save - flash[:notice] = l(:notice_successful_create) - redirect_to issue_statuses_url - else - render :action => 'new' - end - end - - def edit - @issue_status = IssueStatus.find(params[:id]) - end - - def update - @issue_status = IssueStatus.find(params[:id]) - if request.put? && @issue_status.update_attributes(params[:issue_status]) - flash[:notice] = l(:notice_successful_update) - redirect_to issue_statuses_url - else - render :action => 'edit' - end - end - - def destroy - IssueStatus.find(params[:id]).destroy - redirect_to issue_statuses_url - rescue - flash[:error] = l(:error_unable_delete_issue_status) - redirect_to issue_statuses_url - end - - def update_issue_done_ratio - if request.post? && IssueStatus.update_issue_done_ratios - flash[:notice] = l(:notice_issue_done_ratios_updated) - else - flash[:error] = l(:error_issue_done_ratios_not_updated) - end - redirect_to issue_statuses_url - 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 IssueStatusesController < ApplicationController + layout 'admin' + + before_filter :require_admin, :except => :index + before_filter :require_admin_or_api_request, :only => :index + accept_api_auth :index + + def index + respond_to do |format| + format.html { + @issue_status_pages, @issue_statuses = paginate IssueStatus.sorted, :per_page => 25 + render :action => "index", :layout => false if request.xhr? + } + format.api { + @issue_statuses = IssueStatus.all(:order => 'position') + } + end + end + + def new + @issue_status = IssueStatus.new + end + + def create + @issue_status = IssueStatus.new(params[:issue_status]) + if request.post? && @issue_status.save + flash[:notice] = l(:notice_successful_create) + redirect_to issue_statuses_url + else + render :action => 'new' + end + end + + def edit + @issue_status = IssueStatus.find(params[:id]) + end + + def update + @issue_status = IssueStatus.find(params[:id]) + if request.put? && @issue_status.update_attributes(params[:issue_status]) + flash[:notice] = l(:notice_successful_update) + redirect_to issue_statuses_url + else + render :action => 'edit' + end + end + + def destroy + IssueStatus.find(params[:id]).destroy + redirect_to issue_statuses_url + rescue + flash[:error] = l(:error_unable_delete_issue_status) + redirect_to issue_statuses_url + end + + def update_issue_done_ratio + if request.post? && IssueStatus.update_issue_done_ratios + flash[:notice] = l(:notice_issue_done_ratios_updated) + else + flash[:error] = l(:error_issue_done_ratios_not_updated) + end + redirect_to issue_statuses_url + end +end diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index aa68f5867..97c0ce4f6 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -1,481 +1,481 @@ -# 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 IssuesController < ApplicationController - layout 'base_projects'#Added by young - menu_item :new_issue, :only => [:new, :create] - default_search_scope :issues - - before_filter :find_issue, :only => [:show, :edit, :update] - before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy] - before_filter :find_project, :only => [:new, :create, :update_form] - before_filter :authorize, :except => [:index] - before_filter :find_optional_project, :only => [:index] - before_filter :check_for_default_issue_status, :only => [:new, :create] - before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form] - accept_rss_auth :index, :show - accept_api_auth :index, :show, :create, :update, :destroy - - rescue_from Query::StatementInvalid, :with => :query_statement_invalid - - helper :journals - helper :projects - include ProjectsHelper - helper :custom_fields - include CustomFieldsHelper - helper :issue_relations - include IssueRelationsHelper - helper :watchers - include WatchersHelper - helper :attachments - include AttachmentsHelper - helper :queries - include QueriesHelper - helper :repositories - include RepositoriesHelper - helper :sort - include SortHelper - include IssuesHelper - helper :timelog - include Redmine::Export::PDF - helper :project_score - - def index - retrieve_query - sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) - sort_update(@query.sortable_columns) - @query.sort_criteria = sort_criteria.to_a - - @project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young - - if @query.valid? - case params[:format] - when 'csv', 'pdf' - @limit = 10#Setting.issues_export_limit.to_i - when 'atom' - @limit = 10#Setting.feeds_limit.to_i - when 'xml', 'json' - @offset, @limit = api_offset_and_limit({:limit => 10}) - else - @limit = 10#per_page_option - end - - @issue_count = @query.issue_count - @issue_pages = Paginator.new @issue_count, @limit, params['page'] - @offset ||= @issue_pages.offset - @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version], - :order => sort_clause, - :offset => @offset, - :limit => @limit) - @issue_count_by_group = @query.issue_count_by_group - - - - - - respond_to do |format| - format.html { render :template => 'issues/index', :layout => @project_base_tag }#by young - format.api { - Issue.load_visible_relations(@issues) if include_in_api_response?('relations') - } - format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") } - format.csv { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') } - format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'issues.pdf') } - end - else - respond_to do |format| - format.html { render(:template => 'issues/index', :layout => @project_base_tag) }#by young - format.any(:atom, :csv, :pdf) { render(:nothing => true) } - format.api { render_validation_errors(@query) } - end - end - rescue ActiveRecord::RecordNotFound - render_404 - end - - def show - - @journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all - @journals.each_with_index {|j,i| j.indice = i+1} - @journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) - @journals.reverse! if User.current.wants_comments_in_reverse_order? - - @changesets = @issue.changesets.visible.all - @changesets.reverse! if User.current.wants_comments_in_reverse_order? - - @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? } - @allowed_statuses = @issue.new_statuses_allowed_to(User.current) - @edit_allowed = User.current.allowed_to?(:edit_issues, @project) - @priorities = IssuePriority.active - @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) - - @project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young - @available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq - - respond_to do |format| - format.html { - retrieve_previous_and_next_issue_ids - render :template => 'issues/show', :layout => @project_base_tag#by young - } - format.api - format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' } - format.pdf { - pdf = issue_to_pdf(@issue, :journals => @journals) - send_data(pdf, :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") - } - end - end - - # Add a new issue - # The new issue will be created from an existing one if copy_from parameter is given - def new - respond_to do |format| - format.html { render :action => 'new', :layout => 'base_projects' } - end - end - - def create - call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue }) - @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads])) - if @issue.save - call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue}) - respond_to do |format| - format.html { - render_attachment_warning_if_needed(@issue) - flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("#{@issue.source_from}", issue_path(@issue), :title => @issue.subject)) - #flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject)) - if params[:continue] - attrs = {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} - redirect_to new_project_issue_url(@issue.project, :issue => attrs) - else - redirect_to issue_url(@issue) - end - } - format.api { render :action => 'show', :status => :created, :location => issue_url(@issue) } - end - return - else - respond_to do |format| - format.html { render :action => 'new' } - format.api { render_validation_errors(@issue) } - end - end - end - - def edit - return unless update_issue_from_params - - respond_to do |format| - format.html {render :layout => 'base_projects' }#added by young - format.xml { } - end - end - - def update - return unless update_issue_from_params - @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads])) - saved = false - begin - saved = @issue.save_issue_with_child_records(params, @time_entry) - rescue ActiveRecord::StaleObjectError - @conflict = true - if params[:last_journal_id] - @conflict_journals = @issue.journals_after(params[:last_journal_id]).all - @conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) - end - end - - if saved - - #修改界面增加跟踪者 - watcherlist = @issue.watcher_users - select_users = [] - if params[:issue] - if params[:issue][:watcher_user_ids] - params[:issue][:watcher_user_ids].each do |user_id| - select_users << User.find(user_id) - end - end - end - select_users.each do |user| - if watcherlist.include? user - else - @issue.add_watcher user - end - end - watcherlist.each do |user| - if select_users.include? user - else - @issue.remove_watcher user - end - end - - render_attachment_warning_if_needed(@issue) - reply_id = params[:reference_user_id].to_i - if reply_id > 0 - JournalReply.add_reply(@issue.current_journal.id, reply_id, User.current.id) - end - flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record? - - respond_to do |format| - format.html { redirect_back_or_default issue_path(@issue) } - format.api { render_api_ok } - end - else - respond_to do |format| - format.html { render :action => 'edit' } - format.api { render_validation_errors(@issue) } - end - end - end - - # Updates the issue form when changing the project, status or tracker - # on issue creation/update - def update_form - end - - # Bulk edit/copy a set of issues - def bulk_edit - @issues.sort! - @copy = params[:copy].present? - @notes = params[:notes] - - if User.current.allowed_to?(:move_issues, @projects) - @allowed_projects = Issue.allowed_target_projects_on_move - if params[:issue] - @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s} - if @target_project - target_projects = [@target_project] - end - end - end - target_projects ||= @projects - - if @copy - @available_statuses = [IssueStatus.default] - else - @available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&) - end - @custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&) - @assignables = target_projects.map(&:assignable_users).reduce(:&) - @trackers = target_projects.map(&:trackers).reduce(:&) - @versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&) - @categories = target_projects.map {|p| p.issue_categories}.reduce(:&) - if @copy - @attachments_present = @issues.detect {|i| i.attachments.any?}.present? - @subtasks_present = @issues.detect {|i| !i.leaf?}.present? - end - - @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&) - render :layout => false if request.xhr? - end - - def bulk_update - @issues.sort! - @copy = params[:copy].present? - attributes = parse_params_for_bulk_issue_attributes(params) - - unsaved_issue_ids = [] - moved_issues = [] - - if @copy && params[:copy_subtasks].present? - # Descendant issues will be copied with the parent task - # Don't copy them twice - @issues.reject! {|issue| @issues.detect {|other| issue.is_descendant_of?(other)}} - end - - @issues.each do |issue| - issue.reload - if @copy - issue = issue.copy({}, - :attachments => params[:copy_attachments].present?, - :subtasks => params[:copy_subtasks].present? - ) - end - journal = issue.init_journal(User.current, params[:notes]) - issue.safe_attributes = attributes - call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) - if issue.save - moved_issues << issue - else - # Keep unsaved issue ids to display them in flash error - unsaved_issue_ids << issue.id - end - end - set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) - - if params[:follow] - if @issues.size == 1 && moved_issues.size == 1 - redirect_to issue_url(moved_issues.first) - elsif moved_issues.map(&:project).uniq.size == 1 - redirect_to project_issues_url(moved_issues.map(&:project).first) - end - else - redirect_back_or_default _project_issues_path(@project) - end - end - - def destroy - @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f - if @hours > 0 - case params[:todo] - when 'destroy' - # nothing to do - when 'nullify' - TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues]) - when 'reassign' - reassign_to = @project.issues.find_by_id(params[:reassign_to_id]) - if reassign_to.nil? - flash.now[:error] = l(:error_issue_not_found_in_project) - return - else - TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues]) - end - else - # display the destroy form if it's a user request - return unless api_request? - end - end - @issues.each do |issue| - begin - issue.reload.destroy - rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists - # nothing to do, issue was already deleted (eg. by a parent) - end - end - respond_to do |format| - format.html { redirect_back_or_default _project_issues_path(@project) } - format.api { render_api_ok } - end - end - - private - - def find_project - project_id = params[:project_id] || (params[:issue] && params[:issue][:project_id]) - @project = Project.find(project_id) - rescue ActiveRecord::RecordNotFound - render_404 - end - - def retrieve_previous_and_next_issue_ids - retrieve_query_from_session - if @query - sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) - sort_update(@query.sortable_columns, 'issues_index_sort') - limit = 500 - issue_ids = @query.issue_ids(:order => sort_clause, :limit => (limit + 1), :include => [:assigned_to, :tracker, :priority, :category, :fixed_version]) - if (idx = issue_ids.index(@issue.id)) && idx < limit - if issue_ids.size < 500 - @issue_position = idx + 1 - @issue_count = issue_ids.size - end - @prev_issue_id = issue_ids[idx - 1] if idx > 0 - @next_issue_id = issue_ids[idx + 1] if idx < (issue_ids.size - 1) - end - end - end - - # Used by #edit and #update to set some common instance variables - # from the params - # TODO: Refactor, not everything in here is needed by #edit - def update_issue_from_params - @edit_allowed = User.current.allowed_to?(:edit_issues, @project) - @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) - @time_entry.attributes = params[:time_entry] - - @issue.init_journal(User.current) - - issue_attributes = params[:issue] - if issue_attributes && params[:conflict_resolution] - case params[:conflict_resolution] - when 'overwrite' - issue_attributes = issue_attributes.dup - issue_attributes.delete(:lock_version) - when 'add_notes' - issue_attributes = issue_attributes.slice(:notes) - when 'cancel' - redirect_to issue_url(@issue) - return false - end - end - @issue.safe_attributes = issue_attributes - @priorities = IssuePriority.active - @allowed_statuses = @issue.new_statuses_allowed_to(User.current) - true - end - - # TODO: Refactor, lots of extra code in here - # TODO: Changing tracker on an existing issue should not trigger this - def build_new_issue_from_params - if params[:id].blank? - @issue = Issue.new - if params[:copy_from] - begin - @copy_from = Issue.visible.find(params[:copy_from]) - @copy_attachments = params[:copy_attachments].present? || request.get? - @copy_subtasks = params[:copy_subtasks].present? || request.get? - @issue.copy_from(@copy_from, :attachments => @copy_attachments, :subtasks => @copy_subtasks) - rescue ActiveRecord::RecordNotFound - render_404 - return - end - end - @issue.project = @project - else - @issue = @project.issues.visible.find(params[:id]) - end - - @issue.project = @project - @issue.author ||= User.current - # Tracker must be set before custom field values - @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first) - if @issue.tracker.nil? - render_error l(:error_no_tracker_in_project) - return false - end - @issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date? - @issue.safe_attributes = params[:issue] - - @priorities = IssuePriority.active - @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true) - @available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq - end - - def check_for_default_issue_status - if IssueStatus.default.nil? - render_error l(:error_no_default_issue_status) - return false - end - end - - def parse_params_for_bulk_issue_attributes(params) - attributes = (params[:issue] || {}).reject {|k,v| v.blank?} - attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} - if custom = attributes[:custom_field_values] - custom.reject! {|k,v| v.blank?} - custom.keys.each do |k| - if custom[k].is_a?(Array) - custom[k] << '' if custom[k].delete('__none__') - else - custom[k] = '' if custom[k] == '__none__' - end - end - end - attributes - 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 IssuesController < ApplicationController + layout 'base_projects'#Added by young + menu_item :new_issue, :only => [:new, :create] + default_search_scope :issues + + before_filter :find_issue, :only => [:show, :edit, :update] + before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy] + before_filter :find_project, :only => [:new, :create, :update_form] + before_filter :authorize, :except => [:index] + before_filter :find_optional_project, :only => [:index] + before_filter :check_for_default_issue_status, :only => [:new, :create] + before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form] + accept_rss_auth :index, :show + accept_api_auth :index, :show, :create, :update, :destroy + + rescue_from Query::StatementInvalid, :with => :query_statement_invalid + + helper :journals + helper :projects + include ProjectsHelper + helper :custom_fields + include CustomFieldsHelper + helper :issue_relations + include IssueRelationsHelper + helper :watchers + include WatchersHelper + helper :attachments + include AttachmentsHelper + helper :queries + include QueriesHelper + helper :repositories + include RepositoriesHelper + helper :sort + include SortHelper + include IssuesHelper + helper :timelog + include Redmine::Export::PDF + helper :project_score + + def index + retrieve_query + sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) + sort_update(@query.sortable_columns) + @query.sort_criteria = sort_criteria.to_a + + @project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young + + if @query.valid? + case params[:format] + when 'csv', 'pdf' + @limit = 10#Setting.issues_export_limit.to_i + when 'atom' + @limit = 10#Setting.feeds_limit.to_i + when 'xml', 'json' + @offset, @limit = api_offset_and_limit({:limit => 10}) + else + @limit = 10#per_page_option + end + + @issue_count = @query.issue_count + @issue_pages = Paginator.new @issue_count, @limit, params['page'] + @offset ||= @issue_pages.offset + @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version], + :order => sort_clause, + :offset => @offset, + :limit => @limit) + @issue_count_by_group = @query.issue_count_by_group + + + + + + respond_to do |format| + format.html { render :template => 'issues/index', :layout => @project_base_tag }#by young + format.api { + Issue.load_visible_relations(@issues) if include_in_api_response?('relations') + } + format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") } + format.csv { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') } + format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'issues.pdf') } + end + else + respond_to do |format| + format.html { render(:template => 'issues/index', :layout => @project_base_tag) }#by young + format.any(:atom, :csv, :pdf) { render(:nothing => true) } + format.api { render_validation_errors(@query) } + end + end + rescue ActiveRecord::RecordNotFound + render_404 + end + + def show + + @journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all + @journals.each_with_index {|j,i| j.indice = i+1} + @journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) + @journals.reverse! if User.current.wants_comments_in_reverse_order? + + @changesets = @issue.changesets.visible.all + @changesets.reverse! if User.current.wants_comments_in_reverse_order? + + @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? } + @allowed_statuses = @issue.new_statuses_allowed_to(User.current) + @edit_allowed = User.current.allowed_to?(:edit_issues, @project) + @priorities = IssuePriority.active + @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) + + @project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young + @available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq + + respond_to do |format| + format.html { + retrieve_previous_and_next_issue_ids + render :template => 'issues/show', :layout => @project_base_tag#by young + } + format.api + format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' } + format.pdf { + pdf = issue_to_pdf(@issue, :journals => @journals) + send_data(pdf, :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") + } + end + end + + # Add a new issue + # The new issue will be created from an existing one if copy_from parameter is given + def new + respond_to do |format| + format.html { render :action => 'new', :layout => 'base_projects' } + end + end + + def create + call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue }) + @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads])) + if @issue.save + call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue}) + respond_to do |format| + format.html { + render_attachment_warning_if_needed(@issue) + flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("#{@issue.source_from}", issue_path(@issue), :title => @issue.subject)) + #flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject)) + if params[:continue] + attrs = {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} + redirect_to new_project_issue_url(@issue.project, :issue => attrs) + else + redirect_to issue_url(@issue) + end + } + format.api { render :action => 'show', :status => :created, :location => issue_url(@issue) } + end + return + else + respond_to do |format| + format.html { render :action => 'new' } + format.api { render_validation_errors(@issue) } + end + end + end + + def edit + return unless update_issue_from_params + + respond_to do |format| + format.html {render :layout => 'base_projects' }#added by young + format.xml { } + end + end + + def update + return unless update_issue_from_params + @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads])) + saved = false + begin + saved = @issue.save_issue_with_child_records(params, @time_entry) + rescue ActiveRecord::StaleObjectError + @conflict = true + if params[:last_journal_id] + @conflict_journals = @issue.journals_after(params[:last_journal_id]).all + @conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) + end + end + + if saved + + #修改界面增加跟踪者 + watcherlist = @issue.watcher_users + select_users = [] + if params[:issue] + if params[:issue][:watcher_user_ids] + params[:issue][:watcher_user_ids].each do |user_id| + select_users << User.find(user_id) + end + end + end + select_users.each do |user| + if watcherlist.include? user + else + @issue.add_watcher user + end + end + watcherlist.each do |user| + if select_users.include? user + else + @issue.remove_watcher user + end + end + + render_attachment_warning_if_needed(@issue) + reply_id = params[:reference_user_id].to_i + if reply_id > 0 + JournalReply.add_reply(@issue.current_journal.id, reply_id, User.current.id) + end + flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record? + + respond_to do |format| + format.html { redirect_back_or_default issue_path(@issue) } + format.api { render_api_ok } + end + else + respond_to do |format| + format.html { render :action => 'edit' } + format.api { render_validation_errors(@issue) } + end + end + end + + # Updates the issue form when changing the project, status or tracker + # on issue creation/update + def update_form + end + + # Bulk edit/copy a set of issues + def bulk_edit + @issues.sort! + @copy = params[:copy].present? + @notes = params[:notes] + + if User.current.allowed_to?(:move_issues, @projects) + @allowed_projects = Issue.allowed_target_projects_on_move + if params[:issue] + @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s} + if @target_project + target_projects = [@target_project] + end + end + end + target_projects ||= @projects + + if @copy + @available_statuses = [IssueStatus.default] + else + @available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&) + end + @custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&) + @assignables = target_projects.map(&:assignable_users).reduce(:&) + @trackers = target_projects.map(&:trackers).reduce(:&) + @versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&) + @categories = target_projects.map {|p| p.issue_categories}.reduce(:&) + if @copy + @attachments_present = @issues.detect {|i| i.attachments.any?}.present? + @subtasks_present = @issues.detect {|i| !i.leaf?}.present? + end + + @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&) + render :layout => false if request.xhr? + end + + def bulk_update + @issues.sort! + @copy = params[:copy].present? + attributes = parse_params_for_bulk_issue_attributes(params) + + unsaved_issue_ids = [] + moved_issues = [] + + if @copy && params[:copy_subtasks].present? + # Descendant issues will be copied with the parent task + # Don't copy them twice + @issues.reject! {|issue| @issues.detect {|other| issue.is_descendant_of?(other)}} + end + + @issues.each do |issue| + issue.reload + if @copy + issue = issue.copy({}, + :attachments => params[:copy_attachments].present?, + :subtasks => params[:copy_subtasks].present? + ) + end + journal = issue.init_journal(User.current, params[:notes]) + issue.safe_attributes = attributes + call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue }) + if issue.save + moved_issues << issue + else + # Keep unsaved issue ids to display them in flash error + unsaved_issue_ids << issue.id + end + end + set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids) + + if params[:follow] + if @issues.size == 1 && moved_issues.size == 1 + redirect_to issue_url(moved_issues.first) + elsif moved_issues.map(&:project).uniq.size == 1 + redirect_to project_issues_url(moved_issues.map(&:project).first) + end + else + redirect_back_or_default _project_issues_path(@project) + end + end + + def destroy + @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f + if @hours > 0 + case params[:todo] + when 'destroy' + # nothing to do + when 'nullify' + TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues]) + when 'reassign' + reassign_to = @project.issues.find_by_id(params[:reassign_to_id]) + if reassign_to.nil? + flash.now[:error] = l(:error_issue_not_found_in_project) + return + else + TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues]) + end + else + # display the destroy form if it's a user request + return unless api_request? + end + end + @issues.each do |issue| + begin + issue.reload.destroy + rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists + # nothing to do, issue was already deleted (eg. by a parent) + end + end + respond_to do |format| + format.html { redirect_back_or_default _project_issues_path(@project) } + format.api { render_api_ok } + end + end + + private + + def find_project + project_id = params[:project_id] || (params[:issue] && params[:issue][:project_id]) + @project = Project.find(project_id) + rescue ActiveRecord::RecordNotFound + render_404 + end + + def retrieve_previous_and_next_issue_ids + retrieve_query_from_session + if @query + sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) + sort_update(@query.sortable_columns, 'issues_index_sort') + limit = 500 + issue_ids = @query.issue_ids(:order => sort_clause, :limit => (limit + 1), :include => [:assigned_to, :tracker, :priority, :category, :fixed_version]) + if (idx = issue_ids.index(@issue.id)) && idx < limit + if issue_ids.size < 500 + @issue_position = idx + 1 + @issue_count = issue_ids.size + end + @prev_issue_id = issue_ids[idx - 1] if idx > 0 + @next_issue_id = issue_ids[idx + 1] if idx < (issue_ids.size - 1) + end + end + end + + # Used by #edit and #update to set some common instance variables + # from the params + # TODO: Refactor, not everything in here is needed by #edit + def update_issue_from_params + @edit_allowed = User.current.allowed_to?(:edit_issues, @project) + @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project) + @time_entry.attributes = params[:time_entry] + + @issue.init_journal(User.current) + + issue_attributes = params[:issue] + if issue_attributes && params[:conflict_resolution] + case params[:conflict_resolution] + when 'overwrite' + issue_attributes = issue_attributes.dup + issue_attributes.delete(:lock_version) + when 'add_notes' + issue_attributes = issue_attributes.slice(:notes) + when 'cancel' + redirect_to issue_url(@issue) + return false + end + end + @issue.safe_attributes = issue_attributes + @priorities = IssuePriority.active + @allowed_statuses = @issue.new_statuses_allowed_to(User.current) + true + end + + # TODO: Refactor, lots of extra code in here + # TODO: Changing tracker on an existing issue should not trigger this + def build_new_issue_from_params + if params[:id].blank? + @issue = Issue.new + if params[:copy_from] + begin + @copy_from = Issue.visible.find(params[:copy_from]) + @copy_attachments = params[:copy_attachments].present? || request.get? + @copy_subtasks = params[:copy_subtasks].present? || request.get? + @issue.copy_from(@copy_from, :attachments => @copy_attachments, :subtasks => @copy_subtasks) + rescue ActiveRecord::RecordNotFound + render_404 + return + end + end + @issue.project = @project + else + @issue = @project.issues.visible.find(params[:id]) + end + + @issue.project = @project + @issue.author ||= User.current + # Tracker must be set before custom field values + @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first) + if @issue.tracker.nil? + render_error l(:error_no_tracker_in_project) + return false + end + @issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date? + @issue.safe_attributes = params[:issue] + + @priorities = IssuePriority.active + @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true) + @available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq + end + + def check_for_default_issue_status + if IssueStatus.default.nil? + render_error l(:error_no_default_issue_status) + return false + end + end + + def parse_params_for_bulk_issue_attributes(params) + attributes = (params[:issue] || {}).reject {|k,v| v.blank?} + attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} + if custom = attributes[:custom_field_values] + custom.reject! {|k,v| v.blank?} + custom.keys.each do |k| + if custom[k].is_a?(Array) + custom[k] << '' if custom[k].delete('__none__') + else + custom[k] = '' if custom[k] == '__none__' + end + end + end + attributes + end +end diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb index 4ebef9971..f6e17593f 100644 --- a/app/controllers/journals_controller.rb +++ b/app/controllers/journals_controller.rb @@ -1,117 +1,117 @@ -# 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 JournalsController < ApplicationController - before_filter :find_journal, :only => [:edit, :diff, :destroy] - before_filter :find_issue, :only => [:new] - before_filter :find_optional_project, :only => [:index] - before_filter :authorize, :only => [:new, :edit, :diff] - accept_rss_auth :index - menu_item :issues - - helper :issues - helper :custom_fields - helper :queries - include QueriesHelper - helper :sort - include SortHelper - - def index - retrieve_query - sort_init 'id', 'desc' - sort_update(@query.sortable_columns) - - if @query.valid? - @journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC", - :limit => 25) - end - @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name) - render :layout => false, :content_type => 'application/atom+xml' - rescue ActiveRecord::RecordNotFound - render_404 - end - - def diff - @issue = @journal.issue - if params[:detail_id].present? - @detail = @journal.details.find_by_id(params[:detail_id]) - else - @detail = @journal.details.detect {|d| d.prop_key == 'description'} - end - (render_404; return false) unless @issue && @detail - @diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value) - respond_to do |format| - format.html { - render :layout => 'project_base' - } - end - end - - def new - @journal = Journal.visible.find(params[:journal_id]) if params[:journal_id] - if @journal - user = @journal.user - text = @journal.notes - else - user = @issue.author - text = @issue.description - end - # Replaces pre blocks with [...] - text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') - @content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> " - @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - @id = user.id - rescue ActiveRecord::RecordNotFound - render_404 - end - - def edit - (render_403; return false) unless @journal.editable_by?(User.current) - if request.post? - @journal.update_attributes(:notes => params[:notes]) if params[:notes] - @journal.destroy if @journal.details.empty? && @journal.notes.blank? - call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params}) - respond_to do |format| - format.html { redirect_to issue_url(@journal.journalized) } - format.js { render :action => 'update' } - end - else - respond_to do |format| - format.html { - # TODO: implement non-JS journal update - render :nothing => true - } - format.js - end - end - end - - # Delete a journals added by young - def destroy - @journal.destroy - redirect_to issue_url(@journal.journalized) - end - - private - - def find_journal - @journal = Journal.visible.find(params[:id]) - @project = @journal.journalized.project - 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. + +class JournalsController < ApplicationController + before_filter :find_journal, :only => [:edit, :diff, :destroy] + before_filter :find_issue, :only => [:new] + before_filter :find_optional_project, :only => [:index] + before_filter :authorize, :only => [:new, :edit, :diff] + accept_rss_auth :index + menu_item :issues + + helper :issues + helper :custom_fields + helper :queries + include QueriesHelper + helper :sort + include SortHelper + + def index + retrieve_query + sort_init 'id', 'desc' + sort_update(@query.sortable_columns) + + if @query.valid? + @journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC", + :limit => 25) + end + @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name) + render :layout => false, :content_type => 'application/atom+xml' + rescue ActiveRecord::RecordNotFound + render_404 + end + + def diff + @issue = @journal.issue + if params[:detail_id].present? + @detail = @journal.details.find_by_id(params[:detail_id]) + else + @detail = @journal.details.detect {|d| d.prop_key == 'description'} + end + (render_404; return false) unless @issue && @detail + @diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value) + respond_to do |format| + format.html { + render :layout => 'project_base' + } + end + end + + def new + @journal = Journal.visible.find(params[:journal_id]) if params[:journal_id] + if @journal + user = @journal.user + text = @journal.notes + else + user = @issue.author + text = @issue.description + end + # Replaces pre blocks with [...] + text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') + @content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> " + @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + @id = user.id + rescue ActiveRecord::RecordNotFound + render_404 + end + + def edit + (render_403; return false) unless @journal.editable_by?(User.current) + if request.post? + @journal.update_attributes(:notes => params[:notes]) if params[:notes] + @journal.destroy if @journal.details.empty? && @journal.notes.blank? + call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params}) + respond_to do |format| + format.html { redirect_to issue_url(@journal.journalized) } + format.js { render :action => 'update' } + end + else + respond_to do |format| + format.html { + # TODO: implement non-JS journal update + render :nothing => true + } + format.js + end + end + end + + # Delete a journals added by young + def destroy + @journal.destroy + redirect_to issue_url(@journal.journalized) + end + + private + + def find_journal + @journal = Journal.visible.find(params[:id]) + @project = @journal.journalized.project + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 12d979098..fa19a1a3d 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -1,326 +1,326 @@ -# -*coding:utf-8 -*- -# 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 MembersController < ApplicationController - model_object Member - before_filter :find_model_object, :except => [:index, :create, :autocomplete] - #before_filter :find_model_object_contest, :except => [:index, :create, :autocomplete] - before_filter :find_project_from_association, :except => [:index, :create, :autocomplete] - before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete] - before_filter :authorize - accept_api_auth :index, :show, :create, :update, :destroy - - def index - @offset, @limit = api_offset_and_limit - @member_count = @project.member_principals.count - @member_pages = Paginator.new @member_count, @limit, params['page'] - @offset ||= @member_pages.offset - @members = @project.member_principals.all( - :order => "#{Member.table_name}.id", - :limit => @limit, - :offset => @offset - ) - - respond_to do |format| - format.html { head 406 } - format.api - end - end - - def show - respond_to do |format| - format.html { head 406 } - format.api - end - end - - def create - if params[:refusal_button] - members = [] - applied_members = true - if params[:membership] - if params[:membership][:user_ids] - attrs = params[:membership].dup - user_ids = attrs.delete(:user_ids) - user_ids.each do |user_id| - AppliedProject.deleteappiled(user_id, @project.id) - end - end - end - else - #modify by nwb - #更改课程成员逻辑 - applied_members = false - members = [] - user_grades = [] - if @project - project_info = [] - if params[:membership] - if params[:membership][:user_ids] - attrs = params[:membership].dup - user_ids = attrs.delete(:user_ids) - user_ids.each do |user_id| - members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) - user_grades << UserGrade.new(:user_id => user_id, :project_id => @project.id) - ## added by nie - - if (params[:membership][:role_ids]) - role = Role.find(params[:membership][:role_ids][0]) - project_info << ProjectInfo.new(:user_id => user_id, :project_id => @project.id) if role.allowed_to?(:is_manager) - # ProjectInfo.create(:name => "test", :user_id => 123) - end - ## end - end - else - members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) - user_grades << UserGrade.new(:user_id => params[:membership][:user_id], :project_id => @project.id) - ## added by nie - if (params[:membership][:role_ids]) - role = Role.find(params[:membership][:role_ids][0]) - project_info << ProjectInfo.new(:project_id => @project.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager) - end - ## end - end - @project.members << members - # added by nie - @project.project_infos << project_info - @project.user_grades << user_grades - # end - end - if members.present? && members.all? { |m| m.valid? } - members.each do |member| - AppliedProject.deleteappiled(member.user_id, @project.id) - end - end - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.js { @members = members; @applied_members = applied_members; } - format.api { - @member = members.first - if @member.valid? - render :action => 'show', :status => :created, :location => membership_url(@member) - else - render_validation_errors(@member) - end - } - end - elsif @course - course_info = [] - if params[:membership] - if params[:membership][:user_ids] - attrs = params[:membership].dup - user_ids = attrs.delete(:user_ids) - user_ids.each do |user_id| - member = Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) - role = Role.find_by_id(params[:membership][:role_ids]) - # 这里的判断只能通过角色名,可以弄成常量 - if role.name == "学生" - StudentsForCourse.create(:student_id => user_id, :course_id =>@course.id) - end - members << member - #user_grades << UserGrade.new(:user_id => user_id, :course_id => @course.id) - if (params[:membership][:role_ids]) - role = Role.find(params[:membership][:role_ids][0]) - course_info << CourseInfo.new(:user_id => user_id, :course_id => @course.id) if role.allowed_to?(:is_manager) - end - end - else - members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) - if (params[:membership][:role_ids]) - role = Role.find(params[:membership][:role_ids][0]) - course_info << CourseInfo.new(:course_id => @course.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager) - end - end - @course.members << members - @course.course_infos << course_info - end - respond_to do |format| - format.html { redirect_to_settings_in_courses } - format.js { @members = members; @applied_members = applied_members; } - format.api { - @member = members.first - if @member.valid? - render :action => 'show', :status => :created, :location => membership_url(@member) - else - render_validation_errors(@member) - end - } - end - end # end of if @project - - end # end of params[:refusal_button] - - end - - def update - #modify by nwb - #增加对课程成员修改的支持 - if @project - if params[:membership] - @member.role_ids = params[:membership][:role_ids] - - #added by nie - if (params[:membership][:role_ids]) - role = Role.find(params[:membership][:role_ids][0]) - if role.allowed_to?(:is_manager) - @projectInfo = ProjectInfo.new(:user_id => @member.user_id, :project_id => @project.id) - @projectInfo.save - else - user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id) - if user_admin.size > 0 - user_admin.each do |user| - user.destroy - end - end - end - end - end - - saved = @member.save - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.js - format.api { - if saved - render_api_ok - else - render_validation_errors(@member) - end - } - end - elsif @course - if params[:membership] - @member.role_ids = params[:membership][:role_ids] - - if (params[:membership][:role_ids]) - role = Role.find(params[:membership][:role_ids][0]) - # 这里的判断只能通过角色名,可以弄成常量 - if role.name == "学生" - StudentsForCourse.create(:student_id => @member.user_id, :course_id =>@course.id) - else - joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id) - joined.each do |join| - join.delete - end - end - if role.allowed_to?(:is_manager) - @courseInfo = CourseInfos.new(:user_id => @member.user_id, :course_id => @course.id) - @courseInfo.save - else - user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id) - if user_admin.size > 0 - user_admin.each do |user| - user.destroy - end - end - end - end - end - - saved = @member.save - respond_to do |format| - format.html { redirect_to_settings_in_courses } - format.js - format.api { - if saved - render_api_ok - else - render_validation_errors(@member) - end - } - end - end - - end - - def destroy - #modify by nwb - #课程成员删除修改 - if @project - if request.delete? && @member.deletable? - @member.destroy - # end - user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id) - if user_admin.size > 0 - user_admin.each do |user| - user.destroy - end - end - user_grade = UserGrade.where("user_id = ? and project_id = ?", @member.user_id, @project.id) - if user_grade.size > 0 - user_grade.each do |grade| - grade.destroy - end - end - end - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.js - format.api { - if @member.destroyed? - render_api_ok - else - head :unprocessable_entity - end - } - end - elsif @course - if request.delete? && @member.deletable? - @member.destroy - user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id) - if user_admin.size > 0 - user_admin.each do |user| - user.destroy - end - end - joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id) - joined.each do |join| - join.delete - end - - end - respond_to do |format| - format.html { redirect_to_settings_in_courses } - format.js - format.api { - if @member.destroyed? - render_api_ok - else - head :unprocessable_entity - end - } - end - end - end - - def autocomplete - respond_to do |format| - format.js - end - end - - private - - def redirect_to_settings_in_projects - redirect_to settings_project_url(@project, :tab => 'members') - end - - def redirect_to_settings_in_courses - redirect_to settings_course_url(@course, :tab => 'members') - end -end +# -*coding:utf-8 -*- +# 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 MembersController < ApplicationController + model_object Member + before_filter :find_model_object, :except => [:index, :create, :autocomplete] + #before_filter :find_model_object_contest, :except => [:index, :create, :autocomplete] + before_filter :find_project_from_association, :except => [:index, :create, :autocomplete] + before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete] + before_filter :authorize + accept_api_auth :index, :show, :create, :update, :destroy + + def index + @offset, @limit = api_offset_and_limit + @member_count = @project.member_principals.count + @member_pages = Paginator.new @member_count, @limit, params['page'] + @offset ||= @member_pages.offset + @members = @project.member_principals.all( + :order => "#{Member.table_name}.id", + :limit => @limit, + :offset => @offset + ) + + respond_to do |format| + format.html { head 406 } + format.api + end + end + + def show + respond_to do |format| + format.html { head 406 } + format.api + end + end + + def create + if params[:refusal_button] + members = [] + applied_members = true + if params[:membership] + if params[:membership][:user_ids] + attrs = params[:membership].dup + user_ids = attrs.delete(:user_ids) + user_ids.each do |user_id| + AppliedProject.deleteappiled(user_id, @project.id) + end + end + end + else + #modify by nwb + #更改课程成员逻辑 + applied_members = false + members = [] + user_grades = [] + if @project + project_info = [] + if params[:membership] + if params[:membership][:user_ids] + attrs = params[:membership].dup + user_ids = attrs.delete(:user_ids) + user_ids.each do |user_id| + members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) + user_grades << UserGrade.new(:user_id => user_id, :project_id => @project.id) + ## added by nie + + if (params[:membership][:role_ids]) + role = Role.find(params[:membership][:role_ids][0]) + project_info << ProjectInfo.new(:user_id => user_id, :project_id => @project.id) if role.allowed_to?(:is_manager) + # ProjectInfo.create(:name => "test", :user_id => 123) + end + ## end + end + else + members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) + user_grades << UserGrade.new(:user_id => params[:membership][:user_id], :project_id => @project.id) + ## added by nie + if (params[:membership][:role_ids]) + role = Role.find(params[:membership][:role_ids][0]) + project_info << ProjectInfo.new(:project_id => @project.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager) + end + ## end + end + @project.members << members + # added by nie + @project.project_infos << project_info + @project.user_grades << user_grades + # end + end + if members.present? && members.all? { |m| m.valid? } + members.each do |member| + AppliedProject.deleteappiled(member.user_id, @project.id) + end + end + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.js { @members = members; @applied_members = applied_members; } + format.api { + @member = members.first + if @member.valid? + render :action => 'show', :status => :created, :location => membership_url(@member) + else + render_validation_errors(@member) + end + } + end + elsif @course + course_info = [] + if params[:membership] + if params[:membership][:user_ids] + attrs = params[:membership].dup + user_ids = attrs.delete(:user_ids) + user_ids.each do |user_id| + member = Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) + role = Role.find_by_id(params[:membership][:role_ids]) + # 这里的判断只能通过角色名,可以弄成常量 + if role.name == "学生" + StudentsForCourse.create(:student_id => user_id, :course_id =>@course.id) + end + members << member + #user_grades << UserGrade.new(:user_id => user_id, :course_id => @course.id) + if (params[:membership][:role_ids]) + role = Role.find(params[:membership][:role_ids][0]) + course_info << CourseInfo.new(:user_id => user_id, :course_id => @course.id) if role.allowed_to?(:is_manager) + end + end + else + members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) + if (params[:membership][:role_ids]) + role = Role.find(params[:membership][:role_ids][0]) + course_info << CourseInfo.new(:course_id => @course.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager) + end + end + @course.members << members + @course.course_infos << course_info + end + respond_to do |format| + format.html { redirect_to_settings_in_courses } + format.js { @members = members; @applied_members = applied_members; } + format.api { + @member = members.first + if @member.valid? + render :action => 'show', :status => :created, :location => membership_url(@member) + else + render_validation_errors(@member) + end + } + end + end # end of if @project + + end # end of params[:refusal_button] + + end + + def update + #modify by nwb + #增加对课程成员修改的支持 + if @project + if params[:membership] + @member.role_ids = params[:membership][:role_ids] + + #added by nie + if (params[:membership][:role_ids]) + role = Role.find(params[:membership][:role_ids][0]) + if role.allowed_to?(:is_manager) + @projectInfo = ProjectInfo.new(:user_id => @member.user_id, :project_id => @project.id) + @projectInfo.save + else + user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end + end + end + end + end + + saved = @member.save + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.js + format.api { + if saved + render_api_ok + else + render_validation_errors(@member) + end + } + end + elsif @course + if params[:membership] + @member.role_ids = params[:membership][:role_ids] + + if (params[:membership][:role_ids]) + role = Role.find(params[:membership][:role_ids][0]) + # 这里的判断只能通过角色名,可以弄成常量 + if role.name == "学生" + StudentsForCourse.create(:student_id => @member.user_id, :course_id =>@course.id) + else + joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id) + joined.each do |join| + join.delete + end + end + if role.allowed_to?(:is_manager) + @courseInfo = CourseInfos.new(:user_id => @member.user_id, :course_id => @course.id) + @courseInfo.save + else + user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end + end + end + end + end + + saved = @member.save + respond_to do |format| + format.html { redirect_to_settings_in_courses } + format.js + format.api { + if saved + render_api_ok + else + render_validation_errors(@member) + end + } + end + end + + end + + def destroy + #modify by nwb + #课程成员删除修改 + if @project + if request.delete? && @member.deletable? + @member.destroy + # end + user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end + end + user_grade = UserGrade.where("user_id = ? and project_id = ?", @member.user_id, @project.id) + if user_grade.size > 0 + user_grade.each do |grade| + grade.destroy + end + end + end + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.js + format.api { + if @member.destroyed? + render_api_ok + else + head :unprocessable_entity + end + } + end + elsif @course + if request.delete? && @member.deletable? + @member.destroy + user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end + end + joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id) + joined.each do |join| + join.delete + end + + end + respond_to do |format| + format.html { redirect_to_settings_in_courses } + format.js + format.api { + if @member.destroyed? + render_api_ok + else + head :unprocessable_entity + end + } + end + end + end + + def autocomplete + respond_to do |format| + format.js + end + end + + private + + def redirect_to_settings_in_projects + redirect_to settings_project_url(@project, :tab => 'members') + end + + def redirect_to_settings_in_courses + redirect_to settings_course_url(@course, :tab => 'members') + end +end diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index b980331df..9257888dd 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -1,207 +1,207 @@ -class MemosController < ApplicationController - default_search_scope :memos - before_filter :find_forum, :only => [:new, :create, :preview] - before_filter :find_attachments, :only => [:preview] - before_filter :find_memo, :except => [:new, :create, :preview] - before_filter :authenticate_user_edit, :only => [:edit, :update] - before_filter :authenticate_user_destroy, :only => [:destroy] - before_filter :require_login, :only => [:new, :create] - - helper :attachments - include AttachmentsHelper - include ApplicationHelper - - layout 'base_memos' - - def quote - @subject = @memo.subject - @subject = "RE: #{@subject}" unless @subject.starts_with?('RE:') - - @content = "#{ll(Setting.default_language, :text_user_wrote, @memo.author)}
  " - @content << @memo.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n") + "\n\n
" - @content = "
" << @content - #@content = "> #{ll(Setting.default_language, :text_user_wrote, @memo.author)}\n> " - #@content << @memo.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - #@content_html = textilizable(@content) - @temp = Memo.new - @temp.content = @content - end - - def new - @memo = Memo.new - @memo.forum_id = @forum.id - - respond_to do |format| - format.html { - render action: :new ,layout: 'base' - } - format.json { render json: @memo } - end - end - - def create - - if params[:quote].nil? - @quote = "" - else - @quote = params[:quote] - end - - #unless params[:quote].nil? - # @quote = params[:quote][:quote] - #end - - @memo = Memo.new(params[:memo]) - @memo.forum_id = params[:forum_id] - @memo.author_id = User.current.id - - @memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads])) - @memo.content = @quote + @memo.content - respond_to do |format| - if @memo.save - format.html { redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}" } - format.json { render json: @memo, status: :created, location: @memo } - else - flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" - # back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id) - pre_count = REPLIES_PER_PAGE - - @memo_new = @memo.dup - @memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示 - unless @memo.new_record? - @memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1)) - end - - - page = params[:page] - if params[:r] && page.nil? - offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count - page = 1 + offset / pre_count - else - - end - @reply_count = @memo.children.count - @reply_pages = Paginator.new @reply_count, pre_count, page - @replies = @memo.children. - includes(:author, :attachments). - reorder("#{Memo.table_name}.created_at DESC"). - limit(@reply_pages.per_page). - offset(@reply_pages.offset). - all - if @memo.new_record? - format.html { render :new,:layout=>'base'} - else - format.html { render action: :show } - format.json { render json: @memo.errors, status: :unprocessable_entity } - end - - end - end - end - - REPLIES_PER_PAGE = 20 unless const_defined?(:REPLIES_PER_PAGE) - def show - pre_count = REPLIES_PER_PAGE - - @memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示 - @memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1)) - - page = params[:page] - if params[:r] && page.nil? - offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count - page = 1 + offset / pre_count - else - - end - @reply_count = @memo.children.count - @reply_pages = Paginator.new @reply_count, pre_count, page - @replies = @memo.children. - includes(:author, :attachments). - reorder("#{Memo.table_name}.created_at DESC"). - limit(@reply_pages.per_page). - offset(@reply_pages.offset). - all - - @memo_new = Memo.new - - - # @memo = Memo.find_by_id(params[:id]) - # @forum = Forum.find(params[:forum_id]) - # @replies = @memo.replies - # @mome_new = Memo.new - - respond_to do |format| - format.html # show.html.erb - format.json { render json: @memo } - format.xml { render xml: @memo } - end - end - - def edit - @replying = false - end - - def update - respond_to do |format| - if( @memo.update_column(:subject, params[:memo][:subject]) && - @memo.update_column(:content, params[:memo][:content]) && - @memo.update_column(:sticky, params[:memo][:sticky]) && - @memo.update_column(:lock, params[:memo][:lock])) - @memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads])) - @memo.save - # @memo.root.update_attribute(:updated_at, @memo.updated_at) - format.html {redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}"} - else - format.html { render action: "edit" } - format.json { render json: @person.errors, status: :unprocessable_entity } - end - end - end - - def destroy - @memo.destroy - - respond_to do |format| - # format.html { redirect_to @back_url } - format.html { redirect_to back_memo_or_forum_url } - format.json { head :no_content } - end - end - - private - - def find_memo - return unless find_forum - #@memo = @forum.memos.find(params[:id]) - @memo = Memo.find(params[:id]) - rescue ActiveRecord::RecordNotFound - render_404 - nil - end - - def find_forum - @forum = Forum.find(params[:forum_id]) - rescue ActiveRecord::RecordNotFound - render_404 - nil - end - - def authenticate_user_edit - find_memo - render_403 unless @memo.editable_by? User.current - end - - def authenticate_user_destroy - find_memo - render_403 unless @memo.destroyable_by? User.current - end - - def back_memo_url - forum_memo_path(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id)) - end - - def back_memo_or_forum_url - @memo.parent_id.nil? ? forum_url(@forum) : forum_memo_url(@forum, @memo.parent_id) - end - -end +class MemosController < ApplicationController + default_search_scope :memos + before_filter :find_forum, :only => [:new, :create, :preview] + before_filter :find_attachments, :only => [:preview] + before_filter :find_memo, :except => [:new, :create, :preview] + before_filter :authenticate_user_edit, :only => [:edit, :update] + before_filter :authenticate_user_destroy, :only => [:destroy] + before_filter :require_login, :only => [:new, :create] + + helper :attachments + include AttachmentsHelper + include ApplicationHelper + + layout 'base_memos' + + def quote + @subject = @memo.subject + @subject = "RE: #{@subject}" unless @subject.starts_with?('RE:') + + @content = "#{ll(Setting.default_language, :text_user_wrote, @memo.author)}
  " + @content << @memo.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n") + "
\n\n
" + @content = "
" << @content + #@content = "> #{ll(Setting.default_language, :text_user_wrote, @memo.author)}\n> " + #@content << @memo.content.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + #@content_html = textilizable(@content) + @temp = Memo.new + @temp.content = @content + end + + def new + @memo = Memo.new + @memo.forum_id = @forum.id + + respond_to do |format| + format.html { + render action: :new ,layout: 'base' + } + format.json { render json: @memo } + end + end + + def create + + if params[:quote].nil? + @quote = "" + else + @quote = params[:quote] + end + + #unless params[:quote].nil? + # @quote = params[:quote][:quote] + #end + + @memo = Memo.new(params[:memo]) + @memo.forum_id = params[:forum_id] + @memo.author_id = User.current.id + + @memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads])) + @memo.content = @quote + @memo.content + respond_to do |format| + if @memo.save + format.html { redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}" } + format.json { render json: @memo, status: :created, location: @memo } + else + flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" + # back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id) + pre_count = REPLIES_PER_PAGE + + @memo_new = @memo.dup + @memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示 + unless @memo.new_record? + @memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1)) + end + + + page = params[:page] + if params[:r] && page.nil? + offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count + page = 1 + offset / pre_count + else + + end + @reply_count = @memo.children.count + @reply_pages = Paginator.new @reply_count, pre_count, page + @replies = @memo.children. + includes(:author, :attachments). + reorder("#{Memo.table_name}.created_at DESC"). + limit(@reply_pages.per_page). + offset(@reply_pages.offset). + all + if @memo.new_record? + format.html { render :new,:layout=>'base'} + else + format.html { render action: :show } + format.json { render json: @memo.errors, status: :unprocessable_entity } + end + + end + end + end + + REPLIES_PER_PAGE = 20 unless const_defined?(:REPLIES_PER_PAGE) + def show + pre_count = REPLIES_PER_PAGE + + @memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示 + @memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1)) + + page = params[:page] + if params[:r] && page.nil? + offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count + page = 1 + offset / pre_count + else + + end + @reply_count = @memo.children.count + @reply_pages = Paginator.new @reply_count, pre_count, page + @replies = @memo.children. + includes(:author, :attachments). + reorder("#{Memo.table_name}.created_at DESC"). + limit(@reply_pages.per_page). + offset(@reply_pages.offset). + all + + @memo_new = Memo.new + + + # @memo = Memo.find_by_id(params[:id]) + # @forum = Forum.find(params[:forum_id]) + # @replies = @memo.replies + # @mome_new = Memo.new + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @memo } + format.xml { render xml: @memo } + end + end + + def edit + @replying = false + end + + def update + respond_to do |format| + if( @memo.update_column(:subject, params[:memo][:subject]) && + @memo.update_column(:content, params[:memo][:content]) && + @memo.update_column(:sticky, params[:memo][:sticky]) && + @memo.update_column(:lock, params[:memo][:lock])) + @memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads])) + @memo.save + # @memo.root.update_attribute(:updated_at, @memo.updated_at) + format.html {redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}"} + else + format.html { render action: "edit" } + format.json { render json: @person.errors, status: :unprocessable_entity } + end + end + end + + def destroy + @memo.destroy + + respond_to do |format| + # format.html { redirect_to @back_url } + format.html { redirect_to back_memo_or_forum_url } + format.json { head :no_content } + end + end + + private + + def find_memo + return unless find_forum + #@memo = @forum.memos.find(params[:id]) + @memo = Memo.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + nil + end + + def find_forum + @forum = Forum.find(params[:forum_id]) + rescue ActiveRecord::RecordNotFound + render_404 + nil + end + + def authenticate_user_edit + find_memo + render_403 unless @memo.editable_by? User.current + end + + def authenticate_user_destroy + find_memo + render_403 unless @memo.destroyable_by? User.current + end + + def back_memo_url + forum_memo_path(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id)) + end + + def back_memo_or_forum_url + @memo.parent_id.nil? ? forum_url(@forum) : forum_memo_url(@forum, @memo.parent_id) + end + +end diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 4e23fc41b..73565a5ba 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -1,282 +1,282 @@ -# 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 MyController < ApplicationController - layout "users_base" - before_filter :require_login - - helper :issues - helper :users - helper :custom_fields - - BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues, - 'issuesreportedbyme' => :label_reported_issues, - 'issueswatched' => :label_watched_issues, - 'news' => :label_news_latest, - 'calendar' => :label_calendar, - 'documents' => :label_document_plural, - 'timelog' => :label_spent_time - }.merge(Redmine::Views::MyPage::Block.additional_blocks).freeze - - DEFAULT_LAYOUT = { 'left' => ['issuesassignedtome'], - 'right' => ['issuesreportedbyme'] - }.freeze - - def index - - page - render :action => 'page' - end - - # Show user's page - def page - @user = User.current - @Issues= Issue.visible.open. - where(:assigned_to_id => ([User.current.id] + User.current.group_ids)) - @limit = 10 - @feedback_count = @Issues.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @curse_attachments = @Issues[@offset, @limit] - - @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT - end - - def page2 - @limit = 10 - @user = User.current - @Issues= Issue.visible.open. - where(:assigned_to_id => ([User.current.id] + User.current.group_ids)) - @feedback_count = @Issues.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @curse_attachments = @Issues[@offset, @limit] - @state = false - @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT - respond_to do |format| - format.js - end - end - - # Edit user's account - def account - @user = User.current - lg=@user.login - @pref = @user.pref - diskfile = disk_filename('User', @user.id) - diskfile1 = diskfile + 'temp' - if request.post? - @user.safe_attributes = params[:user] - @user.pref.attributes = params[:pref] - @user.pref[:no_self_notified] = (params[:no_self_notified] == '1') - @user.login = params[:login] - unless @user.user_extensions.nil? - if @user.user_extensions.identity == 2 - @user.firstname = params[:enterprise_name] - end - end - - @se = @user.extensions - @se.school_id = params[:occupation] if params[:occupation] - @se.gender = params[:gender] - @se.location = params[:province] if params[:province] - @se.location_city = params[:city] if params[:city] - @se.identity = params[:identity].to_i if params[:identity] - @se.technical_title = params[:technical_title] if params[:technical_title] - @se.student_id = params[:no] if params[:no] - - if @user.save && @se.save - # 头像保存 - if File.exist?(diskfile1) - if File.exist?(diskfile) - File.delete(diskfile) - end - File.open(diskfile1, "rb") do |f| - buffer = f.read(10) - if buffer != "DELETE" - File.open(diskfile1, "rb") do |f1| - File.open(diskfile, "wb") do |f| - buffer = "" - while (buffer = f1.read(8192)) - f.write(buffer) - end - end - end - - # File.rename(diskfile + 'temp',diskfile); - end - end - end - - # 确保文件被删除 - if File.exist?(diskfile1) - File.delete(diskfile1) - end - - @user.pref.save - @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : []) - set_language_if_valid @user.language - flash.now[:notice] = l(:notice_account_updated) - redirect_to user_url(@user) - return - else - # 确保文件被删除 - if File.exist?(diskfile1) - File.delete(diskfile1) - end - @user.login = lg - end - else - # 确保文件被删除 - if File.exist?(diskfile1) - File.delete(diskfile1) - end - end - end - - # Destroys user's account - def destroy - @user = User.current - unless @user.own_account_deletable? - redirect_to my_account_url - return - end - - if request.post? && params[:confirm] - @user.destroy - if @user.destroyed? - logout_user - flash.now[:notice] = l(:notice_account_deleted) - end - redirect_to home_url - end - end - - # Manage user's password - def password - @user = User.current - unless @user.change_password_allowed? - flash.now[:error] = l(:notice_can_t_change_password) - redirect_to my_account_url - return - end - if request.post? - if @user.check_password?(params[:password]) - @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] - - if @user.save - flash.now[:notice] = l(:notice_account_password_updated) - redirect_to my_account_url - end - else - flash.now[:error] = l(:notice_account_wrong_password) - end - end - end - - # Create a new feeds key - def reset_rss_key - if request.post? - if User.current.rss_token - User.current.rss_token.destroy - User.current.reload - end - User.current.rss_key - flash[:notice] = l(:notice_feeds_access_key_reseted) - end - redirect_to my_account_url - end - - # Create a new API key - def reset_api_key - if request.post? - if User.current.api_token - User.current.api_token.destroy - User.current.reload - end - User.current.api_key - flash[:notice] = l(:notice_api_access_key_reseted) - end - redirect_to my_account_url - end - - # User's page layout configuration - def page_layout - @user = User.current - @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup - @block_options = [] - BLOCKS.each do |k, v| - unless %w(top left right).detect {|f| (@blocks[f] ||= []).include?(k)} - @block_options << [l("my.blocks.#{v}", :default => [v, v.to_s.humanize]), k.dasherize] - end - end - end - - # Add a block to user's page - # The block is added on top of the page - # params[:block] : id of the block to add - def add_block - block = params[:block].to_s.underscore - if block.present? && BLOCKS.key?(block) - @user = User.current - layout = @user.pref[:my_page_layout] || {} - # remove if already present in a group - %w(top left right).each {|f| (layout[f] ||= []).delete block } - # add it on top - layout['top'].unshift block - @user.pref[:my_page_layout] = layout - @user.pref.save - end - redirect_to my_page_layout_url - end - - # Remove a block to user's page - # params[:block] : id of the block to remove - def remove_block - block = params[:block].to_s.underscore - @user = User.current - # remove block in all groups - layout = @user.pref[:my_page_layout] || {} - %w(top left right).each {|f| (layout[f] ||= []).delete block } - @user.pref[:my_page_layout] = layout - @user.pref.save - redirect_to my_page_layout_url - end - - # Change blocks order on user's page - # params[:group] : group to order (top, left or right) - # params[:list-(top|left|right)] : array of block ids of the group - def order_blocks - group = params[:group] - @user = User.current - if group.is_a?(String) - group_items = (params["blocks"] || []).collect(&:underscore) - group_items.each {|s| s.sub!(/^block_/, '')} - if group_items and group_items.is_a? Array - layout = @user.pref[:my_page_layout] || {} - # remove group blocks if they are presents in other groups - %w(top left right).each {|f| - layout[f] = (layout[f] || []) - group_items - } - layout[group] = group_items - @user.pref[:my_page_layout] = layout - @user.pref.save - end - end - render :nothing => true - 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 MyController < ApplicationController + layout "users_base" + before_filter :require_login + + helper :issues + helper :users + helper :custom_fields + + BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues, + 'issuesreportedbyme' => :label_reported_issues, + 'issueswatched' => :label_watched_issues, + 'news' => :label_news_latest, + 'calendar' => :label_calendar, + 'documents' => :label_document_plural, + 'timelog' => :label_spent_time + }.merge(Redmine::Views::MyPage::Block.additional_blocks).freeze + + DEFAULT_LAYOUT = { 'left' => ['issuesassignedtome'], + 'right' => ['issuesreportedbyme'] + }.freeze + + def index + + page + render :action => 'page' + end + + # Show user's page + def page + @user = User.current + @Issues= Issue.visible.open. + where(:assigned_to_id => ([User.current.id] + User.current.group_ids)) + @limit = 10 + @feedback_count = @Issues.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @curse_attachments = @Issues[@offset, @limit] + + @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT + end + + def page2 + @limit = 10 + @user = User.current + @Issues= Issue.visible.open. + where(:assigned_to_id => ([User.current.id] + User.current.group_ids)) + @feedback_count = @Issues.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @curse_attachments = @Issues[@offset, @limit] + @state = false + @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT + respond_to do |format| + format.js + end + end + + # Edit user's account + def account + @user = User.current + lg=@user.login + @pref = @user.pref + diskfile = disk_filename('User', @user.id) + diskfile1 = diskfile + 'temp' + if request.post? + @user.safe_attributes = params[:user] + @user.pref.attributes = params[:pref] + @user.pref[:no_self_notified] = (params[:no_self_notified] == '1') + @user.login = params[:login] + unless @user.user_extensions.nil? + if @user.user_extensions.identity == 2 + @user.firstname = params[:enterprise_name] + end + end + + @se = @user.extensions + @se.school_id = params[:occupation] if params[:occupation] + @se.gender = params[:gender] + @se.location = params[:province] if params[:province] + @se.location_city = params[:city] if params[:city] + @se.identity = params[:identity].to_i if params[:identity] + @se.technical_title = params[:technical_title] if params[:technical_title] + @se.student_id = params[:no] if params[:no] + + if @user.save && @se.save + # 头像保存 + if File.exist?(diskfile1) + if File.exist?(diskfile) + File.delete(diskfile) + end + File.open(diskfile1, "rb") do |f| + buffer = f.read(10) + if buffer != "DELETE" + File.open(diskfile1, "rb") do |f1| + File.open(diskfile, "wb") do |f| + buffer = "" + while (buffer = f1.read(8192)) + f.write(buffer) + end + end + end + + # File.rename(diskfile + 'temp',diskfile); + end + end + end + + # 确保文件被删除 + if File.exist?(diskfile1) + File.delete(diskfile1) + end + + @user.pref.save + @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : []) + set_language_if_valid @user.language + flash.now[:notice] = l(:notice_account_updated) + redirect_to user_url(@user) + return + else + # 确保文件被删除 + if File.exist?(diskfile1) + File.delete(diskfile1) + end + @user.login = lg + end + else + # 确保文件被删除 + if File.exist?(diskfile1) + File.delete(diskfile1) + end + end + end + + # Destroys user's account + def destroy + @user = User.current + unless @user.own_account_deletable? + redirect_to my_account_url + return + end + + if request.post? && params[:confirm] + @user.destroy + if @user.destroyed? + logout_user + flash.now[:notice] = l(:notice_account_deleted) + end + redirect_to home_url + end + end + + # Manage user's password + def password + @user = User.current + unless @user.change_password_allowed? + flash.now[:error] = l(:notice_can_t_change_password) + redirect_to my_account_url + return + end + if request.post? + if @user.check_password?(params[:password]) + @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] + + if @user.save + flash.now[:notice] = l(:notice_account_password_updated) + redirect_to my_account_url + end + else + flash.now[:error] = l(:notice_account_wrong_password) + end + end + end + + # Create a new feeds key + def reset_rss_key + if request.post? + if User.current.rss_token + User.current.rss_token.destroy + User.current.reload + end + User.current.rss_key + flash[:notice] = l(:notice_feeds_access_key_reseted) + end + redirect_to my_account_url + end + + # Create a new API key + def reset_api_key + if request.post? + if User.current.api_token + User.current.api_token.destroy + User.current.reload + end + User.current.api_key + flash[:notice] = l(:notice_api_access_key_reseted) + end + redirect_to my_account_url + end + + # User's page layout configuration + def page_layout + @user = User.current + @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup + @block_options = [] + BLOCKS.each do |k, v| + unless %w(top left right).detect {|f| (@blocks[f] ||= []).include?(k)} + @block_options << [l("my.blocks.#{v}", :default => [v, v.to_s.humanize]), k.dasherize] + end + end + end + + # Add a block to user's page + # The block is added on top of the page + # params[:block] : id of the block to add + def add_block + block = params[:block].to_s.underscore + if block.present? && BLOCKS.key?(block) + @user = User.current + layout = @user.pref[:my_page_layout] || {} + # remove if already present in a group + %w(top left right).each {|f| (layout[f] ||= []).delete block } + # add it on top + layout['top'].unshift block + @user.pref[:my_page_layout] = layout + @user.pref.save + end + redirect_to my_page_layout_url + end + + # Remove a block to user's page + # params[:block] : id of the block to remove + def remove_block + block = params[:block].to_s.underscore + @user = User.current + # remove block in all groups + layout = @user.pref[:my_page_layout] || {} + %w(top left right).each {|f| (layout[f] ||= []).delete block } + @user.pref[:my_page_layout] = layout + @user.pref.save + redirect_to my_page_layout_url + end + + # Change blocks order on user's page + # params[:group] : group to order (top, left or right) + # params[:list-(top|left|right)] : array of block ids of the group + def order_blocks + group = params[:group] + @user = User.current + if group.is_a?(String) + group_items = (params["blocks"] || []).collect(&:underscore) + group_items.each {|s| s.sub!(/^block_/, '')} + if group_items and group_items.is_a? Array + layout = @user.pref[:my_page_layout] || {} + # remove group blocks if they are presents in other groups + %w(top left right).each {|f| + layout[f] = (layout[f] || []) - group_items + } + layout[group] = group_items + @user.pref[:my_page_layout] = layout + @user.pref.save + end + end + render :nothing => true + end +end diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index ce06ea199..f1d97cbe7 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -1,176 +1,176 @@ -# 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 NewsController < ApplicationController - layout 'base_projects'# by young - default_search_scope :news - model_object News - before_filter :find_model_object, :except => [:new, :create, :index] - before_filter :find_project_from_association, :except => [:new, :create, :index] - before_filter :find_project_by_project_id, :only => [:new, :create] - before_filter :authorize, :except => [:index] - before_filter :find_optional_project, :only => :index - accept_rss_auth :index - accept_api_auth :index - - helper :watchers - helper :attachments - helper :project_score - - def index - case params[:format] - when 'xml', 'json' - @offset, @limit = api_offset_and_limit - else - @limit = 10 - end - - # modify by nwb - if params[:course_id] && @course==nil - @course = Course.find(params[:course_id]) - end - if @project - scope = @project ? @project.news.visible : News.visible - - @news_count = scope.count - @news_pages = Paginator.new @news_count, @limit, params['page'] - @offset ||= @news_pages.offset - @newss = scope.all(:include => [:author, :project], - :order => "#{News.table_name}.created_on DESC", - :offset => @offset, - :limit => @limit) - - respond_to do |format| - format.html { - @news = News.new # for adding news inline - # huang - - render :layout => false if request.xhr? - } - format.api - format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") } - end - elsif @course - scope = @course ? @course.news.course_visible : News.course_visible - - @news_count = scope.count - @news_pages = Paginator.new @news_count, @limit, params['page'] - @offset ||= @news_pages.offset - @newss = scope.all(:include => [:author, :course], - :order => "#{News.table_name}.created_on DESC", - :offset => @offset, - :limit => @limit) - - respond_to do |format| - format.html { - @news = News.new - render :layout => 'base_courses' - } - format.api - format.atom { render_feed(@newss, :title => (@course ? @course.name : Setting.app_title) + ": #{l(:label_news_plural)}") } - end - end - end - - def show - @comments = @news.comments - @comments.reverse! if User.current.wants_comments_in_reverse_order? - #modify by nwb - if @news.course_id - @course = Course.find(@news.course_id) - if @course - render :layout => 'base_courses' - end - end - end - - def new - #modify by nwb - if @project - @news = News.new(:project => @project, :author => User.current) - elsif @course - @news = News.new(:course => @course, :author => User.current) - render :layout => 'base_courses' - end - end - - def create - #modify by nwb - if @project - @news = News.new(:project => @project, :author => User.current) - @news.safe_attributes = params[:news] - @news.save_attachments(params[:attachments]) - if @news.save - render_attachment_warning_if_needed(@news) - flash[:notice] = l(:notice_successful_create) - redirect_to project_news_index_url(@project) - else - layout_file = @project ? 'base_projects' : 'base_courses' - render :action => 'new', :layout => layout_file - end - elsif @course - @news = News.new(:course => @course, :author => User.current) - @news.safe_attributes = params[:news] - @news.save_attachments(params[:attachments]) - if @news.save - render_attachment_warning_if_needed(@news) - flash[:notice] = l(:notice_successful_create) - redirect_to course_news_index_url(@course) - else - layout_file = 'base_courses' - render :action => 'new', :layout => layout_file - end - end - end - - def edit - end - - def update - @news.safe_attributes = params[:news] - @news.save_attachments(params[:attachments]) - if @news.save - render_attachment_warning_if_needed(@news) - flash[:notice] = l(:notice_successful_update) - redirect_to news_url(@news) - else - #flash[:error] = l(:notice_successful_update) - redirect_to news_url(@news) - end - end - - def destroy - @news.destroy - # modify by nwb - if @project - redirect_to project_news_index_url(@project) - elsif @course - redirect_to course_news_index_url(@course) - end - - end - - private - - def find_optional_project - return true unless params[:project_id] - @project = Project.find(params[:project_id]) - authorize - 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. + +class NewsController < ApplicationController + layout 'base_projects'# by young + default_search_scope :news + model_object News + before_filter :find_model_object, :except => [:new, :create, :index] + before_filter :find_project_from_association, :except => [:new, :create, :index] + before_filter :find_project_by_project_id, :only => [:new, :create] + before_filter :authorize, :except => [:index] + before_filter :find_optional_project, :only => :index + accept_rss_auth :index + accept_api_auth :index + + helper :watchers + helper :attachments + helper :project_score + + def index + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit + else + @limit = 10 + end + + # modify by nwb + if params[:course_id] && @course==nil + @course = Course.find(params[:course_id]) + end + if @project + scope = @project ? @project.news.visible : News.visible + + @news_count = scope.count + @news_pages = Paginator.new @news_count, @limit, params['page'] + @offset ||= @news_pages.offset + @newss = scope.all(:include => [:author, :project], + :order => "#{News.table_name}.created_on DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @news = News.new # for adding news inline + # huang + + render :layout => false if request.xhr? + } + format.api + format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + end + elsif @course + scope = @course ? @course.news.course_visible : News.course_visible + + @news_count = scope.count + @news_pages = Paginator.new @news_count, @limit, params['page'] + @offset ||= @news_pages.offset + @newss = scope.all(:include => [:author, :course], + :order => "#{News.table_name}.created_on DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @news = News.new + render :layout => 'base_courses' + } + format.api + format.atom { render_feed(@newss, :title => (@course ? @course.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + end + end + end + + def show + @comments = @news.comments + @comments.reverse! if User.current.wants_comments_in_reverse_order? + #modify by nwb + if @news.course_id + @course = Course.find(@news.course_id) + if @course + render :layout => 'base_courses' + end + end + end + + def new + #modify by nwb + if @project + @news = News.new(:project => @project, :author => User.current) + elsif @course + @news = News.new(:course => @course, :author => User.current) + render :layout => 'base_courses' + end + end + + def create + #modify by nwb + if @project + @news = News.new(:project => @project, :author => User.current) + @news.safe_attributes = params[:news] + @news.save_attachments(params[:attachments]) + if @news.save + render_attachment_warning_if_needed(@news) + flash[:notice] = l(:notice_successful_create) + redirect_to project_news_index_url(@project) + else + layout_file = @project ? 'base_projects' : 'base_courses' + render :action => 'new', :layout => layout_file + end + elsif @course + @news = News.new(:course => @course, :author => User.current) + @news.safe_attributes = params[:news] + @news.save_attachments(params[:attachments]) + if @news.save + render_attachment_warning_if_needed(@news) + flash[:notice] = l(:notice_successful_create) + redirect_to course_news_index_url(@course) + else + layout_file = 'base_courses' + render :action => 'new', :layout => layout_file + end + end + end + + def edit + end + + def update + @news.safe_attributes = params[:news] + @news.save_attachments(params[:attachments]) + if @news.save + render_attachment_warning_if_needed(@news) + flash[:notice] = l(:notice_successful_update) + redirect_to news_url(@news) + else + #flash[:error] = l(:notice_successful_update) + redirect_to news_url(@news) + end + end + + def destroy + @news.destroy + # modify by nwb + if @project + redirect_to project_news_index_url(@project) + elsif @course + redirect_to course_news_index_url(@course) + end + + end + + private + + def find_optional_project + return true unless params[:project_id] + @project = Project.find(params[:project_id]) + authorize + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/notificationcomments_controller.rb b/app/controllers/notificationcomments_controller.rb index 86345e9c6..9b7e5b249 100644 --- a/app/controllers/notificationcomments_controller.rb +++ b/app/controllers/notificationcomments_controller.rb @@ -1,36 +1,36 @@ -class NotificationcommentsController < ApplicationController - def show - - end - # default_search_scope :contestnotifications - # model_object Contestnotifications - # before_filter :authorize - - def create - #raise Unauthorized unless @contestnotifications.notificationcommentable? - @contest = Contest.find(params[:contest_id]) - @contestnotification = Contestnotification.find(params[:contestnotification_id]) - - # @notificaioncomment = Notificationcomment.new - # @notificaioncomment.safe_attributes = params[:notificationcomment] - # @notificaioncomment.author = User.current - comment = @contestnotification.notificationcomments.new(params[:notificationcomment].merge(author_id: User.current.id)) - if comment.save - flash[:notice] = l(:label_comment_added) - end - - redirect_to contest_contestnotification_url(@contest, @contestnotification) - end - - def destroy - @contest = Contest.find(params[:contest_id]) - @contestnotification = Contestnotification.find(params[:contestnotification_id]) - notificaioncomments = Notificationcomment.find(params[:id]) - notificaioncomments.destroy if notificaioncomments - #@contestnotifications = notificaioncomments.Contestnotification - #@contest = @contestnotifications.contest - #@contestnotifications.notificaioncomments.find(params[:notificaioncomment_id]).destroy - redirect_to contest_contestnotification_url(@contest,@contestnotification) - end - -end +class NotificationcommentsController < ApplicationController + def show + + end + # default_search_scope :contestnotifications + # model_object Contestnotifications + # before_filter :authorize + + def create + #raise Unauthorized unless @contestnotifications.notificationcommentable? + @contest = Contest.find(params[:contest_id]) + @contestnotification = Contestnotification.find(params[:contestnotification_id]) + + # @notificaioncomment = Notificationcomment.new + # @notificaioncomment.safe_attributes = params[:notificationcomment] + # @notificaioncomment.author = User.current + comment = @contestnotification.notificationcomments.new(params[:notificationcomment].merge(author_id: User.current.id)) + if comment.save + flash[:notice] = l(:label_comment_added) + end + + redirect_to contest_contestnotification_url(@contest, @contestnotification) + end + + def destroy + @contest = Contest.find(params[:contest_id]) + @contestnotification = Contestnotification.find(params[:contestnotification_id]) + notificaioncomments = Notificationcomment.find(params[:id]) + notificaioncomments.destroy if notificaioncomments + #@contestnotifications = notificaioncomments.Contestnotification + #@contest = @contestnotifications.contest + #@contestnotifications.notificaioncomments.find(params[:notificaioncomment_id]).destroy + redirect_to contest_contestnotification_url(@contest,@contestnotification) + end + +end diff --git a/app/controllers/open_source_projects_controller.rb b/app/controllers/open_source_projects_controller.rb index d4ac4027a..975bd669d 100644 --- a/app/controllers/open_source_projects_controller.rb +++ b/app/controllers/open_source_projects_controller.rb @@ -1,262 +1,262 @@ -class OpenSourceProjectsController < ApplicationController - - before_filter :find_osp, :only => [:master_apply, :accept_master_apply, :refuse_master_apply] - before_filter :require_master, :only => [:master_apply, :accept_master_apply, :refuse_master_apply] - - helper :sort - include SortHelper - helper :apply_project_masters - include ApplyProjectMastersHelper - helper :no_uses - include NoUsesHelper - # GET /open_source_projects - # GET /open_source_projects.json - def index - - @app_dir = params[:app_dir] - @language = params[:language] - @created_at = params[:created_at] - per_page_option = 10 - - @open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at) - @open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present? - - @os_project_count = @open_source_projects.count - @os_project_pages = Paginator.new @os_project_count, per_page_option, params['page'] - - @open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page) - - @bugs = BugToOsp.order('created_at desc').limit(8) - - # @open_source_projects = OpenSourceProject.all - - respond_to do |format| - format.html # index.html.erb - format.json { render json: @open_source_projects } - end - end - - def master_apply - @apply = @open_source_project.apply_tips - @applicants = @open_source_project.applicants - - respond_to do |format| - format.html { - render :layout => "base_opensource_p" - } - format.json { render json: @open_source_project } - end - end - - # GET /open_source_projects/1 - # GET /open_source_projects/1.json - def show - @open_source_project = OpenSourceProject.find(params[:id]) - - sort_init 'updated_at', 'desc' - sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", - 'replies' => "#{RelativeMemo.table_name}.replies_count", - 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" - - @memo = RelativeMemo.new(:open_source_project => @open_source_project) - @topic_count = @open_source_project.topics.count - @topic_pages = Paginator.new @topic_count, 10, params['page'] - @memos = @open_source_project.topics. - reorder("#{RelativeMemo.table_name}.sticky DESC"). - includes(:last_reply). - limit(@topic_pages.per_page). - offset(@topic_pages.offset). - order(sort_clause). - all - - @bugs = @open_source_project.bugs.limit(6) - - respond_to do |format| - format.html { - render :layout => "base_opensource_p" - } - format.json { render json: @open_source_project } - end - end - - def allbug - @bugs = BugToOsp.visible - - @bug_count = @bugs.count - @bug_pages = Paginator.new @bug_count, per_page_option, params['page'] - @bugs = @bugs.includes(:bug).reorder("#{RelativeMemo.table_name}.created_at DESC").limit(@bug_pages.per_page).offset(@bug_pages.offset).all - - respond_to do |format| - format.html - format.json { render json: @open_source_project } - end - end - - def search - - end - - def showbug - @open_source_project = OpenSourceProject.find(params[:id]) - - sort_init 'updated_at', 'desc' - sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", - 'replies' => "#{RelativeMemo.table_name}.replies_count", - 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" - - @memo = RelativeMemo.new(:open_source_project => @open_source_project) - @topic_count = @open_source_project.bugs.count - @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] - @memos = @open_source_project.bugs. - reorder("#{RelativeMemo.table_name}.sticky DESC"). - includes(:last_reply). - limit(@topic_pages.per_page). - offset(@topic_pages.offset). - order(sort_clause). - all - - respond_to do |format| - format.html { - render :layout => "base_opensource_p" - } - format.json { render json: @open_source_project } - end - end - - # added by yiang 暴力添加,请绕道 - def showmemo - @open_source_project = OpenSourceProject.find(params[:id]) - - sort_init 'updated_at', 'desc' - sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", - 'replies' => "#{RelativeMemo.table_name}.replies_count", - 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" - - @memo = RelativeMemo.new(:open_source_project => @open_source_project) - @topic_count = @open_source_project.topics.count - @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] - @memos = @open_source_project.topics. - reorder("#{RelativeMemo.table_name}.sticky DESC"). - includes(:last_reply). - limit(@topic_pages.per_page). - offset(@topic_pages.offset). - order(sort_clause). - all - - respond_to do |format| - format.html { - render :layout => "base_opensource_p" - } - format.json { render json: @open_source_project } - end - end - - # GET /open_source_projects/new - # GET /open_source_projects/new.json - def new - @open_source_project = OpenSourceProject.new - - respond_to do |format| - format.html # new.html.erb - format.json { render json: @open_source_project } - end - end - - # GET /open_source_projects/1/edit - def edit - @open_source_project = OpenSourceProject.find(params[:id]) - end - - # POST /open_source_projects - # POST /open_source_projects.json - def create - @open_source_project = OpenSourceProject.new(params[:open_source_project]) - - respond_to do |format| - if @open_source_project.save - format.html { redirect_to @open_source_project, notice: 'Open source project was successfully created.' } - format.json { render json: @open_source_project, status: :created, location: @open_source_project } - else - format.html { render action: "new" } - format.json { render json: @open_source_project.errors, status: :unprocessable_entity } - end - end - end - - # PUT /open_source_projects/1 - # PUT /open_source_projects/1.json - def update - @open_source_project = OpenSourceProject.find(params[:id]) - - respond_to do |format| - if @open_source_project.update_attributes(params[:open_source_project]) - format.html { redirect_to @open_source_project, notice: 'Open source project was successfully updated.' } - format.json { head :no_content } - else - format.html { render action: "edit" } - format.json { render json: @open_source_project.errors, status: :unprocessable_entity } - end - end - end - - # DELETE /open_source_projects/1 - # DELETE /open_source_projects/1.json - def destroy - @open_source_project = OpenSourceProject.find(params[:id]) - @open_source_project.destroy - - respond_to do |format| - format.html { redirect_to open_source_projects_url } - format.json { head :no_content } - end - end - - def remove_condition - @app_dir = params[:app_dir] - @language = params[:language] - @created_at = params[:created_at] - redirect_to open_source_projects_url(:app_dir => @app_dir, :language => @language, :created_at => @created_at, :name => params[:name]) - end - - def search - # per_page_option = 10 - # - # @open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at) - # @open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present? - # - # @os_project_count = @open_source_projects.count - # @os_project_pages = Paginator.new @os_project_count, per_page_option, params['page'] - # - # @open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page) - - redirect_to open_source_projects_url(:name => params[:name]) - - end - - def refuse_master_apply - @apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id) - @apply.first.destory - - redirect_to master_apply_open_source_project_url - end - - def accept_master_apply - @apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id) - if @apply.count == 1 - @apply.first.update_attributes(:status => 2) - end - - redirect_to master_apply_open_source_project_url - end - - private - - def require_master - render_403 unless @open_source_project.admin?(User.current) - end - - def find_osp - @open_source_project = OpenSourceProject.find(params[:id]) - render_404 unless @open_source_project.present? - end -end +class OpenSourceProjectsController < ApplicationController + + before_filter :find_osp, :only => [:master_apply, :accept_master_apply, :refuse_master_apply] + before_filter :require_master, :only => [:master_apply, :accept_master_apply, :refuse_master_apply] + + helper :sort + include SortHelper + helper :apply_project_masters + include ApplyProjectMastersHelper + helper :no_uses + include NoUsesHelper + # GET /open_source_projects + # GET /open_source_projects.json + def index + + @app_dir = params[:app_dir] + @language = params[:language] + @created_at = params[:created_at] + per_page_option = 10 + + @open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at) + @open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present? + + @os_project_count = @open_source_projects.count + @os_project_pages = Paginator.new @os_project_count, per_page_option, params['page'] + + @open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page) + + @bugs = BugToOsp.order('created_at desc').limit(8) + + # @open_source_projects = OpenSourceProject.all + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @open_source_projects } + end + end + + def master_apply + @apply = @open_source_project.apply_tips + @applicants = @open_source_project.applicants + + respond_to do |format| + format.html { + render :layout => "base_opensource_p" + } + format.json { render json: @open_source_project } + end + end + + # GET /open_source_projects/1 + # GET /open_source_projects/1.json + def show + @open_source_project = OpenSourceProject.find(params[:id]) + + sort_init 'updated_at', 'desc' + sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", + 'replies' => "#{RelativeMemo.table_name}.replies_count", + 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" + + @memo = RelativeMemo.new(:open_source_project => @open_source_project) + @topic_count = @open_source_project.topics.count + @topic_pages = Paginator.new @topic_count, 10, params['page'] + @memos = @open_source_project.topics. + reorder("#{RelativeMemo.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + all + + @bugs = @open_source_project.bugs.limit(6) + + respond_to do |format| + format.html { + render :layout => "base_opensource_p" + } + format.json { render json: @open_source_project } + end + end + + def allbug + @bugs = BugToOsp.visible + + @bug_count = @bugs.count + @bug_pages = Paginator.new @bug_count, per_page_option, params['page'] + @bugs = @bugs.includes(:bug).reorder("#{RelativeMemo.table_name}.created_at DESC").limit(@bug_pages.per_page).offset(@bug_pages.offset).all + + respond_to do |format| + format.html + format.json { render json: @open_source_project } + end + end + + def search + + end + + def showbug + @open_source_project = OpenSourceProject.find(params[:id]) + + sort_init 'updated_at', 'desc' + sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", + 'replies' => "#{RelativeMemo.table_name}.replies_count", + 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" + + @memo = RelativeMemo.new(:open_source_project => @open_source_project) + @topic_count = @open_source_project.bugs.count + @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + @memos = @open_source_project.bugs. + reorder("#{RelativeMemo.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + all + + respond_to do |format| + format.html { + render :layout => "base_opensource_p" + } + format.json { render json: @open_source_project } + end + end + + # added by yiang 暴力添加,请绕道 + def showmemo + @open_source_project = OpenSourceProject.find(params[:id]) + + sort_init 'updated_at', 'desc' + sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", + 'replies' => "#{RelativeMemo.table_name}.replies_count", + 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" + + @memo = RelativeMemo.new(:open_source_project => @open_source_project) + @topic_count = @open_source_project.topics.count + @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + @memos = @open_source_project.topics. + reorder("#{RelativeMemo.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + all + + respond_to do |format| + format.html { + render :layout => "base_opensource_p" + } + format.json { render json: @open_source_project } + end + end + + # GET /open_source_projects/new + # GET /open_source_projects/new.json + def new + @open_source_project = OpenSourceProject.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @open_source_project } + end + end + + # GET /open_source_projects/1/edit + def edit + @open_source_project = OpenSourceProject.find(params[:id]) + end + + # POST /open_source_projects + # POST /open_source_projects.json + def create + @open_source_project = OpenSourceProject.new(params[:open_source_project]) + + respond_to do |format| + if @open_source_project.save + format.html { redirect_to @open_source_project, notice: 'Open source project was successfully created.' } + format.json { render json: @open_source_project, status: :created, location: @open_source_project } + else + format.html { render action: "new" } + format.json { render json: @open_source_project.errors, status: :unprocessable_entity } + end + end + end + + # PUT /open_source_projects/1 + # PUT /open_source_projects/1.json + def update + @open_source_project = OpenSourceProject.find(params[:id]) + + respond_to do |format| + if @open_source_project.update_attributes(params[:open_source_project]) + format.html { redirect_to @open_source_project, notice: 'Open source project was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @open_source_project.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /open_source_projects/1 + # DELETE /open_source_projects/1.json + def destroy + @open_source_project = OpenSourceProject.find(params[:id]) + @open_source_project.destroy + + respond_to do |format| + format.html { redirect_to open_source_projects_url } + format.json { head :no_content } + end + end + + def remove_condition + @app_dir = params[:app_dir] + @language = params[:language] + @created_at = params[:created_at] + redirect_to open_source_projects_url(:app_dir => @app_dir, :language => @language, :created_at => @created_at, :name => params[:name]) + end + + def search + # per_page_option = 10 + # + # @open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at) + # @open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present? + # + # @os_project_count = @open_source_projects.count + # @os_project_pages = Paginator.new @os_project_count, per_page_option, params['page'] + # + # @open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page) + + redirect_to open_source_projects_url(:name => params[:name]) + + end + + def refuse_master_apply + @apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id) + @apply.first.destory + + redirect_to master_apply_open_source_project_url + end + + def accept_master_apply + @apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id) + if @apply.count == 1 + @apply.first.update_attributes(:status => 2) + end + + redirect_to master_apply_open_source_project_url + end + + private + + def require_master + render_403 unless @open_source_project.admin?(User.current) + end + + def find_osp + @open_source_project = OpenSourceProject.find(params[:id]) + render_404 unless @open_source_project.present? + end +end diff --git a/app/controllers/project_enumerations_controller.rb b/app/controllers/project_enumerations_controller.rb index 0534deed6..bb84dd2be 100644 --- a/app/controllers/project_enumerations_controller.rb +++ b/app/controllers/project_enumerations_controller.rb @@ -1,42 +1,42 @@ -# 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 ProjectEnumerationsController < ApplicationController - before_filter :find_project_by_project_id - before_filter :authorize - - def update - if request.put? && params[:enumerations] - Project.transaction do - params[:enumerations].each do |id, activity| - @project.update_or_create_time_entry_activity(id, activity) - end - end - flash[:notice] = l(:notice_successful_update) - end - - redirect_to settings_project_url(@project, :tab => 'activities') - end - - def destroy - @project.time_entry_activities.each do |time_entry_activity| - time_entry_activity.destroy(time_entry_activity.parent) - end - flash[:notice] = l(:notice_successful_update) - redirect_to settings_project_url(@project, :tab => 'activities') - 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 ProjectEnumerationsController < ApplicationController + before_filter :find_project_by_project_id + before_filter :authorize + + def update + if request.put? && params[:enumerations] + Project.transaction do + params[:enumerations].each do |id, activity| + @project.update_or_create_time_entry_activity(id, activity) + end + end + flash[:notice] = l(:notice_successful_update) + end + + redirect_to settings_project_url(@project, :tab => 'activities') + end + + def destroy + @project.time_entry_activities.each do |time_entry_activity| + time_entry_activity.destroy(time_entry_activity.parent) + end + flash[:notice] = l(:notice_successful_update) + redirect_to settings_project_url(@project, :tab => 'activities') + end +end diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index d9a933c68..de1fa2a21 100644 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -1,106 +1,106 @@ -# 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 QueriesController < ApplicationController - menu_item :issues - before_filter :find_query, :except => [:new, :create, :index] - before_filter :find_optional_project, :only => [:new, :create] - - accept_api_auth :index - - include QueriesHelper - - def index - case params[:format] - when 'xml', 'json' - @offset, @limit = api_offset_and_limit - else - @limit = per_page_option - end - - @query_count = IssueQuery.visible.count - @query_pages = Paginator.new @query_count, @limit, params['page'] - @queries = IssueQuery.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name") - - respond_to do |format| - format.api - end - end - - def new - @query = IssueQuery.new - @query.user = User.current - @query.project = @project - @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin? - @query.build_from_params(params) - end - - def create - @query = IssueQuery.new(params[:query]) - @query.user = User.current - @query.project = params[:query_is_for_all] ? nil : @project - @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin? - @query.build_from_params(params) - @query.column_names = nil if params[:default_columns] - - if @query.save - flash[:notice] = l(:notice_successful_create) - redirect_to _project_issues_url(@project, :query_id => @query) - else - render :action => 'new', :layout => !request.xhr? - end - end - - def edit - end - - def update - @query.attributes = params[:query] - @query.project = nil if params[:query_is_for_all] - @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin? - @query.build_from_params(params) - @query.column_names = nil if params[:default_columns] - - if @query.save - flash[:notice] = l(:notice_successful_update) - redirect_to _project_issues_url(@project, :query_id => @query) - else - render :action => 'edit' - end - end - - def destroy - @query.destroy - redirect_to _project_issues_url(@project, :set_filter => 1) - end - -private - def find_query - @query = IssueQuery.find(params[:id]) - @project = @query.project - render_403 unless @query.editable_by?(User.current) - rescue ActiveRecord::RecordNotFound - render_404 - end - - def find_optional_project - @project = Project.find(params[:project_id]) if params[:project_id] - render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true) - 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. + +class QueriesController < ApplicationController + menu_item :issues + before_filter :find_query, :except => [:new, :create, :index] + before_filter :find_optional_project, :only => [:new, :create] + + accept_api_auth :index + + include QueriesHelper + + def index + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit + else + @limit = per_page_option + end + + @query_count = IssueQuery.visible.count + @query_pages = Paginator.new @query_count, @limit, params['page'] + @queries = IssueQuery.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name") + + respond_to do |format| + format.api + end + end + + def new + @query = IssueQuery.new + @query.user = User.current + @query.project = @project + @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin? + @query.build_from_params(params) + end + + def create + @query = IssueQuery.new(params[:query]) + @query.user = User.current + @query.project = params[:query_is_for_all] ? nil : @project + @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin? + @query.build_from_params(params) + @query.column_names = nil if params[:default_columns] + + if @query.save + flash[:notice] = l(:notice_successful_create) + redirect_to _project_issues_url(@project, :query_id => @query) + else + render :action => 'new', :layout => !request.xhr? + end + end + + def edit + end + + def update + @query.attributes = params[:query] + @query.project = nil if params[:query_is_for_all] + @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin? + @query.build_from_params(params) + @query.column_names = nil if params[:default_columns] + + if @query.save + flash[:notice] = l(:notice_successful_update) + redirect_to _project_issues_url(@project, :query_id => @query) + else + render :action => 'edit' + end + end + + def destroy + @query.destroy + redirect_to _project_issues_url(@project, :set_filter => 1) + end + +private + def find_query + @query = IssueQuery.find(params[:id]) + @project = @query.project + render_403 unless @query.editable_by?(User.current) + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_optional_project + @project = Project.find(params[:project_id]) if params[:project_id] + render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true) + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 5d1ab45d9..20ad4a7f3 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -1,108 +1,108 @@ -# 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 RolesController < ApplicationController - layout 'admin' - - before_filter :require_admin, :except => [:index, :show] - before_filter :require_admin_or_api_request, :only => [:index, :show] - before_filter :find_role, :only => [:show, :edit, :update, :destroy] - accept_api_auth :index, :show - - def index - respond_to do |format| - format.html { - @role_pages, @roles = paginate Role.sorted, :per_page => 25 - render :action => "index", :layout => false if request.xhr? - } - format.api { - @roles = Role.givable.all - } - end - end - - def show - respond_to do |format| - format.api - end - end - - def new - # Prefills the form with 'Non member' role permissions by default - @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions}) - if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy]) - @role.copy_from(@copy_from) - end - @roles = Role.sorted.all - end - - def create - @role = Role.new(params[:role]) - if request.post? && @role.save - # workflow copy - if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from])) - @role.workflow_rules.copy(copy_from) - end - flash[:notice] = l(:notice_successful_create) - redirect_to roles_url - else - @roles = Role.sorted.all - render :action => 'new' - end - end - - def edit - end - - def update - if request.put? and @role.update_attributes(params[:role]) - flash[:notice] = l(:notice_successful_update) - redirect_to roles_url - else - render :action => 'edit' - end - end - - def destroy - @role.destroy - redirect_to roles_url - rescue - flash[:error] = l(:error_can_not_remove_role) - redirect_to roles_url - end - - def permissions - @roles = Role.sorted.all - @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? } - if request.post? - @roles.each do |role| - role.permissions = params[:permissions][role.id.to_s] - role.save - end - flash[:notice] = l(:notice_successful_update) - redirect_to roles_url - end - end - - private - - def find_role - @role = Role.find(params[:id]) - 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. + +class RolesController < ApplicationController + layout 'admin' + + before_filter :require_admin, :except => [:index, :show] + before_filter :require_admin_or_api_request, :only => [:index, :show] + before_filter :find_role, :only => [:show, :edit, :update, :destroy] + accept_api_auth :index, :show + + def index + respond_to do |format| + format.html { + @role_pages, @roles = paginate Role.sorted, :per_page => 25 + render :action => "index", :layout => false if request.xhr? + } + format.api { + @roles = Role.givable.all + } + end + end + + def show + respond_to do |format| + format.api + end + end + + def new + # Prefills the form with 'Non member' role permissions by default + @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions}) + if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy]) + @role.copy_from(@copy_from) + end + @roles = Role.sorted.all + end + + def create + @role = Role.new(params[:role]) + if request.post? && @role.save + # workflow copy + if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from])) + @role.workflow_rules.copy(copy_from) + end + flash[:notice] = l(:notice_successful_create) + redirect_to roles_url + else + @roles = Role.sorted.all + render :action => 'new' + end + end + + def edit + end + + def update + if request.put? and @role.update_attributes(params[:role]) + flash[:notice] = l(:notice_successful_update) + redirect_to roles_url + else + render :action => 'edit' + end + end + + def destroy + @role.destroy + redirect_to roles_url + rescue + flash[:error] = l(:error_can_not_remove_role) + redirect_to roles_url + end + + def permissions + @roles = Role.sorted.all + @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? } + if request.post? + @roles.each do |role| + role.permissions = params[:permissions][role.id.to_s] + role.save + end + flash[:notice] = l(:notice_successful_update) + redirect_to roles_url + end + end + + private + + def find_role + @role = Role.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 112bc173e..67b80dbe9 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,111 +1,111 @@ -# 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 SearchController < ApplicationController - before_filter :find_optional_project - - def index - @question = params[:q] || "" - @question.strip! - @all_words = params[:all_words] ? params[:all_words].present? : true - @titles_only = params[:titles_only] ? params[:titles_only].present? : false - - projects_to_search = - case params[:scope] - when 'all' - nil - when 'my_projects' - User.current.memberships.collect(&:project) - when 'subprojects' - @project ? (@project.self_and_descendants.active.all) : nil - else - @project - end - - offset = nil - begin; offset = params[:offset].to_time if params[:offset]; rescue; end - - # quick jump to an issue - if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i)) - redirect_to issue_url(issue) - return - end - - @object_types = Redmine::Search.available_search_types.dup - if projects_to_search.is_a? Project - # don't search projects - @object_types.delete('projects') - # only show what the user is allowed to view - @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)} - end - - @scope = @object_types.select {|t| params[t]} - @scope = @object_types if @scope.empty? - - # extract tokens from the question - # eg. hello "bye bye" => ["hello", "bye bye"] - @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')} - # tokens must be at least 2 characters long - @tokens = @tokens.uniq.select {|w| w.length > 1 } - - if !@tokens.empty? - # no more than 5 tokens to search for - @tokens.slice! 5..-1 if @tokens.size > 5 - - @results = [] - @results_by_type = Hash.new {|h,k| h[k] = 0} - - limit = 10 - @scope.each do |s| - r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search, - :all_words => @all_words, - :titles_only => @titles_only, - :limit => (limit+1), - :offset => offset, - :before => params[:previous].nil?) - @results += r - @results_by_type[s] += c - end - @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime} - if params[:previous].nil? - @pagination_previous_date = @results[0].event_datetime if offset && @results[0] - if @results.size > limit - @pagination_next_date = @results[limit-1].event_datetime - @results = @results[0, limit] - end - else - @pagination_next_date = @results[-1].event_datetime if offset && @results[-1] - if @results.size > limit - @pagination_previous_date = @results[-(limit)].event_datetime - @results = @results[-(limit), limit] - end - end - else - @question = "" - end - render :layout => false if request.xhr? - end - -private - def find_optional_project - return true unless params[:id] - @project = Project.find(params[:id]) - check_project_privacy - 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. + +class SearchController < ApplicationController + before_filter :find_optional_project + + def index + @question = params[:q] || "" + @question.strip! + @all_words = params[:all_words] ? params[:all_words].present? : true + @titles_only = params[:titles_only] ? params[:titles_only].present? : false + + projects_to_search = + case params[:scope] + when 'all' + nil + when 'my_projects' + User.current.memberships.collect(&:project) + when 'subprojects' + @project ? (@project.self_and_descendants.active.all) : nil + else + @project + end + + offset = nil + begin; offset = params[:offset].to_time if params[:offset]; rescue; end + + # quick jump to an issue + if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i)) + redirect_to issue_url(issue) + return + end + + @object_types = Redmine::Search.available_search_types.dup + if projects_to_search.is_a? Project + # don't search projects + @object_types.delete('projects') + # only show what the user is allowed to view + @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)} + end + + @scope = @object_types.select {|t| params[t]} + @scope = @object_types if @scope.empty? + + # extract tokens from the question + # eg. hello "bye bye" => ["hello", "bye bye"] + @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')} + # tokens must be at least 2 characters long + @tokens = @tokens.uniq.select {|w| w.length > 1 } + + if !@tokens.empty? + # no more than 5 tokens to search for + @tokens.slice! 5..-1 if @tokens.size > 5 + + @results = [] + @results_by_type = Hash.new {|h,k| h[k] = 0} + + limit = 10 + @scope.each do |s| + r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search, + :all_words => @all_words, + :titles_only => @titles_only, + :limit => (limit+1), + :offset => offset, + :before => params[:previous].nil?) + @results += r + @results_by_type[s] += c + end + @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime} + if params[:previous].nil? + @pagination_previous_date = @results[0].event_datetime if offset && @results[0] + if @results.size > limit + @pagination_next_date = @results[limit-1].event_datetime + @results = @results[0, limit] + end + else + @pagination_next_date = @results[-1].event_datetime if offset && @results[-1] + if @results.size > limit + @pagination_previous_date = @results[-(limit)].event_datetime + @results = @results[-(limit), limit] + end + end + else + @question = "" + end + render :layout => false if request.xhr? + end + +private + def find_optional_project + return true unless params[:id] + @project = Project.find(params[:id]) + check_project_privacy + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index a3f07e21a..c60d1bd8f 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -1,73 +1,73 @@ -# 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 SettingsController < ApplicationController - layout 'admin' - menu_item :plugins, :only => :plugin - - helper :queries - - before_filter :require_admin - - def index - edit - render :action => 'edit' - end - - def edit - @notifiables = Redmine::Notifiable.all - if request.post? && params[:settings] && params[:settings].is_a?(Hash) - settings = (params[:settings] || {}).dup.symbolize_keys - settings.each do |name, value| - # remove blank values in array settings - value.delete_if {|v| v.blank? } if value.is_a?(Array) - Setting[name] = value - end - flash[:notice] = l(:notice_successful_update) - redirect_to settings_url(:tab => params[:tab]) - else - @options = {} - user_format = User::USER_FORMATS.collect{|key, value| [key, value[:setting_order]]}.sort{|a, b| a[1] <=> b[1]} - @options[:user_format] = user_format.collect{|f| [User.current.name(f[0]), f[0].to_s]} - @deliveries = ActionMailer::Base.perform_deliveries - - @guessed_host_and_path = request.host_with_port.dup - @guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank? - - Redmine::Themes.rescan - end - end - - def plugin - @plugin = Redmine::Plugin.find(params[:id]) - unless @plugin.configurable? - render_404 - return - end - - if request.post? - Setting.send "plugin_#{@plugin.id}=", params[:settings] - flash[:notice] = l(:notice_successful_update) - redirect_to plugin_settings_url(@plugin) - else - @partial = @plugin.settings[:partial] - @settings = Setting.send "plugin_#{@plugin.id}" - end - rescue Redmine::PluginNotFound - 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. + +class SettingsController < ApplicationController + layout 'admin' + menu_item :plugins, :only => :plugin + + helper :queries + + before_filter :require_admin + + def index + edit + render :action => 'edit' + end + + def edit + @notifiables = Redmine::Notifiable.all + if request.post? && params[:settings] && params[:settings].is_a?(Hash) + settings = (params[:settings] || {}).dup.symbolize_keys + settings.each do |name, value| + # remove blank values in array settings + value.delete_if {|v| v.blank? } if value.is_a?(Array) + Setting[name] = value + end + flash[:notice] = l(:notice_successful_update) + redirect_to settings_url(:tab => params[:tab]) + else + @options = {} + user_format = User::USER_FORMATS.collect{|key, value| [key, value[:setting_order]]}.sort{|a, b| a[1] <=> b[1]} + @options[:user_format] = user_format.collect{|f| [User.current.name(f[0]), f[0].to_s]} + @deliveries = ActionMailer::Base.perform_deliveries + + @guessed_host_and_path = request.host_with_port.dup + @guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank? + + Redmine::Themes.rescan + end + end + + def plugin + @plugin = Redmine::Plugin.find(params[:id]) + unless @plugin.configurable? + render_404 + return + end + + if request.post? + Setting.send "plugin_#{@plugin.id}=", params[:settings] + flash[:notice] = l(:notice_successful_update) + redirect_to plugin_settings_url(@plugin) + else + @partial = @plugin.settings[:partial] + @settings = Setting.send "plugin_#{@plugin.id}" + end + rescue Redmine::PluginNotFound + render_404 + end +end diff --git a/app/controllers/softapplications_controller.rb b/app/controllers/softapplications_controller.rb index 5d87bebb6..0c7e2ade1 100644 --- a/app/controllers/softapplications_controller.rb +++ b/app/controllers/softapplications_controller.rb @@ -1,356 +1,356 @@ -class SoftapplicationsController < ApplicationController - layout "contest_base" - before_filter :find_softapplication, only: [:edit, :update, :destroy] - before_filter :editable, only: [:edit, :update] - before_filter :destroyable, only: :destroy - - # GET /softapplications - # GET /softapplications.json - def index - @softapplications = Softapplication.all - - #new added fenyefunction - @limit = 5 - @softapplication_count = @softapplications.count - @softapplication_pages = Paginator.new @softapplication_count, @limit, params['page'] - @offset ||= @softapplication_pages.offset - #@softapplications = @softapplications[@offset,@limit] - #new added end - - #new added sort - if params[:softapplication_sort_type].present? - case params[:softapplication_sort_type] - when '0' - @softapplications = @softapplications[@offset, @limit] - @s_state = 0 - when '1' - @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] - @s_state = 1 - end - else - @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] - @s_state = 1 - end - #new added end - - respond_to do |format| - format.html # index.html.erb - format.json { render json: @softapplications } - end - end - - # GET /softapplications/1 - # GET /softapplications/1.json - - def percent_of(num, percent) - num.to_f / percent.to_f * 100.0 - end - - def show - @softapplication = Softapplication.find(params[:id]) - @project = @softapplication.project - # 打分统计 - stars_reates = @softapplication. - rates(:quality) - stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count - stars_status = stars_reates.select("stars, count(*) as scount"). - group("stars") - - @stars_status_map = Hash.new(0.0) - stars_status.each do |star_status| - percent = percent_of(star_status.scount, stars_reates_count).to_f - percent_m = format("%.2f", percent) - @stars_status_map["star#{star_status.stars.to_i}".to_sym] = - percent_m.to_s + "%" - end - @jours = @softapplication.journals_for_messages.order('created_on DESC') - @image_results = [] - @softapplication.attachments.each do |f| - f.image? ? @image_results << f : @image_results - end - @app_items = [] - @softapplication.attachments.each do |f| - f.pack? ? @app_items << f : @app_items - 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 - respond_to do |format| - format.html # show.html.erb - format.json { render json: @softapplication } - end - end - - # GET /softapplications/new - # GET /softapplications/new.json - def new - @softapplication = Softapplication.new - - #添加当前用户创建过的项目作为托管项目(下拉项目列表) - project = Project.find(params[:user_id]) - #end - - respond_to do |format| - format.html # new.html.erb - format.json { render json: @softapplication } - end - end - - # GET /softapplications/1/edit - def edit - @softapplication = Softapplication.find(params[:id]) - - @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) - @option = [] - # @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) - @option << membership.project - end - end - end - - end - - # POST /softapplications - # POST /softapplications.json - # def create - # @softapplication = Softapplication.new(params[:softapplication]) - # @softapplication.user = User.current - # @softapplication.save_attachments(params[:attachments]) - # respond_to do |format| - # if @softapplication.save - # format.js - # format.html { redirect_to @softapplication, notice: 'Softapplication was successfully created.' } - # # format.json { render json: @softapplication, status: :created, location: @softapplication } - # else - # format.js { render status: 406 } - # format.html { render action: "new" } - # # format.json { render json: @softapplication.errors, status: :unprocessable_entity } - # end - # end - # end - - -#new changed created function - def create - #options = params[:softapplication] - #options[:app_type_name] = params[:other_input] if options[:app_type_name] == "其他" && params[:other_input] - @softapplication = Softapplication.new(params[:softapplication]) - @softapplication.user = User.current - #@softapplication.deposit_project = params[:project] - @softapplication.project = Project.find_by_id(params[:project]) - @softapplication.app_type_name = params[:other_input] if params[:other_input] != "" - @softapplication.save_attachments(params[:attachments]) - respond_to do |format| - if @softapplication.save - ContestingSoftapplication.create(:contest_id => params[:contest_id], :softapplication_id => @softapplication.id) - #ProjectingSoftapplication.create_softapplication_projecting(:project_id => params[:project_id], :softapplication_id => @softapplication.id) - #ProjectingSoftapplication.create_softapplication_projecting(@project.id, softapplication.id) - format.html { redirect_to show_attendingcontest_contest_url(:id => params[:contest_id]), notice: l(:notice_attendingcontest_work_successfully_created) } - # format.json { render json: @softapplication, status: :created, location: @softapplication } - else - #format.js { render status: 406 } - format.html { render action: "contests/show_attendingcontest" } - # format.json { render json: @softapplication.errors, status: :unprocessable_entity } - end - end - #关联新建的参赛作品 - - # @contesting_softapplication = paginateHelper @contest.contesting_softapplications - - - - end - # PUT /softapplications/1 - # PUT /softapplications/1.json - def update - # @softapplication = Softapplication.find(params[:id]) - #@softapplication.attachments.map{|attach| attach.destroy } - @softapplication.save_attachments(params[:attachments]) if params[:attachments] - #@softapplication.deposit_project = params[:project] - @softapplication.project = Project.find_by_id(params[:project]) - - @softapplication.name = params[:softapplication][:name] - @softapplication.android_min_version_available = params[:softapplication][:android_min_version_available] - @softapplication.app_type_name = params[:other_input] == "" ? params[:softapplication][:app_type_name] : params[:other_input] - @softapplication.description = params[:softapplication][:description] - @softapplication.application_developers = params[:softapplication][:application_developers] - #@softapplication.app_type_name = params[:other_input] if params[:other_input] != "" - respond_to do |format| - #if @softapplication.update_attributes(params[:softapplication]) - if @softapplication.save - format.html { redirect_to @softapplication, notice: l(:notice_softapplication_was_successfully_updated) } - format.json { head :no_content } - else - format.html { render action: "edit" } - format.json { render json: @softapplication.errors, status: :unprocessable_entity } - end - end - end - - def add_attach - @softapplication = Softapplication.find(params[:id]) - @softapplication.save_attachments(params[:attachments]) - end - - # DELETE /softapplications/1 - # DELETE /softapplications/1.json - def destroy - # @softapplication = Softapplication.find(params[:id]) - @softapplication.destroy - - respond_to do |format| - format.html { redirect_to home_url } - format.json { head :no_content } - end - end - - #应用评价涉及到的方法 - def new_message - @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] - if @jour - user = @jour.user - text = @jour.notes - else - user = @softapplication.user - text = @softapplication.description - end - text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') - @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " - @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - @id = user.id - rescue ActiveRecord::RecordNotFound - render_404 - end - - #新建评价 - def create_message - - if params[:reference_content] - message = params[:softapplication_message][:message] + "\n" + params[:reference_content] - else - message = params[:softapplication_message][:message] - end - refer_user_id = params[:softapplication_message][:reference_user_id].to_i - @softapplication = Softapplication.find(params[:id]) - @softapplication.add_jour(User.current, message, refer_user_id) - - - @user = @softapplication.user - @jours = @softapplication.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - #@softapplication.set_commit(@feedback_count) - - respond_to do |format| - format.js - end - - end - - ##删除评价 - def destroy_message - @user = @softapplication.user - if User.current.admin? || User.current.id == @user.id - JournalsForMessage.delete_message(params[:object_id]) - end - @jours = @softapplication.journals_for_messages.reverse - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - - @softapplication.set_commit(@feedback_count) - respond_to do |format| - format.js - end - end - - # - def more - @jour = @softapplication.journals_for_messages - @jour.each_with_index {|j,i| j.indice = i+1} - @state = true - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - # - def back - @jour = @softapplication.journals_for_messages - @jour.each_with_index {|j,i| j.indice = i+1} - @state = false - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - def search - @softapplications = Softapplication.where("name like '%#{params[:name]}%'") - - #new added fenyefunction - @limit = 5 - @softapplication_count = @softapplications.count - @softapplication_pages = Paginator.new @softapplication_count, @limit, params['page'] - @offset ||= @softapplication_pages.offset - - #new added sort - if params[:softapplication_sort_type].present? - case params[:softapplication_sort_type] - when '0' - @softapplications = @softapplications[@offset, @limit] - @s_state = 0 - when '1' - @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] - @s_state = 1 - end - else - @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] - @s_state = 1 - end - #new added end - - respond_to do |format| - format.html - end - end - - private - def find_softapplication - @softapplication = Softapplication.find_by_id(params[:id]) - end - - def editable - unless @softapplication.editable_by? User.current - render_403 - return false - end - end - - def destroyable - unless @softapplication.destroyable_by? User.current - render_403 - return false - end - end - -end +class SoftapplicationsController < ApplicationController + layout "contest_base" + before_filter :find_softapplication, only: [:edit, :update, :destroy] + before_filter :editable, only: [:edit, :update] + before_filter :destroyable, only: :destroy + + # GET /softapplications + # GET /softapplications.json + def index + @softapplications = Softapplication.all + + #new added fenyefunction + @limit = 5 + @softapplication_count = @softapplications.count + @softapplication_pages = Paginator.new @softapplication_count, @limit, params['page'] + @offset ||= @softapplication_pages.offset + #@softapplications = @softapplications[@offset,@limit] + #new added end + + #new added sort + if params[:softapplication_sort_type].present? + case params[:softapplication_sort_type] + when '0' + @softapplications = @softapplications[@offset, @limit] + @s_state = 0 + when '1' + @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] + @s_state = 1 + end + else + @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] + @s_state = 1 + end + #new added end + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @softapplications } + end + end + + # GET /softapplications/1 + # GET /softapplications/1.json + + def percent_of(num, percent) + num.to_f / percent.to_f * 100.0 + end + + def show + @softapplication = Softapplication.find(params[:id]) + @project = @softapplication.project + # 打分统计 + stars_reates = @softapplication. + rates(:quality) + stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count + stars_status = stars_reates.select("stars, count(*) as scount"). + group("stars") + + @stars_status_map = Hash.new(0.0) + stars_status.each do |star_status| + percent = percent_of(star_status.scount, stars_reates_count).to_f + percent_m = format("%.2f", percent) + @stars_status_map["star#{star_status.stars.to_i}".to_sym] = + percent_m.to_s + "%" + end + @jours = @softapplication.journals_for_messages.order('created_on DESC') + @image_results = [] + @softapplication.attachments.each do |f| + f.image? ? @image_results << f : @image_results + end + @app_items = [] + @softapplication.attachments.each do |f| + f.pack? ? @app_items << f : @app_items + 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 + respond_to do |format| + format.html # show.html.erb + format.json { render json: @softapplication } + end + end + + # GET /softapplications/new + # GET /softapplications/new.json + def new + @softapplication = Softapplication.new + + #添加当前用户创建过的项目作为托管项目(下拉项目列表) + project = Project.find(params[:user_id]) + #end + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @softapplication } + end + end + + # GET /softapplications/1/edit + def edit + @softapplication = Softapplication.find(params[:id]) + + @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + @option = [] + # @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) + @option << membership.project + end + end + end + + end + + # POST /softapplications + # POST /softapplications.json + # def create + # @softapplication = Softapplication.new(params[:softapplication]) + # @softapplication.user = User.current + # @softapplication.save_attachments(params[:attachments]) + # respond_to do |format| + # if @softapplication.save + # format.js + # format.html { redirect_to @softapplication, notice: 'Softapplication was successfully created.' } + # # format.json { render json: @softapplication, status: :created, location: @softapplication } + # else + # format.js { render status: 406 } + # format.html { render action: "new" } + # # format.json { render json: @softapplication.errors, status: :unprocessable_entity } + # end + # end + # end + + +#new changed created function + def create + #options = params[:softapplication] + #options[:app_type_name] = params[:other_input] if options[:app_type_name] == "其他" && params[:other_input] + @softapplication = Softapplication.new(params[:softapplication]) + @softapplication.user = User.current + #@softapplication.deposit_project = params[:project] + @softapplication.project = Project.find_by_id(params[:project]) + @softapplication.app_type_name = params[:other_input] if params[:other_input] != "" + @softapplication.save_attachments(params[:attachments]) + respond_to do |format| + if @softapplication.save + ContestingSoftapplication.create(:contest_id => params[:contest_id], :softapplication_id => @softapplication.id) + #ProjectingSoftapplication.create_softapplication_projecting(:project_id => params[:project_id], :softapplication_id => @softapplication.id) + #ProjectingSoftapplication.create_softapplication_projecting(@project.id, softapplication.id) + format.html { redirect_to show_attendingcontest_contest_url(:id => params[:contest_id]), notice: l(:notice_attendingcontest_work_successfully_created) } + # format.json { render json: @softapplication, status: :created, location: @softapplication } + else + #format.js { render status: 406 } + format.html { render action: "contests/show_attendingcontest" } + # format.json { render json: @softapplication.errors, status: :unprocessable_entity } + end + end + #关联新建的参赛作品 + + # @contesting_softapplication = paginateHelper @contest.contesting_softapplications + + + + end + # PUT /softapplications/1 + # PUT /softapplications/1.json + def update + # @softapplication = Softapplication.find(params[:id]) + #@softapplication.attachments.map{|attach| attach.destroy } + @softapplication.save_attachments(params[:attachments]) if params[:attachments] + #@softapplication.deposit_project = params[:project] + @softapplication.project = Project.find_by_id(params[:project]) + + @softapplication.name = params[:softapplication][:name] + @softapplication.android_min_version_available = params[:softapplication][:android_min_version_available] + @softapplication.app_type_name = params[:other_input] == "" ? params[:softapplication][:app_type_name] : params[:other_input] + @softapplication.description = params[:softapplication][:description] + @softapplication.application_developers = params[:softapplication][:application_developers] + #@softapplication.app_type_name = params[:other_input] if params[:other_input] != "" + respond_to do |format| + #if @softapplication.update_attributes(params[:softapplication]) + if @softapplication.save + format.html { redirect_to @softapplication, notice: l(:notice_softapplication_was_successfully_updated) } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @softapplication.errors, status: :unprocessable_entity } + end + end + end + + def add_attach + @softapplication = Softapplication.find(params[:id]) + @softapplication.save_attachments(params[:attachments]) + end + + # DELETE /softapplications/1 + # DELETE /softapplications/1.json + def destroy + # @softapplication = Softapplication.find(params[:id]) + @softapplication.destroy + + respond_to do |format| + format.html { redirect_to home_url } + format.json { head :no_content } + end + end + + #应用评价涉及到的方法 + def new_message + @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] + if @jour + user = @jour.user + text = @jour.notes + else + user = @softapplication.user + text = @softapplication.description + end + text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') + @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " + @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + @id = user.id + rescue ActiveRecord::RecordNotFound + render_404 + end + + #新建评价 + def create_message + + if params[:reference_content] + message = params[:softapplication_message][:message] + "\n" + params[:reference_content] + else + message = params[:softapplication_message][:message] + end + refer_user_id = params[:softapplication_message][:reference_user_id].to_i + @softapplication = Softapplication.find(params[:id]) + @softapplication.add_jour(User.current, message, refer_user_id) + + + @user = @softapplication.user + @jours = @softapplication.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + #@softapplication.set_commit(@feedback_count) + + respond_to do |format| + format.js + end + + end + + ##删除评价 + def destroy_message + @user = @softapplication.user + if User.current.admin? || User.current.id == @user.id + JournalsForMessage.delete_message(params[:object_id]) + end + @jours = @softapplication.journals_for_messages.reverse + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + + @softapplication.set_commit(@feedback_count) + respond_to do |format| + format.js + end + end + + # + def more + @jour = @softapplication.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = true + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + # + def back + @jour = @softapplication.journals_for_messages + @jour.each_with_index {|j,i| j.indice = i+1} + @state = false + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def search + @softapplications = Softapplication.where("name like '%#{params[:name]}%'") + + #new added fenyefunction + @limit = 5 + @softapplication_count = @softapplications.count + @softapplication_pages = Paginator.new @softapplication_count, @limit, params['page'] + @offset ||= @softapplication_pages.offset + + #new added sort + if params[:softapplication_sort_type].present? + case params[:softapplication_sort_type] + when '0' + @softapplications = @softapplications[@offset, @limit] + @s_state = 0 + when '1' + @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] + @s_state = 1 + end + else + @softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit] + @s_state = 1 + end + #new added end + + respond_to do |format| + format.html + end + end + + private + def find_softapplication + @softapplication = Softapplication.find_by_id(params[:id]) + end + + def editable + unless @softapplication.editable_by? User.current + render_403 + return false + end + end + + def destroyable + unless @softapplication.destroyable_by? User.current + render_403 + return false + end + end + +end diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index e26608cf5..b80f47d72 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -1,315 +1,315 @@ -# 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 TimelogController < ApplicationController - layout 'base_projects'#added by young - menu_item :issues - - before_filter :find_project_for_new_time_entry, :only => [:create] - before_filter :find_time_entry, :only => [:show, :edit, :update] - before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy] - before_filter :authorize, :except => [:new, :index, :report] - - before_filter :find_optional_project, :only => [:index, :report] - before_filter :find_optional_project_for_new_time_entry, :only => [:new] - before_filter :authorize_global, :only => [:new, :index, :report] - - accept_rss_auth :index - accept_api_auth :index, :show, :create, :update, :destroy - - rescue_from Query::StatementInvalid, :with => :query_statement_invalid - - helper :sort - include SortHelper - helper :issues - include TimelogHelper - helper :custom_fields - include CustomFieldsHelper - helper :queries - include QueriesHelper - - def index - @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_') - scope = time_entry_scope - - sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria) - sort_update(@query.sortable_columns) - - respond_to do |format| - format.html { - # Paginate results - @entry_count = scope.count - @entry_pages = Paginator.new @entry_count, per_page_option, params['page'] - @entries = scope.all( - :include => [:project, :activity, :user, {:issue => :tracker}], - :order => sort_clause, - :limit => @entry_pages.per_page, - :offset => @entry_pages.offset - ) - @total_hours = scope.sum(:hours).to_f - - render :layout => !request.xhr? - } - format.api { - @entry_count = scope.count - @offset, @limit = api_offset_and_limit - @entries = scope.all( - :include => [:project, :activity, :user, {:issue => :tracker}], - :order => sort_clause, - :limit => @limit, - :offset => @offset - ) - } - format.atom { - entries = scope.all( - :include => [:project, :activity, :user, {:issue => :tracker}], - :order => "#{TimeEntry.table_name}.created_on DESC", - :limit => Setting.feeds_limit.to_i - ) - render_feed(entries, :title => l(:label_spent_time)) - } - format.csv { - # Export all entries - @entries = scope.all( - :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], - :order => sort_clause - ) - send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv') - } - end - end - - def report - @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_') - scope = time_entry_scope - - @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope) - - respond_to do |format| - format.html { render :layout => !request.xhr? } - format.csv { send_data(report_to_csv(@report), :type => 'text/csv; header=present', :filename => 'timelog.csv') } - end - end - - def show - respond_to do |format| - # TODO: Implement html response - format.html { render :nothing => true, :status => 406 } - format.api - end - end - - def new - @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today) - @time_entry.safe_attributes = params[:time_entry] - end - - def create - @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today) - @time_entry.safe_attributes = params[:time_entry] - - call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry }) - - if @time_entry.save - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_create) - if params[:continue] - if params[:project_id] - options = { - :time_entry => {:issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id}, - :back_url => params[:back_url] - } - if @time_entry.issue - redirect_to new_project_issue_time_entry_url(@time_entry.project, @time_entry.issue, options) - else - redirect_to new_project_time_entry_url(@time_entry.project, options) - end - else - options = { - :time_entry => {:project_id => @time_entry.project_id, :issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id}, - :back_url => params[:back_url] - } - redirect_to new_time_entry_url(options) - end - else - redirect_back_or_default project_time_entries_path(@time_entry.project) - end - } - format.api { render :action => 'show', :status => :created, :location => time_entry_url(@time_entry) } - end - else - respond_to do |format| - format.html { render :action => 'new' } - format.api { render_validation_errors(@time_entry) } - end - end - end - - def edit - @time_entry.safe_attributes = params[:time_entry] - end - - def update - @time_entry.safe_attributes = params[:time_entry] - - call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry }) - - if @time_entry.save - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_back_or_default project_time_entries_path(@time_entry.project) - } - format.api { render_api_ok } - end - else - respond_to do |format| - format.html { render :action => 'edit' } - format.api { render_validation_errors(@time_entry) } - end - end - end - - def bulk_edit - @available_activities = TimeEntryActivity.shared.active - @custom_fields = TimeEntry.first.available_custom_fields - end - - def bulk_update - attributes = parse_params_for_bulk_time_entry_attributes(params) - - unsaved_time_entry_ids = [] - @time_entries.each do |time_entry| - time_entry.reload - time_entry.safe_attributes = attributes - call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry }) - unless time_entry.save - # Keep unsaved time_entry ids to display them in flash error - unsaved_time_entry_ids << time_entry.id - end - end - set_flash_from_bulk_time_entry_save(@time_entries, unsaved_time_entry_ids) - redirect_back_or_default project_time_entries_path(@projects.first) - end - - def destroy - destroyed = TimeEntry.transaction do - @time_entries.each do |t| - unless t.destroy && t.destroyed? - raise ActiveRecord::Rollback - end - end - end - - respond_to do |format| - format.html { - if destroyed - flash[:notice] = l(:notice_successful_delete) - else - flash[:error] = l(:notice_unable_delete_time_entry) - end - redirect_back_or_default project_time_entries_path(@projects.first) - } - format.api { - if destroyed - render_api_ok - else - render_validation_errors(@time_entries) - end - } - end - end - -private - def find_time_entry - @time_entry = TimeEntry.find(params[:id]) - unless @time_entry.editable_by?(User.current) - render_403 - return false - end - @project = @time_entry.project - rescue ActiveRecord::RecordNotFound - render_404 - end - - def find_time_entries - @time_entries = TimeEntry.find_all_by_id(params[:id] || params[:ids]) - raise ActiveRecord::RecordNotFound if @time_entries.empty? - @projects = @time_entries.collect(&:project).compact.uniq - @project = @projects.first if @projects.size == 1 - rescue ActiveRecord::RecordNotFound - render_404 - end - - def set_flash_from_bulk_time_entry_save(time_entries, unsaved_time_entry_ids) - if unsaved_time_entry_ids.empty? - flash[:notice] = l(:notice_successful_update) unless time_entries.empty? - else - flash[:error] = l(:notice_failed_to_save_time_entries, - :count => unsaved_time_entry_ids.size, - :total => time_entries.size, - :ids => '#' + unsaved_time_entry_ids.join(', #')) - end - end - - def find_optional_project_for_new_time_entry - if (project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])).present? - @project = Project.find(project_id) - end - if (issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])).present? - @issue = Issue.find(issue_id) - @project ||= @issue.project - end - rescue ActiveRecord::RecordNotFound - render_404 - end - - def find_project_for_new_time_entry - find_optional_project_for_new_time_entry - if @project.nil? - render_404 - end - end - - def find_optional_project - if !params[:issue_id].blank? - @issue = Issue.find(params[:issue_id]) - @project = @issue.project - elsif !params[:project_id].blank? - @project = Project.find(params[:project_id]) - end - end - - # Returns the TimeEntry scope for index and report actions - def time_entry_scope - scope = TimeEntry.visible.where(@query.statement) - if @issue - scope = scope.on_issue(@issue) - elsif @project - scope = scope.on_project(@project, Setting.display_subprojects_issues?) - end - scope - end - - def parse_params_for_bulk_time_entry_attributes(params) - attributes = (params[:time_entry] || {}).reject {|k,v| v.blank?} - attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} - attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] - attributes - 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 TimelogController < ApplicationController + layout 'base_projects'#added by young + menu_item :issues + + before_filter :find_project_for_new_time_entry, :only => [:create] + before_filter :find_time_entry, :only => [:show, :edit, :update] + before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy] + before_filter :authorize, :except => [:new, :index, :report] + + before_filter :find_optional_project, :only => [:index, :report] + before_filter :find_optional_project_for_new_time_entry, :only => [:new] + before_filter :authorize_global, :only => [:new, :index, :report] + + accept_rss_auth :index + accept_api_auth :index, :show, :create, :update, :destroy + + rescue_from Query::StatementInvalid, :with => :query_statement_invalid + + helper :sort + include SortHelper + helper :issues + include TimelogHelper + helper :custom_fields + include CustomFieldsHelper + helper :queries + include QueriesHelper + + def index + @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_') + scope = time_entry_scope + + sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria) + sort_update(@query.sortable_columns) + + respond_to do |format| + format.html { + # Paginate results + @entry_count = scope.count + @entry_pages = Paginator.new @entry_count, per_page_option, params['page'] + @entries = scope.all( + :include => [:project, :activity, :user, {:issue => :tracker}], + :order => sort_clause, + :limit => @entry_pages.per_page, + :offset => @entry_pages.offset + ) + @total_hours = scope.sum(:hours).to_f + + render :layout => !request.xhr? + } + format.api { + @entry_count = scope.count + @offset, @limit = api_offset_and_limit + @entries = scope.all( + :include => [:project, :activity, :user, {:issue => :tracker}], + :order => sort_clause, + :limit => @limit, + :offset => @offset + ) + } + format.atom { + entries = scope.all( + :include => [:project, :activity, :user, {:issue => :tracker}], + :order => "#{TimeEntry.table_name}.created_on DESC", + :limit => Setting.feeds_limit.to_i + ) + render_feed(entries, :title => l(:label_spent_time)) + } + format.csv { + # Export all entries + @entries = scope.all( + :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], + :order => sort_clause + ) + send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv') + } + end + end + + def report + @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_') + scope = time_entry_scope + + @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope) + + respond_to do |format| + format.html { render :layout => !request.xhr? } + format.csv { send_data(report_to_csv(@report), :type => 'text/csv; header=present', :filename => 'timelog.csv') } + end + end + + def show + respond_to do |format| + # TODO: Implement html response + format.html { render :nothing => true, :status => 406 } + format.api + end + end + + def new + @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today) + @time_entry.safe_attributes = params[:time_entry] + end + + def create + @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today) + @time_entry.safe_attributes = params[:time_entry] + + call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry }) + + if @time_entry.save + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_create) + if params[:continue] + if params[:project_id] + options = { + :time_entry => {:issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id}, + :back_url => params[:back_url] + } + if @time_entry.issue + redirect_to new_project_issue_time_entry_url(@time_entry.project, @time_entry.issue, options) + else + redirect_to new_project_time_entry_url(@time_entry.project, options) + end + else + options = { + :time_entry => {:project_id => @time_entry.project_id, :issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id}, + :back_url => params[:back_url] + } + redirect_to new_time_entry_url(options) + end + else + redirect_back_or_default project_time_entries_path(@time_entry.project) + end + } + format.api { render :action => 'show', :status => :created, :location => time_entry_url(@time_entry) } + end + else + respond_to do |format| + format.html { render :action => 'new' } + format.api { render_validation_errors(@time_entry) } + end + end + end + + def edit + @time_entry.safe_attributes = params[:time_entry] + end + + def update + @time_entry.safe_attributes = params[:time_entry] + + call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry }) + + if @time_entry.save + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_back_or_default project_time_entries_path(@time_entry.project) + } + format.api { render_api_ok } + end + else + respond_to do |format| + format.html { render :action => 'edit' } + format.api { render_validation_errors(@time_entry) } + end + end + end + + def bulk_edit + @available_activities = TimeEntryActivity.shared.active + @custom_fields = TimeEntry.first.available_custom_fields + end + + def bulk_update + attributes = parse_params_for_bulk_time_entry_attributes(params) + + unsaved_time_entry_ids = [] + @time_entries.each do |time_entry| + time_entry.reload + time_entry.safe_attributes = attributes + call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry }) + unless time_entry.save + # Keep unsaved time_entry ids to display them in flash error + unsaved_time_entry_ids << time_entry.id + end + end + set_flash_from_bulk_time_entry_save(@time_entries, unsaved_time_entry_ids) + redirect_back_or_default project_time_entries_path(@projects.first) + end + + def destroy + destroyed = TimeEntry.transaction do + @time_entries.each do |t| + unless t.destroy && t.destroyed? + raise ActiveRecord::Rollback + end + end + end + + respond_to do |format| + format.html { + if destroyed + flash[:notice] = l(:notice_successful_delete) + else + flash[:error] = l(:notice_unable_delete_time_entry) + end + redirect_back_or_default project_time_entries_path(@projects.first) + } + format.api { + if destroyed + render_api_ok + else + render_validation_errors(@time_entries) + end + } + end + end + +private + def find_time_entry + @time_entry = TimeEntry.find(params[:id]) + unless @time_entry.editable_by?(User.current) + render_403 + return false + end + @project = @time_entry.project + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_time_entries + @time_entries = TimeEntry.find_all_by_id(params[:id] || params[:ids]) + raise ActiveRecord::RecordNotFound if @time_entries.empty? + @projects = @time_entries.collect(&:project).compact.uniq + @project = @projects.first if @projects.size == 1 + rescue ActiveRecord::RecordNotFound + render_404 + end + + def set_flash_from_bulk_time_entry_save(time_entries, unsaved_time_entry_ids) + if unsaved_time_entry_ids.empty? + flash[:notice] = l(:notice_successful_update) unless time_entries.empty? + else + flash[:error] = l(:notice_failed_to_save_time_entries, + :count => unsaved_time_entry_ids.size, + :total => time_entries.size, + :ids => '#' + unsaved_time_entry_ids.join(', #')) + end + end + + def find_optional_project_for_new_time_entry + if (project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])).present? + @project = Project.find(project_id) + end + if (issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])).present? + @issue = Issue.find(issue_id) + @project ||= @issue.project + end + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_project_for_new_time_entry + find_optional_project_for_new_time_entry + if @project.nil? + render_404 + end + end + + def find_optional_project + if !params[:issue_id].blank? + @issue = Issue.find(params[:issue_id]) + @project = @issue.project + elsif !params[:project_id].blank? + @project = Project.find(params[:project_id]) + end + end + + # Returns the TimeEntry scope for index and report actions + def time_entry_scope + scope = TimeEntry.visible.where(@query.statement) + if @issue + scope = scope.on_issue(@issue) + elsif @project + scope = scope.on_project(@project, Setting.display_subprojects_issues?) + end + scope + end + + def parse_params_for_bulk_time_entry_attributes(params) + attributes = (params[:time_entry] || {}).reject {|k,v| v.blank?} + attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'} + attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] + attributes + end +end diff --git a/app/controllers/trackers_controller.rb b/app/controllers/trackers_controller.rb index 988f03952..01bc47a2f 100644 --- a/app/controllers/trackers_controller.rb +++ b/app/controllers/trackers_controller.rb @@ -1,108 +1,108 @@ -# 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 TrackersController < ApplicationController - layout 'admin' - helper "project_score" - before_filter :require_admin, :except => :index - before_filter :require_admin_or_api_request, :only => :index - accept_api_auth :index - include CoursesHelper - def index - respond_to do |format| - format.html { - @tracker_pages, @trackers = paginate Tracker.sorted, :per_page => 25 - render :action => "index", :layout => false if request.xhr? - } - format.api { - @trackers = Tracker.sorted.all - } - end - end - - def new - @tracker ||= Tracker.new(params[:tracker]) - @trackers = Tracker.sorted.all - @projects = Project.where("project_type = #{Project::ProjectType_project}").all - @courses = Course.all - @course_activity_count=Hash.new - @courses.each do |course| - @course_activity_count[course.id]=0 - end - @course_activity_count=get_course_activity @courses,@course_activity_count - end - - def create - @tracker = Tracker.new(params[:tracker]) - if @tracker.save - # workflow copy - if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from])) - @tracker.workflow_rules.copy(copy_from) - end - flash[:notice] = l(:notice_successful_create) - redirect_to trackers_url - return - end - new - render :action => 'new' - end - - def edit - @tracker ||= Tracker.find(params[:id]) - @projects = Project.where("project_type = #{Project::ProjectType_project}").all - @courses = Course.all - end - - def update - @tracker = Tracker.find(params[:id]) - if @tracker.update_attributes(params[:tracker]) - flash[:notice] = l(:notice_successful_update) - redirect_to trackers_url - return - end - edit - render :action => 'edit' - end - - def destroy - @tracker = Tracker.find(params[:id]) - unless @tracker.issues.empty? - flash[:error] = l(:error_can_not_delete_tracker) - else - @tracker.destroy - end - redirect_to trackers_url - end - - def fields - if request.post? && params[:trackers] - params[:trackers].each do |tracker_id, tracker_params| - tracker = Tracker.find_by_id(tracker_id) - if tracker - tracker.core_fields = tracker_params[:core_fields] - tracker.custom_field_ids = tracker_params[:custom_field_ids] - tracker.save - end - end - flash[:notice] = l(:notice_successful_update) - redirect_to fields_trackers_url - return - end - @trackers = Tracker.sorted.all - @custom_fields = IssueCustomField.all.sort - 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 TrackersController < ApplicationController + layout 'admin' + helper "project_score" + before_filter :require_admin, :except => :index + before_filter :require_admin_or_api_request, :only => :index + accept_api_auth :index + include CoursesHelper + def index + respond_to do |format| + format.html { + @tracker_pages, @trackers = paginate Tracker.sorted, :per_page => 25 + render :action => "index", :layout => false if request.xhr? + } + format.api { + @trackers = Tracker.sorted.all + } + end + end + + def new + @tracker ||= Tracker.new(params[:tracker]) + @trackers = Tracker.sorted.all + @projects = Project.where("project_type = #{Project::ProjectType_project}").all + @courses = Course.all + @course_activity_count=Hash.new + @courses.each do |course| + @course_activity_count[course.id]=0 + end + @course_activity_count=get_course_activity @courses,@course_activity_count + end + + def create + @tracker = Tracker.new(params[:tracker]) + if @tracker.save + # workflow copy + if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from])) + @tracker.workflow_rules.copy(copy_from) + end + flash[:notice] = l(:notice_successful_create) + redirect_to trackers_url + return + end + new + render :action => 'new' + end + + def edit + @tracker ||= Tracker.find(params[:id]) + @projects = Project.where("project_type = #{Project::ProjectType_project}").all + @courses = Course.all + end + + def update + @tracker = Tracker.find(params[:id]) + if @tracker.update_attributes(params[:tracker]) + flash[:notice] = l(:notice_successful_update) + redirect_to trackers_url + return + end + edit + render :action => 'edit' + end + + def destroy + @tracker = Tracker.find(params[:id]) + unless @tracker.issues.empty? + flash[:error] = l(:error_can_not_delete_tracker) + else + @tracker.destroy + end + redirect_to trackers_url + end + + def fields + if request.post? && params[:trackers] + params[:trackers].each do |tracker_id, tracker_params| + tracker = Tracker.find_by_id(tracker_id) + if tracker + tracker.core_fields = tracker_params[:core_fields] + tracker.custom_field_ids = tracker_params[:custom_field_ids] + tracker.save + end + end + flash[:notice] = l(:notice_successful_update) + redirect_to fields_trackers_url + return + end + @trackers = Tracker.sorted.all + @custom_fields = IssueCustomField.all.sort + end +end diff --git a/app/controllers/web_footer_companies_controller.rb b/app/controllers/web_footer_companies_controller.rb index 0fa076c2f..fdc037be2 100644 --- a/app/controllers/web_footer_companies_controller.rb +++ b/app/controllers/web_footer_companies_controller.rb @@ -1,52 +1,52 @@ -class WebFooterCompaniesController < ApplicationController - layout 'admin' - menu_item :projects, :only => :projects - menu_item :plugins, :only => :plugins - menu_item :info, :only => :info - before_filter :require_admin - - def index - @companys = WebFooterCompany.all - end - - def new - @company ||= WebFooterCompany.new - end - - def create - @company = WebFooterCompany.new(params[:web_footer_company]) - if @company.save - flash[:notice] = l(:notice_successful_create) - redirect_to web_footer_companies_url - else - flash[:error] = "#{l :web_footer_company_create_fail}: #{@company.errors.full_messages[0]}" - respond_to do |format| - format.html { render :action => 'new'} - format.api { render_validation_errors(@company) } - end - - end - end - - def destroy - @company = WebFooterCompany.find(params[:id]) - @company.destroy - redirect_to web_footer_companies_url - end - - def edit - @company = WebFooterCompany.find(params[:id]) - end - - def update - @company = WebFooterCompany.find(params[:id]) - if @company.update_attributes(params[:web_footer_company]) - flash[:notice] = l(:notice_successful_update) - redirect_to web_footer_companies_url - else - flash[:error] = "#{l :web_footer_company_update_fail}: #{@company.errors.full_messages[0]}" - render :action => 'edit' - end - end - -end +class WebFooterCompaniesController < ApplicationController + layout 'admin' + menu_item :projects, :only => :projects + menu_item :plugins, :only => :plugins + menu_item :info, :only => :info + before_filter :require_admin + + def index + @companys = WebFooterCompany.all + end + + def new + @company ||= WebFooterCompany.new + end + + def create + @company = WebFooterCompany.new(params[:web_footer_company]) + if @company.save + flash[:notice] = l(:notice_successful_create) + redirect_to web_footer_companies_url + else + flash[:error] = "#{l :web_footer_company_create_fail}: #{@company.errors.full_messages[0]}" + respond_to do |format| + format.html { render :action => 'new'} + format.api { render_validation_errors(@company) } + end + + end + end + + def destroy + @company = WebFooterCompany.find(params[:id]) + @company.destroy + redirect_to web_footer_companies_url + end + + def edit + @company = WebFooterCompany.find(params[:id]) + end + + def update + @company = WebFooterCompany.find(params[:id]) + if @company.update_attributes(params[:web_footer_company]) + flash[:notice] = l(:notice_successful_update) + redirect_to web_footer_companies_url + else + flash[:error] = "#{l :web_footer_company_update_fail}: #{@company.errors.full_messages[0]}" + render :action => 'edit' + end + end + +end diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index de9e53554..f74fbb04d 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -1,358 +1,358 @@ -# 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 'diff' - -# The WikiController follows the Rails REST controller pattern but with -# a few differences -# -# * index - shows a list of WikiPages grouped by page or date -# * new - not used -# * create - not used -# * show - will also show the form for creating a new wiki page -# * edit - used to edit an existing or new page -# * update - used to save a wiki page update to the database, including new pages -# * destroy - normal -# -# Other member and collection methods are also used -# -# TODO: still being worked on -class WikiController < ApplicationController - layout 'base_projects'#by young - default_search_scope :wiki_pages - before_filter :find_wiki, :authorize - before_filter :find_existing_or_new_page, :only => [:show, :edit, :update] - before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version] - accept_api_auth :index, :show, :update, :destroy - before_filter :find_attachments, :only => [:preview] - - helper :attachments - include AttachmentsHelper - helper :watchers - include Redmine::Export::PDF - helper :project_score - - # List of pages, sorted alphabetically and by parent (hierarchy) - def index - load_pages_for_index - - respond_to do |format| - format.html { - @pages_by_parent_id = @pages.group_by(&:parent_id) - } - format.api - end - end - - # List of page, by last update - def date_index - load_pages_for_index - @pages_by_date = @pages.group_by {|p| p.updated_on.to_date} - end - - # display a page (in editing mode if it doesn't exist) - def show - if @page.new_record? - if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request? - edit - render :action => 'edit' - else - render_404 - end - return - end - if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project) - deny_access - return - end - @content = @page.content_for_version(params[:version]) - if User.current.allowed_to?(:export_wiki_pages, @project) - if params[:format] == 'pdf' - send_data(wiki_page_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf") - return - elsif params[:format] == 'html' - export = render_to_string :action => 'export', :layout => false - send_data(export, :type => 'text/html', :filename => "#{@page.title}.html") - return - elsif params[:format] == 'txt' - send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt") - return - end - end - @editable = editable? - @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) && - @content.current_version? && - Redmine::WikiFormatting.supports_section_edit? - - respond_to do |format| - format.html - format.api - end - end - - # edit an existing page or a new one - def edit - return render_403 unless editable? - if @page.new_record? - @page.content = WikiContent.new(:page => @page) - if params[:parent].present? - @page.parent = @page.wiki.find_page(params[:parent].to_s) - end - end - - @content = @page.content_for_version(params[:version]) - @content.text = initial_page_content(@page) if @content.text.blank? - # don't keep previous comment - @content.comments = nil - - # To prevent StaleObjectError exception when reverting to a previous version - @content.version = @page.content.version - - @text = @content.text - if params[:section].present? && Redmine::WikiFormatting.supports_section_edit? - @section = params[:section].to_i - @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section) - render_404 if @text.blank? - end - end - - # Creates a new page or updates an existing one - def update - return render_403 unless editable? - was_new_page = @page.new_record? - @page.content = WikiContent.new(:page => @page) if @page.new_record? - @page.safe_attributes = params[:wiki_page] - - @content = @page.content - content_params = params[:content] - if content_params.nil? && params[:wiki_page].is_a?(Hash) - content_params = params[:wiki_page].slice(:text, :comments, :version) - end - content_params ||= {} - - @content.comments = content_params[:comments] - @text = content_params[:text] - if params[:section].present? && Redmine::WikiFormatting.supports_section_edit? - @section = params[:section].to_i - @section_hash = params[:section_hash] - @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash) - else - @content.version = content_params[:version] if content_params[:version] - @content.text = @text - end - @content.author = User.current - - if @page.save_with_content - attachments = Attachment.attach_files(@page, params[:attachments]) - render_attachment_warning_if_needed(@page) - call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page}) - - respond_to do |format| - format.html { redirect_to project_wiki_page_url(@project, @page.title) } - format.api { - if was_new_page - render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title) - else - render_api_ok - end - } - end - else - respond_to do |format| - format.html { render :action => 'edit' } - format.api { render_validation_errors(@content) } - end - end - - rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError - # Optimistic locking exception - respond_to do |format| - format.html { - flash.now[:error] = l(:notice_locking_conflict) - render :action => 'edit' - } - format.api { render_api_head :conflict } - end - rescue ActiveRecord::RecordNotSaved - respond_to do |format| - format.html { render :action => 'edit' } - format.api { render_validation_errors(@content) } - end - end - - # rename a page - def rename - return render_403 unless editable? - @page.redirect_existing_links = true - # used to display the *original* title if some AR validation errors occur - @original_title = @page.pretty_title - if request.post? && @page.update_attributes(params[:wiki_page]) - flash[:notice] = l(:notice_successful_update) - redirect_to project_wiki_page_url(@project, @page.title) - end - end - - def protect - @page.update_attribute :protected, params[:protected] - redirect_to project_wiki_page_url(@project, @page.title) - end - - # show page history - def history - @version_count = @page.content.versions.count - @version_pages = Paginator.new @version_count, per_page_option, params['page'] - # don't load text - @versions = @page.content.versions. - select("id, author_id, comments, updated_on, version"). - reorder('version DESC'). - limit(@version_pages.per_page + 1). - offset(@version_pages.offset). - all - - render :layout => false if request.xhr? - end - - def diff - @diff = @page.diff(params[:version], params[:version_from]) - render_404 unless @diff - end - - def annotate - @annotate = @page.annotate(params[:version]) - render_404 unless @annotate - end - - # Removes a wiki page and its history - # Children can be either set as root pages, removed or reassigned to another parent page - def destroy - return render_403 unless editable? - - @descendants_count = @page.descendants.size - if @descendants_count > 0 - case params[:todo] - when 'nullify' - # Nothing to do - when 'destroy' - # Removes all its descendants - @page.descendants.each(&:destroy) - when 'reassign' - # Reassign children to another parent page - reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i) - return unless reassign_to - @page.children.each do |child| - child.update_attribute(:parent, reassign_to) - end - else - @reassignable_to = @wiki.pages - @page.self_and_descendants - # display the destroy form if it's a user request - return unless api_request? - end - end - @page.destroy - respond_to do |format| - format.html { redirect_to project_wiki_index_url(@project) } - format.api { render_api_ok } - end - end - - def destroy_version - return render_403 unless editable? - - @content = @page.content_for_version(params[:version]) - @content.destroy - redirect_to_referer_or history_project_wiki_page_url(@project, @page.title) - end - - # Export wiki to a single pdf or html file - def export - @pages = @wiki.pages.all(:order => 'title', :include => [:content, {:attachments => :author}]) - respond_to do |format| - format.html { - export = render_to_string :action => 'export_multiple', :layout => false - send_data(export, :type => 'text/html', :filename => "wiki.html") - } - format.pdf { - send_data(wiki_pages_to_pdf(@pages, @project), :type => 'application/pdf', :filename => "#{@project.identifier}.pdf") - } - end - end - - def preview - page = @wiki.find_page(params[:id]) - # page is nil when previewing a new page - return render_403 unless page.nil? || editable?(page) - if page - @attachments += page.attachments - @previewed = page.content - end - @text = params[:content][:text] - render :partial => 'common/preview' - end - - def add_attachment - return render_403 unless editable? - attachments = Attachment.attach_files(@page, params[:attachments]) - render_attachment_warning_if_needed(@page) - redirect_to :action => 'show', :id => @page.title, :project_id => @project - end - -private - - def find_wiki - @project = Project.find(params[:project_id]) - @wiki = @project.wiki - render_404 unless @wiki - rescue ActiveRecord::RecordNotFound - render_404 - end - - # Finds the requested page or a new page if it doesn't exist - def find_existing_or_new_page - @page = @wiki.find_or_new_page(params[:id]) - if @wiki.page_found_with_redirect? - redirect_to params.update(:id => @page.title) - end - end - - # Finds the requested page and returns a 404 error if it doesn't exist - def find_existing_page - @page = @wiki.find_page(params[:id]) - if @page.nil? - render_404 - return - end - if @wiki.page_found_with_redirect? - redirect_to params.update(:id => @page.title) - end - end - - # Returns true if the current user is allowed to edit the page, otherwise false - def editable?(page = @page) - page.editable_by?(User.current) - end - - # Returns the default content of a new wiki page - def initial_page_content(page) - helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting) - extend helper unless self.instance_of?(helper) - helper.instance_method(:initial_page_content).bind(self).call(page) - end - - def load_pages_for_index - @pages = @wiki.pages.with_updated_on.reorder("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all - 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 'diff' + +# The WikiController follows the Rails REST controller pattern but with +# a few differences +# +# * index - shows a list of WikiPages grouped by page or date +# * new - not used +# * create - not used +# * show - will also show the form for creating a new wiki page +# * edit - used to edit an existing or new page +# * update - used to save a wiki page update to the database, including new pages +# * destroy - normal +# +# Other member and collection methods are also used +# +# TODO: still being worked on +class WikiController < ApplicationController + layout 'base_projects'#by young + default_search_scope :wiki_pages + before_filter :find_wiki, :authorize + before_filter :find_existing_or_new_page, :only => [:show, :edit, :update] + before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version] + accept_api_auth :index, :show, :update, :destroy + before_filter :find_attachments, :only => [:preview] + + helper :attachments + include AttachmentsHelper + helper :watchers + include Redmine::Export::PDF + helper :project_score + + # List of pages, sorted alphabetically and by parent (hierarchy) + def index + load_pages_for_index + + respond_to do |format| + format.html { + @pages_by_parent_id = @pages.group_by(&:parent_id) + } + format.api + end + end + + # List of page, by last update + def date_index + load_pages_for_index + @pages_by_date = @pages.group_by {|p| p.updated_on.to_date} + end + + # display a page (in editing mode if it doesn't exist) + def show + if @page.new_record? + if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request? + edit + render :action => 'edit' + else + render_404 + end + return + end + if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project) + deny_access + return + end + @content = @page.content_for_version(params[:version]) + if User.current.allowed_to?(:export_wiki_pages, @project) + if params[:format] == 'pdf' + send_data(wiki_page_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf") + return + elsif params[:format] == 'html' + export = render_to_string :action => 'export', :layout => false + send_data(export, :type => 'text/html', :filename => "#{@page.title}.html") + return + elsif params[:format] == 'txt' + send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt") + return + end + end + @editable = editable? + @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) && + @content.current_version? && + Redmine::WikiFormatting.supports_section_edit? + + respond_to do |format| + format.html + format.api + end + end + + # edit an existing page or a new one + def edit + return render_403 unless editable? + if @page.new_record? + @page.content = WikiContent.new(:page => @page) + if params[:parent].present? + @page.parent = @page.wiki.find_page(params[:parent].to_s) + end + end + + @content = @page.content_for_version(params[:version]) + @content.text = initial_page_content(@page) if @content.text.blank? + # don't keep previous comment + @content.comments = nil + + # To prevent StaleObjectError exception when reverting to a previous version + @content.version = @page.content.version + + @text = @content.text + if params[:section].present? && Redmine::WikiFormatting.supports_section_edit? + @section = params[:section].to_i + @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section) + render_404 if @text.blank? + end + end + + # Creates a new page or updates an existing one + def update + return render_403 unless editable? + was_new_page = @page.new_record? + @page.content = WikiContent.new(:page => @page) if @page.new_record? + @page.safe_attributes = params[:wiki_page] + + @content = @page.content + content_params = params[:content] + if content_params.nil? && params[:wiki_page].is_a?(Hash) + content_params = params[:wiki_page].slice(:text, :comments, :version) + end + content_params ||= {} + + @content.comments = content_params[:comments] + @text = content_params[:text] + if params[:section].present? && Redmine::WikiFormatting.supports_section_edit? + @section = params[:section].to_i + @section_hash = params[:section_hash] + @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash) + else + @content.version = content_params[:version] if content_params[:version] + @content.text = @text + end + @content.author = User.current + + if @page.save_with_content + attachments = Attachment.attach_files(@page, params[:attachments]) + render_attachment_warning_if_needed(@page) + call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page}) + + respond_to do |format| + format.html { redirect_to project_wiki_page_url(@project, @page.title) } + format.api { + if was_new_page + render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title) + else + render_api_ok + end + } + end + else + respond_to do |format| + format.html { render :action => 'edit' } + format.api { render_validation_errors(@content) } + end + end + + rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError + # Optimistic locking exception + respond_to do |format| + format.html { + flash.now[:error] = l(:notice_locking_conflict) + render :action => 'edit' + } + format.api { render_api_head :conflict } + end + rescue ActiveRecord::RecordNotSaved + respond_to do |format| + format.html { render :action => 'edit' } + format.api { render_validation_errors(@content) } + end + end + + # rename a page + def rename + return render_403 unless editable? + @page.redirect_existing_links = true + # used to display the *original* title if some AR validation errors occur + @original_title = @page.pretty_title + if request.post? && @page.update_attributes(params[:wiki_page]) + flash[:notice] = l(:notice_successful_update) + redirect_to project_wiki_page_url(@project, @page.title) + end + end + + def protect + @page.update_attribute :protected, params[:protected] + redirect_to project_wiki_page_url(@project, @page.title) + end + + # show page history + def history + @version_count = @page.content.versions.count + @version_pages = Paginator.new @version_count, per_page_option, params['page'] + # don't load text + @versions = @page.content.versions. + select("id, author_id, comments, updated_on, version"). + reorder('version DESC'). + limit(@version_pages.per_page + 1). + offset(@version_pages.offset). + all + + render :layout => false if request.xhr? + end + + def diff + @diff = @page.diff(params[:version], params[:version_from]) + render_404 unless @diff + end + + def annotate + @annotate = @page.annotate(params[:version]) + render_404 unless @annotate + end + + # Removes a wiki page and its history + # Children can be either set as root pages, removed or reassigned to another parent page + def destroy + return render_403 unless editable? + + @descendants_count = @page.descendants.size + if @descendants_count > 0 + case params[:todo] + when 'nullify' + # Nothing to do + when 'destroy' + # Removes all its descendants + @page.descendants.each(&:destroy) + when 'reassign' + # Reassign children to another parent page + reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i) + return unless reassign_to + @page.children.each do |child| + child.update_attribute(:parent, reassign_to) + end + else + @reassignable_to = @wiki.pages - @page.self_and_descendants + # display the destroy form if it's a user request + return unless api_request? + end + end + @page.destroy + respond_to do |format| + format.html { redirect_to project_wiki_index_url(@project) } + format.api { render_api_ok } + end + end + + def destroy_version + return render_403 unless editable? + + @content = @page.content_for_version(params[:version]) + @content.destroy + redirect_to_referer_or history_project_wiki_page_url(@project, @page.title) + end + + # Export wiki to a single pdf or html file + def export + @pages = @wiki.pages.all(:order => 'title', :include => [:content, {:attachments => :author}]) + respond_to do |format| + format.html { + export = render_to_string :action => 'export_multiple', :layout => false + send_data(export, :type => 'text/html', :filename => "wiki.html") + } + format.pdf { + send_data(wiki_pages_to_pdf(@pages, @project), :type => 'application/pdf', :filename => "#{@project.identifier}.pdf") + } + end + end + + def preview + page = @wiki.find_page(params[:id]) + # page is nil when previewing a new page + return render_403 unless page.nil? || editable?(page) + if page + @attachments += page.attachments + @previewed = page.content + end + @text = params[:content][:text] + render :partial => 'common/preview' + end + + def add_attachment + return render_403 unless editable? + attachments = Attachment.attach_files(@page, params[:attachments]) + render_attachment_warning_if_needed(@page) + redirect_to :action => 'show', :id => @page.title, :project_id => @project + end + +private + + def find_wiki + @project = Project.find(params[:project_id]) + @wiki = @project.wiki + render_404 unless @wiki + rescue ActiveRecord::RecordNotFound + render_404 + end + + # Finds the requested page or a new page if it doesn't exist + def find_existing_or_new_page + @page = @wiki.find_or_new_page(params[:id]) + if @wiki.page_found_with_redirect? + redirect_to params.update(:id => @page.title) + end + end + + # Finds the requested page and returns a 404 error if it doesn't exist + def find_existing_page + @page = @wiki.find_page(params[:id]) + if @page.nil? + render_404 + return + end + if @wiki.page_found_with_redirect? + redirect_to params.update(:id => @page.title) + end + end + + # Returns true if the current user is allowed to edit the page, otherwise false + def editable?(page = @page) + page.editable_by?(User.current) + end + + # Returns the default content of a new wiki page + def initial_page_content(page) + helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting) + extend helper unless self.instance_of?(helper) + helper.instance_method(:initial_page_content).bind(self).call(page) + end + + def load_pages_for_index + @pages = @wiki.pages.with_updated_on.reorder("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all + end +end diff --git a/app/controllers/wikis_controller.rb b/app/controllers/wikis_controller.rb index d600efe78..a8205710f 100644 --- a/app/controllers/wikis_controller.rb +++ b/app/controllers/wikis_controller.rb @@ -1,36 +1,36 @@ -# 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 WikisController < ApplicationController - menu_item :settings - before_filter :find_project, :authorize - - # Create or update a project's wiki - def edit - @wiki = @project.wiki || Wiki.new(:project => @project) - @wiki.safe_attributes = params[:wiki] - @wiki.save if request.post? - end - - # Delete a project's wiki - def destroy - if request.post? && params[:confirm] && @project.wiki - @project.wiki.destroy - redirect_to settings_project_url(@project, :tab => 'wiki') - 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 WikisController < ApplicationController + menu_item :settings + before_filter :find_project, :authorize + + # Create or update a project's wiki + def edit + @wiki = @project.wiki || Wiki.new(:project => @project) + @wiki.safe_attributes = params[:wiki] + @wiki.save if request.post? + end + + # Delete a project's wiki + def destroy + if request.post? && params[:confirm] && @project.wiki + @project.wiki.destroy + redirect_to settings_project_url(@project, :tab => 'wiki') + end + end +end diff --git a/app/controllers/words_controller.rb b/app/controllers/words_controller.rb index 7752b530b..e6ba74874 100644 --- a/app/controllers/words_controller.rb +++ b/app/controllers/words_controller.rb @@ -1,283 +1,283 @@ -# encoding: utf-8 -#####leave message fq -class WordsController < ApplicationController - - before_filter :find_user, :only => [:new, :create, :destroy, :more, :back] - def create - if params[:new_form][:user_message].size>0 - unless params[:user_id].nil? - if params[:reference_content] - message = params[:new_form][:user_message] + "\n" + params[:reference_content] - else - message = params[:new_form][:user_message] - end - refer_user_id = params[:new_form][:reference_user_id].to_i - - @user.add_jour(User.current, message, refer_user_id) - unless refer_user_id == 0 || refer_user_id == User.current.id - User.find(refer_user_id).add_jour(User.current, message, refer_user_id) - end - @user.count_new_jour - # if a_message.size > 5 - # @message = a_message[-5, 5] - # else - # @message = a_message - # end - # @message_count = a_message.count - end - end - @jours = @user.journals_for_messages.where('m_parent_id IS NULL').reverse - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - - respond_to do |format| - # format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}} - format.js - #format.api { render_api_ok } - end - end - - - def create_reply - # 这里是创建回复所使用的方法,此方法只针对回复,每一个新的留言并不在此方法管理范围内。 - # 由于多个地方用到了留言,而之前的表设计也有jour_type/jour_id这类信息 - # 所以在方法 add_reply_adapter 中判断所有调用此方法的来源页面, - # 为了保证兼容以往所有的代码,保证以往的方法可以调用,在返回页面中都做了各式各样的判断。 - # 页面保证 render new_respond/journal_reply - # 修改 add_reply_adapter 中可以确保留言创建成功 - # 删除留言功能要调用destroy,也记得在destroy.js中修改 - - # deny api. api useless - parent_id = params[:reference_id] - author_id = User.current.id - reply_user_id = params[:reference_user_id] - reply_id = params[:reference_message_id] # 暂时不实现 - content = params[:user_notes] - options = {:user_id => author_id, - :status => true, - :m_parent_id => parent_id, - :m_reply_id => reply_id, - :reply_id => reply_user_id, - :notes => content, - :is_readed => false} - @jfm = add_reply_adapter options - - respond_to do |format| - # format.html { - # if @jfm.errors.empty? - # flash.now.notice = l(:label_feedback_success) - # else - # flash.now.errors = l(:label_feedback_fail) - # end - # render 'test/index' - # } - format.js{ - @save_succ = true if @jfm.errors.empty? - } - end - end - - def destroy - @journal_destroyed = JournalsForMessage.delete_message(params[:object_id]) - - respond_to do |format| - format.js - #format.api { render_api_ok } - end - end - - def destroyJournal - @journalP=JournalsForMessage.find(params[:object_id]) - @journalP.destroy - - @page = params[:page] - @page = @page.to_i - @project = Project.find params[:project_id] - # Find the page of the requested reply - @jours = @project.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - @limit = 10 - - offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i]) - page = 1 + offset / @limit - if params[:r] && @page.nil? - @page = page - end - - if @page < 0 - @page = 1 - end - if @page > page - @page = page - end - - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, @page - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - @state = false - @base_courses_tag = @project.project_type - - respond_to do |format| - format.js - end - end - - def new - @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] - if @jour - user = @jour.user - text = @jour.notes - else - user = @user - text = [] - end - # Replaces pre blocks with [...] - text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') - @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " - @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - - # @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" - # @content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> " - - @id = user.id - rescue ActiveRecord::RecordNotFound - render_404 - end - - def more - @jours = @user.journals_for_messages.reverse - @limit = 10 - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - @jour = @jours[@offset, @limit] - @state = true - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - def back - @jours = @user.journals_for_messages.reverse - @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 - - respond_to do |format| - format.html { redirect_to :back } - format.js - #format.api { render_api_ok } - end - end - - def add_project_respond - user = User.current - message = params[:new_form][:project_message] - Project.add_jour(user, message) - - redirect_to project_feedback_url('trustie') - # redirect_to signin_path - end - - def leave_project_message - user = User.current - message = params[:new_form][:project_message] - feedback = Project.add_new_jour(user, message, params[:id]) - if(feedback.errors.empty?) - redirect_to project_feedback_url(params[:id]), notice: l(:label_feedback_success) - else - flash[:error] = feedback.errors.full_messages[0] - redirect_to project_feedback_url(params[:id]) - end - - end - - # add by nwb - def leave_course_message - user = User.current - message = params[:new_form][:course_message] - feedback = Course.add_new_jour(user, message, params[:id]) - if(feedback.errors.empty?) - redirect_to course_feedback_url(params[:id]), notice: l(:label_feedback_success) - else - flash[:error] = feedback.errors.full_messages[0] - redirect_to course_feedback_url(params[:id]) - end - - end - - def add_brief_introdution - user = User.current - message = params[:new_form][:user_introduction] - UserExtensions.introduction(user, message) - redirect_to user_url(user.id) - end - - private - - def find_user - if params[:user_id] - @user = User.find(params[:user_id]) - end - rescue - render_404 - end - - def obj_distinguish_url_origin - #modify by nwb - #添加对课程留言的支持 - referer = request.headers["Referer"] - obj_id = referer.match(%r(/([0-9]{1,})(/|\?|$)))[1] - if referer.match(/project/) - obj = Project.find_by_id(obj_id) - elsif referer.match(/course/) - obj = Course.find_by_id(obj_id) - elsif referer.match(/user/) - obj = User.find_by_id(obj_id) - elsif ( referer.match(/bids/) || referer.match(/calls/) ) - obj = Bid.find_by_id(obj_id) - elsif ( referer.match(/contests/) || referer.match(/contests/) ) #new added - obj = Contest.find_by_id(obj_id) - elsif ( referer.match(/softapplications/) || referer.match(/softapplications/) ) #new added - obj = Softapplication.find_by_id(obj_id) - elsif ( referer.match(/homework_attach/) || referer.match(/homework_attach/) ) #new added - obj = HomeworkAttach.find_by_id(obj_id) - else - raise "create reply obj unknow type.#{referer}" - end - obj - end - - def add_reply_adapter options - #modify by nwb - #添加对课程留言的支持 - obj = obj_distinguish_url_origin - if obj.kind_of? User - obj.add_jour(nil, nil, nil, options) - elsif obj.kind_of? Project - Project.add_new_jour(nil, nil, obj.id, options) - elsif obj.kind_of? Course - Course.add_new_jour(nil, nil, obj.id, options) - elsif obj.kind_of? Bid - obj.add_jour(nil, nil, nil, options) - elsif obj.kind_of? Contest - obj.add_jour(nil, nil, obj.id, options) #new added - elsif obj.kind_of? Softapplication - obj.add_jour(nil, nil, obj.id, options) #new added - elsif obj.kind_of? HomeworkAttach - obj.add_jour(nil, nil, obj.id, options) #new added - else - raise "create reply obj unknow type.#{obj.class}" - end - end - #######end of message -end +# encoding: utf-8 +#####leave message fq +class WordsController < ApplicationController + + before_filter :find_user, :only => [:new, :create, :destroy, :more, :back] + def create + if params[:new_form][:user_message].size>0 + unless params[:user_id].nil? + if params[:reference_content] + message = params[:new_form][:user_message] + "\n" + params[:reference_content] + else + message = params[:new_form][:user_message] + end + refer_user_id = params[:new_form][:reference_user_id].to_i + + @user.add_jour(User.current, message, refer_user_id) + unless refer_user_id == 0 || refer_user_id == User.current.id + User.find(refer_user_id).add_jour(User.current, message, refer_user_id) + end + @user.count_new_jour + # if a_message.size > 5 + # @message = a_message[-5, 5] + # else + # @message = a_message + # end + # @message_count = a_message.count + end + end + @jours = @user.journals_for_messages.where('m_parent_id IS NULL').reverse + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + + respond_to do |format| + # format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}} + format.js + #format.api { render_api_ok } + end + end + + + def create_reply + # 这里是创建回复所使用的方法,此方法只针对回复,每一个新的留言并不在此方法管理范围内。 + # 由于多个地方用到了留言,而之前的表设计也有jour_type/jour_id这类信息 + # 所以在方法 add_reply_adapter 中判断所有调用此方法的来源页面, + # 为了保证兼容以往所有的代码,保证以往的方法可以调用,在返回页面中都做了各式各样的判断。 + # 页面保证 render new_respond/journal_reply + # 修改 add_reply_adapter 中可以确保留言创建成功 + # 删除留言功能要调用destroy,也记得在destroy.js中修改 + + # deny api. api useless + parent_id = params[:reference_id] + author_id = User.current.id + reply_user_id = params[:reference_user_id] + reply_id = params[:reference_message_id] # 暂时不实现 + content = params[:user_notes] + options = {:user_id => author_id, + :status => true, + :m_parent_id => parent_id, + :m_reply_id => reply_id, + :reply_id => reply_user_id, + :notes => content, + :is_readed => false} + @jfm = add_reply_adapter options + + respond_to do |format| + # format.html { + # if @jfm.errors.empty? + # flash.now.notice = l(:label_feedback_success) + # else + # flash.now.errors = l(:label_feedback_fail) + # end + # render 'test/index' + # } + format.js{ + @save_succ = true if @jfm.errors.empty? + } + end + end + + def destroy + @journal_destroyed = JournalsForMessage.delete_message(params[:object_id]) + + respond_to do |format| + format.js + #format.api { render_api_ok } + end + end + + def destroyJournal + @journalP=JournalsForMessage.find(params[:object_id]) + @journalP.destroy + + @page = params[:page] + @page = @page.to_i + @project = Project.find params[:project_id] + # Find the page of the requested reply + @jours = @project.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @limit = 10 + + offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i]) + page = 1 + offset / @limit + if params[:r] && @page.nil? + @page = page + end + + if @page < 0 + @page = 1 + end + if @page > page + @page = page + end + + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, @page + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @state = false + @base_courses_tag = @project.project_type + + respond_to do |format| + format.js + end + end + + def new + @jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id] + if @jour + user = @jour.user + text = @jour.notes + else + user = @user + text = [] + end + # Replaces pre blocks with [...] + text = text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]') + @content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> " + @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + + # @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" + # @content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> " + + @id = user.id + rescue ActiveRecord::RecordNotFound + render_404 + end + + def more + @jours = @user.journals_for_messages.reverse + @limit = 10 + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @state = true + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def back + @jours = @user.journals_for_messages.reverse + @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 + + respond_to do |format| + format.html { redirect_to :back } + format.js + #format.api { render_api_ok } + end + end + + def add_project_respond + user = User.current + message = params[:new_form][:project_message] + Project.add_jour(user, message) + + redirect_to project_feedback_url('trustie') + # redirect_to signin_path + end + + def leave_project_message + user = User.current + message = params[:new_form][:project_message] + feedback = Project.add_new_jour(user, message, params[:id]) + if(feedback.errors.empty?) + redirect_to project_feedback_url(params[:id]), notice: l(:label_feedback_success) + else + flash[:error] = feedback.errors.full_messages[0] + redirect_to project_feedback_url(params[:id]) + end + + end + + # add by nwb + def leave_course_message + user = User.current + message = params[:new_form][:course_message] + feedback = Course.add_new_jour(user, message, params[:id]) + if(feedback.errors.empty?) + redirect_to course_feedback_url(params[:id]), notice: l(:label_feedback_success) + else + flash[:error] = feedback.errors.full_messages[0] + redirect_to course_feedback_url(params[:id]) + end + + end + + def add_brief_introdution + user = User.current + message = params[:new_form][:user_introduction] + UserExtensions.introduction(user, message) + redirect_to user_url(user.id) + end + + private + + def find_user + if params[:user_id] + @user = User.find(params[:user_id]) + end + rescue + render_404 + end + + def obj_distinguish_url_origin + #modify by nwb + #添加对课程留言的支持 + referer = request.headers["Referer"] + obj_id = referer.match(%r(/([0-9]{1,})(/|\?|$)))[1] + if referer.match(/project/) + obj = Project.find_by_id(obj_id) + elsif referer.match(/course/) + obj = Course.find_by_id(obj_id) + elsif referer.match(/user/) + obj = User.find_by_id(obj_id) + elsif ( referer.match(/bids/) || referer.match(/calls/) ) + obj = Bid.find_by_id(obj_id) + elsif ( referer.match(/contests/) || referer.match(/contests/) ) #new added + obj = Contest.find_by_id(obj_id) + elsif ( referer.match(/softapplications/) || referer.match(/softapplications/) ) #new added + obj = Softapplication.find_by_id(obj_id) + elsif ( referer.match(/homework_attach/) || referer.match(/homework_attach/) ) #new added + obj = HomeworkAttach.find_by_id(obj_id) + else + raise "create reply obj unknow type.#{referer}" + end + obj + end + + def add_reply_adapter options + #modify by nwb + #添加对课程留言的支持 + obj = obj_distinguish_url_origin + if obj.kind_of? User + obj.add_jour(nil, nil, nil, options) + elsif obj.kind_of? Project + Project.add_new_jour(nil, nil, obj.id, options) + elsif obj.kind_of? Course + Course.add_new_jour(nil, nil, obj.id, options) + elsif obj.kind_of? Bid + obj.add_jour(nil, nil, nil, options) + elsif obj.kind_of? Contest + obj.add_jour(nil, nil, obj.id, options) #new added + elsif obj.kind_of? Softapplication + obj.add_jour(nil, nil, obj.id, options) #new added + elsif obj.kind_of? HomeworkAttach + obj.add_jour(nil, nil, obj.id, options) #new added + else + raise "create reply obj unknow type.#{obj.class}" + end + end + #######end of message +end diff --git a/app/controllers/workflows_controller.rb b/app/controllers/workflows_controller.rb index 44b76cb87..b7ee0c963 100644 --- a/app/controllers/workflows_controller.rb +++ b/app/controllers/workflows_controller.rb @@ -1,128 +1,128 @@ -# 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 WorkflowsController < ApplicationController - layout 'admin' - - before_filter :require_admin, :find_roles, :find_trackers - - def index - @workflow_counts = WorkflowTransition.count_by_tracker_and_role - end - - def edit - @role = Role.find_by_id(params[:role_id]) if params[:role_id] - @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id] - - if request.post? - WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id]) - (params[:issue_status] || []).each { |status_id, transitions| - transitions.each { |new_status_id, options| - author = options.is_a?(Array) && options.include?('author') && !options.include?('always') - assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always') - WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee) - } - } - if @role.save - redirect_to workflows_edit_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only]) - return - end - end - - @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true) - if @tracker && @used_statuses_only && @tracker.issue_statuses.any? - @statuses = @tracker.issue_statuses - end - @statuses ||= IssueStatus.sorted.all - - if @tracker && @role && @statuses.any? - workflows = WorkflowTransition.where(:role_id => @role.id, :tracker_id => @tracker.id).all - @workflows = {} - @workflows['always'] = workflows.select {|w| !w.author && !w.assignee} - @workflows['author'] = workflows.select {|w| w.author} - @workflows['assignee'] = workflows.select {|w| w.assignee} - end - end - - def permissions - @role = Role.find_by_id(params[:role_id]) if params[:role_id] - @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id] - - if request.post? && @role && @tracker - WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {}) - redirect_to workflows_permissions_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only]) - return - end - - @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true) - if @tracker && @used_statuses_only && @tracker.issue_statuses.any? - @statuses = @tracker.issue_statuses - end - @statuses ||= IssueStatus.sorted.all - - if @role && @tracker - @fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]} - @custom_fields = @tracker.custom_fields - - @permissions = WorkflowPermission.where(:tracker_id => @tracker.id, :role_id => @role.id).all.inject({}) do |h, w| - h[w.old_status_id] ||= {} - h[w.old_status_id][w.field_name] = w.rule - h - end - @statuses.each {|status| @permissions[status.id] ||= {}} - end - end - - def copy - - if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any' - @source_tracker = nil - else - @source_tracker = Tracker.find_by_id(params[:source_tracker_id].to_i) - end - if params[:source_role_id].blank? || params[:source_role_id] == 'any' - @source_role = nil - else - @source_role = Role.find_by_id(params[:source_role_id].to_i) - end - - @target_trackers = params[:target_tracker_ids].blank? ? nil : Tracker.find_all_by_id(params[:target_tracker_ids]) - @target_roles = params[:target_role_ids].blank? ? nil : Role.find_all_by_id(params[:target_role_ids]) - - if request.post? - if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?) - flash.now[:error] = l(:error_workflow_copy_source) - elsif @target_trackers.blank? || @target_roles.blank? - flash.now[:error] = l(:error_workflow_copy_target) - else - WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles) - flash[:notice] = l(:notice_successful_update) - redirect_to workflows_copy_url(:source_tracker_id => @source_tracker, :source_role_id => @source_role) - end - end - end - - private - - def find_roles - @roles = Role.sorted.all - end - - def find_trackers - @trackers = Tracker.sorted.all - 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 WorkflowsController < ApplicationController + layout 'admin' + + before_filter :require_admin, :find_roles, :find_trackers + + def index + @workflow_counts = WorkflowTransition.count_by_tracker_and_role + end + + def edit + @role = Role.find_by_id(params[:role_id]) if params[:role_id] + @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id] + + if request.post? + WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id]) + (params[:issue_status] || []).each { |status_id, transitions| + transitions.each { |new_status_id, options| + author = options.is_a?(Array) && options.include?('author') && !options.include?('always') + assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always') + WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee) + } + } + if @role.save + redirect_to workflows_edit_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only]) + return + end + end + + @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true) + if @tracker && @used_statuses_only && @tracker.issue_statuses.any? + @statuses = @tracker.issue_statuses + end + @statuses ||= IssueStatus.sorted.all + + if @tracker && @role && @statuses.any? + workflows = WorkflowTransition.where(:role_id => @role.id, :tracker_id => @tracker.id).all + @workflows = {} + @workflows['always'] = workflows.select {|w| !w.author && !w.assignee} + @workflows['author'] = workflows.select {|w| w.author} + @workflows['assignee'] = workflows.select {|w| w.assignee} + end + end + + def permissions + @role = Role.find_by_id(params[:role_id]) if params[:role_id] + @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id] + + if request.post? && @role && @tracker + WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {}) + redirect_to workflows_permissions_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only]) + return + end + + @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true) + if @tracker && @used_statuses_only && @tracker.issue_statuses.any? + @statuses = @tracker.issue_statuses + end + @statuses ||= IssueStatus.sorted.all + + if @role && @tracker + @fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]} + @custom_fields = @tracker.custom_fields + + @permissions = WorkflowPermission.where(:tracker_id => @tracker.id, :role_id => @role.id).all.inject({}) do |h, w| + h[w.old_status_id] ||= {} + h[w.old_status_id][w.field_name] = w.rule + h + end + @statuses.each {|status| @permissions[status.id] ||= {}} + end + end + + def copy + + if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any' + @source_tracker = nil + else + @source_tracker = Tracker.find_by_id(params[:source_tracker_id].to_i) + end + if params[:source_role_id].blank? || params[:source_role_id] == 'any' + @source_role = nil + else + @source_role = Role.find_by_id(params[:source_role_id].to_i) + end + + @target_trackers = params[:target_tracker_ids].blank? ? nil : Tracker.find_all_by_id(params[:target_tracker_ids]) + @target_roles = params[:target_role_ids].blank? ? nil : Role.find_all_by_id(params[:target_role_ids]) + + if request.post? + if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?) + flash.now[:error] = l(:error_workflow_copy_source) + elsif @target_trackers.blank? || @target_roles.blank? + flash.now[:error] = l(:error_workflow_copy_target) + else + WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles) + flash[:notice] = l(:notice_successful_update) + redirect_to workflows_copy_url(:source_tracker_id => @source_tracker, :source_role_id => @source_role) + end + end + end + + private + + def find_roles + @roles = Role.sorted.all + end + + def find_trackers + @trackers = Tracker.sorted.all + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index bcba064ec..2ba16c742 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,1898 +1,1898 @@ -# encoding: utf-8 -# -# 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 'forwardable' -require 'cgi' - -module ApplicationHelper - include Redmine::WikiFormatting::Macros::Definitions - include Redmine::I18n - include GravatarHelper::PublicMethods - include Redmine::Pagination::Helper - include AvatarHelper - ## added by william - include PraiseTreadHelper - include CoursesHelper - - extend Forwardable - def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter - - # Added by young - # Define the course menu's link class - # 不是数组的转化成数组,然后判断当前menu_item是否在给定的列表 - # REVIEW: 目测menu的机制,貌似不是很需要转换,再说 - def link_class(label) - labels = label.is_a?(Array) ? label : ([] << label) - #a = current_menu_item - labels.include?(current_menu_item) ? 'selected' : '' - - end - #Ended by young - # Return true if user is authorized for controller/action, otherwise false - def authorize_for(controller, action) - User.current.allowed_to?({:controller => controller, :action => action}, @project) - end - - # add by nwb - def authorize_for_course(controller, action) - User.current.allowed_to?({:controller => controller, :action => action}, @course) - end - - def authorize_for_contest(controller, action) - User.current.allowed_to?({:controller => controller, :action => action}, @contest) - end - - # Display a link if user is authorized - # - # @param [String] name Anchor text (passed to link_to) - # @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized - # @param [optional, Hash] html_options Options passed to link_to - # @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to - def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference) - link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action]) - end - - def link_to_if_authorized_course(name, options = {}, html_options = nil, *parameters_for_method_reference) - link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_course(options[:controller] || params[:controller], options[:action]) - end - - def link_to_if_authorized_contest(name, options = {}, html_options = nil, *parameters_for_method_reference) - link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_contest(options[:controller] || params[:controller], options[:action]) - end - # Displays a link to user's account page if active - def link_to_user(user, canShowRealName = false, options={}) - if user.is_a?(User) - if canShowRealName - name = h(user.realname(options[:format])) - else - name = h(user.name(options[:format])) - end - - #if user.active? || (User.current.admin? && user.logged?) - # link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.user_domain}, :class => user.css_classes - #else - # name - #end - link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.user_domain}, :class => user.css_classes - else - h(user.to_s) - end - end - - # Displays a link to +issue+ with its subject. - # Examples: - # - # link_to_issue(issue) # => Defect #6: This is the subject - # link_to_issue(issue, :truncate => 6) # => Defect #6: This i... - # link_to_issue(issue, :subject => false) # => Defect #6 - # link_to_issue(issue, :project => true) # => Foo - Defect #6 - # link_to_issue(issue, :subject => false, :tracker => false) # => #6 - # - def link_to_issue(issue, options={}) - title = nil - subject = nil - text = options[:tracker] == false ? "##{issue.id}" : "#{issue.tracker} ##{issue.id}" - if options[:subject] == false - title = truncate(issue.subject, :length => 60) - else - subject = issue.subject - if options[:truncate] - subject = truncate(subject, :length => options[:truncate]) - end - end - s = link_to text, issue_path(issue), :class => issue.css_classes, :title => title - s << h(": #{subject}") if subject - s = h("#{issue.project} - ") + s if options[:project] - s - end - - # Generates a link to an attachment. - # Options: - # * :text - Link text (default to attachment filename) - # * :download - Force download (default: false) - def link_to_short_attachment(attachment, options={}) - text = h(truncate(options.delete(:text) || attachment.filename, length: 23, omission: '...')) - route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path - html_options = options.slice!(:only_path) - url = send(route_method, attachment, attachment.filename, options) - link_to text, url, html_options - end - - # Generates a link to an attachment. - # Options: - # * :text - Link text (default to attachment filename) - # * :download - Force download (default: false) - def link_to_attachment(attachment, options={}) - text = options.delete(:text) || attachment.filename - route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path - html_options = options.slice!(:only_path) - url = send(route_method, attachment, attachment.filename, options) - link_to text, url, html_options - end - - def link_to_attachment_img(attachment, options={}) - text = options.delete(:text) || attachment.filename - route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path - html_options = options.slice!(:only_path) - url = send(route_method, attachment, attachment.filename, options) - image_tag url, html_options - end - - # Generates a link to a SCM revision - # Options: - # * :text - Link text (default to the formatted revision) - def link_to_revision(revision, repository, options={}) - if repository.is_a?(Project) - repository = repository.repository - end - text = options.delete(:text) || format_revision(revision) - rev = revision.respond_to?(:identifier) ? revision.identifier : revision - link_to( - h(text), - {:controller => 'repositories', :action => 'revision', :id => repository.project, :repository_id => repository.identifier_param, :rev => rev}, - :title => l(:label_revision_id, format_revision(revision)) - ) - end - - # Generates a link to a message - def link_to_message(message, options={}, html_options = nil) - link_to( - truncate(message.subject, :length => 60), - board_message_path(message.board_id, message.parent_id || message.id, { - :r => (message.parent_id && message.id), - :anchor => (message.parent_id ? "message-#{message.id}" : nil) - }.merge(options)), - html_options - ) - end - - # Generates a link to a project if active - # Examples: - # - # link_to_project(project) # => link to the specified project overview - # link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options - # link_to_project(project, {}, :class => "project") # => html options with default url (project overview) - # - def link_to_project(project, options={}, html_options = nil) - if project.archived? - h(project.name) - elsif options.key?(:action) - ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0." - url = {:controller => 'projects', :action => 'show', :id => project}.merge(options) - link_to project.name, url, html_options - else - link_to project.name, project_path(project, options), html_options - end - end - - def link_to_course(course, options={}, html_options = nil) - if course.archived? - h(course.name) - elsif options.key?(:action) - ActiveSupport::Deprecation.warn "#link_to_course with :action option is deprecated and will be removed in Redmine 3.0." - url = {:controller => 'courses', :action => 'show', :id => project}.merge(options) - link_to course.name, url, html_options - else - link_to course.name, course_path(course, options), html_options - end - end - - # Generates a link to a project settings if active - def link_to_project_settings(project, options={}, html_options=nil) - if project.active? - link_to project.name, settings_project_path(project, options), html_options - elsif project.archived? - h(project.name) - else - link_to project.name, project_path(project, options), html_options - end - end - - def wiki_page_path(page, options={}) - url_for({:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title}.merge(options)) - end - - def thumbnail_tag(attachment) - link_to image_tag(thumbnail_path(attachment)), - named_attachment_path(attachment, attachment.filename), - :title => attachment.filename - end - - # 图片缩略图链接 - def thumbnail_small_tag(attachment) - imagesize = attachment.thumbnail(:size => "200*200") - imagepath = named_attachment_path(attachment, attachment.filename) - if imagesize - link_to image_tag(imagesize), - imagepath, - :title => attachment.filename - else - link_to image_tag(imagepath , height: '200', width: '250'), - imagepath, - :title => attachment.filename - end - end - - def toggle_link(name, id, options={}) - onclick = "$('##{id}').toggle(); " - onclick << (options[:focus] ? "$('##{options[:focus]}').focus(); " : "this.blur(); ") - onclick << "return false;" - link_to(name, "#", :onclick => onclick) - end - - def image_to_function(name, function, html_options = {}) - html_options.symbolize_keys! - tag(:input, html_options.merge({ - :type => "image", :src => image_path(name), - :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};" - })) - end - - def format_activity_title(text) - h(truncate_single_line(text, :length => 100)) - end - - def format_activity_day(date) - date == User.current.today ? l(:label_today).titleize : format_date(date) - end - - def format_activity_description(text) - h(truncate(text.to_s, :length => 120).gsub(%r{[\r\n]*<(pre|code)>.*$}m, '...')).gsub(/[\r\n]+/, "
").html_safe - #h(truncate(text.to_s, :length => 120).gsub(/<\/?.*?>/,"")).html_safe - end - - def format_version_name(version) - if version.project == @project - h(version) - else - h("#{version.project} - #{version}") - end - end - - def due_date_distance_in_words(date) - if date - l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date)) - end - end - - # Renders a tree of projects as a nested set of unordered lists - # The given collection may be a subset of the whole project tree - # (eg. some intermediate nodes are private and can not be seen) - #Modified by nie. - def render_project_nested_lists(projects) - s = '' - if projects.any? - ancestors = [] - original_project = @project - #modified by nie - projects.each do |project| - # set the project environment to please macros. - @project = project - if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) -# s << "\n" * ancestors.size) - @project = original_project - end - s.html_safe - end - - def render_course_nested_lists(courses) - s = '' - if courses.any? - ancestors = [] - original_course = @course - #modified by nie - courses.each do |course| - # set the project environment to please macros. - @course = course - if (ancestors.empty? )#|| course.is_descendant_of?(ancestors.last)) - s << "\n" - end - end - classes = (ancestors.empty? ? 'root' : 'child') - s << "
  • " - - s << (render :partial => 'courses/course', :locals => {:course => course}).to_s - s << "
    \n" - ancestors << course - end - s << ("
  • \n" * ancestors.size) - @course = original_course - end - s.html_safe - end - - - #added by young - def render_project_nested_lists_new(projects) - s = '' - if projects.any? - ancestors = [] - original_project = @project - projects.sort_by(&:lft).each do |project| - # set the project environment to please macros. - @project = project - if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) -# s << "\n" * ancestors.size) - @project = original_project - end - s.html_safe - end - #end - def render_page_hierarchy(pages, node=nil, options={}) - content = '' - if pages[node] - content << "\n" - end - content.html_safe - end - - # Renders flash messages - def render_flash_messages - s = '' - flash.each do |k,v| - s << content_tag('div', v.html_safe, :class => "flash #{k}", :id => "flash_#{k}") - end - s.html_safe - end - - # Renders tabs and their content - def render_tabs(tabs) - if tabs.any? - render :partial => 'common/tabs', :locals => {:tabs => tabs} - else - content_tag 'p', l(:label_no_data), :class => "nodata" - end - end - - # Renders the project quick-jump box - def render_project_jump_box - return unless User.current.logged? - projects = User.current.memberships.collect(&:project).compact.select(&:active?).uniq - if projects.any? - options = - ("" + - '').html_safe - - options << project_tree_options_for_select(projects, :selected => @project) do |p| - { :value => project_path(:id => p, :jump => current_menu_item) } - end - - select_tag('project_quick_jump_box', options, :onchange => 'if (this.value != \'\') { window.location = this.value; }') - end - end - - def project_tree_options_for_select(projects, options = {}) - s = '' - project_tree(projects) do |project, level| - name_prefix = (level > 0 ? ' ' * 2 * level + '» ' : '').html_safe - tag_options = {:value => project.id} - if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project)) - tag_options[:selected] = 'selected' - else - tag_options[:selected] = nil - end - tag_options.merge!(yield(project)) if block_given? - s << content_tag('option', name_prefix + h(project), tag_options) - end - s.html_safe - end - - # Yields the given block for each project with its level in the tree - # - # Wrapper for Project#project_tree - def project_tree(projects, &block) - Project.project_tree(projects, &block) - end - - def principals_check_box_tags(name, principals) - s = '' - principals.each do |principal| - s << "\n" - end - s.html_safe - end - - #扩展的checkbox生成 - def principals_check_box_tags_ex(name, principals) - s = '' - principals.each do |principal| - s << "\n" - end - s.html_safe - end - - #扩展的checkbox生成 - def principals_radio_box_tags_ex(name, principals) - s = '' - principals.each do |principal| - s << "\n" - end - s.html_safe - end - - - # Returns a string for users/groups option tags - def principals_options_for_select(collection, selected=nil) - s = '' - if collection.include?(User.current) - s << content_tag('option', "<< #{l(:label_me)} >>", :value => User.current.id) - end - groups = '' - collection.sort.each do |element| - selected_attribute = ' selected="selected"' if option_value_selected?(element, selected) - (element.is_a?(Group) ? groups : s) << %() - end - unless groups.empty? - s << %(#{groups}) - end - s.html_safe - end - - # Options for the new membership projects combo-box - def options_for_membership_project_select(principal, projects) - options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---") - options << project_tree_options_for_select(projects) do |p| - {:disabled => principal.projects.to_a.include?(p)} - end - options - end - - # Truncates and returns the string as a single line - def truncate_single_line(string, *args) - truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ') - end - - # Truncates at line break after 250 characters or options[:length] - def truncate_lines(string, options={}) - length = options[:length] || 250 - if string.to_s =~ /\A(.{#{length}}.*?)$/m - "#{$1}..." - else - string - end - end - - def anchor(text) - text.to_s.gsub(' ', '_') - end - - def html_hours(text) - text.gsub(%r{(\d+)\.(\d+)}, '\1.\2').html_safe - end - - def authoring(created, author, options={}) - l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe - end - - def added_time(created) - l(:label_added_time, :age => time_tag(created)).html_safe - end - - def user_url_and_time(user_name, user_url, created) - unless user_name.nil? || user_name == '' - l(:label_added_time_by, :author => link_to(user_name, user_url), :age => time_tag(created)).html_safe - else - l(:label_added_time, :age => time_tag(created)).html_safe - end - end - - #huang - def betweentime(enddate) - ss=(DateTime.parse("#{enddate.to_date}")-DateTime.parse("#{DateTime.now.to_date}")).to_i - return ss - end - - def time_tag(time) - text = distance_of_time_in_words(Time.now, time) - if @project - link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)}, :title => format_time(time)) - else - content_tag('acronym', text, :title => format_time(time)) - end - end - - def syntax_highlight_lines(name, content) - lines = [] - syntax_highlight(name, content).each_line { |line| lines << line } - lines - end - - def syntax_highlight(name, content) - Redmine::SyntaxHighlighting.highlight_by_filename(content, name) - end - - def to_path_param(path) - str = path.to_s.split(%r{[/\\]}).select{|p| !p.blank?}.join("/") - str.blank? ? nil : str - end - - def reorder_links(name, url, method = :post) - link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), - url.merge({"#{name}[move_to]" => 'highest'}), - :method => method, :title => l(:label_sort_highest)) + - link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), - url.merge({"#{name}[move_to]" => 'higher'}), - :method => method, :title => l(:label_sort_higher)) + - link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), - url.merge({"#{name}[move_to]" => 'lower'}), - :method => method, :title => l(:label_sort_lower)) + - link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), - url.merge({"#{name}[move_to]" => 'lowest'}), - :method => method, :title => l(:label_sort_lowest)) - end - - def breadcrumb(*args) - elements = args.flatten - elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'breadcrumb') : nil - end - - def other_formats_links(&block) - concat('

    '.html_safe + l(:label_export_to)) - yield Redmine::Views::OtherFormatsBuilder.new(self) - concat('

    '.html_safe) - end - - def page_header_title - if @project.nil? || @project.new_record? - h(Setting.app_title) - else - b = [] - ancestors = (@project.root? ? [] : @project.ancestors.visible.all) - if ancestors.any? - root = ancestors.shift - b << link_to_project(root, {:jump => current_menu_item}, :class => 'root') - if ancestors.size > 2 - b << "\xe2\x80\xa6" - ancestors = ancestors[-2, 2] - end - b += ancestors.collect {|p| link_to_project(p, {:jump => current_menu_item}, :class => 'ancestor') } - end - b << h(@project) - b.join(" \xc2\xbb ").html_safe - end - end - - def html_title(*args) - #點擊項目版本庫 多觸發一次 字符串為"/" - #暫時解決方法 直接判斷 - if(args == ["/"]) - args = [] - end - first_page = FirstPage.find_by_page_type('project') - if args.empty? - title = @html_title || [] - title << @project.name if @project - if first_page.nil? || first_page.web_title.nil? - title << Setting.app_title unless Setting.app_title == title.last - else - title << first_page.web_title unless first_page.web_title == title.last - end - title.select {|t| !t.blank? }.join(' - ') - else - @html_title ||= [] - @html_title += args - end - end - - # Returns the theme, controller name, and action as css classes for the - # HTML body. - def body_css_classes - css = [] - if theme = Redmine::Themes.theme(Setting.ui_theme) - css << 'theme-' + theme.name - end - - css << 'controller-' + controller_name - css << 'action-' + action_name - css.join(' ') - end - - def accesskey(s) - @used_accesskeys ||= [] - key = Redmine::AccessKeys.key_for(s) - return nil if @used_accesskeys.include?(key) - @used_accesskeys << key - key - end - - # Formats text according to system settings. - # 2 ways to call this method: - # * with a String: textilizable(text, options) - # * with an object and one of its attribute: textilizable(issue, :description, options) - 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' - end - return '' if text.blank? - project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) - only_path = options.delete(:only_path) == false ? false : true - - text = text.dup - macros = catch_macros(text) - text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) - - @parsed_headings = [] - @heading_anchors = {} - @current_section = 0 if options[:edit_section_links] - - parse_sections(text, project, obj, attr, only_path, options) - text = parse_non_pre_blocks(text, obj, macros) do |text| - [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name| - send method_name, text, project, obj, attr, only_path, options - end - end - parse_headings(text, project, obj, attr, only_path, options) - - if @parsed_headings.any? - replace_toc(text, @parsed_headings) - end - - text.html_safe - end - - # - #格式化字符串,不转义html代码 - def textAreailizable(*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' - end - return '' if text.blank? - project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) - only_path = options.delete(:only_path) == false ? false : true - - text = text.dup - macros = catch_macros(text) - #text = Redmine::WikiFormatting.to_html("CKEditor", text, :object => obj, :attribute => attr) - - @parsed_headings = [] - @heading_anchors = {} - @current_section = 0 if options[:edit_section_links] - - parse_sections(text, project, obj, attr, only_path, options) - text = parse_non_pre_blocks(text, obj, macros) do |text| - [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name| - send method_name, text, project, obj, attr, only_path, options - end - end - parse_headings(text, project, obj, attr, only_path, options) - - if @parsed_headings.any? - replace_toc(text, @parsed_headings) - end - - text.html_safe - end - - def parse_non_pre_blocks(text, obj, macros) - s = StringScanner.new(text) - tags = [] - parsed = '' - while !s.eos? - s.scan(/(.*?)(<(\/)?(pre|code)(.*?)>|\z)/im) - text, full_tag, closing, tag = s[1], s[2], s[3], s[4] - if tags.empty? - yield text - inject_macros(text, obj, macros) if macros.any? - else - inject_macros(text, obj, macros, false) if macros.any? - end - parsed << text - if tag - if closing - if tags.last == tag.downcase - tags.pop - end - else - tags << tag.downcase - end - parsed << full_tag - end - end - # Close any non closing tags - while tag = tags.pop - parsed << "" - end - parsed - end - - def parse_inline_attachments(text, project, obj, attr, only_path, options) - # when using an image link, try to use an attachment, if possible - attachments = options[:attachments] || [] - attachments += obj.attachments if obj.respond_to?(:attachments) - if attachments.present? - text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m| - filename, ext, alt, alttext = $1.downcase, $2, $3, $4 - # search for the picture in attachments - if found = Attachment.latest_attach(attachments, filename) - image_url = download_named_attachment_path(found, found.filename, :only_path => only_path) - desc = found.description.to_s.gsub('"', '') - if !desc.blank? && alttext.blank? - alt = " title=\"#{desc}\" alt=\"#{desc}\"" - end - "src=\"#{image_url}\"#{alt}" - else - m - end - end - end - end - - # Wiki links - # - # Examples: - # [[mypage]] - # [[mypage|mytext]] - # wiki links can refer other project wikis, using project name or identifier: - # [[project:]] -> wiki starting page - # [[project:|mytext]] - # [[project:mypage]] - # [[project:mypage|mytext]] - def parse_wiki_links(text, project, obj, attr, only_path, options) - text.gsub!(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m| - link_project = project - esc, all, page, title = $1, $2, $3, $5 - if esc.nil? - if page =~ /^([^\:]+)\:(.*)$/ - identifier, page = $1, $2 - link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier) - title ||= identifier if page.blank? - end - - if link_project && link_project.wiki - # extract anchor - anchor = nil - if page =~ /^(.+?)\#(.+)$/ - page, anchor = $1, $2 - end - anchor = sanitize_anchor_name(anchor) if anchor.present? - # check if page exists - wiki_page = link_project.wiki.find_page(page) - url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page - "##{anchor}" - else - case options[:wiki_links] - when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '') - when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export - else - wiki_page_id = page.present? ? Wiki.titleize(page) : nil - parent = wiki_page.nil? && obj.is_a?(WikiContent) && obj.page && project == link_project ? obj.page.title : nil - url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project, - :id => wiki_page_id, :version => nil, :anchor => anchor, :parent => parent) - end - end - link_to(title.present? ? title.html_safe : h(page), url, :class => ('wiki-page' + (wiki_page ? '' : ' new'))) - else - # project or wiki doesn't exist - all - end - else - all - end - end - end - - def select_option_helper option - tmp = Hash.new - tmp={"" => ""} - if option.nil? - else - option.each do |project| - tmp[project.name] = project.id - end - end - tmp - end - # Redmine links - # - # Examples: - # Issues: - # #52 -> Link to issue #52 - # Changesets: - # r52 -> Link to revision 52 - # commit:a85130f -> Link to scmid starting with a85130f - # Documents: - # document#17 -> Link to document with id 17 - # document:Greetings -> Link to the document with title "Greetings" - # document:"Some document" -> Link to the document with title "Some document" - # Versions: - # version#3 -> Link to version with id 3 - # version:1.0.0 -> Link to version named "1.0.0" - # version:"1.0 beta 2" -> Link to version named "1.0 beta 2" - # Attachments: - # attachment:file.zip -> Link to the attachment of the current object named file.zip - # Source files: - # source:some/file -> Link to the file located at /some/file in the project's repository - # source:some/file@52 -> Link to the file's revision 52 - # source:some/file#L120 -> Link to line 120 of the file - # source:some/file@52#L120 -> Link to line 120 of the file's revision 52 - # export:some/file -> Force the download of the file - # Forum messages: - # message#1218 -> Link to message with id 1218 - # - # Links can refer other objects from other projects, using project identifier: - # identifier:r52 - # identifier:document:"Some document" - # identifier:version:1.0.0 - # identifier:source:some/file - def parse_redmine_links(text, default_project, obj, attr, only_path, options) - text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m| - leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17 - link = nil - project = default_project - if project_identifier - project = Project.visible.find_by_identifier(project_identifier) - end - if esc.nil? - if prefix.nil? && sep == 'r' - if project - repository = nil - if repo_identifier - repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} - else - repository = project.repository - end - # project.changesets.visible raises an SQL error because of a double join on repositories - if repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(repository.id, identifier)) - link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.revision}, - :class => 'changeset', - :title => truncate_single_line(changeset.comments, :length => 100)) - end - end - elsif sep == '#' - oid = identifier.to_i - case prefix - when nil - if oid.to_s == identifier && issue = Issue.visible.find_by_id(oid, :include => :status) - anchor = comment_id ? "note-#{comment_id}" : nil - link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid, :anchor => anchor}, - :class => issue.css_classes, - :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})") - end - when 'document' - if document = Document.visible.find_by_id(oid) - link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, - :class => 'document' - end - when 'version' - if version = Version.visible.find_by_id(oid) - link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, - :class => 'version' - end - when 'message' - if message = Message.visible.find_by_id(oid, :include => :parent) - link = link_to_message(message, {:only_path => only_path}, :class => 'message') - end - when 'forum' - if board = Board.visible.find_by_id(oid) - link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, - :class => 'board' - end - when 'news' - if news = News.visible.find_by_id(oid) - link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, - :class => 'news' - end - when 'project' - if p = Project.visible.find_by_id(oid) - link = link_to_project(p, {:only_path => only_path}, :class => 'project') - end - end - elsif sep == ':' - # removes the double quotes if any - name = identifier.gsub(%r{^"(.*)"$}, "\\1") - case prefix - when 'document' - if project && document = project.documents.visible.find_by_title(name) - link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, - :class => 'document' - end - when 'version' - if project && version = project.versions.visible.find_by_name(name) - link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, - :class => 'version' - end - when 'forum' - if project && board = project.boards.visible.find_by_name(name) - link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, - :class => 'board' - end - when 'news' - if project && news = project.news.visible.find_by_title(name) - link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, - :class => 'news' - end - when 'commit', 'source', 'export' - if project - repository = nil - if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$} - repo_prefix, repo_identifier, name = $1, $2, $3 - repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} - else - repository = project.repository - end - if prefix == 'commit' - if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first) - link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier}, - :class => 'changeset', - :title => truncate_single_line(changeset.comments, :length => 100) - end - else - if repository && User.current.allowed_to?(:browse_repository, project) - name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$} - path, rev, anchor = $1, $3, $5 - link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param, - :path => to_path_param(path), - :rev => rev, - :anchor => anchor}, - :class => (prefix == 'export' ? 'source download' : 'source') - end - end - repo_prefix = nil - end - when 'attachment' - attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil) - if attachments && attachment = Attachment.latest_attach(attachments, name) - link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment') - end - when 'project' - if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first - link = link_to_project(p, {:only_path => only_path}, :class => 'project') - end - end - end - end - (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}")) - end - end - - HEADING_RE = /(]+)?>(.+?)<\/h(\d)>)/i unless const_defined?(:HEADING_RE) - - def parse_sections(text, project, obj, attr, only_path, options) - return unless options[:edit_section_links] - text.gsub!(HEADING_RE) do - heading = $1 - @current_section += 1 - if @current_section > 1 - content_tag('div', - link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)), - :class => 'contextual', - :title => l(:button_edit_section)) + heading.html_safe - else - heading - end - end - end - - # Headings and TOC - # Adds ids and links to headings unless options[:headings] is set to false - def parse_headings(text, project, obj, attr, only_path, options) - return if options[:headings] == false - - text.gsub!(HEADING_RE) do - level, attrs, content = $2.to_i, $3, $4 - item = strip_tags(content).strip - anchor = sanitize_anchor_name(item) - # used for single-file wiki export - anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) - @heading_anchors[anchor] ||= 0 - idx = (@heading_anchors[anchor] += 1) - if idx > 1 - anchor = "#{anchor}-#{idx}" - end - @parsed_headings << [level, anchor, item] - "\n#{content}" - end - end - - MACROS_RE = /( - (!)? # escaping - ( - \{\{ # opening tag - ([\w]+) # macro name - (\(([^\n\r]*?)\))? # optional arguments - ([\n\r].*?[\n\r])? # optional block of text - \}\} # closing tag - ) - )/mx unless const_defined?(:MACROS_RE) - - MACRO_SUB_RE = /( - \{\{ - macro\((\d+)\) - \}\} - )/x unless const_defined?(:MACRO_SUB_RE) - - # Extracts macros from text - def catch_macros(text) - macros = {} - text.gsub!(MACROS_RE) do - all, macro = $1, $4.downcase - if macro_exists?(macro) || all =~ MACRO_SUB_RE - index = macros.size - macros[index] = all - "{{macro(#{index})}}" - else - all - end - end - macros - end - - # Executes and replaces macros in text - def inject_macros(text, obj, macros, execute=true) - text.gsub!(MACRO_SUB_RE) do - all, index = $1, $2.to_i - orig = macros.delete(index) - if execute && orig && orig =~ MACROS_RE - esc, all, macro, args, block = $2, $3, $4.downcase, $6.to_s, $7.try(:strip) - if esc.nil? - h(exec_macro(macro, obj, args, block) || all) - else - h(all) - end - elsif orig - h(orig) - else - h(all) - end - end - end - - TOC_RE = /

    \{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE) - - # Renders the TOC with given headings - def replace_toc(text, headings) - text.gsub!(TOC_RE) do - # Keep only the 4 first levels - headings = headings.select{|level, anchor, item| level <= 4} - if headings.empty? - '' - else - div_class = 'toc' - div_class << ' right' if $1 == '>' - div_class << ' left' if $1 == '<' - out = "

    • " - root = headings.map(&:first).min - current = root - started = false - headings.each do |level, anchor, item| - if level > current - out << '
      • ' * (level - current) - elsif level < current - out << "
      \n" * (current - level) + "
    • " - elsif started - out << '
    • ' - end - out << "#{item}" - current = level - started = true - end - out << '
    ' * (current - root) - out << '' - end - end - end - - # Same as Rails' simple_format helper without using paragraphs - def simple_format_without_paragraph(text) - text.to_s. - gsub(/\r\n?/, "\n"). # \r\n and \r -> \n - gsub(/\n\n+/, "

    "). # 2+ newline -> 2 br - gsub(/([^\n]\n)(?=[^\n])/, '\1
    '). # 1 newline -> br - html_safe - end - - def lang_options_for_select(blank=true) - { 'Chinese简体中文 '=> 'zh', :English => :en} - end - - def label_tag_for(name, option_tags = nil, options = {}) - label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "") - content_tag("label", label_text) - end - - def labelled_form_for(*args, &proc) - args << {} unless args.last.is_a?(Hash) - options = args.last - if args.first.is_a?(Symbol) - options.merge!(:as => args.shift) - end - options.merge!({:builder => Redmine::Views::LabelledFormBuilder}) - form_for(*args, &proc) - end - - def labelled_fields_for(*args, &proc) - args << {} unless args.last.is_a?(Hash) - options = args.last - options.merge!({:builder => Redmine::Views::LabelledFormBuilder}) - fields_for(*args, &proc) - end - - def labelled_remote_form_for(*args, &proc) - ActiveSupport::Deprecation.warn "ApplicationHelper#labelled_remote_form_for is deprecated and will be removed in Redmine 2.2." - args << {} unless args.last.is_a?(Hash) - options = args.last - options.merge!({:builder => Redmine::Views::LabelledFormBuilder, :remote => true}) - form_for(*args, &proc) - end - - def error_messages_for(*objects) - html = "" - # modified by fq - if objects.first.is_a?(Array) - objects = objects.first - end - # end - if objects != nil - objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact - errors = objects.map {|o| o.errors.full_messages}.flatten - if errors.any? - html << "
      \n" - errors.each do |error| - ###by xianbo - if(error!=l(:label_repository_path_not_null)) - html << "
    • #{h error}
    • \n" - end - ###xianbo - end - ###by xianbo - unless params[:repository].nil? - if params[:repository][:upassword]=="" - html << "
    • "+ l(:label_password_not_null) +"
    • \n" - end - end - ###xianbo - html << "
    \n" - end - end - html.html_safe - end - - def delete_link(url, options={}) - options = { - :method => :delete, - :data => {:confirm => l(:text_are_you_sure)}, - :class => 'icon icon-del' - }.merge(options) - - link_to l(:button_delete), url, options - end - - def preview_link(url, form, target='preview', options={}) - content_tag 'a', l(:label_preview), { - :href => "#", - :onclick => %|submitPreview("#{escape_javascript url_for(url)}", "#{escape_javascript form}", "#{escape_javascript target}"); return false;|, - :accesskey => accesskey(:preview) - }.merge(options) - end - - def link_to_function(name, function, html_options={}) - content_tag(:a, name, {:href => '#', :onclick => "#{function}; return false;"}.merge(html_options)) - end - - # Helper to render JSON in views - def raw_json(arg) - arg.to_json.to_s.gsub('/', '\/').html_safe - end - - def back_url - url = params[:back_url] - if url.nil? && referer = request.env['HTTP_REFERER'] - url = CGI.unescape(referer.to_s) - end - url - end - - def back_url_hidden_field_tag - url = back_url - hidden_field_tag('back_url', url, :id => nil) unless url.blank? - end - - def check_all_links(form_name) - link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") + - " | ".html_safe + - link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)") - end - - def progress_bar(pcts, options={}) - pcts = [pcts, pcts] unless pcts.is_a?(Array) - pcts = pcts.collect(&:round) - pcts[1] = pcts[1] - pcts[0] - pcts << (100 - pcts[1] - pcts[0]) - width = options[:width] || '100px;' - legend = options[:legend] || '' - content_tag('table', - content_tag('tr', - (pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed') : ''.html_safe) + - (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) + - (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe) - ), :class => 'progress', :style => "width: #{width};").html_safe + - content_tag('p', legend, :class => 'percent').html_safe - end - - def checked_image(checked=true) - if checked - image_tag 'toggle_check.png' - end - end - - def context_menu(url) - unless @context_menu_included - content_for :header_tags do - javascript_include_tag('context_menu') + - stylesheet_link_tag('context_menu') - end - if l(:direction) == 'rtl' - content_for :header_tags do - stylesheet_link_tag('context_menu_rtl') - end - end - @context_menu_included = true - end - javascript_tag "contextMenuInit('#{ url_for(url) }')" - end - - def calendar_for(field_id,start_day=nil) - include_calendar_headers_tags(start_day) - javascript_tag("$(function() { $('##{field_id}').datepicker(datepickerOptions); });") - end - - def include_calendar_headers_tags(start_day=nil) - if start_day.nil? - unless @calendar_headers_tags_included - @calendar_headers_tags_included = true - content_for :header_tags do - start_of_week = Setting.start_of_week - start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank? - # Redmine uses 1..7 (monday..sunday) in settings and locales - # JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0 - start_of_week = start_of_week.to_i % 7 - - tags = javascript_tag( - "var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " + - "showOn: 'button', buttonImageOnly: true, buttonImage: '" + - path_to_image('/images/calendar.png') + - "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};") - jquery_locale = l('jquery.locale', :default => current_language.to_s) - unless jquery_locale == 'en' - tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js") - end - tags - end - end - else - unless @calendar_headers_tags_included - @calendar_headers_tags_included = true - content_for :header_tags do - start_of_week = Setting.start_of_week - start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank? - # Redmine uses 1..7 (monday..sunday) in settings and locales - # JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0 - start_of_week = start_of_week.to_i % 7 - - tags = javascript_tag( - "var datepickerOptions={dateFormat: 'yy-mm-dd',minDate: new Date(), firstDay: #{start_of_week}, " + - "showOn: 'button', buttonImageOnly: true, buttonImage: '" + - path_to_image('/images/calendar.png') + - "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true, onClose: function(dateText, inst) {TimeClose(dateText,inst);}, beforeShow : function(input){TimeBeforeShow(input);} };") - jquery_locale = l('jquery.locale', :default => current_language.to_s) - unless jquery_locale == 'en' - tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js") - end - tags - end - end - end - - end - - # Overrides Rails' stylesheet_link_tag with themes and plugins support. - # Examples: - # stylesheet_link_tag('styles') # => picks styles.css from the current theme or defaults - # stylesheet_link_tag('styles', :plugin => 'foo) # => picks styles.css from plugin's assets - # - def stylesheet_link_tag(*sources) - options = sources.last.is_a?(Hash) ? sources.pop : {} - plugin = options.delete(:plugin) - sources = sources.map do |source| - if plugin - "/plugin_assets/#{plugin}/stylesheets/#{source}" - elsif current_theme && current_theme.stylesheets.include?(source) - current_theme.stylesheet_path(source) - else - source - end - end - super sources, options - end - - # Overrides Rails' image_tag with themes and plugins support. - # Examples: - # image_tag('image.png') # => picks image.png from the current theme or defaults - # image_tag('image.png', :plugin => 'foo) # => picks image.png from plugin's assets - # - def image_tag(source, options={}) - if plugin = options.delete(:plugin) - source = "/plugin_assets/#{plugin}/images/#{source}" - elsif current_theme && current_theme.images.include?(source) - source = current_theme.image_path(source) - end - super source, options - end - - # Overrides Rails' javascript_include_tag with plugins support - # Examples: - # javascript_include_tag('scripts') # => picks scripts.js from defaults - # javascript_include_tag('scripts', :plugin => 'foo) # => picks scripts.js from plugin's assets - # - def javascript_include_tag(*sources) - options = sources.last.is_a?(Hash) ? sources.pop : {} - if plugin = options.delete(:plugin) - sources = sources.map do |source| - if plugin - "/plugin_assets/#{plugin}/javascripts/#{source}" - else - source - end - end - end - super sources, options - end - - def content_for(name, content = nil, &block) - @has_content ||= {} - @has_content[name] = true - super(name, content, &block) - end - - def has_content?(name) - (@has_content && @has_content[name]) || false - end - - def sidebar_content? - has_content?(:sidebar) || view_layouts_base_sidebar_hook_response.present? - end - - def view_layouts_base_sidebar_hook_response - @view_layouts_base_sidebar_hook_response ||= call_hook(:view_layouts_base_sidebar) - end - - def email_delivery_enabled? - !!ActionMailer::Base.perform_deliveries - end - - # Returns the avatar image tag for the given +user+ if avatars are enabled - # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe ') - def avatar(user, options = { }) - if Setting.gravatar_enabled? - options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default}) - email = nil - if user.respond_to?(:mail) - email = user.mail - elsif user.to_s =~ %r{<(.+?)>} - email = $1 - end - return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil - #options ={"class" => ["avatar2"],"width" =>["80px"],"height" =>["80px"]} - #return image_tag url_to_avatar(user), options - else - '' - end - end - - def sanitize_anchor_name(anchor) - if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java' - anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-') - else - # TODO: remove when ruby1.8 is no longer supported - anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-') - end - end - - # Returns the javascript tags that are included in the html layout head - def javascript_heads - tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application', 'jquery.colorbox-min') - unless User.current.pref.warn_on_leaving_unsaved == '0' - tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });") - end - tags - end - - def hubspot_head - tags = javascript_include_tag('hubspot/messenger.min', 'hubspot/messenger-theme-future') - tags << stylesheet_link_tag('hubspot/messenger', 'hubspot/messenger-theme-future', 'hubspot/messenger-theme-flat') - end - - def bootstrap_head - tags = stylesheet_link_tag('bootstrap/bootstrap.min', 'bootstrap/bootstrap-theme.min') - tags << javascript_include_tag('bootstrap/affix') - tags << javascript_include_tag('bootstrap/alert') - tags << javascript_include_tag('bootstrap/button') - tags << javascript_include_tag('bootstrap/carousel') - tags << javascript_include_tag('bootstrap/collapse') - tags << javascript_include_tag('bootstrap/dropdown') - tags << javascript_include_tag('bootstrap/modal') - tags << javascript_include_tag('bootstrap/popover') - tags << javascript_include_tag('bootstrap/scrollspy') - tags << javascript_include_tag('bootstrap/tab') - tags << javascript_include_tag('bootstrap/tooltip') - tags << javascript_include_tag('bootstrap/transition') - tags - end - - def favicon - "".html_safe - end - - def robot_exclusion_tag - ''.html_safe - end - - # Returns true if arg is expected in the API response - def include_in_api_response?(arg) - unless @included_in_api_response - param = params[:include] - @included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',') - @included_in_api_response.collect!(&:strip) - end - @included_in_api_response.include?(arg.to_s) - end - - # Returns options or nil if nometa param or X-Redmine-Nometa header - # was set in the request - def api_meta(options) - if params[:nometa].present? || request.headers['X-Redmine-Nometa'] - # compatibility mode for activeresource clients that raise - # an error when unserializing an array with attributes - nil - else - options - end - end - - # Add by Tao - def url_to_avatar(source) - source = nil if source.kind_of?(String) - get_avatar(source) - end - # Endof Tao's code - - def date_format_local(time) - date = time.strftime("%Y年%m月%d日") - end - - #当TAG数量过多时,更多链接 - #1代表是user类型 2代表是project类型 3代表是issue类型 4代表需求 9代表课程 - def more_tags id,object_flag - a= 1 - case object_flag - when "1" - s = link_to l(:label_more_tags),:controller => "users", :action => "show", :id => id - when "2" - s = link_to l(:label_more_tags),:controller => "projects", :action => "show", :id => id - when "3" - s = link_to l(:label_more_tags),:controller => "issues", :action => "show", :id => id - when "4" - s = link_to l(:label_more_tags),:controller => "bids", :action => "show", :id => id - when "9" - s = link_to l(:label_more_tags),:controller => "courses", :action => "show", :id => id - end - s - end - - private - - def wiki_helper - helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting) - extend helper - return self - end - - def link_to_content_update(text, url_params = {}, html_options = {}) - link_to(text, url_params, html_options) - end - -#added by nie -# Display watcher picture - def show_more_watchers?(obj) - if User.watched_by(obj.id).count > 6 - return true - else - return false - end - end - - def show_watcher_profile(obj) - count = 0 - html = '' - if User.watched_by(obj.id).count == 0 - html << (content_tag "span", l(:label_no_current_watchers)) - end - for user in User.watched_by(obj.id) - html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}") - count = count + 1 - if count >= 12 - break - end - end - html.html_safe - end - -#display bid project - def show_more_bid_project?(bid) - if bid.projects.where('is_public = 1').count > 12 - return true - else - return false - end - end - - def show_bid_project(bid) - html = '' - if bid.projects.where('is_public = 1').count == 0 - html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") - else - bid.projects.where('is_public = 1').take(12).each do |project| - html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") - end - end - html.html_safe - end - - def show_bid_fans_picture(obj) - html = '' - if obj.watcher_users.count == 0 - html << (content_tag "span", l(:label_project_no_follow)) - else - obj.watcher_users.take(12).each do |user| - html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) - end - end - html.html_safe - end - -#display contest project - def show_more_contest_project?(contest) - if contest.projects.where('is_public = 1').count > 12 - return true - else - return false - end - end - - def show_more_contest_softapplication?(contest) - if contest.softapplications.where('is_public = 1').count > 12 - return true - else - return false - end - end - - def show_contest_project(bid) - html = '' - if contest.projects.where('is_public = 1').count == 0 - html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") - else - contest.projects.where('is_public = 1').take(12).each do |project| - html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") - end - end - html.html_safe - end - - def show_contest_project(contest) - html = '' - if contest.projects.where('is_public = 1').count == 0 - html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") - else - contest.projects.where('is_public = 1').take(12).each do |project| - html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") - end - end - html.html_safe - end - - def show_contest_softapplication(contest) - html = '' - if contest.softapplications.where('is_public = 1').count == 0 - html << (content_tag "p", l(:label_no_contest_softapplication), :class => "font_lighter") - else - contest.softapplications.where('is_public = 1').take(12).each do |softapplication| - html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") - end - end - html.html_safe - end - - def show_contest_fans_picture(obj) - html = '' - if obj.watcher_users.count == 0 - html << (content_tag "span", l(:label_project_no_follow)) - else - obj.watcher_users.take(12).each do |user| - html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) - end - end - html.html_safe - end - -#display fans picture - def show_more_fans?(obj) - if obj.watcher_users.count > 12 - return true - else - return false - end - end - - def show_fans_picture(obj) - html = '' - if obj.watcher_users.count == 0 - html << (content_tag "span", l(:label_no_current_fans)) - else - obj.watcher_users.take(12).each do |user| - html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) - end - end - html.html_safe - end - - # added by bai - def show_more_participate?(obj) - if obj.join_in_contests.count > 12 - return true - else - return false - end - end - - def show_participate_picture(obj) - html = '' - count = 0 - if obj.join_in_contests.count == 0 - html << (content_tag "span", l(:label_no_current_participate)) - end - for temp in obj.join_in_contests - html << (link_to image_tag(url_to_avatar(temp.user), :class => "avatar"), user_path(temp.user), :class => "avatar", :title => "#{temp.user.name}") - count = count + 1 - if count >= 12 - break - end - end - html.html_safe - end - -#end - -# add by huang - def show_watcher_list(user) - html = '' - count = 0 - for user in User.watched_by(user.id) - html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}") - count = count + 1 - if count >= 12 - break - end - end - html.html_safe - end -# end - -#added by william - def get_fans_num(user) - user.watcher_users.count - end -#end - - - def hadcommittedhomework(cur,curb) - bid = Bid.find_by_id(curb) - return true if bid.nil? - - case bid.homework_type - when Bid::HomeworkFile - attaches = HomeworkAttach.where(bid_id: curb) - attaches.map(&:user_id).include? cur - when Bid::HomeworkProject - attaches = BidingProject.where(user_id: User.current, bid_id: bid) - attaches.count > 0 # > 0 则有提交记录 - else - true - end - - end - - def render_dynamic_nav - home_link = link_to l(:field_homepage), {:controller => 'welcome', :action => 'index'} - home_link = "
  • " << home_link << "
  • " - # bootstrap_render_dynamic_nav - content_tag :ul, (home_link.html_safe+bootstrap_render_dynamic_nav) - end - - def bootstrap_render_dynamic_nav - - main_course_link = link_to l(:label_course_practice), {:controller => 'welcome', :action => 'index', :host => Setting.course_domain} - main_project_link = link_to l(:label_project_deposit), {:controller => 'welcome', :action => 'index', :host => Setting.project_domain} - main_contest_link = link_to l(:label_contest_innovate), {:controller => 'welcome', :action => 'index', :host => Setting.contest_domain} - - course_all_course_link = link_to l(:label_course_all), {:controller => 'courses', :action => 'index'} - course_teacher_all_link = link_to l(:label_teacher_all), {:controller => 'users', :action => 'index', :role => 'teacher', :host => Setting.course_domain} - courses_link = link_to l(:label_course_practice), {:controller => 'courses', :action => 'index'} - projects_link = link_to l(:label_project_deposit), {:controller => 'projects', :action => 'index', :project_type => 0, :host => Setting.project_domain} - users_link = link_to l(:label_software_user), {:controller => 'users', :action => 'index', :host => Setting.user_domain} - contest_link = link_to l(:label_contest_innovate), {:controller => 'contests', :action => 'index'} - bids_link = link_to l(:label_requirement_enterprise), {:controller => 'bids', :action => 'index'} - forum_link = link_to l(:label_project_module_forums), {:controller => "forums", :action => "index"} - stores_link = link_to l(:label_stores_index), {:controller => 'stores', :action=> 'index'} - - - school_all_school_link = link_to l(:label_school_all), {:controller => 'school', :action => 'index'} - - - #@nav_dispaly_project_label - nav_list = Array.new - nav_list.push(school_all_school_link) if @nav_dispaly_course_all_label && @show_course == 1 - nav_list.push(course_all_course_link) if @nav_dispaly_course_all_label && @show_course == 1 - nav_list.push(course_teacher_all_link) if @nav_dispaly_teacher_all_label && @show_course == 1 - - nav_list.push(main_project_link) if @nav_dispaly_main_project_label - nav_list.push(main_course_link) if @nav_dispaly_main_course_label && @show_course == 1 - nav_list.push(main_contest_link) if @nav_dispaly_main_contest_label && @show_contest == 1 - - nav_list.push(courses_link) if @nav_dispaly_course_label && @show_course == 1 - nav_list.push(projects_link) if @nav_dispaly_project_label - nav_list.push(users_link) if @nav_dispaly_user_label - nav_list.push(contest_link) if @nav_dispaly_contest_label && @show_contest == 1 - nav_list.push(bids_link) if @nav_dispaly_bid_label - nav_list.push(forum_link) if @nav_dispaly_forum_label - nav_list.push(stores_link) if @nav_dispaly_store_all_label - - content_li = '' - nav_list.collect do |nav_item| - content_li << content_tag(:li, nav_item) - end - content_li.html_safe - end - - def current_user - User.current - end - - # def hadcommittedforcontest(curu) - # message = JournalsForMessage.find_by_sql("select * from journals_for_messages where jour_type = 'Softapplication' ") - # message.each do |createmessage| - # if createmessage.user_id == curu - # return true - # end - # end - # end - - def footer_logo(ul_class=nil, li_class=nil) - logos = [] - logos.push(link_to image_tag('/images/footer_logo/nudt.png',:alt=>"nudt"),"http://www.nudt.edu.cn/special.asp?classid=12" ) - logos.push(link_to image_tag('/images/footer_logo/peking_eecs.png', :alt=>"peking_eecs"), "http://eecs.pku.edu.cn" ) - logos.push(link_to image_tag('/images/footer_logo/buaa_scse.png', :alt=>"buaa_scse"), "http://scse.buaa.edu.cn/" ) - logos.push(link_to image_tag('/images/footer_logo/iscas.png', :alt=>"iscas"), "http://www.iscas.ac.cn" ) - logos.push(link_to image_tag('/images/footer_logo/inforbus.png', :alt=>"inforbus"), "http://www.inforbus.com" ) - - logos.collect! { |logo| - content_tag(:li, logo.html_safe, :class => li_class.to_s) - } - - content_tag(:ul, logos.join("").html_safe, :class => ul_class.to_s).html_safe - end - - -end +# encoding: utf-8 +# +# 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 'forwardable' +require 'cgi' + +module ApplicationHelper + include Redmine::WikiFormatting::Macros::Definitions + include Redmine::I18n + include GravatarHelper::PublicMethods + include Redmine::Pagination::Helper + include AvatarHelper + ## added by william + include PraiseTreadHelper + include CoursesHelper + + extend Forwardable + def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter + + # Added by young + # Define the course menu's link class + # 不是数组的转化成数组,然后判断当前menu_item是否在给定的列表 + # REVIEW: 目测menu的机制,貌似不是很需要转换,再说 + def link_class(label) + labels = label.is_a?(Array) ? label : ([] << label) + #a = current_menu_item + labels.include?(current_menu_item) ? 'selected' : '' + + end + #Ended by young + # Return true if user is authorized for controller/action, otherwise false + def authorize_for(controller, action) + User.current.allowed_to?({:controller => controller, :action => action}, @project) + end + + # add by nwb + def authorize_for_course(controller, action) + User.current.allowed_to?({:controller => controller, :action => action}, @course) + end + + def authorize_for_contest(controller, action) + User.current.allowed_to?({:controller => controller, :action => action}, @contest) + end + + # Display a link if user is authorized + # + # @param [String] name Anchor text (passed to link_to) + # @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized + # @param [optional, Hash] html_options Options passed to link_to + # @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to + def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference) + link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action]) + end + + def link_to_if_authorized_course(name, options = {}, html_options = nil, *parameters_for_method_reference) + link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_course(options[:controller] || params[:controller], options[:action]) + end + + def link_to_if_authorized_contest(name, options = {}, html_options = nil, *parameters_for_method_reference) + link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_contest(options[:controller] || params[:controller], options[:action]) + end + # Displays a link to user's account page if active + def link_to_user(user, canShowRealName = false, options={}) + if user.is_a?(User) + if canShowRealName + name = h(user.realname(options[:format])) + else + name = h(user.name(options[:format])) + end + + #if user.active? || (User.current.admin? && user.logged?) + # link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.user_domain}, :class => user.css_classes + #else + # name + #end + link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.user_domain}, :class => user.css_classes + else + h(user.to_s) + end + end + + # Displays a link to +issue+ with its subject. + # Examples: + # + # link_to_issue(issue) # => Defect #6: This is the subject + # link_to_issue(issue, :truncate => 6) # => Defect #6: This i... + # link_to_issue(issue, :subject => false) # => Defect #6 + # link_to_issue(issue, :project => true) # => Foo - Defect #6 + # link_to_issue(issue, :subject => false, :tracker => false) # => #6 + # + def link_to_issue(issue, options={}) + title = nil + subject = nil + text = options[:tracker] == false ? "##{issue.id}" : "#{issue.tracker} ##{issue.id}" + if options[:subject] == false + title = truncate(issue.subject, :length => 60) + else + subject = issue.subject + if options[:truncate] + subject = truncate(subject, :length => options[:truncate]) + end + end + s = link_to text, issue_path(issue), :class => issue.css_classes, :title => title + s << h(": #{subject}") if subject + s = h("#{issue.project} - ") + s if options[:project] + s + end + + # Generates a link to an attachment. + # Options: + # * :text - Link text (default to attachment filename) + # * :download - Force download (default: false) + def link_to_short_attachment(attachment, options={}) + text = h(truncate(options.delete(:text) || attachment.filename, length: 23, omission: '...')) + route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path + html_options = options.slice!(:only_path) + url = send(route_method, attachment, attachment.filename, options) + link_to text, url, html_options + end + + # Generates a link to an attachment. + # Options: + # * :text - Link text (default to attachment filename) + # * :download - Force download (default: false) + def link_to_attachment(attachment, options={}) + text = options.delete(:text) || attachment.filename + route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path + html_options = options.slice!(:only_path) + url = send(route_method, attachment, attachment.filename, options) + link_to text, url, html_options + end + + def link_to_attachment_img(attachment, options={}) + text = options.delete(:text) || attachment.filename + route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path + html_options = options.slice!(:only_path) + url = send(route_method, attachment, attachment.filename, options) + image_tag url, html_options + end + + # Generates a link to a SCM revision + # Options: + # * :text - Link text (default to the formatted revision) + def link_to_revision(revision, repository, options={}) + if repository.is_a?(Project) + repository = repository.repository + end + text = options.delete(:text) || format_revision(revision) + rev = revision.respond_to?(:identifier) ? revision.identifier : revision + link_to( + h(text), + {:controller => 'repositories', :action => 'revision', :id => repository.project, :repository_id => repository.identifier_param, :rev => rev}, + :title => l(:label_revision_id, format_revision(revision)) + ) + end + + # Generates a link to a message + def link_to_message(message, options={}, html_options = nil) + link_to( + truncate(message.subject, :length => 60), + board_message_path(message.board_id, message.parent_id || message.id, { + :r => (message.parent_id && message.id), + :anchor => (message.parent_id ? "message-#{message.id}" : nil) + }.merge(options)), + html_options + ) + end + + # Generates a link to a project if active + # Examples: + # + # link_to_project(project) # => link to the specified project overview + # link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options + # link_to_project(project, {}, :class => "project") # => html options with default url (project overview) + # + def link_to_project(project, options={}, html_options = nil) + if project.archived? + h(project.name) + elsif options.key?(:action) + ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0." + url = {:controller => 'projects', :action => 'show', :id => project}.merge(options) + link_to project.name, url, html_options + else + link_to project.name, project_path(project, options), html_options + end + end + + def link_to_course(course, options={}, html_options = nil) + if course.archived? + h(course.name) + elsif options.key?(:action) + ActiveSupport::Deprecation.warn "#link_to_course with :action option is deprecated and will be removed in Redmine 3.0." + url = {:controller => 'courses', :action => 'show', :id => project}.merge(options) + link_to course.name, url, html_options + else + link_to course.name, course_path(course, options), html_options + end + end + + # Generates a link to a project settings if active + def link_to_project_settings(project, options={}, html_options=nil) + if project.active? + link_to project.name, settings_project_path(project, options), html_options + elsif project.archived? + h(project.name) + else + link_to project.name, project_path(project, options), html_options + end + end + + def wiki_page_path(page, options={}) + url_for({:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title}.merge(options)) + end + + def thumbnail_tag(attachment) + link_to image_tag(thumbnail_path(attachment)), + named_attachment_path(attachment, attachment.filename), + :title => attachment.filename + end + + # 图片缩略图链接 + def thumbnail_small_tag(attachment) + imagesize = attachment.thumbnail(:size => "200*200") + imagepath = named_attachment_path(attachment, attachment.filename) + if imagesize + link_to image_tag(imagesize), + imagepath, + :title => attachment.filename + else + link_to image_tag(imagepath , height: '200', width: '250'), + imagepath, + :title => attachment.filename + end + end + + def toggle_link(name, id, options={}) + onclick = "$('##{id}').toggle(); " + onclick << (options[:focus] ? "$('##{options[:focus]}').focus(); " : "this.blur(); ") + onclick << "return false;" + link_to(name, "#", :onclick => onclick) + end + + def image_to_function(name, function, html_options = {}) + html_options.symbolize_keys! + tag(:input, html_options.merge({ + :type => "image", :src => image_path(name), + :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};" + })) + end + + def format_activity_title(text) + h(truncate_single_line(text, :length => 100)) + end + + def format_activity_day(date) + date == User.current.today ? l(:label_today).titleize : format_date(date) + end + + def format_activity_description(text) + h(truncate(text.to_s, :length => 120).gsub(%r{[\r\n]*<(pre|code)>.*$}m, '...')).gsub(/[\r\n]+/, "
    ").html_safe + #h(truncate(text.to_s, :length => 120).gsub(/<\/?.*?>/,"")).html_safe + end + + def format_version_name(version) + if version.project == @project + h(version) + else + h("#{version.project} - #{version}") + end + end + + def due_date_distance_in_words(date) + if date + l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date)) + end + end + + # Renders a tree of projects as a nested set of unordered lists + # The given collection may be a subset of the whole project tree + # (eg. some intermediate nodes are private and can not be seen) + #Modified by nie. + def render_project_nested_lists(projects) + s = '' + if projects.any? + ancestors = [] + original_project = @project + #modified by nie + projects.each do |project| + # set the project environment to please macros. + @project = project + if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) +# s << "
      \n" + s << "
        \n" + else + ancestors.pop + s << "" + while (ancestors.any? && !project.is_descendant_of?(ancestors.last)) + ancestors.pop + s << "
      \n" + end + end + classes = (ancestors.empty? ? 'root' : 'child') + s << "
    • " + if project.try(:project_type) == Project::ProjectType_project + s << h(block_given? ? yield(project) : project.name) + else + end + + if project.try(:project_type) == Project::ProjectType_project + unless User.current.member_of?(@project) + s << "" + s << watcher_link(@project, User.current)#, ['whiteButton']) + s << "" + end + s << (render :partial => 'projects/project', :locals => {:project => project}).to_s + else + s << (render :partial => 'projects/course', :locals => {:project => project}).to_s + end + s << "
      \n" + ancestors << project + end + s << ("
    \n" * ancestors.size) + @project = original_project + end + s.html_safe + end + + def render_course_nested_lists(courses) + s = '' + if courses.any? + ancestors = [] + original_course = @course + #modified by nie + courses.each do |course| + # set the project environment to please macros. + @course = course + if (ancestors.empty? )#|| course.is_descendant_of?(ancestors.last)) + s << "
      \n" + else + ancestors.pop + s << "" + while (ancestors.any? )#&& !course.is_descendant_of?(ancestors.last)) + ancestors.pop + s << "
    \n" + end + end + classes = (ancestors.empty? ? 'root' : 'child') + s << "
  • " + + s << (render :partial => 'courses/course', :locals => {:course => course}).to_s + s << "
    \n" + ancestors << course + end + s << ("
  • \n" * ancestors.size) + @course = original_course + end + s.html_safe + end + + + #added by young + def render_project_nested_lists_new(projects) + s = '' + if projects.any? + ancestors = [] + original_project = @project + projects.sort_by(&:lft).each do |project| + # set the project environment to please macros. + @project = project + if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) +# s << "
      \n" + s << "
        \n" + else + ancestors.pop + s << "" + while (ancestors.any? && !project.is_descendant_of?(ancestors.last)) + ancestors.pop + s << "
      \n" + end + end + classes = (ancestors.empty? ? 'root' : 'child') + s << h(block_given? ? yield(project) : project.name) + ancestors << project + end + s << ("
    \n" * ancestors.size) + @project = original_project + end + s.html_safe + end + #end + def render_page_hierarchy(pages, node=nil, options={}) + content = '' + if pages[node] + content << "
      \n" + pages[node].each do |page| + content << "
    • " + content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil}, + :title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil)) + content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id] + content << "
    • \n" + end + content << "
    \n" + end + content.html_safe + end + + # Renders flash messages + def render_flash_messages + s = '' + flash.each do |k,v| + s << content_tag('div', v.html_safe, :class => "flash #{k}", :id => "flash_#{k}") + end + s.html_safe + end + + # Renders tabs and their content + def render_tabs(tabs) + if tabs.any? + render :partial => 'common/tabs', :locals => {:tabs => tabs} + else + content_tag 'p', l(:label_no_data), :class => "nodata" + end + end + + # Renders the project quick-jump box + def render_project_jump_box + return unless User.current.logged? + projects = User.current.memberships.collect(&:project).compact.select(&:active?).uniq + if projects.any? + options = + ("" + + '').html_safe + + options << project_tree_options_for_select(projects, :selected => @project) do |p| + { :value => project_path(:id => p, :jump => current_menu_item) } + end + + select_tag('project_quick_jump_box', options, :onchange => 'if (this.value != \'\') { window.location = this.value; }') + end + end + + def project_tree_options_for_select(projects, options = {}) + s = '' + project_tree(projects) do |project, level| + name_prefix = (level > 0 ? ' ' * 2 * level + '» ' : '').html_safe + tag_options = {:value => project.id} + if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project)) + tag_options[:selected] = 'selected' + else + tag_options[:selected] = nil + end + tag_options.merge!(yield(project)) if block_given? + s << content_tag('option', name_prefix + h(project), tag_options) + end + s.html_safe + end + + # Yields the given block for each project with its level in the tree + # + # Wrapper for Project#project_tree + def project_tree(projects, &block) + Project.project_tree(projects, &block) + end + + def principals_check_box_tags(name, principals) + s = '' + principals.each do |principal| + s << "\n" + end + s.html_safe + end + + #扩展的checkbox生成 + def principals_check_box_tags_ex(name, principals) + s = '' + principals.each do |principal| + s << "\n" + end + s.html_safe + end + + #扩展的checkbox生成 + def principals_radio_box_tags_ex(name, principals) + s = '' + principals.each do |principal| + s << "\n" + end + s.html_safe + end + + + # Returns a string for users/groups option tags + def principals_options_for_select(collection, selected=nil) + s = '' + if collection.include?(User.current) + s << content_tag('option', "<< #{l(:label_me)} >>", :value => User.current.id) + end + groups = '' + collection.sort.each do |element| + selected_attribute = ' selected="selected"' if option_value_selected?(element, selected) + (element.is_a?(Group) ? groups : s) << %() + end + unless groups.empty? + s << %(#{groups}) + end + s.html_safe + end + + # Options for the new membership projects combo-box + def options_for_membership_project_select(principal, projects) + options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---") + options << project_tree_options_for_select(projects) do |p| + {:disabled => principal.projects.to_a.include?(p)} + end + options + end + + # Truncates and returns the string as a single line + def truncate_single_line(string, *args) + truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ') + end + + # Truncates at line break after 250 characters or options[:length] + def truncate_lines(string, options={}) + length = options[:length] || 250 + if string.to_s =~ /\A(.{#{length}}.*?)$/m + "#{$1}..." + else + string + end + end + + def anchor(text) + text.to_s.gsub(' ', '_') + end + + def html_hours(text) + text.gsub(%r{(\d+)\.(\d+)}, '\1.\2').html_safe + end + + def authoring(created, author, options={}) + l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe + end + + def added_time(created) + l(:label_added_time, :age => time_tag(created)).html_safe + end + + def user_url_and_time(user_name, user_url, created) + unless user_name.nil? || user_name == '' + l(:label_added_time_by, :author => link_to(user_name, user_url), :age => time_tag(created)).html_safe + else + l(:label_added_time, :age => time_tag(created)).html_safe + end + end + + #huang + def betweentime(enddate) + ss=(DateTime.parse("#{enddate.to_date}")-DateTime.parse("#{DateTime.now.to_date}")).to_i + return ss + end + + def time_tag(time) + text = distance_of_time_in_words(Time.now, time) + if @project + link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)}, :title => format_time(time)) + else + content_tag('acronym', text, :title => format_time(time)) + end + end + + def syntax_highlight_lines(name, content) + lines = [] + syntax_highlight(name, content).each_line { |line| lines << line } + lines + end + + def syntax_highlight(name, content) + Redmine::SyntaxHighlighting.highlight_by_filename(content, name) + end + + def to_path_param(path) + str = path.to_s.split(%r{[/\\]}).select{|p| !p.blank?}.join("/") + str.blank? ? nil : str + end + + def reorder_links(name, url, method = :post) + link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), + url.merge({"#{name}[move_to]" => 'highest'}), + :method => method, :title => l(:label_sort_highest)) + + link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), + url.merge({"#{name}[move_to]" => 'higher'}), + :method => method, :title => l(:label_sort_higher)) + + link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), + url.merge({"#{name}[move_to]" => 'lower'}), + :method => method, :title => l(:label_sort_lower)) + + link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), + url.merge({"#{name}[move_to]" => 'lowest'}), + :method => method, :title => l(:label_sort_lowest)) + end + + def breadcrumb(*args) + elements = args.flatten + elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'breadcrumb') : nil + end + + def other_formats_links(&block) + concat('

    '.html_safe + l(:label_export_to)) + yield Redmine::Views::OtherFormatsBuilder.new(self) + concat('

    '.html_safe) + end + + def page_header_title + if @project.nil? || @project.new_record? + h(Setting.app_title) + else + b = [] + ancestors = (@project.root? ? [] : @project.ancestors.visible.all) + if ancestors.any? + root = ancestors.shift + b << link_to_project(root, {:jump => current_menu_item}, :class => 'root') + if ancestors.size > 2 + b << "\xe2\x80\xa6" + ancestors = ancestors[-2, 2] + end + b += ancestors.collect {|p| link_to_project(p, {:jump => current_menu_item}, :class => 'ancestor') } + end + b << h(@project) + b.join(" \xc2\xbb ").html_safe + end + end + + def html_title(*args) + #點擊項目版本庫 多觸發一次 字符串為"/" + #暫時解決方法 直接判斷 + if(args == ["/"]) + args = [] + end + first_page = FirstPage.find_by_page_type('project') + if args.empty? + title = @html_title || [] + title << @project.name if @project + if first_page.nil? || first_page.web_title.nil? + title << Setting.app_title unless Setting.app_title == title.last + else + title << first_page.web_title unless first_page.web_title == title.last + end + title.select {|t| !t.blank? }.join(' - ') + else + @html_title ||= [] + @html_title += args + end + end + + # Returns the theme, controller name, and action as css classes for the + # HTML body. + def body_css_classes + css = [] + if theme = Redmine::Themes.theme(Setting.ui_theme) + css << 'theme-' + theme.name + end + + css << 'controller-' + controller_name + css << 'action-' + action_name + css.join(' ') + end + + def accesskey(s) + @used_accesskeys ||= [] + key = Redmine::AccessKeys.key_for(s) + return nil if @used_accesskeys.include?(key) + @used_accesskeys << key + key + end + + # Formats text according to system settings. + # 2 ways to call this method: + # * with a String: textilizable(text, options) + # * with an object and one of its attribute: textilizable(issue, :description, options) + 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' + end + return '' if text.blank? + project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) + only_path = options.delete(:only_path) == false ? false : true + + text = text.dup + macros = catch_macros(text) + text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) + + @parsed_headings = [] + @heading_anchors = {} + @current_section = 0 if options[:edit_section_links] + + parse_sections(text, project, obj, attr, only_path, options) + text = parse_non_pre_blocks(text, obj, macros) do |text| + [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name| + send method_name, text, project, obj, attr, only_path, options + end + end + parse_headings(text, project, obj, attr, only_path, options) + + if @parsed_headings.any? + replace_toc(text, @parsed_headings) + end + + text.html_safe + end + + # + #格式化字符串,不转义html代码 + def textAreailizable(*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' + end + return '' if text.blank? + project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) + only_path = options.delete(:only_path) == false ? false : true + + text = text.dup + macros = catch_macros(text) + #text = Redmine::WikiFormatting.to_html("CKEditor", text, :object => obj, :attribute => attr) + + @parsed_headings = [] + @heading_anchors = {} + @current_section = 0 if options[:edit_section_links] + + parse_sections(text, project, obj, attr, only_path, options) + text = parse_non_pre_blocks(text, obj, macros) do |text| + [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name| + send method_name, text, project, obj, attr, only_path, options + end + end + parse_headings(text, project, obj, attr, only_path, options) + + if @parsed_headings.any? + replace_toc(text, @parsed_headings) + end + + text.html_safe + end + + def parse_non_pre_blocks(text, obj, macros) + s = StringScanner.new(text) + tags = [] + parsed = '' + while !s.eos? + s.scan(/(.*?)(<(\/)?(pre|code)(.*?)>|\z)/im) + text, full_tag, closing, tag = s[1], s[2], s[3], s[4] + if tags.empty? + yield text + inject_macros(text, obj, macros) if macros.any? + else + inject_macros(text, obj, macros, false) if macros.any? + end + parsed << text + if tag + if closing + if tags.last == tag.downcase + tags.pop + end + else + tags << tag.downcase + end + parsed << full_tag + end + end + # Close any non closing tags + while tag = tags.pop + parsed << "" + end + parsed + end + + def parse_inline_attachments(text, project, obj, attr, only_path, options) + # when using an image link, try to use an attachment, if possible + attachments = options[:attachments] || [] + attachments += obj.attachments if obj.respond_to?(:attachments) + if attachments.present? + text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m| + filename, ext, alt, alttext = $1.downcase, $2, $3, $4 + # search for the picture in attachments + if found = Attachment.latest_attach(attachments, filename) + image_url = download_named_attachment_path(found, found.filename, :only_path => only_path) + desc = found.description.to_s.gsub('"', '') + if !desc.blank? && alttext.blank? + alt = " title=\"#{desc}\" alt=\"#{desc}\"" + end + "src=\"#{image_url}\"#{alt}" + else + m + end + end + end + end + + # Wiki links + # + # Examples: + # [[mypage]] + # [[mypage|mytext]] + # wiki links can refer other project wikis, using project name or identifier: + # [[project:]] -> wiki starting page + # [[project:|mytext]] + # [[project:mypage]] + # [[project:mypage|mytext]] + def parse_wiki_links(text, project, obj, attr, only_path, options) + text.gsub!(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m| + link_project = project + esc, all, page, title = $1, $2, $3, $5 + if esc.nil? + if page =~ /^([^\:]+)\:(.*)$/ + identifier, page = $1, $2 + link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier) + title ||= identifier if page.blank? + end + + if link_project && link_project.wiki + # extract anchor + anchor = nil + if page =~ /^(.+?)\#(.+)$/ + page, anchor = $1, $2 + end + anchor = sanitize_anchor_name(anchor) if anchor.present? + # check if page exists + wiki_page = link_project.wiki.find_page(page) + url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page + "##{anchor}" + else + case options[:wiki_links] + when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '') + when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export + else + wiki_page_id = page.present? ? Wiki.titleize(page) : nil + parent = wiki_page.nil? && obj.is_a?(WikiContent) && obj.page && project == link_project ? obj.page.title : nil + url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project, + :id => wiki_page_id, :version => nil, :anchor => anchor, :parent => parent) + end + end + link_to(title.present? ? title.html_safe : h(page), url, :class => ('wiki-page' + (wiki_page ? '' : ' new'))) + else + # project or wiki doesn't exist + all + end + else + all + end + end + end + + def select_option_helper option + tmp = Hash.new + tmp={"" => ""} + if option.nil? + else + option.each do |project| + tmp[project.name] = project.id + end + end + tmp + end + # Redmine links + # + # Examples: + # Issues: + # #52 -> Link to issue #52 + # Changesets: + # r52 -> Link to revision 52 + # commit:a85130f -> Link to scmid starting with a85130f + # Documents: + # document#17 -> Link to document with id 17 + # document:Greetings -> Link to the document with title "Greetings" + # document:"Some document" -> Link to the document with title "Some document" + # Versions: + # version#3 -> Link to version with id 3 + # version:1.0.0 -> Link to version named "1.0.0" + # version:"1.0 beta 2" -> Link to version named "1.0 beta 2" + # Attachments: + # attachment:file.zip -> Link to the attachment of the current object named file.zip + # Source files: + # source:some/file -> Link to the file located at /some/file in the project's repository + # source:some/file@52 -> Link to the file's revision 52 + # source:some/file#L120 -> Link to line 120 of the file + # source:some/file@52#L120 -> Link to line 120 of the file's revision 52 + # export:some/file -> Force the download of the file + # Forum messages: + # message#1218 -> Link to message with id 1218 + # + # Links can refer other objects from other projects, using project identifier: + # identifier:r52 + # identifier:document:"Some document" + # identifier:version:1.0.0 + # identifier:source:some/file + def parse_redmine_links(text, default_project, obj, attr, only_path, options) + text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m| + leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17 + link = nil + project = default_project + if project_identifier + project = Project.visible.find_by_identifier(project_identifier) + end + if esc.nil? + if prefix.nil? && sep == 'r' + if project + repository = nil + if repo_identifier + repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} + else + repository = project.repository + end + # project.changesets.visible raises an SQL error because of a double join on repositories + if repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(repository.id, identifier)) + link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.revision}, + :class => 'changeset', + :title => truncate_single_line(changeset.comments, :length => 100)) + end + end + elsif sep == '#' + oid = identifier.to_i + case prefix + when nil + if oid.to_s == identifier && issue = Issue.visible.find_by_id(oid, :include => :status) + anchor = comment_id ? "note-#{comment_id}" : nil + link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid, :anchor => anchor}, + :class => issue.css_classes, + :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})") + end + when 'document' + if document = Document.visible.find_by_id(oid) + link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, + :class => 'document' + end + when 'version' + if version = Version.visible.find_by_id(oid) + link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, + :class => 'version' + end + when 'message' + if message = Message.visible.find_by_id(oid, :include => :parent) + link = link_to_message(message, {:only_path => only_path}, :class => 'message') + end + when 'forum' + if board = Board.visible.find_by_id(oid) + link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, + :class => 'board' + end + when 'news' + if news = News.visible.find_by_id(oid) + link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, + :class => 'news' + end + when 'project' + if p = Project.visible.find_by_id(oid) + link = link_to_project(p, {:only_path => only_path}, :class => 'project') + end + end + elsif sep == ':' + # removes the double quotes if any + name = identifier.gsub(%r{^"(.*)"$}, "\\1") + case prefix + when 'document' + if project && document = project.documents.visible.find_by_title(name) + link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, + :class => 'document' + end + when 'version' + if project && version = project.versions.visible.find_by_name(name) + link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, + :class => 'version' + end + when 'forum' + if project && board = project.boards.visible.find_by_name(name) + link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, + :class => 'board' + end + when 'news' + if project && news = project.news.visible.find_by_title(name) + link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, + :class => 'news' + end + when 'commit', 'source', 'export' + if project + repository = nil + if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$} + repo_prefix, repo_identifier, name = $1, $2, $3 + repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} + else + repository = project.repository + end + if prefix == 'commit' + if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first) + link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier}, + :class => 'changeset', + :title => truncate_single_line(changeset.comments, :length => 100) + end + else + if repository && User.current.allowed_to?(:browse_repository, project) + name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$} + path, rev, anchor = $1, $3, $5 + link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param, + :path => to_path_param(path), + :rev => rev, + :anchor => anchor}, + :class => (prefix == 'export' ? 'source download' : 'source') + end + end + repo_prefix = nil + end + when 'attachment' + attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil) + if attachments && attachment = Attachment.latest_attach(attachments, name) + link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment') + end + when 'project' + if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first + link = link_to_project(p, {:only_path => only_path}, :class => 'project') + end + end + end + end + (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}")) + end + end + + HEADING_RE = /(]+)?>(.+?)<\/h(\d)>)/i unless const_defined?(:HEADING_RE) + + def parse_sections(text, project, obj, attr, only_path, options) + return unless options[:edit_section_links] + text.gsub!(HEADING_RE) do + heading = $1 + @current_section += 1 + if @current_section > 1 + content_tag('div', + link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)), + :class => 'contextual', + :title => l(:button_edit_section)) + heading.html_safe + else + heading + end + end + end + + # Headings and TOC + # Adds ids and links to headings unless options[:headings] is set to false + def parse_headings(text, project, obj, attr, only_path, options) + return if options[:headings] == false + + text.gsub!(HEADING_RE) do + level, attrs, content = $2.to_i, $3, $4 + item = strip_tags(content).strip + anchor = sanitize_anchor_name(item) + # used for single-file wiki export + anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) + @heading_anchors[anchor] ||= 0 + idx = (@heading_anchors[anchor] += 1) + if idx > 1 + anchor = "#{anchor}-#{idx}" + end + @parsed_headings << [level, anchor, item] + "\n#{content}" + end + end + + MACROS_RE = /( + (!)? # escaping + ( + \{\{ # opening tag + ([\w]+) # macro name + (\(([^\n\r]*?)\))? # optional arguments + ([\n\r].*?[\n\r])? # optional block of text + \}\} # closing tag + ) + )/mx unless const_defined?(:MACROS_RE) + + MACRO_SUB_RE = /( + \{\{ + macro\((\d+)\) + \}\} + )/x unless const_defined?(:MACRO_SUB_RE) + + # Extracts macros from text + def catch_macros(text) + macros = {} + text.gsub!(MACROS_RE) do + all, macro = $1, $4.downcase + if macro_exists?(macro) || all =~ MACRO_SUB_RE + index = macros.size + macros[index] = all + "{{macro(#{index})}}" + else + all + end + end + macros + end + + # Executes and replaces macros in text + def inject_macros(text, obj, macros, execute=true) + text.gsub!(MACRO_SUB_RE) do + all, index = $1, $2.to_i + orig = macros.delete(index) + if execute && orig && orig =~ MACROS_RE + esc, all, macro, args, block = $2, $3, $4.downcase, $6.to_s, $7.try(:strip) + if esc.nil? + h(exec_macro(macro, obj, args, block) || all) + else + h(all) + end + elsif orig + h(orig) + else + h(all) + end + end + end + + TOC_RE = /

    \{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE) + + # Renders the TOC with given headings + def replace_toc(text, headings) + text.gsub!(TOC_RE) do + # Keep only the 4 first levels + headings = headings.select{|level, anchor, item| level <= 4} + if headings.empty? + '' + else + div_class = 'toc' + div_class << ' right' if $1 == '>' + div_class << ' left' if $1 == '<' + out = "

    • " + root = headings.map(&:first).min + current = root + started = false + headings.each do |level, anchor, item| + if level > current + out << '
      • ' * (level - current) + elsif level < current + out << "
      \n" * (current - level) + "
    • " + elsif started + out << '
    • ' + end + out << "#{item}" + current = level + started = true + end + out << '
    ' * (current - root) + out << '' + end + end + end + + # Same as Rails' simple_format helper without using paragraphs + def simple_format_without_paragraph(text) + text.to_s. + gsub(/\r\n?/, "\n"). # \r\n and \r -> \n + gsub(/\n\n+/, "

    "). # 2+ newline -> 2 br + gsub(/([^\n]\n)(?=[^\n])/, '\1
    '). # 1 newline -> br + html_safe + end + + def lang_options_for_select(blank=true) + { 'Chinese简体中文 '=> 'zh', :English => :en} + end + + def label_tag_for(name, option_tags = nil, options = {}) + label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "") + content_tag("label", label_text) + end + + def labelled_form_for(*args, &proc) + args << {} unless args.last.is_a?(Hash) + options = args.last + if args.first.is_a?(Symbol) + options.merge!(:as => args.shift) + end + options.merge!({:builder => Redmine::Views::LabelledFormBuilder}) + form_for(*args, &proc) + end + + def labelled_fields_for(*args, &proc) + args << {} unless args.last.is_a?(Hash) + options = args.last + options.merge!({:builder => Redmine::Views::LabelledFormBuilder}) + fields_for(*args, &proc) + end + + def labelled_remote_form_for(*args, &proc) + ActiveSupport::Deprecation.warn "ApplicationHelper#labelled_remote_form_for is deprecated and will be removed in Redmine 2.2." + args << {} unless args.last.is_a?(Hash) + options = args.last + options.merge!({:builder => Redmine::Views::LabelledFormBuilder, :remote => true}) + form_for(*args, &proc) + end + + def error_messages_for(*objects) + html = "" + # modified by fq + if objects.first.is_a?(Array) + objects = objects.first + end + # end + if objects != nil + objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact + errors = objects.map {|o| o.errors.full_messages}.flatten + if errors.any? + html << "
      \n" + errors.each do |error| + ###by xianbo + if(error!=l(:label_repository_path_not_null)) + html << "
    • #{h error}
    • \n" + end + ###xianbo + end + ###by xianbo + unless params[:repository].nil? + if params[:repository][:upassword]=="" + html << "
    • "+ l(:label_password_not_null) +"
    • \n" + end + end + ###xianbo + html << "
    \n" + end + end + html.html_safe + end + + def delete_link(url, options={}) + options = { + :method => :delete, + :data => {:confirm => l(:text_are_you_sure)}, + :class => 'icon icon-del' + }.merge(options) + + link_to l(:button_delete), url, options + end + + def preview_link(url, form, target='preview', options={}) + content_tag 'a', l(:label_preview), { + :href => "#", + :onclick => %|submitPreview("#{escape_javascript url_for(url)}", "#{escape_javascript form}", "#{escape_javascript target}"); return false;|, + :accesskey => accesskey(:preview) + }.merge(options) + end + + def link_to_function(name, function, html_options={}) + content_tag(:a, name, {:href => '#', :onclick => "#{function}; return false;"}.merge(html_options)) + end + + # Helper to render JSON in views + def raw_json(arg) + arg.to_json.to_s.gsub('/', '\/').html_safe + end + + def back_url + url = params[:back_url] + if url.nil? && referer = request.env['HTTP_REFERER'] + url = CGI.unescape(referer.to_s) + end + url + end + + def back_url_hidden_field_tag + url = back_url + hidden_field_tag('back_url', url, :id => nil) unless url.blank? + end + + def check_all_links(form_name) + link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") + + " | ".html_safe + + link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)") + end + + def progress_bar(pcts, options={}) + pcts = [pcts, pcts] unless pcts.is_a?(Array) + pcts = pcts.collect(&:round) + pcts[1] = pcts[1] - pcts[0] + pcts << (100 - pcts[1] - pcts[0]) + width = options[:width] || '100px;' + legend = options[:legend] || '' + content_tag('table', + content_tag('tr', + (pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed') : ''.html_safe) + + (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) + + (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe) + ), :class => 'progress', :style => "width: #{width};").html_safe + + content_tag('p', legend, :class => 'percent').html_safe + end + + def checked_image(checked=true) + if checked + image_tag 'toggle_check.png' + end + end + + def context_menu(url) + unless @context_menu_included + content_for :header_tags do + javascript_include_tag('context_menu') + + stylesheet_link_tag('context_menu') + end + if l(:direction) == 'rtl' + content_for :header_tags do + stylesheet_link_tag('context_menu_rtl') + end + end + @context_menu_included = true + end + javascript_tag "contextMenuInit('#{ url_for(url) }')" + end + + def calendar_for(field_id,start_day=nil) + include_calendar_headers_tags(start_day) + javascript_tag("$(function() { $('##{field_id}').datepicker(datepickerOptions); });") + end + + def include_calendar_headers_tags(start_day=nil) + if start_day.nil? + unless @calendar_headers_tags_included + @calendar_headers_tags_included = true + content_for :header_tags do + start_of_week = Setting.start_of_week + start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank? + # Redmine uses 1..7 (monday..sunday) in settings and locales + # JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0 + start_of_week = start_of_week.to_i % 7 + + tags = javascript_tag( + "var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " + + "showOn: 'button', buttonImageOnly: true, buttonImage: '" + + path_to_image('/images/calendar.png') + + "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};") + jquery_locale = l('jquery.locale', :default => current_language.to_s) + unless jquery_locale == 'en' + tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js") + end + tags + end + end + else + unless @calendar_headers_tags_included + @calendar_headers_tags_included = true + content_for :header_tags do + start_of_week = Setting.start_of_week + start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank? + # Redmine uses 1..7 (monday..sunday) in settings and locales + # JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0 + start_of_week = start_of_week.to_i % 7 + + tags = javascript_tag( + "var datepickerOptions={dateFormat: 'yy-mm-dd',minDate: new Date(), firstDay: #{start_of_week}, " + + "showOn: 'button', buttonImageOnly: true, buttonImage: '" + + path_to_image('/images/calendar.png') + + "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true, onClose: function(dateText, inst) {TimeClose(dateText,inst);}, beforeShow : function(input){TimeBeforeShow(input);} };") + jquery_locale = l('jquery.locale', :default => current_language.to_s) + unless jquery_locale == 'en' + tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js") + end + tags + end + end + end + + end + + # Overrides Rails' stylesheet_link_tag with themes and plugins support. + # Examples: + # stylesheet_link_tag('styles') # => picks styles.css from the current theme or defaults + # stylesheet_link_tag('styles', :plugin => 'foo) # => picks styles.css from plugin's assets + # + def stylesheet_link_tag(*sources) + options = sources.last.is_a?(Hash) ? sources.pop : {} + plugin = options.delete(:plugin) + sources = sources.map do |source| + if plugin + "/plugin_assets/#{plugin}/stylesheets/#{source}" + elsif current_theme && current_theme.stylesheets.include?(source) + current_theme.stylesheet_path(source) + else + source + end + end + super sources, options + end + + # Overrides Rails' image_tag with themes and plugins support. + # Examples: + # image_tag('image.png') # => picks image.png from the current theme or defaults + # image_tag('image.png', :plugin => 'foo) # => picks image.png from plugin's assets + # + def image_tag(source, options={}) + if plugin = options.delete(:plugin) + source = "/plugin_assets/#{plugin}/images/#{source}" + elsif current_theme && current_theme.images.include?(source) + source = current_theme.image_path(source) + end + super source, options + end + + # Overrides Rails' javascript_include_tag with plugins support + # Examples: + # javascript_include_tag('scripts') # => picks scripts.js from defaults + # javascript_include_tag('scripts', :plugin => 'foo) # => picks scripts.js from plugin's assets + # + def javascript_include_tag(*sources) + options = sources.last.is_a?(Hash) ? sources.pop : {} + if plugin = options.delete(:plugin) + sources = sources.map do |source| + if plugin + "/plugin_assets/#{plugin}/javascripts/#{source}" + else + source + end + end + end + super sources, options + end + + def content_for(name, content = nil, &block) + @has_content ||= {} + @has_content[name] = true + super(name, content, &block) + end + + def has_content?(name) + (@has_content && @has_content[name]) || false + end + + def sidebar_content? + has_content?(:sidebar) || view_layouts_base_sidebar_hook_response.present? + end + + def view_layouts_base_sidebar_hook_response + @view_layouts_base_sidebar_hook_response ||= call_hook(:view_layouts_base_sidebar) + end + + def email_delivery_enabled? + !!ActionMailer::Base.perform_deliveries + end + + # Returns the avatar image tag for the given +user+ if avatars are enabled + # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe ') + def avatar(user, options = { }) + if Setting.gravatar_enabled? + options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default}) + email = nil + if user.respond_to?(:mail) + email = user.mail + elsif user.to_s =~ %r{<(.+?)>} + email = $1 + end + return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil + #options ={"class" => ["avatar2"],"width" =>["80px"],"height" =>["80px"]} + #return image_tag url_to_avatar(user), options + else + '' + end + end + + def sanitize_anchor_name(anchor) + if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java' + anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-') + else + # TODO: remove when ruby1.8 is no longer supported + anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-') + end + end + + # Returns the javascript tags that are included in the html layout head + def javascript_heads + tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application', 'jquery.colorbox-min') + unless User.current.pref.warn_on_leaving_unsaved == '0' + tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });") + end + tags + end + + def hubspot_head + tags = javascript_include_tag('hubspot/messenger.min', 'hubspot/messenger-theme-future') + tags << stylesheet_link_tag('hubspot/messenger', 'hubspot/messenger-theme-future', 'hubspot/messenger-theme-flat') + end + + def bootstrap_head + tags = stylesheet_link_tag('bootstrap/bootstrap.min', 'bootstrap/bootstrap-theme.min') + tags << javascript_include_tag('bootstrap/affix') + tags << javascript_include_tag('bootstrap/alert') + tags << javascript_include_tag('bootstrap/button') + tags << javascript_include_tag('bootstrap/carousel') + tags << javascript_include_tag('bootstrap/collapse') + tags << javascript_include_tag('bootstrap/dropdown') + tags << javascript_include_tag('bootstrap/modal') + tags << javascript_include_tag('bootstrap/popover') + tags << javascript_include_tag('bootstrap/scrollspy') + tags << javascript_include_tag('bootstrap/tab') + tags << javascript_include_tag('bootstrap/tooltip') + tags << javascript_include_tag('bootstrap/transition') + tags + end + + def favicon + "".html_safe + end + + def robot_exclusion_tag + ''.html_safe + end + + # Returns true if arg is expected in the API response + def include_in_api_response?(arg) + unless @included_in_api_response + param = params[:include] + @included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',') + @included_in_api_response.collect!(&:strip) + end + @included_in_api_response.include?(arg.to_s) + end + + # Returns options or nil if nometa param or X-Redmine-Nometa header + # was set in the request + def api_meta(options) + if params[:nometa].present? || request.headers['X-Redmine-Nometa'] + # compatibility mode for activeresource clients that raise + # an error when unserializing an array with attributes + nil + else + options + end + end + + # Add by Tao + def url_to_avatar(source) + source = nil if source.kind_of?(String) + get_avatar(source) + end + # Endof Tao's code + + def date_format_local(time) + date = time.strftime("%Y年%m月%d日") + end + + #当TAG数量过多时,更多链接 + #1代表是user类型 2代表是project类型 3代表是issue类型 4代表需求 9代表课程 + def more_tags id,object_flag + a= 1 + case object_flag + when "1" + s = link_to l(:label_more_tags),:controller => "users", :action => "show", :id => id + when "2" + s = link_to l(:label_more_tags),:controller => "projects", :action => "show", :id => id + when "3" + s = link_to l(:label_more_tags),:controller => "issues", :action => "show", :id => id + when "4" + s = link_to l(:label_more_tags),:controller => "bids", :action => "show", :id => id + when "9" + s = link_to l(:label_more_tags),:controller => "courses", :action => "show", :id => id + end + s + end + + private + + def wiki_helper + helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting) + extend helper + return self + end + + def link_to_content_update(text, url_params = {}, html_options = {}) + link_to(text, url_params, html_options) + end + +#added by nie +# Display watcher picture + def show_more_watchers?(obj) + if User.watched_by(obj.id).count > 6 + return true + else + return false + end + end + + def show_watcher_profile(obj) + count = 0 + html = '' + if User.watched_by(obj.id).count == 0 + html << (content_tag "span", l(:label_no_current_watchers)) + end + for user in User.watched_by(obj.id) + html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}") + count = count + 1 + if count >= 12 + break + end + end + html.html_safe + end + +#display bid project + def show_more_bid_project?(bid) + if bid.projects.where('is_public = 1').count > 12 + return true + else + return false + end + end + + def show_bid_project(bid) + html = '' + if bid.projects.where('is_public = 1').count == 0 + html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") + else + bid.projects.where('is_public = 1').take(12).each do |project| + html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") + end + end + html.html_safe + end + + def show_bid_fans_picture(obj) + html = '' + if obj.watcher_users.count == 0 + html << (content_tag "span", l(:label_project_no_follow)) + else + obj.watcher_users.take(12).each do |user| + html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) + end + end + html.html_safe + end + +#display contest project + def show_more_contest_project?(contest) + if contest.projects.where('is_public = 1').count > 12 + return true + else + return false + end + end + + def show_more_contest_softapplication?(contest) + if contest.softapplications.where('is_public = 1').count > 12 + return true + else + return false + end + end + + def show_contest_project(bid) + html = '' + if contest.projects.where('is_public = 1').count == 0 + html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") + else + contest.projects.where('is_public = 1').take(12).each do |project| + html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") + end + end + html.html_safe + end + + def show_contest_project(contest) + html = '' + if contest.projects.where('is_public = 1').count == 0 + html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") + else + contest.projects.where('is_public = 1').take(12).each do |project| + html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") + end + end + html.html_safe + end + + def show_contest_softapplication(contest) + html = '' + if contest.softapplications.where('is_public = 1').count == 0 + html << (content_tag "p", l(:label_no_contest_softapplication), :class => "font_lighter") + else + contest.softapplications.where('is_public = 1').take(12).each do |softapplication| + html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") + end + end + html.html_safe + end + + def show_contest_fans_picture(obj) + html = '' + if obj.watcher_users.count == 0 + html << (content_tag "span", l(:label_project_no_follow)) + else + obj.watcher_users.take(12).each do |user| + html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) + end + end + html.html_safe + end + +#display fans picture + def show_more_fans?(obj) + if obj.watcher_users.count > 12 + return true + else + return false + end + end + + def show_fans_picture(obj) + html = '' + if obj.watcher_users.count == 0 + html << (content_tag "span", l(:label_no_current_fans)) + else + obj.watcher_users.take(12).each do |user| + html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) + end + end + html.html_safe + end + + # added by bai + def show_more_participate?(obj) + if obj.join_in_contests.count > 12 + return true + else + return false + end + end + + def show_participate_picture(obj) + html = '' + count = 0 + if obj.join_in_contests.count == 0 + html << (content_tag "span", l(:label_no_current_participate)) + end + for temp in obj.join_in_contests + html << (link_to image_tag(url_to_avatar(temp.user), :class => "avatar"), user_path(temp.user), :class => "avatar", :title => "#{temp.user.name}") + count = count + 1 + if count >= 12 + break + end + end + html.html_safe + end + +#end + +# add by huang + def show_watcher_list(user) + html = '' + count = 0 + for user in User.watched_by(user.id) + html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}") + count = count + 1 + if count >= 12 + break + end + end + html.html_safe + end +# end + +#added by william + def get_fans_num(user) + user.watcher_users.count + end +#end + + + def hadcommittedhomework(cur,curb) + bid = Bid.find_by_id(curb) + return true if bid.nil? + + case bid.homework_type + when Bid::HomeworkFile + attaches = HomeworkAttach.where(bid_id: curb) + attaches.map(&:user_id).include? cur + when Bid::HomeworkProject + attaches = BidingProject.where(user_id: User.current, bid_id: bid) + attaches.count > 0 # > 0 则有提交记录 + else + true + end + + end + + def render_dynamic_nav + home_link = link_to l(:field_homepage), {:controller => 'welcome', :action => 'index'} + home_link = "
  • " << home_link << "
  • " + # bootstrap_render_dynamic_nav + content_tag :ul, (home_link.html_safe+bootstrap_render_dynamic_nav) + end + + def bootstrap_render_dynamic_nav + + main_course_link = link_to l(:label_course_practice), {:controller => 'welcome', :action => 'index', :host => Setting.course_domain} + main_project_link = link_to l(:label_project_deposit), {:controller => 'welcome', :action => 'index', :host => Setting.project_domain} + main_contest_link = link_to l(:label_contest_innovate), {:controller => 'welcome', :action => 'index', :host => Setting.contest_domain} + + course_all_course_link = link_to l(:label_course_all), {:controller => 'courses', :action => 'index'} + course_teacher_all_link = link_to l(:label_teacher_all), {:controller => 'users', :action => 'index', :role => 'teacher', :host => Setting.course_domain} + courses_link = link_to l(:label_course_practice), {:controller => 'courses', :action => 'index'} + projects_link = link_to l(:label_project_deposit), {:controller => 'projects', :action => 'index', :project_type => 0, :host => Setting.project_domain} + users_link = link_to l(:label_software_user), {:controller => 'users', :action => 'index', :host => Setting.user_domain} + contest_link = link_to l(:label_contest_innovate), {:controller => 'contests', :action => 'index'} + bids_link = link_to l(:label_requirement_enterprise), {:controller => 'bids', :action => 'index'} + forum_link = link_to l(:label_project_module_forums), {:controller => "forums", :action => "index"} + stores_link = link_to l(:label_stores_index), {:controller => 'stores', :action=> 'index'} + + + school_all_school_link = link_to l(:label_school_all), {:controller => 'school', :action => 'index'} + + + #@nav_dispaly_project_label + nav_list = Array.new + nav_list.push(school_all_school_link) if @nav_dispaly_course_all_label && @show_course == 1 + nav_list.push(course_all_course_link) if @nav_dispaly_course_all_label && @show_course == 1 + nav_list.push(course_teacher_all_link) if @nav_dispaly_teacher_all_label && @show_course == 1 + + nav_list.push(main_project_link) if @nav_dispaly_main_project_label + nav_list.push(main_course_link) if @nav_dispaly_main_course_label && @show_course == 1 + nav_list.push(main_contest_link) if @nav_dispaly_main_contest_label && @show_contest == 1 + + nav_list.push(courses_link) if @nav_dispaly_course_label && @show_course == 1 + nav_list.push(projects_link) if @nav_dispaly_project_label + nav_list.push(users_link) if @nav_dispaly_user_label + nav_list.push(contest_link) if @nav_dispaly_contest_label && @show_contest == 1 + nav_list.push(bids_link) if @nav_dispaly_bid_label + nav_list.push(forum_link) if @nav_dispaly_forum_label + nav_list.push(stores_link) if @nav_dispaly_store_all_label + + content_li = '' + nav_list.collect do |nav_item| + content_li << content_tag(:li, nav_item) + end + content_li.html_safe + end + + def current_user + User.current + end + + # def hadcommittedforcontest(curu) + # message = JournalsForMessage.find_by_sql("select * from journals_for_messages where jour_type = 'Softapplication' ") + # message.each do |createmessage| + # if createmessage.user_id == curu + # return true + # end + # end + # end + + def footer_logo(ul_class=nil, li_class=nil) + logos = [] + logos.push(link_to image_tag('/images/footer_logo/nudt.png',:alt=>"nudt"),"http://www.nudt.edu.cn/special.asp?classid=12" ) + logos.push(link_to image_tag('/images/footer_logo/peking_eecs.png', :alt=>"peking_eecs"), "http://eecs.pku.edu.cn" ) + logos.push(link_to image_tag('/images/footer_logo/buaa_scse.png', :alt=>"buaa_scse"), "http://scse.buaa.edu.cn/" ) + logos.push(link_to image_tag('/images/footer_logo/iscas.png', :alt=>"iscas"), "http://www.iscas.ac.cn" ) + logos.push(link_to image_tag('/images/footer_logo/inforbus.png', :alt=>"inforbus"), "http://www.inforbus.com" ) + + logos.collect! { |logo| + content_tag(:li, logo.html_safe, :class => li_class.to_s) + } + + content_tag(:ul, logos.join("").html_safe, :class => ul_class.to_s).html_safe + end + + +end diff --git a/app/helpers/attachments_helper.rb b/app/helpers/attachments_helper.rb index 060ced940..7ea49dad2 100644 --- a/app/helpers/attachments_helper.rb +++ b/app/helpers/attachments_helper.rb @@ -1,219 +1,219 @@ -# encoding: utf-8 -# -# 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. - -module AttachmentsHelper - # Displays view/delete links to the attachments of the given object - # 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) - - if container.attachments.any? - options = {:deletable => container.attachments_deletable?, :author => true}.merge(options) - render :partial => 'attachments/links', - :locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)} - end - end - - def attach_delete(project) - if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.roles&Role.where('id = ? or id = ?', 3, 7)).size >0) || project.user_id == User.current.id) - true - else - false - end - - end - - def render_api_attachment(attachment, api) - api.attachment do - api.id attachment.id - api.filename attachment.filename - api.filesize attachment.filesize - api.content_type attachment.content_type - api.description attachment.description - api.content_url url_for(:controller => 'attachments', :action => 'download', :id => attachment, :filename => attachment.filename, :only_path => false) - api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author - api.created_on attachment.created_on - end - end - - def link_to_memo_attachments(container, options = {}) - options.assert_valid_keys(:author, :thumbnails) - - if container.attachments.any? - options = {:deletable => deletable?(container), :author => true}.merge(options) - render :partial => 'attachments/links', - :locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)} - end - end - - private - - def deletable? container, user=User.current - User.current.logged? && (container.author == user || user.admin?) - end - - # this method is used to get all projects that tagged one tag - # added by william - def get_attachments_by_tag(tag_name) - Attachment.tagged_with(tag_name).order('created_on desc') - end - - # this method is used to get all attachments that from one project and tagged one tag - # added by Long Jun - def get_attachments_by_project_tag(tag_name, obj) - @project_id =nil - if obj.container_type == 'Version' - @project_id = Version.find(obj.container_id).project_id - - elsif obj.container_type == 'Project' - @project_id = obj.container_id - - end - attachments = Attachment.tagged_with(tag_name).order('created_on desc').where("(container_id = :project_id and container_type = 'Project') or - (container_id in (select id from versions where project_id =:project_id) and container_type = 'Version')", {:project_id => @project_id}) - return attachments - end - - - def render_attachments_for_new_project(project, limit=nil) - # 查询条件 - params[:q] ||= "" - filename_condition = params[:q].strip - - attachAll = Attachment.scoped - # 当前项目所有资源 - # attachments = Attachment.find_all_by_container_type_and_container_id(project.class, project.id) - # attachments = Attachment.where("container_type = '#{project.class}' and container_id = #{project.id}") - - # 除去当前项目的所有资源 - nobelong_attach = Attachment.where("!(container_type = '#{project.class}' and container_id = #{project.id})") unless project.blank? - - # 搜索域确定 - domain = project.nil? ? attachAll : nobelong_attach - - # 搜索到的资源 - searched_attach = domain.where("is_public=1 and filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc') - #searched_attach = private_filter searched_attach - searched_attach = paginateHelper(searched_attach, 10) - - s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments') - links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options| - link_to text, attachments_autocomplete_path( parameters.merge(:project_id=>project.id,:q => params[:q], :format => 'js')), :remote => true } - - return s + content_tag('div', content_tag('ul', links), :class => 'pagination') - - # ================================================================================================ - - # attach_count = searched_attach.count - # attach_pages = Redmine::Pagination::Paginator.new attach_count, 10, params['page'] #by young - # attachs = searched_attach.offset(attach_pages.offset).limit(attach_pages.per_page).all - - # s = content_tag('div', attachments_check_box_tags('attachment[attach][]', attachs), :id => 'attachments') - # links = pagination_links_full(attach_pages, attach_count, :per_page_links => false) {|text, parameters, options| - # link_to text, attachments_autocomplete_path( parameters.merge(:q => params[:q], :format => 'js')), :remote => true } - - # return s + content_tag('div', content_tag('ul', links), :class => 'pagination') - # return searched_attach.to_json - end - - # add by nwb - def render_attachments_for_new_course(course, limit=nil) - # 查询条件 - params[:q] ||= "" - filename_condition = params[:q].strip - - #attachAll = Attachment.where("author_id = #{User.current.id}") - # - ## 除去当前课程的所有资源 - #nobelong_attach = - - # 搜索域确定 - course.nil? ? - domain=Attachment.where("author_id = #{User.current.id}") - : - domain=Attachment.where("author_id = #{User.current.id} and container_type = 'Course' and container_id <> #{course.id}") unless course.blank? - - # 搜索到的资源 - searched_attach = domain.where("filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc') - #searched_attach = private_filter searched_attach - searched_attach = paginateHelper(searched_attach, 10) - - #testattach = Attachment.public_attachments - - s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments') - links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options| - link_to text, attachments_autocomplete_path( parameters.merge(:course_id=>course.id,:q => params[:q], :format => 'js')), :remote => true } - - return s + content_tag('div', content_tag('ul', links), :class => 'pagination') - - end - - def attachments_check_box_tags(name, attachs) - s = '' - attachs.each do |attach| - s << "
    " - end - s.html_safe - end - - # Modified by Longjun - # 有参数的方法要加() - def private_filter(resultSet) - result = resultSet.to_a.dup - - # modify by nwb - #添加对课程资源文件的判断 - resultSet.map { |res| - if(res.container.nil? || - (res.container.class.to_s=="Project" && res.container.is_public == false) || - (res.container.has_attribute?(:project) && res.container.project && res.container.project.is_public == false) || - (res.container.class.to_s=="HomeworkAttach" && res.container.bid.reward_type == 3) || - (res.container.class.to_s=="Course" && res.container.is_public == false) || - (res.container.has_attribute?(:course) && res.container.course && res.container.course.is_public == false) - ) - result.delete(res) - end - } - result - end - - # 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 - obj.limit(@obj_pages.per_page).offset(@obj_pages.offset) - elsif obj.kind_of? Array - obj[@obj_pages.offset, @obj_pages.per_page] - else - logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}" - raise RuntimeError, 'unknow type, Please input you type into this helper.' - end - end - -end +# encoding: utf-8 +# +# 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. + +module AttachmentsHelper + # Displays view/delete links to the attachments of the given object + # 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) + + if container.attachments.any? + options = {:deletable => container.attachments_deletable?, :author => true}.merge(options) + render :partial => 'attachments/links', + :locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)} + end + end + + def attach_delete(project) + if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.roles&Role.where('id = ? or id = ?', 3, 7)).size >0) || project.user_id == User.current.id) + true + else + false + end + + end + + def render_api_attachment(attachment, api) + api.attachment do + api.id attachment.id + api.filename attachment.filename + api.filesize attachment.filesize + api.content_type attachment.content_type + api.description attachment.description + api.content_url url_for(:controller => 'attachments', :action => 'download', :id => attachment, :filename => attachment.filename, :only_path => false) + api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author + api.created_on attachment.created_on + end + end + + def link_to_memo_attachments(container, options = {}) + options.assert_valid_keys(:author, :thumbnails) + + if container.attachments.any? + options = {:deletable => deletable?(container), :author => true}.merge(options) + render :partial => 'attachments/links', + :locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)} + end + end + + private + + def deletable? container, user=User.current + User.current.logged? && (container.author == user || user.admin?) + end + + # this method is used to get all projects that tagged one tag + # added by william + def get_attachments_by_tag(tag_name) + Attachment.tagged_with(tag_name).order('created_on desc') + end + + # this method is used to get all attachments that from one project and tagged one tag + # added by Long Jun + def get_attachments_by_project_tag(tag_name, obj) + @project_id =nil + if obj.container_type == 'Version' + @project_id = Version.find(obj.container_id).project_id + + elsif obj.container_type == 'Project' + @project_id = obj.container_id + + end + attachments = Attachment.tagged_with(tag_name).order('created_on desc').where("(container_id = :project_id and container_type = 'Project') or + (container_id in (select id from versions where project_id =:project_id) and container_type = 'Version')", {:project_id => @project_id}) + return attachments + end + + + def render_attachments_for_new_project(project, limit=nil) + # 查询条件 + params[:q] ||= "" + filename_condition = params[:q].strip + + attachAll = Attachment.scoped + # 当前项目所有资源 + # attachments = Attachment.find_all_by_container_type_and_container_id(project.class, project.id) + # attachments = Attachment.where("container_type = '#{project.class}' and container_id = #{project.id}") + + # 除去当前项目的所有资源 + nobelong_attach = Attachment.where("!(container_type = '#{project.class}' and container_id = #{project.id})") unless project.blank? + + # 搜索域确定 + domain = project.nil? ? attachAll : nobelong_attach + + # 搜索到的资源 + searched_attach = domain.where("is_public=1 and filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc') + #searched_attach = private_filter searched_attach + searched_attach = paginateHelper(searched_attach, 10) + + s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments') + links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options| + link_to text, attachments_autocomplete_path( parameters.merge(:project_id=>project.id,:q => params[:q], :format => 'js')), :remote => true } + + return s + content_tag('div', content_tag('ul', links), :class => 'pagination') + + # ================================================================================================ + + # attach_count = searched_attach.count + # attach_pages = Redmine::Pagination::Paginator.new attach_count, 10, params['page'] #by young + # attachs = searched_attach.offset(attach_pages.offset).limit(attach_pages.per_page).all + + # s = content_tag('div', attachments_check_box_tags('attachment[attach][]', attachs), :id => 'attachments') + # links = pagination_links_full(attach_pages, attach_count, :per_page_links => false) {|text, parameters, options| + # link_to text, attachments_autocomplete_path( parameters.merge(:q => params[:q], :format => 'js')), :remote => true } + + # return s + content_tag('div', content_tag('ul', links), :class => 'pagination') + # return searched_attach.to_json + end + + # add by nwb + def render_attachments_for_new_course(course, limit=nil) + # 查询条件 + params[:q] ||= "" + filename_condition = params[:q].strip + + #attachAll = Attachment.where("author_id = #{User.current.id}") + # + ## 除去当前课程的所有资源 + #nobelong_attach = + + # 搜索域确定 + course.nil? ? + domain=Attachment.where("author_id = #{User.current.id}") + : + domain=Attachment.where("author_id = #{User.current.id} and container_type = 'Course' and container_id <> #{course.id}") unless course.blank? + + # 搜索到的资源 + searched_attach = domain.where("filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc') + #searched_attach = private_filter searched_attach + searched_attach = paginateHelper(searched_attach, 10) + + #testattach = Attachment.public_attachments + + s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments') + links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options| + link_to text, attachments_autocomplete_path( parameters.merge(:course_id=>course.id,:q => params[:q], :format => 'js')), :remote => true } + + return s + content_tag('div', content_tag('ul', links), :class => 'pagination') + + end + + def attachments_check_box_tags(name, attachs) + s = '' + attachs.each do |attach| + s << "
    " + end + s.html_safe + end + + # Modified by Longjun + # 有参数的方法要加() + def private_filter(resultSet) + result = resultSet.to_a.dup + + # modify by nwb + #添加对课程资源文件的判断 + resultSet.map { |res| + if(res.container.nil? || + (res.container.class.to_s=="Project" && res.container.is_public == false) || + (res.container.has_attribute?(:project) && res.container.project && res.container.project.is_public == false) || + (res.container.class.to_s=="HomeworkAttach" && res.container.bid.reward_type == 3) || + (res.container.class.to_s=="Course" && res.container.is_public == false) || + (res.container.has_attribute?(:course) && res.container.course && res.container.course.is_public == false) + ) + result.delete(res) + end + } + result + end + + # 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 + obj.limit(@obj_pages.per_page).offset(@obj_pages.offset) + elsif obj.kind_of? Array + obj[@obj_pages.offset, @obj_pages.per_page] + else + logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}" + raise RuntimeError, 'unknow type, Please input you type into this helper.' + end + end + +end diff --git a/app/helpers/logger_helper.rb b/app/helpers/logger_helper.rb index af04e38d3..3a7953c02 100644 --- a/app/helpers/logger_helper.rb +++ b/app/helpers/logger_helper.rb @@ -1,27 +1,27 @@ -module LoggerHelper - - #输出日志 - def OutLogger - #日志输出级别 - #Rails.logger.level = Logger::INFO - - if(!File.exist?("database")) - Dir.mkdir("database") - end - if(!File.exist?("database/get")) - Dir.mkdir("database/get") - end - if(!File.exist?("database/sql")) - Dir.mkdir("database/sql") - end - if(!File.exist?("database/controller")) - Dir.mkdir("database/controller") - end - - Rails.logger = Logger.new("database/get/#{Date.today.to_s}.log", "daily") - ActiveRecord::Base.logger = Logger.new("database/sql/#{Date.today.to_s}.log", "daily") - ActionController::Base.logger = Logger.new("database/controller/#{Date.today.to_s}.log", "daily") - end - -end - +module LoggerHelper + + #输出日志 + def OutLogger + #日志输出级别 + #Rails.logger.level = Logger::INFO + + if(!File.exist?("database")) + Dir.mkdir("database") + end + if(!File.exist?("database/get")) + Dir.mkdir("database/get") + end + if(!File.exist?("database/sql")) + Dir.mkdir("database/sql") + end + if(!File.exist?("database/controller")) + Dir.mkdir("database/controller") + end + + Rails.logger = Logger.new("database/get/#{Date.today.to_s}.log", "daily") + ActiveRecord::Base.logger = Logger.new("database/sql/#{Date.today.to_s}.log", "daily") + ActionController::Base.logger = Logger.new("database/controller/#{Date.today.to_s}.log", "daily") + end + +end + diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index a19819a02..5df3644ad 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -1,378 +1,378 @@ -# encoding: utf-8 -# -# 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. - -include AvatarHelper -module ProjectsHelper - def link_to_version(version, options = {}) - return '' unless version && version.is_a?(Version) - link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, options - end - - def project_settings_tabs - tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural}, - {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural}, - {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural}, - {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural}, - {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural}, - # {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki}, - {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural}, - #{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}, - {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities} - ] - tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} - - end - - # added bu huang - def sort_project_enterprise(state, project_type) - 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") - when 1 - - content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") - 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))) - when 2 - 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), :class=>"selected"), :class=>"selected") - content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type))) - end - content = content_tag('ul', content) - content_tag('div', content, :class => "tabs_enterprise") - end - - def sort_course(state, project_type, school_id) - content = ''.html_safe - case state - when 0 - 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, :class=>"selected"), :class=>"selected") - 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))) - 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), :class=>"selected"), :class=>"selected") - end - #gcmend - - content = content_tag('ul', content) - content_tag('div', content, :class => "tabs") - end - # end - - def sort_project(state, project_type) - 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") - when 1 - - content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") - 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))) - when 2 - 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), :class=>"selected"), :class=>"selected") - content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type))) - end - content = content_tag('ul', content) - content_tag('div', content, :class => "tabs") - end - - # def sort_course(state, project_type) - # content = ''.html_safe - # case state - # when 0 -# - # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type))) - # 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_time), course_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") - # when 1 -# - # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type), :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_time), course_path(:project_sort_type => '0', :project_type => project_type))) - # when 2 - # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type))) - # 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_time), course_path(:project_sort_type => '0', :project_type => project_type))) - # end - # content = content_tag('ul', content) - # content_tag('div', content, :class => "tabs") - # end - - - # 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}, - # {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural}, - {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural} - ] - tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} - end - # Ended by young - - - - - def parent_project_select_tag(project) - selected = project.parent - # retrieve the requested parent project - parent_id = (params[:project] && params[:project][:parent_id]) || params[:parent_id] - if parent_id - selected = (parent_id.blank? ? nil : Project.find(parent_id)) - end - - options = '' - options << "" if project.allowed_parents.include?(nil) - options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected) - content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id') - end - - # Renders the projects index - def render_project_hierarchy(projects) - render_project_nested_lists(projects) do |project| - #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(:label_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(:label_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 - end - end - - # Returns a set of options for a select field, grouped by project. - def version_options_for_select(versions, selected=nil) - grouped = Hash.new {|h,k| h[k] = []} - versions.each do |version| - grouped[version.project.name] << [version.name, version.id] - end - - if grouped.keys.size > 1 - grouped_options_for_select(grouped, selected && selected.id) - else - options_for_select((grouped.values.first || []), selected && selected.id) - end - end - - def format_version_sharing(sharing) - sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing) - l("label_version_sharing_#{sharing}") - end - - # this method is used to get all projects that tagged one tag - # added by william - def get_projects_by_tag(tag_name) - Project.tagged_with(tag_name).order('updated_on desc') - end - - # added by fq - def homework_type_option - type = [] - option1 = [] - option2 = [] - option1 << l(:label_task_submit_form_accessory) - option1 << 1 - option2 << l(:label_task_submit_form_project) - option2 << 2 - type << option1 - type << option2 - end - - #是否启动互评下拉框 - def is_evaluation_option - type = [] - option1 = [] - option2 = [] - option1 << l(:lable_start_mutual_evaluation) - option1 << 1 - option2 << l(:lable_close_mutual_evaluation) - option2 << 2 - type << option1 - type << option2 - end - - # 用来判断用户是否是项目的管理员 - # added by william - def is_manager?(user_id,project_id) - @result = false - @user_id = ProjectInfo.find_by_project_id(project_id) - - # modified by longjun - # if @user_id == user.id - # @result = true - # end - - @result = true if @user_id = user.id - # end longjun - return @result - end - - # 将动态中类型转换为可读的字符串 - def eventToLanguage event_type - case event_type - when "issue-note" - l :label_issue - when "issue" - l :label_issue - when "attachment" - l :label_attachment - when "news" - l :label_news - else - "" - end - end - - def eventToLanguageCourse event_type, project - case event_type - when "issue-note" - l :label_issue - when "issue" - l :label_issue - when "attachment" - l :label_attachment - when "news" - project.project_type == 1 ? (l :label_notification) : (l :label_news) - else - "" - end - end - - def rolesToLanguage rolesArray - rolesArray = ([] << rolesArray) unless rolesArray.is_a?(Array) - rolesArray.map{ |roleName| - case roleName.to_sym - when :Manager - l :default_role_manager - when :Developer - l :default_role_developer - when :Reporter - l :default_role_reporter - else - 'Unkown' - end - } - end - - def sort_project_by_hot - return sort_project_by_hot_rails - @projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1) - @projects_status = @projects_status.reorder('grade').all.reverse - @projects = [] - @projects_status.each do |obj| - break if(@projects_status[10] == obj) - @projects << Project.visible.find_by_id("#{obj.project_id}")#where('id=:id', id: obj.project_id) - end - @projects - rescue NoMethodError => e - logger.error "Logger.Error [ProjectsHelper] ===> #sort_project_by_hot, NoMethodError: #{e}" - [] - end - - def sort_project_by_hot_rails - # @projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1) - # @projects_status = @projects_status.reorder('grade').all.reverse - # Project.joins(@projects_status).limit(10) - limit = 10 - #Project.find_by_sql("SELECT * FROM projects RIGHT OUTER JOIN (SELECT * FROM project_statuses ORDER BY grade DESC LIMIT #{limit} ) AS t ON projects.id = t.project_id ") - Project.find_by_sql(" - SELECT p.id, p.name, p.description, p.identifier, t.project_id - FROM projects AS p RIGHT OUTER JOIN ( - SELECT project_id,grade FROM project_statuses - WHERE project_type = 0 ORDER BY grade DESC LIMIT #{limit} ) AS t ON p.id = t.project_id ") - end - - - # 判断课程是否结束,快别用,这个定日子的方法有问题 - def course_timeout? project - 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 - return false - elsif (courses_year < current_year) && (Time.now.month < 3) - return false - else - return true - end - end - - def find_project_repository project - unless project.repositories.nil? - project.repositories.each do |repository| - repository.fetch_changesets if Setting.autofetch_changesets? - end - end - end -end +# encoding: utf-8 +# +# 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. + +include AvatarHelper +module ProjectsHelper + def link_to_version(version, options = {}) + return '' unless version && version.is_a?(Version) + link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, options + end + + def project_settings_tabs + tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural}, + {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural}, + {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural}, + {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural}, + {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural}, + # {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki}, + {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural}, + #{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}, + {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities} + ] + tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} + + end + + # added bu huang + def sort_project_enterprise(state, project_type) + 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") + when 1 + + content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") + 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))) + when 2 + 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), :class=>"selected"), :class=>"selected") + content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type))) + end + content = content_tag('ul', content) + content_tag('div', content, :class => "tabs_enterprise") + end + + def sort_course(state, project_type, school_id) + content = ''.html_safe + case state + when 0 + 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, :class=>"selected"), :class=>"selected") + 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))) + 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), :class=>"selected"), :class=>"selected") + end + #gcmend + + content = content_tag('ul', content) + content_tag('div', content, :class => "tabs") + end + # end + + def sort_project(state, project_type) + 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") + when 1 + + content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") + 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))) + when 2 + 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), :class=>"selected"), :class=>"selected") + content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type))) + end + content = content_tag('ul', content) + content_tag('div', content, :class => "tabs") + end + + # def sort_course(state, project_type) + # content = ''.html_safe + # case state + # when 0 +# + # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type))) + # 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_time), course_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") + # when 1 +# + # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type), :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_time), course_path(:project_sort_type => '0', :project_type => project_type))) + # when 2 + # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type))) + # 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_time), course_path(:project_sort_type => '0', :project_type => project_type))) + # end + # content = content_tag('ul', content) + # content_tag('div', content, :class => "tabs") + # end + + + # 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}, + # {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural}, + {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural} + ] + tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} + end + # Ended by young + + + + + def parent_project_select_tag(project) + selected = project.parent + # retrieve the requested parent project + parent_id = (params[:project] && params[:project][:parent_id]) || params[:parent_id] + if parent_id + selected = (parent_id.blank? ? nil : Project.find(parent_id)) + end + + options = '' + options << "" if project.allowed_parents.include?(nil) + options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected) + content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id') + end + + # Renders the projects index + def render_project_hierarchy(projects) + render_project_nested_lists(projects) do |project| + #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(:label_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(:label_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 + end + end + + # Returns a set of options for a select field, grouped by project. + def version_options_for_select(versions, selected=nil) + grouped = Hash.new {|h,k| h[k] = []} + versions.each do |version| + grouped[version.project.name] << [version.name, version.id] + end + + if grouped.keys.size > 1 + grouped_options_for_select(grouped, selected && selected.id) + else + options_for_select((grouped.values.first || []), selected && selected.id) + end + end + + def format_version_sharing(sharing) + sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing) + l("label_version_sharing_#{sharing}") + end + + # this method is used to get all projects that tagged one tag + # added by william + def get_projects_by_tag(tag_name) + Project.tagged_with(tag_name).order('updated_on desc') + end + + # added by fq + def homework_type_option + type = [] + option1 = [] + option2 = [] + option1 << l(:label_task_submit_form_accessory) + option1 << 1 + option2 << l(:label_task_submit_form_project) + option2 << 2 + type << option1 + type << option2 + end + + #是否启动互评下拉框 + def is_evaluation_option + type = [] + option1 = [] + option2 = [] + option1 << l(:lable_start_mutual_evaluation) + option1 << 1 + option2 << l(:lable_close_mutual_evaluation) + option2 << 2 + type << option1 + type << option2 + end + + # 用来判断用户是否是项目的管理员 + # added by william + def is_manager?(user_id,project_id) + @result = false + @user_id = ProjectInfo.find_by_project_id(project_id) + + # modified by longjun + # if @user_id == user.id + # @result = true + # end + + @result = true if @user_id = user.id + # end longjun + return @result + end + + # 将动态中类型转换为可读的字符串 + def eventToLanguage event_type + case event_type + when "issue-note" + l :label_issue + when "issue" + l :label_issue + when "attachment" + l :label_attachment + when "news" + l :label_news + else + "" + end + end + + def eventToLanguageCourse event_type, project + case event_type + when "issue-note" + l :label_issue + when "issue" + l :label_issue + when "attachment" + l :label_attachment + when "news" + project.project_type == 1 ? (l :label_notification) : (l :label_news) + else + "" + end + end + + def rolesToLanguage rolesArray + rolesArray = ([] << rolesArray) unless rolesArray.is_a?(Array) + rolesArray.map{ |roleName| + case roleName.to_sym + when :Manager + l :default_role_manager + when :Developer + l :default_role_developer + when :Reporter + l :default_role_reporter + else + 'Unkown' + end + } + end + + def sort_project_by_hot + return sort_project_by_hot_rails + @projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1) + @projects_status = @projects_status.reorder('grade').all.reverse + @projects = [] + @projects_status.each do |obj| + break if(@projects_status[10] == obj) + @projects << Project.visible.find_by_id("#{obj.project_id}")#where('id=:id', id: obj.project_id) + end + @projects + rescue NoMethodError => e + logger.error "Logger.Error [ProjectsHelper] ===> #sort_project_by_hot, NoMethodError: #{e}" + [] + end + + def sort_project_by_hot_rails + # @projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1) + # @projects_status = @projects_status.reorder('grade').all.reverse + # Project.joins(@projects_status).limit(10) + limit = 10 + #Project.find_by_sql("SELECT * FROM projects RIGHT OUTER JOIN (SELECT * FROM project_statuses ORDER BY grade DESC LIMIT #{limit} ) AS t ON projects.id = t.project_id ") + Project.find_by_sql(" + SELECT p.id, p.name, p.description, p.identifier, t.project_id + FROM projects AS p RIGHT OUTER JOIN ( + SELECT project_id,grade FROM project_statuses + WHERE project_type = 0 ORDER BY grade DESC LIMIT #{limit} ) AS t ON p.id = t.project_id ") + end + + + # 判断课程是否结束,快别用,这个定日子的方法有问题 + def course_timeout? project + 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 + return false + elsif (courses_year < current_year) && (Time.now.month < 3) + return false + else + return true + end + end + + def find_project_repository project + unless project.repositories.nil? + project.repositories.each do |repository| + repository.fetch_changesets if Setting.autofetch_changesets? + end + end + end +end diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index 155485b4c..166dfd0ec 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -64,8 +64,8 @@ module WatchersHelper :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort) ) method = watched ? 'delete' : 'post' - - link_to text, url, :remote => true, :method => method, :class => css + + link_to text, url, :remote => true, :method => method, :class => css, :onclick => "location.reload()" end # add by nwb diff --git a/app/helpers/welcome_helper.rb b/app/helpers/welcome_helper.rb index 5ada224ae..8de7f4ec4 100644 --- a/app/helpers/welcome_helper.rb +++ b/app/helpers/welcome_helper.rb @@ -1,512 +1,512 @@ -# encoding: utf-8 -# -# 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. - -module WelcomeHelper - - include CoursesHelper - include ProjectsHelper - - def get_timestamp(obj) - if obj.respond_to? :updated_on - :updated_on - elsif obj.respond_to? :updated_at - :updated_at - elsif obj.respond_to? :created_on - :created_on - elsif obj.respond_to? :created_at - :created_at - else - Time.now.to_i.to_s.to_sym - end - end - - def cache_key_for_project(obj) - timestamp = get_timestamp(obj) - "welcome_index_project_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" - end - def cache_key_for_event(obj) - timestamp = get_timestamp(obj) - "welcome_index_event_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" - end - def cache_key_for_topic(obj) - timestamp = get_timestamp(obj) - "welcome_index_topic_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" - end - - def welcome_join_in_course(project, user) - if(user.logged? && - !(course_endTime_timeout? project) && - (project.course_extra.teacher.id != user.id) - ) - join_in_course(project, user) - end - end - - def get_course_avatar project - if get_avatar?(project) - url_to_avatar(project) - else - '../images/avatars/Project/course.jpg' - end - end - - def get_project_avatar project - if get_avatar?(project) - url_to_avatar(project) - else - '../images/avatars/Project/0' - end - end - # 前略·天国の首页君/Earth has been unable stop to welcomePage's. - # sum - 要搜索的项目数量 - # max_rate - 新项目所占所有项目的比重,10分制 - # - # Examples - # - # find_miracle_course(10, 7) - # # => 前7个项目为新课程,后面三个是参与人数最多的 - # - # Returns project&courses array - # 原来的取课程逻辑 - def find_miracle_course_base(sum=10, max_rate=7, school_id) - - if User.current.user_extensions.school.nil? and school_id.nil? - Project.active.visible.course_entities. - joins(:course_extra). - joins(:memberships). - group('members.project_id'). - reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum -# elseif school_id.nil? - - else - if school_id.nil? - Project.active.visible.course_entities. - joins(:course_extra). - joins(:memberships). - where("#{Course.table_name}.school_id = ?", User.current.user_extensions.school.id). - group('members.project_id'). - reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum - else - if school_id == "0" - Project.active.visible.course_entities. - joins(:course_extra). - joins(:memberships). - group('members.project_id'). - reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum - else - Project.active.visible.course_entities. - joins(:course_extra). - joins(:memberships). - where("#{Course.table_name}.school_id = ?", school_id). - group('members.project_id'). - reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum - end - end - end -# else -# Project.active.visible.course_entities. -# joins(:course_extra). -# joins(:memberships). -# where("#{Course.table_name}.school_id = ?", school_id). -# group('members.project_id'). -# reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum -# end - # max = sum*(max_rate.to_f/10) - # c1 = find_new_course(sum).to_a.dup - # c2 = find_all_hot_course(sum).to_a.dup - # c2 = c2 - c1 - # (c1.take(max)+c2).take(sum) - end - - #获取课程列表 - # add by nwb - def find_miracle_course(sum=10, max_rate=7, school_id, time,term) - if User.current.user_extensions.nil? && User.current.user_extensions.school.nil? and school_id.nil? - Course.active.visible. - joins(:memberships). - where("courses.time = #{time} and courses.term = #{term}"). - group('members.course_id'). - reorder("courses.created_at DESC, COUNT(members.course_id) DESC").take sum - else - if school_id.nil? - Course.active.visible. - joins(:memberships). - where("#{Course.table_name}.school_id = ? and courses.time = ? and courses.term = ?", User.current.user_extensions.school.id, time, term). - group('members.course_id'). - reorder("COUNT(members.course_id) DESC").take sum - else - if school_id == "0" - Course.active.visible. - joins(:memberships). - where("courses.time = #{time} and courses.term = #{term}"). - group('members.course_id'). - reorder("COUNT(members.course_id) DESC").take sum - else - Course.active.visible. - joins(:memberships). - where("#{Course.table_name}.school_id = ? and courses.time = ? and courses.term = ?", school_id, time, term). - group('members.course_id'). - reorder("COUNT(members.course_id) DESC").take sum - end - end - end -# else -# Project.active.visible.course_entities. -# joins(:course_extra). -# joins(:memberships). -# where("#{Course.table_name}.school_id = ?", school_id). -# group('members.project_id'). -# reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum -# end -# max = sum*(max_rate.to_f/10) -# c1 = find_new_course(sum).to_a.dup -# c2 = find_all_hot_course(sum).to_a.dup -# c2 = c2 - c1 -# (c1.take(max)+c2).take(sum) - end - - #查找所有学校按每个学校开设课程数量降序排序 - #page 分页查询开始条数的编号,从0开始 - #limit 分页查询的数量 - def find_maxmin_course_school page,limit - School.find_by_sql("SELECT *,(SELECT COUNT(*) FROM courses WHERE school_id = schools.id) AS a - FROM schools - ORDER BY a DESC LIMIT #{page},#{limit}") - #School.where(" id IN (SELECT school_id FROM courses GROUP BY school_id)").limit limit; - #School.order("#{School.course_count}").limit(limit).all - #@school = School.all.sort - #@school.each do |s| - # s.courses.count - #end - #result = [] - #@school = School.all.to_ary - #i = 1 - #for i in i < School.count - # j = i - 1 - # for j in j > 0 - # if @school[j].courses.count > - # end - #end - end - - def find_miracle_project(sum, max_rate,order) - #max = sum*(max_rate.to_f/10) - #c1 = find_new_project(sum).to_a.dup - #c2 = find_all_hot_project(sum).to_a.dup - #(c2.take(sum-max)+c1.take(max)).take(sum) - find_all_hot_project(sum,order).to_a.dup - end - - def find_new_course limit=15 - Project.visible.joins(:course_extra).where("#{Project.table_name}.project_type = ? ", 1).order("courses.time DESC, #{Project.table_name}.created_on DESC").limit(limit).all - end - - def find_new_project limit=15 - Project.visible.where("#{Project.table_name}.project_type = ? ", 0).order("#{Project.table_name}.updated_on DESC, #{Project.table_name}.created_on DESC").limit(limit).all - end - - - def find_all_hot_project limit=15,order - sort_project_by_hot limit,order - end - - def find_all_hot_course limit=15 - sort_course_by_hot limit - end - - # modif by nwb - def find_all_new_hot_course limit = 9 ,school_id = nil, year_now, course_term - #sort_project_by_hot_rails 1, 'course_ac_para DESC', limit - #time_now = Time.new.strftime("%Y") - #if school_id - #courses = Course.includes(:school, :members).visible.joins(:course_status).where("#{Course.table_name}.created_at like '%#{time_now}%' and #{Course.table_name}.school_id <> - # ?", school_id).order("course_ac_para DESC").limit(limit).all - #else - # courses = Course.includes(:school, :members).visible.joins(:course_status).where("#{Course.table_name}.created_at like '%#{time_now}%' and #{Course.table_name}.school_id is not NULL - # ").order("course_ac_para DESC").limit(limit).all - # end - school_id.nil? ? - courses = Course.includes(:school, :members).visible. - joins(:memberships). - where("courses.time = ? and courses.term = ? and courses.school_id is not NULL", year_now, course_term). - group('members.course_id'). - reorder("COUNT(members.course_id) DESC").limit(limit).all - : - courses = Course.includes(:school, :members).visible. - joins(:memberships). - where("courses.time = ? and courses.term = ? and courses.school_id <> ?",year_now, course_term, school_id). - group('members.course_id'). - reorder("COUNT(members.course_id) DESC").limit(limit).all - courses - end - - def find_all_hot_bid - sort_bid_by_hot - end - - def find_all_hot_contest limit=10 - Contest.reorder("created_on DESC").all.take limit - # mix_bid = [] - # mix_bid += Contest.reorder("created_on DESC").take(limit).to_a - # mix_bid += Bid.visible.where('reward_type = ?', 2).reorder('bids.created_on desc').take(limit).to_a - # mix_bid.sort do |older, newer| - # newer.created_on - older.created_on - # end - # mix_bid.take limit - end - - def find_all_hot_softapplication limit=10 - Softapplication.reorder("created_at DESC").all.take limit - end - - def cal_memos_count event - return nil if event.parent_id - event.replies_count - rescue NoMethodError - nil - end - - def cal_issues_count event - event.journals.count - rescue NoMethodError - nil - end - - def topic_last_time topic - return topic.event_datetime if ( !(topic.methods.to_s =~ %r[last_reply]) || topic.last_reply.nil? ) - topic.last_reply.event_datetime - end - - - def time_tag_welcome time - text = distance_of_time_in_words(Time.now, time) - content_tag('span', text, :title => format_time(time)) - end - - def show_grade project - grade = 0 - begin - #ActiveRecord::Base.connection.execute("CALL sp_project_status_cursor();")#执行存储过程速度慢 - grade = project.project_status.grade if project && project.project_status - rescue Exception => e - logger.error "Logger.Error [WelcomeHelper] ===> #{e}" - end - "项目评分:".html_safe << grade.to_s - end - - def show_user_content event - str = ' '.html_safe - case event.event_type - when 'news' - str << content_tag("span", "发表了") << - content_tag("span", find_all_event_type(event)) << - ': '.html_safe << - link_to(strip_tags(event.event_description).gsub(/ /,''), event.event_url) - when 'issue', 'message' , 'bid' , 'wiki-page' , 'document' - str << content_tag("span", "发表了") << - content_tag("span", find_all_event_type(event)) << - ': '.html_safe << - link_to(event.event_title, event.event_url) - when 'reply' ,'Reply', 'Memo' - str << content_tag("span", "发表了") << - content_tag("span", find_all_event_type(event)) << - ': '.html_safe << - link_to(strip_tags(event.event_description).gsub(/ /,''), event.event_url) - when 'attachment' - str << content_tag('span', '上传了') << - content_tag('span', find_all_event_type(event)) << - ': '.html_safe << - link_to(event.event_title, event.event_url) << - link_to((' ['.html_safe+l(:label_downloads_list).to_s << ']'), project_files_path(event.container.project), :class => "attachments_list_color") - else - str << content_tag("span", "更新了") << - content_tag("span", find_all_event_type(event)) << - ': '.html_safe << link_to(event.event_title, event.event_url) - end - str - rescue Exception => e - str << content_tag("span", '未知内容') - end - - def show_event_reply event - str = "回复(" - case event.event_type - when 'news' - str << link_to( event.comments.count, news_path(event)) << ")" - when "issue" - str << link_to(cal_issues_count(event), issue_path(event)) << ")" - when "Memo" - str << link_to(cal_memos_count(event), forum_memo_path(event.forum_id,event.id)) << ")" - else - str = "" - end - str.html_safe - end - - def find_new_forum_topics limit=7 - # Memo.where('memos.parent_id IS NULL').reorder('memos.created_at DESC').limit(limit) - # activity = Redmine::Activity::Fetcher.new(nil) - # activity.scope=['memos'] - # activity.events_welcome(nil, nil, {:limit => limit}) - - resultSet = Memo.where('memos.parent_id IS NULL').includes(:last_reply).order('COALESCE (last_replies_memos.created_at, memos.created_at) DESC').limit(limit) - # resultSet += Message.where('messages.parent_id IS NULL').includes(:last_reply).order('COALESCE (last_replies_messages.created_on, messages.created_on) DESC').limit(limit) - - # resultSet = Memo.includes(:children).where('parent_id IS NULL').order('updated_at DESC').limit(limit) - # resultSet += Message.includes(:children).where('parent_id IS NULL').order('updated_on DESC').limit(limit) - # resultSet.sort! {|x,y| y.event_datetime <=> x.event_datetime} - # resultSet = resultSet.to_a - # for i in 0..(resultSet.size-1) - # resultSet[i] = resultSet[i].children.last if resultSet[i].children.count > 0 - # end - # resultSet.take(limit) - end - - private - - def sort_project_by_hot limit=15,order - #'grade DESC' - sort_project_by_hot_rails 0,order , limit - end - - def sort_course_by_hot limit=15 - sort_project_by_hot_rails 1, 'course_ac_para DESC', limit - end - - def sort_bid_by_hot - sort_bid_by_hot_rails 1 - end - - def sort_contest_by_hot - sort_bid_by_hot_rails 2 - end -#new added by linchun - def sort_contest_by_time - sort_bid_by_time 2 - end - - #取得所有活动 - def find_all_activities limit=6 - # users = [] - # activities = Activity.find_by_sql("select distinct user_id from activities order by id DESC limit #{limit}" ) - # activities.each { |activity| - # users << activity.user_id - # } - # user_objs = User.find_by_sql("SELECT * FROM users WHERE (users.id IN #{"(" << users.join(',') << ")"} )") - activity = Redmine::Activity::Fetcher.new(nil) - has = { # TODO: 待完成 - "show_issues" => true, - "show_files" => true, - "show_documents" => true, - "show_messages" => true, - "show_news" => true, - "show_bids" => true, - "show_contest" => true - } - activity.scope_select{|t| ['changesets', 'documents', 'memos', 'messages', 'journals_for_messages', 'bids', 'news', 'contestnotification'].include?(t) ? - nil : 'You may think you know what the following code does, may be. but why don"t you close this file and go play with something else, Now?' } - activity.events_welcome(nil, nil, {:limit => limit, :types => 'welcome'}) - end - - #取得论坛数据 - def find_hot_forum_topics limit=9 - ## 以下语句会内链接自身查询出最后一条回复时间,没有回复的帖子不会显示 - # Memo.find_by_sql(" - # SELECT memos.*, reply.created_at AS last_reply_date FROM memos AS memos - # INNER JOIN memos - # AS reply ON memos.last_reply_id=reply.id - # WHERE memos.parent_id IS NULL - # ORDER BY memos.replies_count DESC, memos.created_at DESC - # LIMIT #{limit}") - - #Memo.order('replies_count DESC').where('replies_count <> 0').limit(limit) - - resultSet = Memo.order('replies_count DESC, created_at DESC').where('parent_id IS NULL').limit(limit) - resultSet += Message.order('replies_count DESC, created_on DESC').where('parent_id IS NULL').limit(limit) - resultSet.sort! {|x,y| (y.replies_count <=> x.replies_count).nonzero? || (y.event_datetime <=> x.event_datetime)} - resultSet.take(limit) - end - - def sort_project_by_hot_rails project_type=0, order_by='score DESC', limit=15 - # Project.find_by_sql(" - # SELECT p.id, p.name, p.description, p.identifier, t.project_id - # FROM projects AS p LEFT OUTER JOIN ( - # SELECT project_id,grade FROM project_statuses - # WHERE project_type = #{project_type} ORDER BY #{order_by} LIMIT #{limit} ) AS t ON p.id = t.project_id ") - Project.visible.joins(:project_status).joins("LEFT JOIN #{ProjectScore.table_name} ON #{Project.table_name}.id = #{ProjectScore.table_name}.project_id").where("#{Project.table_name}.project_type = ?", project_type).order(order_by).limit(limit).all - end - - def sort_bid_by_hot_rails reward_type, limit = 10 - Bid.visible.where('reward_type = ?', reward_type).reorder('bids.commit desc').limit(limit) - end - - def sort_bid_by_time reward_type, limit = 10 - Bid.visible.where('reward_type = ?', reward_type).reorder('bids.created_on desc').limit(limit) - end - - def find_all_event_type event - case event.event_type - when 'news' - '新闻' - when 'issue' - '缺陷' - when 'attachment' - '附件' - when 'message' - '主题' - when 'Reply','reply' - '回复' - when 'bid' - '作业' - when 'Memo' - '主题' - when 'document' - '文件' - when 'changeset' - '版本库' - when 'issue-note' - '问题说明' - else - event.event_type - end - end - - def newbie_send_path - create_new_forum_path '新手讨论' - end - def suggestion_send_path - create_new_forum_path '网站建议' - end - - private - - def create_new_forum_path name - # 没有论坛则返回'#' 不能发帖 - # 否则到指定论坛里发帖 - # 没有找到置顶论坛就跑默认第一个论坛发帖 - forum_relation = create_find_undefine_forum name - backUrl = '#' - backUrl = new_forum_memo_path(Forum.first) if Forum.count > 0 - backUrl = new_forum_memo_path(forum_relation.first) if !forum_relation.empty? - return backUrl - end - def create_find_undefine_forum name - Forum.where("name LIKE \'%#{name}%\'") - end -end +# encoding: utf-8 +# +# 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. + +module WelcomeHelper + + include CoursesHelper + include ProjectsHelper + + def get_timestamp(obj) + if obj.respond_to? :updated_on + :updated_on + elsif obj.respond_to? :updated_at + :updated_at + elsif obj.respond_to? :created_on + :created_on + elsif obj.respond_to? :created_at + :created_at + else + Time.now.to_i.to_s.to_sym + end + end + + def cache_key_for_project(obj) + timestamp = get_timestamp(obj) + "welcome_index_project_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" + end + def cache_key_for_event(obj) + timestamp = get_timestamp(obj) + "welcome_index_event_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" + end + def cache_key_for_topic(obj) + timestamp = get_timestamp(obj) + "welcome_index_topic_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" + end + + def welcome_join_in_course(project, user) + if(user.logged? && + !(course_endTime_timeout? project) && + (project.course_extra.teacher.id != user.id) + ) + join_in_course(project, user) + end + end + + def get_course_avatar project + if get_avatar?(project) + url_to_avatar(project) + else + '../images/avatars/Project/course.jpg' + end + end + + def get_project_avatar project + if get_avatar?(project) + url_to_avatar(project) + else + '../images/avatars/Project/0' + end + end + # 前略·天国の首页君/Earth has been unable stop to welcomePage's. + # sum - 要搜索的项目数量 + # max_rate - 新项目所占所有项目的比重,10分制 + # + # Examples + # + # find_miracle_course(10, 7) + # # => 前7个项目为新课程,后面三个是参与人数最多的 + # + # Returns project&courses array + # 原来的取课程逻辑 + def find_miracle_course_base(sum=10, max_rate=7, school_id) + + if User.current.user_extensions.school.nil? and school_id.nil? + Project.active.visible.course_entities. + joins(:course_extra). + joins(:memberships). + group('members.project_id'). + reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum +# elseif school_id.nil? + + else + if school_id.nil? + Project.active.visible.course_entities. + joins(:course_extra). + joins(:memberships). + where("#{Course.table_name}.school_id = ?", User.current.user_extensions.school.id). + group('members.project_id'). + reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum + else + if school_id == "0" + Project.active.visible.course_entities. + joins(:course_extra). + joins(:memberships). + group('members.project_id'). + reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum + else + Project.active.visible.course_entities. + joins(:course_extra). + joins(:memberships). + where("#{Course.table_name}.school_id = ?", school_id). + group('members.project_id'). + reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum + end + end + end +# else +# Project.active.visible.course_entities. +# joins(:course_extra). +# joins(:memberships). +# where("#{Course.table_name}.school_id = ?", school_id). +# group('members.project_id'). +# reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum +# end + # max = sum*(max_rate.to_f/10) + # c1 = find_new_course(sum).to_a.dup + # c2 = find_all_hot_course(sum).to_a.dup + # c2 = c2 - c1 + # (c1.take(max)+c2).take(sum) + end + + #获取课程列表 + # add by nwb + def find_miracle_course(sum=10, max_rate=7, school_id, time,term) + if User.current.user_extensions.nil? && User.current.user_extensions.school.nil? and school_id.nil? + Course.active.visible. + joins(:memberships). + where("courses.time = #{time} and courses.term = #{term}"). + group('members.course_id'). + reorder("courses.created_at DESC, COUNT(members.course_id) DESC").take sum + else + if school_id.nil? + Course.active.visible. + joins(:memberships). + where("#{Course.table_name}.school_id = ? and courses.time = ? and courses.term = ?", User.current.user_extensions.school.id, time, term). + group('members.course_id'). + reorder("COUNT(members.course_id) DESC").take sum + else + if school_id == "0" + Course.active.visible. + joins(:memberships). + where("courses.time = #{time} and courses.term = #{term}"). + group('members.course_id'). + reorder("COUNT(members.course_id) DESC").take sum + else + Course.active.visible. + joins(:memberships). + where("#{Course.table_name}.school_id = ? and courses.time = ? and courses.term = ?", school_id, time, term). + group('members.course_id'). + reorder("COUNT(members.course_id) DESC").take sum + end + end + end +# else +# Project.active.visible.course_entities. +# joins(:course_extra). +# joins(:memberships). +# where("#{Course.table_name}.school_id = ?", school_id). +# group('members.project_id'). +# reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum +# end +# max = sum*(max_rate.to_f/10) +# c1 = find_new_course(sum).to_a.dup +# c2 = find_all_hot_course(sum).to_a.dup +# c2 = c2 - c1 +# (c1.take(max)+c2).take(sum) + end + + #查找所有学校按每个学校开设课程数量降序排序 + #page 分页查询开始条数的编号,从0开始 + #limit 分页查询的数量 + def find_maxmin_course_school page,limit + School.find_by_sql("SELECT *,(SELECT COUNT(*) FROM courses WHERE school_id = schools.id) AS a + FROM schools + ORDER BY a DESC LIMIT #{page},#{limit}") + #School.where(" id IN (SELECT school_id FROM courses GROUP BY school_id)").limit limit; + #School.order("#{School.course_count}").limit(limit).all + #@school = School.all.sort + #@school.each do |s| + # s.courses.count + #end + #result = [] + #@school = School.all.to_ary + #i = 1 + #for i in i < School.count + # j = i - 1 + # for j in j > 0 + # if @school[j].courses.count > + # end + #end + end + + def find_miracle_project(sum, max_rate,order) + #max = sum*(max_rate.to_f/10) + #c1 = find_new_project(sum).to_a.dup + #c2 = find_all_hot_project(sum).to_a.dup + #(c2.take(sum-max)+c1.take(max)).take(sum) + find_all_hot_project(sum,order).to_a.dup + end + + def find_new_course limit=15 + Project.visible.joins(:course_extra).where("#{Project.table_name}.project_type = ? ", 1).order("courses.time DESC, #{Project.table_name}.created_on DESC").limit(limit).all + end + + def find_new_project limit=15 + Project.visible.where("#{Project.table_name}.project_type = ? ", 0).order("#{Project.table_name}.updated_on DESC, #{Project.table_name}.created_on DESC").limit(limit).all + end + + + def find_all_hot_project limit=15,order + sort_project_by_hot limit,order + end + + def find_all_hot_course limit=15 + sort_course_by_hot limit + end + + # modif by nwb + def find_all_new_hot_course limit = 9 ,school_id = nil, year_now, course_term + #sort_project_by_hot_rails 1, 'course_ac_para DESC', limit + #time_now = Time.new.strftime("%Y") + #if school_id + #courses = Course.includes(:school, :members).visible.joins(:course_status).where("#{Course.table_name}.created_at like '%#{time_now}%' and #{Course.table_name}.school_id <> + # ?", school_id).order("course_ac_para DESC").limit(limit).all + #else + # courses = Course.includes(:school, :members).visible.joins(:course_status).where("#{Course.table_name}.created_at like '%#{time_now}%' and #{Course.table_name}.school_id is not NULL + # ").order("course_ac_para DESC").limit(limit).all + # end + school_id.nil? ? + courses = Course.includes(:school, :members).visible. + joins(:memberships). + where("courses.time = ? and courses.term = ? and courses.school_id is not NULL", year_now, course_term). + group('members.course_id'). + reorder("COUNT(members.course_id) DESC").limit(limit).all + : + courses = Course.includes(:school, :members).visible. + joins(:memberships). + where("courses.time = ? and courses.term = ? and courses.school_id <> ?",year_now, course_term, school_id). + group('members.course_id'). + reorder("COUNT(members.course_id) DESC").limit(limit).all + courses + end + + def find_all_hot_bid + sort_bid_by_hot + end + + def find_all_hot_contest limit=10 + Contest.reorder("created_on DESC").all.take limit + # mix_bid = [] + # mix_bid += Contest.reorder("created_on DESC").take(limit).to_a + # mix_bid += Bid.visible.where('reward_type = ?', 2).reorder('bids.created_on desc').take(limit).to_a + # mix_bid.sort do |older, newer| + # newer.created_on - older.created_on + # end + # mix_bid.take limit + end + + def find_all_hot_softapplication limit=10 + Softapplication.reorder("created_at DESC").all.take limit + end + + def cal_memos_count event + return nil if event.parent_id + event.replies_count + rescue NoMethodError + nil + end + + def cal_issues_count event + event.journals.count + rescue NoMethodError + nil + end + + def topic_last_time topic + return topic.event_datetime if ( !(topic.methods.to_s =~ %r[last_reply]) || topic.last_reply.nil? ) + topic.last_reply.event_datetime + end + + + def time_tag_welcome time + text = distance_of_time_in_words(Time.now, time) + content_tag('span', text, :title => format_time(time)) + end + + def show_grade project + grade = 0 + begin + #ActiveRecord::Base.connection.execute("CALL sp_project_status_cursor();")#执行存储过程速度慢 + grade = project.project_status.grade if project && project.project_status + rescue Exception => e + logger.error "Logger.Error [WelcomeHelper] ===> #{e}" + end + "项目评分:".html_safe << grade.to_s + end + + def show_user_content event + str = ' '.html_safe + case event.event_type + when 'news' + str << content_tag("span", "发表了") << + content_tag("span", find_all_event_type(event)) << + ': '.html_safe << + link_to(strip_tags(event.event_description).gsub(/ /,''), event.event_url) + when 'issue', 'message' , 'bid' , 'wiki-page' , 'document' + str << content_tag("span", "发表了") << + content_tag("span", find_all_event_type(event)) << + ': '.html_safe << + link_to(event.event_title, event.event_url) + when 'reply' ,'Reply', 'Memo' + str << content_tag("span", "发表了") << + content_tag("span", find_all_event_type(event)) << + ': '.html_safe << + link_to(strip_tags(event.event_description).gsub(/ /,''), event.event_url) + when 'attachment' + str << content_tag('span', '上传了') << + content_tag('span', find_all_event_type(event)) << + ': '.html_safe << + link_to(event.event_title, event.event_url) << + link_to((' ['.html_safe+l(:label_downloads_list).to_s << ']'), project_files_path(event.container.project), :class => "attachments_list_color") + else + str << content_tag("span", "更新了") << + content_tag("span", find_all_event_type(event)) << + ': '.html_safe << link_to(event.event_title, event.event_url) + end + str + rescue Exception => e + str << content_tag("span", '未知内容') + end + + def show_event_reply event + str = "回复(" + case event.event_type + when 'news' + str << link_to( event.comments.count, news_path(event)) << ")" + when "issue" + str << link_to(cal_issues_count(event), issue_path(event)) << ")" + when "Memo" + str << link_to(cal_memos_count(event), forum_memo_path(event.forum_id,event.id)) << ")" + else + str = "" + end + str.html_safe + end + + def find_new_forum_topics limit=7 + # Memo.where('memos.parent_id IS NULL').reorder('memos.created_at DESC').limit(limit) + # activity = Redmine::Activity::Fetcher.new(nil) + # activity.scope=['memos'] + # activity.events_welcome(nil, nil, {:limit => limit}) + + resultSet = Memo.where('memos.parent_id IS NULL').includes(:last_reply).order('COALESCE (last_replies_memos.created_at, memos.created_at) DESC').limit(limit) + # resultSet += Message.where('messages.parent_id IS NULL').includes(:last_reply).order('COALESCE (last_replies_messages.created_on, messages.created_on) DESC').limit(limit) + + # resultSet = Memo.includes(:children).where('parent_id IS NULL').order('updated_at DESC').limit(limit) + # resultSet += Message.includes(:children).where('parent_id IS NULL').order('updated_on DESC').limit(limit) + # resultSet.sort! {|x,y| y.event_datetime <=> x.event_datetime} + # resultSet = resultSet.to_a + # for i in 0..(resultSet.size-1) + # resultSet[i] = resultSet[i].children.last if resultSet[i].children.count > 0 + # end + # resultSet.take(limit) + end + + private + + def sort_project_by_hot limit=15,order + #'grade DESC' + sort_project_by_hot_rails 0,order , limit + end + + def sort_course_by_hot limit=15 + sort_project_by_hot_rails 1, 'course_ac_para DESC', limit + end + + def sort_bid_by_hot + sort_bid_by_hot_rails 1 + end + + def sort_contest_by_hot + sort_bid_by_hot_rails 2 + end +#new added by linchun + def sort_contest_by_time + sort_bid_by_time 2 + end + + #取得所有活动 + def find_all_activities limit=6 + # users = [] + # activities = Activity.find_by_sql("select distinct user_id from activities order by id DESC limit #{limit}" ) + # activities.each { |activity| + # users << activity.user_id + # } + # user_objs = User.find_by_sql("SELECT * FROM users WHERE (users.id IN #{"(" << users.join(',') << ")"} )") + activity = Redmine::Activity::Fetcher.new(nil) + has = { # TODO: 待完成 + "show_issues" => true, + "show_files" => true, + "show_documents" => true, + "show_messages" => true, + "show_news" => true, + "show_bids" => true, + "show_contest" => true + } + activity.scope_select{|t| ['changesets', 'documents', 'memos', 'messages', 'journals_for_messages', 'bids', 'news', 'contestnotification'].include?(t) ? + nil : 'You may think you know what the following code does, may be. but why don"t you close this file and go play with something else, Now?' } + activity.events_welcome(nil, nil, {:limit => limit, :types => 'welcome'}) + end + + #取得论坛数据 + def find_hot_forum_topics limit=9 + ## 以下语句会内链接自身查询出最后一条回复时间,没有回复的帖子不会显示 + # Memo.find_by_sql(" + # SELECT memos.*, reply.created_at AS last_reply_date FROM memos AS memos + # INNER JOIN memos + # AS reply ON memos.last_reply_id=reply.id + # WHERE memos.parent_id IS NULL + # ORDER BY memos.replies_count DESC, memos.created_at DESC + # LIMIT #{limit}") + + #Memo.order('replies_count DESC').where('replies_count <> 0').limit(limit) + + resultSet = Memo.order('replies_count DESC, created_at DESC').where('parent_id IS NULL').limit(limit) + resultSet += Message.order('replies_count DESC, created_on DESC').where('parent_id IS NULL').limit(limit) + resultSet.sort! {|x,y| (y.replies_count <=> x.replies_count).nonzero? || (y.event_datetime <=> x.event_datetime)} + resultSet.take(limit) + end + + def sort_project_by_hot_rails project_type=0, order_by='score DESC', limit=15 + # Project.find_by_sql(" + # SELECT p.id, p.name, p.description, p.identifier, t.project_id + # FROM projects AS p LEFT OUTER JOIN ( + # SELECT project_id,grade FROM project_statuses + # WHERE project_type = #{project_type} ORDER BY #{order_by} LIMIT #{limit} ) AS t ON p.id = t.project_id ") + Project.visible.joins(:project_status).joins("LEFT JOIN #{ProjectScore.table_name} ON #{Project.table_name}.id = #{ProjectScore.table_name}.project_id").where("#{Project.table_name}.project_type = ?", project_type).order(order_by).limit(limit).all + end + + def sort_bid_by_hot_rails reward_type, limit = 10 + Bid.visible.where('reward_type = ?', reward_type).reorder('bids.commit desc').limit(limit) + end + + def sort_bid_by_time reward_type, limit = 10 + Bid.visible.where('reward_type = ?', reward_type).reorder('bids.created_on desc').limit(limit) + end + + def find_all_event_type event + case event.event_type + when 'news' + '新闻' + when 'issue' + '缺陷' + when 'attachment' + '附件' + when 'message' + '主题' + when 'Reply','reply' + '回复' + when 'bid' + '作业' + when 'Memo' + '主题' + when 'document' + '文件' + when 'changeset' + '版本库' + when 'issue-note' + '问题说明' + else + event.event_type + end + end + + def newbie_send_path + create_new_forum_path '新手讨论' + end + def suggestion_send_path + create_new_forum_path '网站建议' + end + + private + + def create_new_forum_path name + # 没有论坛则返回'#' 不能发帖 + # 否则到指定论坛里发帖 + # 没有找到置顶论坛就跑默认第一个论坛发帖 + forum_relation = create_find_undefine_forum name + backUrl = '#' + backUrl = new_forum_memo_path(Forum.first) if Forum.count > 0 + backUrl = new_forum_memo_path(forum_relation.first) if !forum_relation.empty? + return backUrl + end + def create_find_undefine_forum name + Forum.where("name LIKE \'%#{name}%\'") + end +end diff --git a/app/models/activity.rb b/app/models/activity.rb index 4676ca7b8..e871ae735 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -1,8 +1,8 @@ -class Activity < ActiveRecord::Base - attr_accessible :act_id, :act_type, :user_id - belongs_to :act, :polymorphic => true - belongs_to :user - validates :act_id, presence: true - validates :act_type, presence: true - validates :user_id, presence: true -end +class Activity < ActiveRecord::Base + attr_accessible :act_id, :act_type, :user_id + belongs_to :act, :polymorphic => true + belongs_to :user + validates :act_id, presence: true + validates :act_type, presence: true + validates :user_id, presence: true +end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index a0012492d..de7912667 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -1,532 +1,532 @@ -# 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 "digest/md5" -require "fileutils" - -class Attachment < ActiveRecord::Base - belongs_to :container, :polymorphic => true - belongs_to :project, foreign_key: 'container_id', conditions: "attachments.container_type = 'Project'" - belongs_to :course, foreign_key: 'container_id', conditions: "attachments.container_type = 'Course'" - belongs_to :softapplication, foreign_key: 'container_id', conditions: "attachments.container_type = 'Softapplication'" - belongs_to :author, :class_name => "User", :foreign_key => "author_id" - belongs_to :attachmentstype, :foreign_key => "attachtype",:primary_key => "id" - - include UserScoreHelper - - validates :filename, presence: true, length: {maximum: 254} - validates :author, presence: true - validates :disk_filename, length: {maximum: 254} - validates :description, length: {maximum: 254} - validate :validate_max_file_size - - - acts_as_taggable - acts_as_event :title => :filename, - :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}} - - #课程资源文件 - acts_as_activity_provider :type => 'course_files', - :is_public => 'attachments.is_public', - :permission => :view_files, - :author_key => :author_id, - :find_options => {:select => "#{Attachment.table_name}.*", - :joins => "LEFT JOIN #{Course.table_name} ON ( #{Attachment.table_name}.container_type='Course' AND #{Attachment.table_name}.container_id = #{Course.table_name}.id )"} - - acts_as_activity_provider :type => 'files', - :is_public => 'attachments.is_public', - :permission => :view_files, - :author_key => :author_id, - :find_options => { :select => "#{Attachment.table_name}.*", - :joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " + - "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )"} - - acts_as_activity_provider :type => 'documents', - :is_public => 'documents.is_public', - :permission => :view_documents, - :author_key => :author_id, - :find_options => {:select => "#{Attachment.table_name}.*", - :joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " + - "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"} - - cattr_accessor :storage_path - @@storage_path = Redmine::Configuration['attachments_storage_path'] || File.join(Rails.root, "files") - - cattr_accessor :thumbnails_storage_path - @@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails") - - before_save :files_to_final_location - after_create :be_user_score # user_score - after_update :be_user_score - after_destroy :delete_from_disk,:down_user_score - - # add by nwb - # 获取所有可公开的资源文件列表 - scope :public_attachments, lambda { - #joins(Project.table_name).where("container_type = 'Project' and ") - joins("LEFT JOIN #{Project.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Project.table_name}.id = #{Attachment.table_name}.container_id and #{Project.table_name}.is_public=1 " + - " LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Document.table_name}.project_id in "+self.public_project_id + - " LEFT JOIN #{Issue.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Issue.table_name}.project_id in "+self.public_project_id + - " LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Version.table_name}.project_id in "+self.public_project_id + - " LEFT JOIN #{WikiPage.table_name} ON #{Attachment.table_name}.container_type='WikiPage' AND #{WikiPage.table_name}.parent_id in "+self.public_wiki_id + - " LEFT JOIN #{Message.table_name} ON #{Attachment.table_name}.container_type='Message' AND #{Message.table_name}.parent_id in "+self.public_board_id + - " LEFT JOIN #{Course.table_name} ON #{Attachment.table_name}.container_type='Course' AND #{Course.table_name}.is_public=1 " + - " LEFT JOIN #{News.table_name} ON #{Attachment.table_name}.container_type='News' AND (#{News.table_name}.project_id in "+self.public_project_id + " OR #{News.table_name}.course_id in " + self.public_course_id + ")" + - " LEFT JOIN #{HomeworkAttach.table_name} ON #{Attachment.table_name}.container_type='HomeworkAttach' AND #{HomeworkAttach.table_name}.bid_id in "+self.public_bid_id) - } - - # add by nwb - # 公开的项目id列表 - def self.public_project_id - idlist = "(" - projects=Project.all_public - count = projects.count - for i in 0...count - project = projects[i] - idlist+="'" + project.id.to_s + "'" - if i != count-1 - idlist+="," - end - end - idlist += ")" - idlist - end - - # add by nwb - # 公开的课程id列表 - def self.public_course_id - idlist = "(" - courses=Course.all_public - count = courses.count - for i in 0...count - course = courses[i] - idlist+="'" + course.id.to_s + "'" - if i != count-1 - idlist = idlist + "," - end - end - idlist += ")" - idlist - end - - # add by nwb - # 公开的wiki id列表 - def self.public_wiki_id - idlist = "(" - wikis=Wiki.where("project_id in " + public_project_id) - count = wikis.count - for i in 0...count - wiki = wikis[i] - idlist+="'" + wiki.id.to_s + "'" - if i != count-1 - idlist = idlist + "," - end - end - idlist += ")" - idlist - end - - # add by nwb - # 公开的board id列表 - def self.public_board_id - idlist = "(" - boards=Board.where("project_id in " + public_project_id + " or course_id in " + public_course_id) - count = boards.count - for i in 0...count - board = boards[i] - idlist+="'" + board.id.to_s + "'" - if i != count-1 - idlist = idlist + "," - end - end - idlist += ")" - idlist - end - - # add by nwb - # 公开的bid id列表 - def self.public_bid_id - idlist = "(" - bids=Bid.where("reward_type=3") - count = bids.count - for i in 0...count - bid = bids[i] - idlist+="'" + bid.id.to_s + "'" - if i != count-1 - idlist = idlist + "," - end - end - idlist += ")" - idlist - end - - # Returns an unsaved copy of the attachment - def copy(attributes=nil) - copy = self.class.new - copy.attributes = self.attributes.dup.except("id", "downloads") - copy.attributes = attributes if attributes - copy - end - - #获取资源的后缀类型 - def suffix_type - childArr = self.filename.split('.') - suffix = '*' - if childArr.length > 1 - suffix = childArr[childArr.length-1] - end - suffix - end - - #获取用来显示的后缀名称 - def show_suffix_type - suffix = 'other' - temp = self.suffix_type.downcase - if self.attachmentstype && self.attachmentstype.suffixArr.include?(temp) - suffix = temp - end - suffix - end - - # 文件密级的字符描述 - def file_dense_str - if self.is_public == 1 - dense = l(:field_is_public) - else - dense = l(:field_is_private) - end - dense - end - - # 文件可设置的密级列表 - def file_dense_list - denselist = [l(:field_is_public),l(:field_is_private)] - end - - def suffixArr - @@SuffixArr - end - - def validate_max_file_size - if @temp_file && self.filesize > Setting.attachment_max_size.to_i.kilobytes - errors.add(:base, l(:error_attachment_too_big, :max_size => Setting.attachment_max_size.to_i.kilobytes)) - end - end - - def file=(incoming_file) - unless incoming_file.nil? - @temp_file = incoming_file - # 允许上传文件大小为0的文件 - #if @temp_file.size > 0 - if @temp_file.respond_to?(:original_filename) - self.filename = @temp_file.original_filename - self.filename.force_encoding("UTF-8") if filename.respond_to?(:force_encoding) - end - if @temp_file.respond_to?(:content_type) - self.content_type = @temp_file.content_type.to_s.chomp - end - if content_type.blank? && filename.present? - self.content_type = Redmine::MimeType.of(filename) - end - self.filesize = @temp_file.size - #end - end - end - - def file - nil - end - - def filename=(arg) - write_attribute :filename, sanitize_filename(arg.to_s) - filename - end - - # Copies the temporary file to its final location - # and computes its MD5 hash - def files_to_final_location - # # 允许上传文件大小为0的文件 - if @temp_file# && (@temp_file.size > 0) - self.disk_directory = target_directory - self.disk_filename = Attachment.disk_filename(filename, disk_directory) - logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)") - path = File.dirname(diskfile) - unless File.directory?(path) - FileUtils.mkdir_p(path) - end - md5 = Digest::MD5.new - File.open(diskfile, "wb") do |f| - if @temp_file.respond_to?(:read) - buffer = "" - while (buffer = @temp_file.read(8192)) - f.write(buffer) - md5.update(buffer) - end - else - f.write(@temp_file) - md5.update(@temp_file) - end - end - self.digest = md5.hexdigest - end - @temp_file = nil - # Don't save the content type if it's longer than the authorized length - if self.content_type && self.content_type.length > 255 - self.content_type = nil - end - end - - # Deletes the file from the file system if it's not referenced by other attachments - def delete_from_disk - if Attachment.where("disk_filename = ? AND id <> ?", disk_filename, id).empty? - delete_from_disk! - end - end - - # Returns file's location on disk - def diskfile - File.join(self.class.storage_path, disk_directory.to_s, disk_filename.to_s) - end - - #标题 - def title - title = filename.to_s - if description.present? - title << " (#{description})" - end - title - end - - def increment_download - increment!(:downloads) - end - - def project - container.try(:project) - end - - def course - container - end - - def visible?(user=User.current) - if container_id - container && container.attachments_visible?(user) - else - author == user - end - end - - def deletable?(user=User.current) - if container_id - container && (container.is_a?(Project) ? container.attachments_deletable?(user) : true ) - else - author == user - end - end - - def image? - !!(self.filename =~ /\.(bmp|gif|jpg|jpe|jpeg|png)$/i) - end - - def pack? - !!(self.filename =~ /\.(zip|rar|tar|gz|exe|jar|7z|iso)$/i) - end - - def thumbnailable? - image? - end - - # Returns the full path the attachment thumbnail, or nil - # if the thumbnail cannot be generated. - def thumbnail(options={}) - if thumbnailable? && readable? - size = options[:size].to_i - if size > 0 - # Limit the number of thumbnails per image - size = (size / 50) * 50 - # Maximum thumbnail size - size = 800 if size > 800 - else - size = Setting.thumbnails_size.to_i - end - size = 100 unless size > 0 - target = File.join(self.class.thumbnails_storage_path, "#{id}_#{digest}_#{size}.thumb") - begin - Redmine::Thumbnail.generate(self.diskfile, target, size) - rescue => e - logger.error "An error occured while generating thumbnail for #{disk_filename} to #{target}\nException was: #{e.message}" if logger - return nil - end - end - end - - # Deletes all thumbnails - def self.clear_thumbnails - Dir.glob(File.join(thumbnails_storage_path, "*.thumb")).each do |file| - File.delete file - end - end - - def is_text? - Redmine::MimeType.is_type?('text', filename) - end - - def is_diff? - self.filename =~ /\.(patch|diff)$/i - end - - # Returns true if the file is readable - def readable? - File.readable?(diskfile) - end - - # Returns the attachment token - def token - "#{id}.#{digest}" - end - - # Finds an attachment that matches the given token and that has no container - def self.find_by_token(token) - attachment = find_by_token_only(token) - attachment if attachment.container.nil? - end - - # Finds an attachment that matches the given token - def self.find_by_token_only(token) - if token.to_s =~ /^(\d+)\.([0-9a-f]+)$/ - attachment_id, attachment_digest = $1, $2 - attachment = Attachment.where(:id => attachment_id, :digest => attachment_digest).first - end - end - - # Bulk attaches a set of files to an object - # - # Returns a Hash of the results: - # :files => array of the attached files - # :unsaved => array of the files that could not be attached - def self.attach_files(obj, attachments) - result = obj.save_attachments(attachments, User.current) - obj.attach_saved_attachments - result - end - - - def self.attach_filesex(obj, attachments,attachment_type) - result = obj.save_attachmentsex(attachments, User.current,attachment_type) - obj.attach_saved_attachments - result - end - - def self.latest_attach(attachments, filename) - attachments.sort_by(&:created_on).reverse.detect { - |att| att.filename.downcase == filename.downcase - } - end - - def self.prune(age=1.day) - Attachment.where("created_on < ? AND (container_type IS NULL OR container_type = '')", Time.now - age).destroy_all - end - - # Moves an existing attachment to its target directory - def move_to_target_directory! - if !new_record? & readable? - src = diskfile - self.disk_directory = target_directory - dest = diskfile - if src != dest && FileUtils.mkdir_p(File.dirname(dest)) && FileUtils.mv(src, dest) - update_column :disk_directory, disk_directory - end - end - end - - # Moves existing attachments that are stored at the root of the files - # directory (ie. created before Redmine 2.3) to their target subdirectories - def self.move_from_root_to_target_directory - Attachment.where("disk_directory IS NULL OR disk_directory = ''").find_each do |attachment| - attachment.move_to_target_directory! - end - end - - private - - # Physically deletes the file from the file system - def delete_from_disk! - if disk_filename.present? && File.exist?(diskfile) - File.delete(diskfile) - end - end - - def sanitize_filename(value) - # get only the filename, not the whole path - just_filename = value.gsub(/^.*(\\|\/)/, '') - - # Finally, replace invalid characters with underscore - @filename = just_filename.gsub(/[\/\?\%\*\:\|\"\'<>]+/, '_') - end - - # Returns the subdirectory in which the attachment will be saved - def target_directory - time = created_on || DateTime.now - time.strftime("%Y/%m") - end - - # Returns an ASCII or hashed filename that do not - # exists yet in the given subdirectory - def self.disk_filename(filename, directory=nil) - timestamp = DateTime.now.strftime("%y%m%d%H%M%S") - ascii = '' - if filename =~ %r{^[a-zA-Z0-9_\.\-]*$} - ascii = filename - else - ascii = Digest::MD5.hexdigest(filename) - # keep the extension if any - ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$} - end - while File.exist?(File.join(storage_path, directory.to_s, "#{timestamp}_#{ascii}")) - timestamp.succ! - end - "#{timestamp}_#{ascii}" - end - - - # update user score - def be_user_score - if self.container_id_changed? - type = self.container_type - types = %w|Document News Version Project Issue Message WikiPage| - if types.include?(type) - #UserScore.project(:push_file, self.author,self, { attachment_id: self.id }) - - end - end - update_attachment(self.author,1) - if self.container_type == 'Project' - update_attachment(self.author,2,self.container) - end - - end - - #删除附件时重新统计用户的附件数量得分 - def down_user_score - update_attachment(self.author,1) - if self.container_type == 'Project' - update_attachment(self.author,2,self.container) - 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. + +require "digest/md5" +require "fileutils" + +class Attachment < ActiveRecord::Base + belongs_to :container, :polymorphic => true + belongs_to :project, foreign_key: 'container_id', conditions: "attachments.container_type = 'Project'" + belongs_to :course, foreign_key: 'container_id', conditions: "attachments.container_type = 'Course'" + belongs_to :softapplication, foreign_key: 'container_id', conditions: "attachments.container_type = 'Softapplication'" + belongs_to :author, :class_name => "User", :foreign_key => "author_id" + belongs_to :attachmentstype, :foreign_key => "attachtype",:primary_key => "id" + + include UserScoreHelper + + validates :filename, presence: true, length: {maximum: 254} + validates :author, presence: true + validates :disk_filename, length: {maximum: 254} + validates :description, length: {maximum: 254} + validate :validate_max_file_size + + + acts_as_taggable + acts_as_event :title => :filename, + :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}} + + #课程资源文件 + acts_as_activity_provider :type => 'course_files', + :is_public => 'attachments.is_public', + :permission => :view_files, + :author_key => :author_id, + :find_options => {:select => "#{Attachment.table_name}.*", + :joins => "LEFT JOIN #{Course.table_name} ON ( #{Attachment.table_name}.container_type='Course' AND #{Attachment.table_name}.container_id = #{Course.table_name}.id )"} + + acts_as_activity_provider :type => 'files', + :is_public => 'attachments.is_public', + :permission => :view_files, + :author_key => :author_id, + :find_options => { :select => "#{Attachment.table_name}.*", + :joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " + + "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )"} + + acts_as_activity_provider :type => 'documents', + :is_public => 'documents.is_public', + :permission => :view_documents, + :author_key => :author_id, + :find_options => {:select => "#{Attachment.table_name}.*", + :joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " + + "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"} + + cattr_accessor :storage_path + @@storage_path = Redmine::Configuration['attachments_storage_path'] || File.join(Rails.root, "files") + + cattr_accessor :thumbnails_storage_path + @@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails") + + before_save :files_to_final_location + after_create :be_user_score # user_score + after_update :be_user_score + after_destroy :delete_from_disk,:down_user_score + + # add by nwb + # 获取所有可公开的资源文件列表 + scope :public_attachments, lambda { + #joins(Project.table_name).where("container_type = 'Project' and ") + joins("LEFT JOIN #{Project.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Project.table_name}.id = #{Attachment.table_name}.container_id and #{Project.table_name}.is_public=1 " + + " LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Document.table_name}.project_id in "+self.public_project_id + + " LEFT JOIN #{Issue.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Issue.table_name}.project_id in "+self.public_project_id + + " LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Version.table_name}.project_id in "+self.public_project_id + + " LEFT JOIN #{WikiPage.table_name} ON #{Attachment.table_name}.container_type='WikiPage' AND #{WikiPage.table_name}.parent_id in "+self.public_wiki_id + + " LEFT JOIN #{Message.table_name} ON #{Attachment.table_name}.container_type='Message' AND #{Message.table_name}.parent_id in "+self.public_board_id + + " LEFT JOIN #{Course.table_name} ON #{Attachment.table_name}.container_type='Course' AND #{Course.table_name}.is_public=1 " + + " LEFT JOIN #{News.table_name} ON #{Attachment.table_name}.container_type='News' AND (#{News.table_name}.project_id in "+self.public_project_id + " OR #{News.table_name}.course_id in " + self.public_course_id + ")" + + " LEFT JOIN #{HomeworkAttach.table_name} ON #{Attachment.table_name}.container_type='HomeworkAttach' AND #{HomeworkAttach.table_name}.bid_id in "+self.public_bid_id) + } + + # add by nwb + # 公开的项目id列表 + def self.public_project_id + idlist = "(" + projects=Project.all_public + count = projects.count + for i in 0...count + project = projects[i] + idlist+="'" + project.id.to_s + "'" + if i != count-1 + idlist+="," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的课程id列表 + def self.public_course_id + idlist = "(" + courses=Course.all_public + count = courses.count + for i in 0...count + course = courses[i] + idlist+="'" + course.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的wiki id列表 + def self.public_wiki_id + idlist = "(" + wikis=Wiki.where("project_id in " + public_project_id) + count = wikis.count + for i in 0...count + wiki = wikis[i] + idlist+="'" + wiki.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的board id列表 + def self.public_board_id + idlist = "(" + boards=Board.where("project_id in " + public_project_id + " or course_id in " + public_course_id) + count = boards.count + for i in 0...count + board = boards[i] + idlist+="'" + board.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的bid id列表 + def self.public_bid_id + idlist = "(" + bids=Bid.where("reward_type=3") + count = bids.count + for i in 0...count + bid = bids[i] + idlist+="'" + bid.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + + # Returns an unsaved copy of the attachment + def copy(attributes=nil) + copy = self.class.new + copy.attributes = self.attributes.dup.except("id", "downloads") + copy.attributes = attributes if attributes + copy + end + + #获取资源的后缀类型 + def suffix_type + childArr = self.filename.split('.') + suffix = '*' + if childArr.length > 1 + suffix = childArr[childArr.length-1] + end + suffix + end + + #获取用来显示的后缀名称 + def show_suffix_type + suffix = 'other' + temp = self.suffix_type.downcase + if self.attachmentstype && self.attachmentstype.suffixArr.include?(temp) + suffix = temp + end + suffix + end + + # 文件密级的字符描述 + def file_dense_str + if self.is_public == 1 + dense = l(:field_is_public) + else + dense = l(:field_is_private) + end + dense + end + + # 文件可设置的密级列表 + def file_dense_list + denselist = [l(:field_is_public),l(:field_is_private)] + end + + def suffixArr + @@SuffixArr + end + + def validate_max_file_size + if @temp_file && self.filesize > Setting.attachment_max_size.to_i.kilobytes + errors.add(:base, l(:error_attachment_too_big, :max_size => Setting.attachment_max_size.to_i.kilobytes)) + end + end + + def file=(incoming_file) + unless incoming_file.nil? + @temp_file = incoming_file + # 允许上传文件大小为0的文件 + #if @temp_file.size > 0 + if @temp_file.respond_to?(:original_filename) + self.filename = @temp_file.original_filename + self.filename.force_encoding("UTF-8") if filename.respond_to?(:force_encoding) + end + if @temp_file.respond_to?(:content_type) + self.content_type = @temp_file.content_type.to_s.chomp + end + if content_type.blank? && filename.present? + self.content_type = Redmine::MimeType.of(filename) + end + self.filesize = @temp_file.size + #end + end + end + + def file + nil + end + + def filename=(arg) + write_attribute :filename, sanitize_filename(arg.to_s) + filename + end + + # Copies the temporary file to its final location + # and computes its MD5 hash + def files_to_final_location + # # 允许上传文件大小为0的文件 + if @temp_file# && (@temp_file.size > 0) + self.disk_directory = target_directory + self.disk_filename = Attachment.disk_filename(filename, disk_directory) + logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)") + path = File.dirname(diskfile) + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + md5 = Digest::MD5.new + File.open(diskfile, "wb") do |f| + if @temp_file.respond_to?(:read) + buffer = "" + while (buffer = @temp_file.read(8192)) + f.write(buffer) + md5.update(buffer) + end + else + f.write(@temp_file) + md5.update(@temp_file) + end + end + self.digest = md5.hexdigest + end + @temp_file = nil + # Don't save the content type if it's longer than the authorized length + if self.content_type && self.content_type.length > 255 + self.content_type = nil + end + end + + # Deletes the file from the file system if it's not referenced by other attachments + def delete_from_disk + if Attachment.where("disk_filename = ? AND id <> ?", disk_filename, id).empty? + delete_from_disk! + end + end + + # Returns file's location on disk + def diskfile + File.join(self.class.storage_path, disk_directory.to_s, disk_filename.to_s) + end + + #标题 + def title + title = filename.to_s + if description.present? + title << " (#{description})" + end + title + end + + def increment_download + increment!(:downloads) + end + + def project + container.try(:project) + end + + def course + container + end + + def visible?(user=User.current) + if container_id + container && container.attachments_visible?(user) + else + author == user + end + end + + def deletable?(user=User.current) + if container_id + container && (container.is_a?(Project) ? container.attachments_deletable?(user) : true ) + else + author == user + end + end + + def image? + !!(self.filename =~ /\.(bmp|gif|jpg|jpe|jpeg|png)$/i) + end + + def pack? + !!(self.filename =~ /\.(zip|rar|tar|gz|exe|jar|7z|iso)$/i) + end + + def thumbnailable? + image? + end + + # Returns the full path the attachment thumbnail, or nil + # if the thumbnail cannot be generated. + def thumbnail(options={}) + if thumbnailable? && readable? + size = options[:size].to_i + if size > 0 + # Limit the number of thumbnails per image + size = (size / 50) * 50 + # Maximum thumbnail size + size = 800 if size > 800 + else + size = Setting.thumbnails_size.to_i + end + size = 100 unless size > 0 + target = File.join(self.class.thumbnails_storage_path, "#{id}_#{digest}_#{size}.thumb") + begin + Redmine::Thumbnail.generate(self.diskfile, target, size) + rescue => e + logger.error "An error occured while generating thumbnail for #{disk_filename} to #{target}\nException was: #{e.message}" if logger + return nil + end + end + end + + # Deletes all thumbnails + def self.clear_thumbnails + Dir.glob(File.join(thumbnails_storage_path, "*.thumb")).each do |file| + File.delete file + end + end + + def is_text? + Redmine::MimeType.is_type?('text', filename) + end + + def is_diff? + self.filename =~ /\.(patch|diff)$/i + end + + # Returns true if the file is readable + def readable? + File.readable?(diskfile) + end + + # Returns the attachment token + def token + "#{id}.#{digest}" + end + + # Finds an attachment that matches the given token and that has no container + def self.find_by_token(token) + attachment = find_by_token_only(token) + attachment if attachment.container.nil? + end + + # Finds an attachment that matches the given token + def self.find_by_token_only(token) + if token.to_s =~ /^(\d+)\.([0-9a-f]+)$/ + attachment_id, attachment_digest = $1, $2 + attachment = Attachment.where(:id => attachment_id, :digest => attachment_digest).first + end + end + + # Bulk attaches a set of files to an object + # + # Returns a Hash of the results: + # :files => array of the attached files + # :unsaved => array of the files that could not be attached + def self.attach_files(obj, attachments) + result = obj.save_attachments(attachments, User.current) + obj.attach_saved_attachments + result + end + + + def self.attach_filesex(obj, attachments,attachment_type) + result = obj.save_attachmentsex(attachments, User.current,attachment_type) + obj.attach_saved_attachments + result + end + + def self.latest_attach(attachments, filename) + attachments.sort_by(&:created_on).reverse.detect { + |att| att.filename.downcase == filename.downcase + } + end + + def self.prune(age=1.day) + Attachment.where("created_on < ? AND (container_type IS NULL OR container_type = '')", Time.now - age).destroy_all + end + + # Moves an existing attachment to its target directory + def move_to_target_directory! + if !new_record? & readable? + src = diskfile + self.disk_directory = target_directory + dest = diskfile + if src != dest && FileUtils.mkdir_p(File.dirname(dest)) && FileUtils.mv(src, dest) + update_column :disk_directory, disk_directory + end + end + end + + # Moves existing attachments that are stored at the root of the files + # directory (ie. created before Redmine 2.3) to their target subdirectories + def self.move_from_root_to_target_directory + Attachment.where("disk_directory IS NULL OR disk_directory = ''").find_each do |attachment| + attachment.move_to_target_directory! + end + end + + private + + # Physically deletes the file from the file system + def delete_from_disk! + if disk_filename.present? && File.exist?(diskfile) + File.delete(diskfile) + end + end + + def sanitize_filename(value) + # get only the filename, not the whole path + just_filename = value.gsub(/^.*(\\|\/)/, '') + + # Finally, replace invalid characters with underscore + @filename = just_filename.gsub(/[\/\?\%\*\:\|\"\'<>]+/, '_') + end + + # Returns the subdirectory in which the attachment will be saved + def target_directory + time = created_on || DateTime.now + time.strftime("%Y/%m") + end + + # Returns an ASCII or hashed filename that do not + # exists yet in the given subdirectory + def self.disk_filename(filename, directory=nil) + timestamp = DateTime.now.strftime("%y%m%d%H%M%S") + ascii = '' + if filename =~ %r{^[a-zA-Z0-9_\.\-]*$} + ascii = filename + else + ascii = Digest::MD5.hexdigest(filename) + # keep the extension if any + ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$} + end + while File.exist?(File.join(storage_path, directory.to_s, "#{timestamp}_#{ascii}")) + timestamp.succ! + end + "#{timestamp}_#{ascii}" + end + + + # update user score + def be_user_score + if self.container_id_changed? + type = self.container_type + types = %w|Document News Version Project Issue Message WikiPage| + if types.include?(type) + #UserScore.project(:push_file, self.author,self, { attachment_id: self.id }) + + end + end + update_attachment(self.author,1) + if self.container_type == 'Project' + update_attachment(self.author,2,self.container) + end + + end + + #删除附件时重新统计用户的附件数量得分 + def down_user_score + update_attachment(self.author,1) + if self.container_type == 'Project' + update_attachment(self.author,2,self.container) + end + end + +end diff --git a/app/models/auth_source.rb b/app/models/auth_source.rb index fdaf622b3..796099a05 100644 --- a/app/models/auth_source.rb +++ b/app/models/auth_source.rb @@ -1,90 +1,90 @@ -# 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. - -# Generic exception for when the AuthSource can not be reached -# (eg. can not connect to the LDAP) -class AuthSourceException < Exception; end -class AuthSourceTimeoutException < AuthSourceException; end - -class AuthSource < ActiveRecord::Base - include Redmine::SubclassFactory - include Redmine::Ciphering - - has_many :users - - validates :name, presence: true, uniqueness: true, length: {maximum: 60} - - def authenticate(login, password) - end - - def test_connection - end - - def auth_method_name - "Abstract" - end - - def account_password - read_ciphered_attribute(:account_password) - end - - def account_password=(arg) - write_ciphered_attribute(:account_password, arg) - end - - def searchable? - false - end - - def self.search(q) - results = [] - AuthSource.all.each do |source| - begin - if source.searchable? - results += source.search(q) - end - rescue AuthSourceException => e - logger.error "Error while searching users in #{source.name}: #{e.message}" - end - end - results - end - - def allow_password_changes? - self.class.allow_password_changes? - end - - # Does this auth source backend allow password changes? - def self.allow_password_changes? - false - end - - # Try to authenticate a user not yet registered against available sources - def self.authenticate(login, password) - AuthSource.where(:onthefly_register => true).all.each do |source| - begin - logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug? - attrs = source.authenticate(login, password) - rescue => e - logger.error "Error during authentication: #{e.message}" - attrs = nil - end - return attrs if attrs - end - return 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. + +# Generic exception for when the AuthSource can not be reached +# (eg. can not connect to the LDAP) +class AuthSourceException < Exception; end +class AuthSourceTimeoutException < AuthSourceException; end + +class AuthSource < ActiveRecord::Base + include Redmine::SubclassFactory + include Redmine::Ciphering + + has_many :users + + validates :name, presence: true, uniqueness: true, length: {maximum: 60} + + def authenticate(login, password) + end + + def test_connection + end + + def auth_method_name + "Abstract" + end + + def account_password + read_ciphered_attribute(:account_password) + end + + def account_password=(arg) + write_ciphered_attribute(:account_password, arg) + end + + def searchable? + false + end + + def self.search(q) + results = [] + AuthSource.all.each do |source| + begin + if source.searchable? + results += source.search(q) + end + rescue AuthSourceException => e + logger.error "Error while searching users in #{source.name}: #{e.message}" + end + end + results + end + + def allow_password_changes? + self.class.allow_password_changes? + end + + # Does this auth source backend allow password changes? + def self.allow_password_changes? + false + end + + # Try to authenticate a user not yet registered against available sources + def self.authenticate(login, password) + AuthSource.where(:onthefly_register => true).all.each do |source| + begin + logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug? + attrs = source.authenticate(login, password) + rescue => e + logger.error "Error during authentication: #{e.message}" + attrs = nil + end + return attrs if attrs + end + return nil + end +end diff --git a/app/models/auth_source_ldap.rb b/app/models/auth_source_ldap.rb index 8eae422e5..08c94abfd 100644 --- a/app/models/auth_source_ldap.rb +++ b/app/models/auth_source_ldap.rb @@ -1,206 +1,206 @@ -# 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 'net/ldap' -require 'net/ldap/dn' -require 'timeout' - -class AuthSourceLdap < AuthSource - validates :host, presence: true, length: {maximum: 60, allow_nil: true} - validates :port, presence: true, numericality: {only_integer: true} - validates :attr_login, presence: true - validates :name, length: {maximum: 60, allow_nil: true} - validates :account, length: {maximum: 255, allow_blank: true} - validates :account_password, length: {maximum: 255, allow_blank: true} - validates :base_dn, length: {maximum: 255, allow_blank: true} - validates :filter, length: {maximum: 255, allow_blank: true} - validates :attr_login, length: {maximum: 30, allow_nil: true} - validates :attr_firstname, length: {maximum: 30, allow_nil: true} - validates :attr_lastname, length: {maximum: 30, allow_nil: true} - validates :attr_mail, length: {maximum: 30, allow_nil: true} - validates :timeout, numericality: { only_integer: true, allow_blank: true} - validate :validate_filter - before_validation :strip_ldap_attributes - - def initialize(attributes=nil, *args) - super - self.port = 389 if self.port == 0 - end - - def authenticate(login, password) - return nil if login.blank? || password.blank? - - with_timeout do - attrs = get_user_dn(login, password) - if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password) - logger.debug "Authentication successful for '#{login}'" if logger && logger.debug? - return attrs.except(:dn) - end - end - rescue Net::LDAP::LdapError => e - raise AuthSourceException.new(e.message) - end - - # test the connection to the LDAP - def test_connection - with_timeout do - ldap_con = initialize_ldap_con(self.account, self.account_password) - ldap_con.open { } - end - rescue Net::LDAP::LdapError => e - raise AuthSourceException.new(e.message) - end - - def auth_method_name - "LDAP" - end - - # Returns true if this source can be searched for users - def searchable? - !account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")} - end - - # Searches the source for users and returns an array of results - def search(q) - q = q.to_s.strip - return [] unless searchable? && q.present? - - results = [] - search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q) - ldap_con = initialize_ldap_con(self.account, self.account_password) - ldap_con.search(:base => self.base_dn, - :filter => search_filter, - :attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail], - :size => 10) do |entry| - attrs = get_user_attributes_from_ldap_entry(entry) - attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login) - results << attrs - end - results - rescue Net::LDAP::LdapError => e - raise AuthSourceException.new(e.message) - end - - private - - def with_timeout(&block) - timeout = self.timeout - timeout = 20 unless timeout && timeout > 0 - Timeout.timeout(timeout) do - return yield - end - rescue Timeout::Error => e - raise AuthSourceTimeoutException.new(e.message) - end - - def ldap_filter - if filter.present? - Net::LDAP::Filter.construct(filter) - end - rescue Net::LDAP::LdapError - nil - end - - def base_filter - filter = Net::LDAP::Filter.eq("objectClass", "*") - if f = ldap_filter - filter = filter & f - end - filter - end - - def validate_filter - if filter.present? && ldap_filter.nil? - errors.add(:filter, :invalid) - end - end - - def strip_ldap_attributes - [:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr| - write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil? - end - end - - def initialize_ldap_con(ldap_user, ldap_password) - options = { :host => self.host, - :port => self.port, - :encryption => (self.tls ? :simple_tls : nil) - } - options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank? - Net::LDAP.new options - end - - def get_user_attributes_from_ldap_entry(entry) - { - :dn => entry.dn, - :firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname), - :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname), - :mail => AuthSourceLdap.get_attr(entry, self.attr_mail), - :auth_source_id => self.id - } - end - - # Return the attributes needed for the LDAP search. It will only - # include the user attributes if on-the-fly registration is enabled - def search_attributes - if onthefly_register? - ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail] - else - ['dn'] - end - end - - # Check if a DN (user record) authenticates with the password - def authenticate_dn(dn, password) - if dn.present? && password.present? - initialize_ldap_con(dn, password).bind - end - end - - # Get the user's dn and any attributes for them, given their login - def get_user_dn(login, password) - ldap_con = nil - if self.account && self.account.include?("$login") - ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password) - else - ldap_con = initialize_ldap_con(self.account, self.account_password) - end - attrs = {} - search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login) - - ldap_con.search( :base => self.base_dn, - :filter => search_filter, - :attributes=> search_attributes) do |entry| - - if onthefly_register? - attrs = get_user_attributes_from_ldap_entry(entry) - else - attrs = {:dn => entry.dn} - end - - logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug? - end - - attrs - end - - def self.get_attr(entry, attr_name) - if !attr_name.blank? - entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name] - 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. + +require 'net/ldap' +require 'net/ldap/dn' +require 'timeout' + +class AuthSourceLdap < AuthSource + validates :host, presence: true, length: {maximum: 60, allow_nil: true} + validates :port, presence: true, numericality: {only_integer: true} + validates :attr_login, presence: true + validates :name, length: {maximum: 60, allow_nil: true} + validates :account, length: {maximum: 255, allow_blank: true} + validates :account_password, length: {maximum: 255, allow_blank: true} + validates :base_dn, length: {maximum: 255, allow_blank: true} + validates :filter, length: {maximum: 255, allow_blank: true} + validates :attr_login, length: {maximum: 30, allow_nil: true} + validates :attr_firstname, length: {maximum: 30, allow_nil: true} + validates :attr_lastname, length: {maximum: 30, allow_nil: true} + validates :attr_mail, length: {maximum: 30, allow_nil: true} + validates :timeout, numericality: { only_integer: true, allow_blank: true} + validate :validate_filter + before_validation :strip_ldap_attributes + + def initialize(attributes=nil, *args) + super + self.port = 389 if self.port == 0 + end + + def authenticate(login, password) + return nil if login.blank? || password.blank? + + with_timeout do + attrs = get_user_dn(login, password) + if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password) + logger.debug "Authentication successful for '#{login}'" if logger && logger.debug? + return attrs.except(:dn) + end + end + rescue Net::LDAP::LdapError => e + raise AuthSourceException.new(e.message) + end + + # test the connection to the LDAP + def test_connection + with_timeout do + ldap_con = initialize_ldap_con(self.account, self.account_password) + ldap_con.open { } + end + rescue Net::LDAP::LdapError => e + raise AuthSourceException.new(e.message) + end + + def auth_method_name + "LDAP" + end + + # Returns true if this source can be searched for users + def searchable? + !account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")} + end + + # Searches the source for users and returns an array of results + def search(q) + q = q.to_s.strip + return [] unless searchable? && q.present? + + results = [] + search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q) + ldap_con = initialize_ldap_con(self.account, self.account_password) + ldap_con.search(:base => self.base_dn, + :filter => search_filter, + :attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail], + :size => 10) do |entry| + attrs = get_user_attributes_from_ldap_entry(entry) + attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login) + results << attrs + end + results + rescue Net::LDAP::LdapError => e + raise AuthSourceException.new(e.message) + end + + private + + def with_timeout(&block) + timeout = self.timeout + timeout = 20 unless timeout && timeout > 0 + Timeout.timeout(timeout) do + return yield + end + rescue Timeout::Error => e + raise AuthSourceTimeoutException.new(e.message) + end + + def ldap_filter + if filter.present? + Net::LDAP::Filter.construct(filter) + end + rescue Net::LDAP::LdapError + nil + end + + def base_filter + filter = Net::LDAP::Filter.eq("objectClass", "*") + if f = ldap_filter + filter = filter & f + end + filter + end + + def validate_filter + if filter.present? && ldap_filter.nil? + errors.add(:filter, :invalid) + end + end + + def strip_ldap_attributes + [:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr| + write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil? + end + end + + def initialize_ldap_con(ldap_user, ldap_password) + options = { :host => self.host, + :port => self.port, + :encryption => (self.tls ? :simple_tls : nil) + } + options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank? + Net::LDAP.new options + end + + def get_user_attributes_from_ldap_entry(entry) + { + :dn => entry.dn, + :firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname), + :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname), + :mail => AuthSourceLdap.get_attr(entry, self.attr_mail), + :auth_source_id => self.id + } + end + + # Return the attributes needed for the LDAP search. It will only + # include the user attributes if on-the-fly registration is enabled + def search_attributes + if onthefly_register? + ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail] + else + ['dn'] + end + end + + # Check if a DN (user record) authenticates with the password + def authenticate_dn(dn, password) + if dn.present? && password.present? + initialize_ldap_con(dn, password).bind + end + end + + # Get the user's dn and any attributes for them, given their login + def get_user_dn(login, password) + ldap_con = nil + if self.account && self.account.include?("$login") + ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password) + else + ldap_con = initialize_ldap_con(self.account, self.account_password) + end + attrs = {} + search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login) + + ldap_con.search( :base => self.base_dn, + :filter => search_filter, + :attributes=> search_attributes) do |entry| + + if onthefly_register? + attrs = get_user_attributes_from_ldap_entry(entry) + else + attrs = {:dn => entry.dn} + end + + logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug? + end + + attrs + end + + def self.get_attr(entry, attr_name) + if !attr_name.blank? + entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name] + end + end +end diff --git a/app/models/biding_project.rb b/app/models/biding_project.rb index 9ebd1b73c..decf85812 100644 --- a/app/models/biding_project.rb +++ b/app/models/biding_project.rb @@ -1,59 +1,59 @@ -## fq -class BidingProject < ActiveRecord::Base - attr_accessible :bid_id, :project_id, :user_id, :description,:reward - - belongs_to :bid - belongs_to :project - belongs_to :user - - DESCRIPTION_LENGTH_LIMIT = 500 - validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT} - validates :user_id, presence: true - validates :bid_id, presence: true, :uniqueness => { :scope => :project_id} - validates :project_id, presence: true - validate :validate_user - validate :validate_bid - validate :validate_project - - def self.cerate_bidding(bid_id, project_id, description = nil) - self.create(:user_id => User.current.id, :bid_id => bid_id, - :project_id => project_id, :description => description) - end - - # used to update the reward ,the value varies from 0,1,2,3,4,5 - # added by william - def update_reward(which) - self.update_attribute(:reward,which) - end - - # return the reward,the value is a type of string - # added by william - def get_reward - self.reward - end - - def cancel_bidding - unless self.nil? - if User.current.id == self.user_id - self.destroy - end - end - end - - private - - def validate_user - errors.add :user_id, :invalid if user.nil? || !user.active? - end - - def validate_bid - errors.add :bid_id, :invalid if bid.nil? - end - - def validate_project - errors.add :project_id, :invalid if project.nil? - end - -end - - +## fq +class BidingProject < ActiveRecord::Base + attr_accessible :bid_id, :project_id, :user_id, :description,:reward + + belongs_to :bid + belongs_to :project + belongs_to :user + + DESCRIPTION_LENGTH_LIMIT = 500 + validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT} + validates :user_id, presence: true + validates :bid_id, presence: true, :uniqueness => { :scope => :project_id} + validates :project_id, presence: true + validate :validate_user + validate :validate_bid + validate :validate_project + + def self.cerate_bidding(bid_id, project_id, description = nil) + self.create(:user_id => User.current.id, :bid_id => bid_id, + :project_id => project_id, :description => description) + end + + # used to update the reward ,the value varies from 0,1,2,3,4,5 + # added by william + def update_reward(which) + self.update_attribute(:reward,which) + end + + # return the reward,the value is a type of string + # added by william + def get_reward + self.reward + end + + def cancel_bidding + unless self.nil? + if User.current.id == self.user_id + self.destroy + end + end + end + + private + + def validate_user + errors.add :user_id, :invalid if user.nil? || !user.active? + end + + def validate_bid + errors.add :bid_id, :invalid if bid.nil? + end + + def validate_project + errors.add :project_id, :invalid if project.nil? + end + +end + + diff --git a/app/models/board.rb b/app/models/board.rb index 0d8c21ab2..edcbe0c9d 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -1,90 +1,90 @@ -# 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 Board < ActiveRecord::Base - include Redmine::SafeAttributes - belongs_to :project - belongs_to :course - has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC" - has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC" - belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id - acts_as_tree :dependent => :nullify - acts_as_list :scope => '(project_id = #{project_id} AND parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"})' - acts_as_watchable - - validates :name, presence: true, length: {maximum: 30} - validates :description, presence: true, length: {maximum: 255} - validate :validate_board - - scope :visible, lambda {|*args| - includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args)) - } - - safe_attributes 'name', 'description', 'parent_id', 'move_to' - - def visible?(user=User.current) - !user.nil? && user.allowed_to?(:view_messages, project) - end - - def reload(*args) - @valid_parents = nil - super - end - - def to_s - name - end - - def valid_parents - @valid_parents ||= project.boards - self_and_descendants - end - - def reset_counters! - self.class.reset_counters!(id) - end - - # Updates topics_count, messages_count and last_message_id attributes for +board_id+ - def self.reset_counters!(board_id) - board_id = board_id.to_i - update_all("topics_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id} AND parent_id IS NULL)," + - " messages_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id})," + - " last_message_id = (SELECT MAX(id) FROM #{Message.table_name} WHERE board_id=#{board_id})", - ["id = ?", board_id]) - end - - def self.board_tree(boards, parent_id=nil, level=0) - tree = [] - boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board| - tree << [board, level] - tree += board_tree(boards, board.id, level+1) - end - if block_given? - tree.each do |board, level| - yield board, level - end - end - tree - end - - protected - - def validate_board - if parent_id && parent_id_changed? - errors.add(:parent_id, :invalid) unless valid_parents.include?(parent) - 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 Board < ActiveRecord::Base + include Redmine::SafeAttributes + belongs_to :project + belongs_to :course + has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC" + has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC" + belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id + acts_as_tree :dependent => :nullify + acts_as_list :scope => '(project_id = #{project_id} AND parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"})' + acts_as_watchable + + validates :name, presence: true, length: {maximum: 30} + validates :description, presence: true, length: {maximum: 255} + validate :validate_board + + scope :visible, lambda {|*args| + includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args)) + } + + safe_attributes 'name', 'description', 'parent_id', 'move_to' + + def visible?(user=User.current) + !user.nil? && user.allowed_to?(:view_messages, project) + end + + def reload(*args) + @valid_parents = nil + super + end + + def to_s + name + end + + def valid_parents + @valid_parents ||= project.boards - self_and_descendants + end + + def reset_counters! + self.class.reset_counters!(id) + end + + # Updates topics_count, messages_count and last_message_id attributes for +board_id+ + def self.reset_counters!(board_id) + board_id = board_id.to_i + update_all("topics_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id} AND parent_id IS NULL)," + + " messages_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id})," + + " last_message_id = (SELECT MAX(id) FROM #{Message.table_name} WHERE board_id=#{board_id})", + ["id = ?", board_id]) + end + + def self.board_tree(boards, parent_id=nil, level=0) + tree = [] + boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board| + tree << [board, level] + tree += board_tree(boards, board.id, level+1) + end + if block_given? + tree.each do |board, level| + yield board, level + end + end + tree + end + + protected + + def validate_board + if parent_id && parent_id_changed? + errors.add(:parent_id, :invalid) unless valid_parents.include?(parent) + end + end +end diff --git a/app/models/bug_to_osp.rb b/app/models/bug_to_osp.rb index 3d93957cf..98a80965b 100644 --- a/app/models/bug_to_osp.rb +++ b/app/models/bug_to_osp.rb @@ -1,11 +1,11 @@ -class BugToOsp < ActiveRecord::Base - # attr_accessible :title, :body - belongs_to :open_source_project, :foreign_key => "osp_id" - belongs_to :bug, :class_name => 'RelativeMemo', :foreign_key => "relative_memo_id" - validates :osp_id, presence: true - validates :relative_memo_id, presence: true - - scope :visible, lambda {|*args| - nil - } -end +class BugToOsp < ActiveRecord::Base + # attr_accessible :title, :body + belongs_to :open_source_project, :foreign_key => "osp_id" + belongs_to :bug, :class_name => 'RelativeMemo', :foreign_key => "relative_memo_id" + validates :osp_id, presence: true + validates :relative_memo_id, presence: true + + scope :visible, lambda {|*args| + nil + } +end diff --git a/app/models/change.rb b/app/models/change.rb index 304a2fb59..8beede196 100644 --- a/app/models/change.rb +++ b/app/models/change.rb @@ -1,39 +1,39 @@ -# 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 Change < ActiveRecord::Base - belongs_to :changeset - - validates :changeset_id, presence: true - validates :action, presence: true - validates :path, presence: true - before_save :init_path - before_validation :replace_invalid_utf8_of_path - - def relative_path - changeset.repository.relative_path(path) - end - - def replace_invalid_utf8_of_path - self.path = Redmine::CodesetUtil.replace_invalid_utf8(self.path) - self.from_path = Redmine::CodesetUtil.replace_invalid_utf8(self.from_path) - end - - def init_path - self.path ||= "" - 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 Change < ActiveRecord::Base + belongs_to :changeset + + validates :changeset_id, presence: true + validates :action, presence: true + validates :path, presence: true + before_save :init_path + before_validation :replace_invalid_utf8_of_path + + def relative_path + changeset.repository.relative_path(path) + end + + def replace_invalid_utf8_of_path + self.path = Redmine::CodesetUtil.replace_invalid_utf8(self.path) + self.from_path = Redmine::CodesetUtil.replace_invalid_utf8(self.from_path) + end + + def init_path + self.path ||= "" + end +end diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 5a617b790..e05a7d2da 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -1,332 +1,332 @@ -# 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 Changeset < ActiveRecord::Base - belongs_to :repository - belongs_to :user - include UserScoreHelper - #after_save :be_user_score # user_score - - has_many :filechanges, :class_name => 'Change', :dependent => :delete_all - # fq - has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy - # end - - #Added by nie - has_one :project_status, :dependent => :destroy - has_one :users_status - #end - - has_and_belongs_to_many :issues - has_and_belongs_to_many :parents, - :class_name => "Changeset", - :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}", - :association_foreign_key => 'parent_id', :foreign_key => 'changeset_id' - has_and_belongs_to_many :children, - :class_name => "Changeset", - :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}", - :association_foreign_key => 'changeset_id', :foreign_key => 'parent_id' - - acts_as_event :title => Proc.new {|o| o.title}, - :description => :long_comments, - :datetime => :committed_on, - :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}} - - acts_as_searchable :columns => 'comments', - :include => {:repository => :project}, - :project_key => "#{Repository.table_name}.project_id", - :date_column => 'committed_on' - - acts_as_activity_provider :timestamp => "#{table_name}.committed_on", - :author_key => :user_id, - :find_options => {:include => [:user, {:repository => :project}]} - validates :repository_id, presence: true - validates :revision, presence: true, uniqueness: {scope: :repository_id} - validates :committed_on, presence: true - validates :commit_date, presence: true - validates :scmid, uniqueness: {scope: :repository_id, allow_nil: true} - - scope :visible, lambda {|*args| - includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args)) - } - - after_create :scan_for_issues,:refresh_changests#:be_user_score # user_score - after_update :be_user_score - after_destroy :down_user_score - before_create :before_create_cs - - # fq - # after_create :act_as_activity - # end - - def revision=(r) - write_attribute :revision, (r.nil? ? nil : r.to_s) - end - - # Returns the identifier of this changeset; depending on repository backends - def identifier - if repository.class.respond_to? :changeset_identifier - repository.class.changeset_identifier self - else - revision.to_s - end - end - - def committed_on=(date) - self.commit_date = date - super - end - - # Returns the readable identifier - def format_identifier - if repository.class.respond_to? :format_changeset_identifier - repository.class.format_changeset_identifier self - else - identifier - end - end - - def project - unless repository.nil? - repository.project - end - end - - def author - user || committer.to_s.split('<').first - end - - def before_create_cs - self.committer = self.class.to_utf8(self.committer, repository.repo_log_encoding) - self.comments = self.class.normalize_comments( - self.comments, repository.repo_log_encoding) - self.user = repository.find_committer_user(self.committer) - end - - def scan_for_issues - scan_comment_for_issue_ids - end - - TIMELOG_RE = / - ( - ((\d+)(h|hours?))((\d+)(m|min)?)? - | - ((\d+)(h|hours?|m|min)) - | - (\d+):(\d+) - | - (\d+([\.,]\d+)?)h? - ) - /x - - def scan_comment_for_issue_ids - return if comments.blank? - # keywords used to reference issues - ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip) - ref_keywords_any = ref_keywords.delete('*') - # keywords used to fix issues - fix_keywords = Setting.commit_fix_keywords.downcase.split(",").collect(&:strip) - - kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|") - - referenced_issues = [] - - comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match| - action, refs = match[2], match[3] - next unless action.present? || ref_keywords_any - - refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m| - issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2] - if issue - referenced_issues << issue - fix_issue(issue) if fix_keywords.include?(action.to_s.downcase) - log_time(issue, hours) if hours && Setting.commit_logtime_enabled? - end - end - end - - referenced_issues.uniq! - self.issues = referenced_issues unless referenced_issues.empty? - end - - def short_comments - @short_comments || split_comments.first - end - - def long_comments - @long_comments || split_comments.last - end - - def text_tag(ref_project=nil) - tag = if scmid? - "commit:#{scmid}" - else - "r#{revision}" - end - if repository && repository.identifier.present? - tag = "#{repository.identifier}|#{tag}" - end - if ref_project && project && ref_project != project - tag = "#{project.identifier}:#{tag}" - end - tag - end - - # Returns the title used for the changeset in the activity/search results - def title - repo = (repository && repository.identifier.present?) ? " (#{repository.identifier})" : '' - comm = short_comments.blank? ? '' : (': ' + short_comments) - "#{l(:label_revision)} #{format_identifier}#{repo}#{comm}" - end - - # Returns the previous changeset - def previous - @previous ||= Changeset.where(["id < ? AND repository_id = ?", id, repository_id]).order('id DESC').first - end - - # Returns the next changeset - def next - @next ||= Changeset.where(["id > ? AND repository_id = ?", id, repository_id]).order('id ASC').first - end - - # Creates a new Change from it's common parameters - def create_change(change) - Change.create(:changeset => self, - :action => change[:action], - :path => change[:path], - :from_path => change[:from_path], - :from_revision => change[:from_revision]) - end - - # Finds an issue that can be referenced by the commit message - def find_referenced_issue_by_id(id) - return nil if id.blank? - issue = Issue.find_by_id(id.to_i, :include => :project) - if Setting.commit_cross_project_ref? - # all issues can be referenced/fixed - elsif issue - # issue that belong to the repository project, a subproject or a parent project only - unless issue.project && - (project == issue.project || project.is_ancestor_of?(issue.project) || - project.is_descendant_of?(issue.project)) - issue = nil - end - end - issue - end - - private - - def act_as_activity - self.acts << Activity.new(:user_id => self.user_id) - end - - def fix_issue(issue) - status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i) - if status.nil? - logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger - return issue - end - - # the issue may have been updated by the closure of another one (eg. duplicate) - issue.reload - # don't change the status is the issue is closed - return if issue.status && issue.status.is_closed? - - journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project))) - issue.status = status - unless Setting.commit_fix_done_ratio.blank? - issue.done_ratio = Setting.commit_fix_done_ratio.to_i - end - Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update, - { :changeset => self, :issue => issue }) - unless issue.save - logger.warn("Issue ##{issue.id} could not be saved by changeset #{id}: #{issue.errors.full_messages}") if logger - end - issue - end - - def log_time(issue, hours) - time_entry = TimeEntry.new( - :user => user, - :hours => hours, - :issue => issue, - :spent_on => commit_date, - :comments => l(:text_time_logged_by_changeset, :value => text_tag(issue.project), - :locale => Setting.default_language) - ) - time_entry.activity = log_time_activity unless log_time_activity.nil? - - unless time_entry.save - logger.warn("TimeEntry could not be created by changeset #{id}: #{time_entry.errors.full_messages}") if logger - end - time_entry - end - - def log_time_activity - if Setting.commit_logtime_activity_id.to_i > 0 - TimeEntryActivity.find_by_id(Setting.commit_logtime_activity_id.to_i) - end - end - - def split_comments - comments =~ /\A(.+?)\r?\n(.*)$/m - @short_comments = $1 || comments - @long_comments = $2.to_s.strip - return @short_comments, @long_comments - end - - public - - # Strips and reencodes a commit log before insertion into the database - def self.normalize_comments(str, encoding) - Changeset.to_utf8(str.to_s.strip, encoding) - end - - def self.to_utf8(str, encoding) - Redmine::CodesetUtil.to_utf8(str, encoding) - end - - private - - # update user score - def be_user_score - UserScore.project(:push_code, self.user,self, { changeset_id: self.id }) - unless self.user.nil? - #更新用户等级 - UserLevels.update_user_level(self.user) - update_changeset(self.user,1) - update_changeset(self.user,2,self.repository.project) - end - - end - - #积分刷新 - def down_user_score - UserLevels.update_user_level(self.user) - update_changeset(self.user,1) - update_changeset(self.user,2,self.repository.project) - end - - #刷新本次提交(补全相关信息如:user_id等) - def refresh_changests - unless self.repository.nil? - self.repository.fetch_changesets if Setting.autofetch_changesets? - 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 Changeset < ActiveRecord::Base + belongs_to :repository + belongs_to :user + include UserScoreHelper + #after_save :be_user_score # user_score + + has_many :filechanges, :class_name => 'Change', :dependent => :delete_all + # fq + has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy + # end + + #Added by nie + has_one :project_status, :dependent => :destroy + has_one :users_status + #end + + has_and_belongs_to_many :issues + has_and_belongs_to_many :parents, + :class_name => "Changeset", + :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}", + :association_foreign_key => 'parent_id', :foreign_key => 'changeset_id' + has_and_belongs_to_many :children, + :class_name => "Changeset", + :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}", + :association_foreign_key => 'changeset_id', :foreign_key => 'parent_id' + + acts_as_event :title => Proc.new {|o| o.title}, + :description => :long_comments, + :datetime => :committed_on, + :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}} + + acts_as_searchable :columns => 'comments', + :include => {:repository => :project}, + :project_key => "#{Repository.table_name}.project_id", + :date_column => 'committed_on' + + acts_as_activity_provider :timestamp => "#{table_name}.committed_on", + :author_key => :user_id, + :find_options => {:include => [:user, {:repository => :project}]} + validates :repository_id, presence: true + validates :revision, presence: true, uniqueness: {scope: :repository_id} + validates :committed_on, presence: true + validates :commit_date, presence: true + validates :scmid, uniqueness: {scope: :repository_id, allow_nil: true} + + scope :visible, lambda {|*args| + includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args)) + } + + after_create :scan_for_issues,:refresh_changests#:be_user_score # user_score + after_update :be_user_score + after_destroy :down_user_score + before_create :before_create_cs + + # fq + # after_create :act_as_activity + # end + + def revision=(r) + write_attribute :revision, (r.nil? ? nil : r.to_s) + end + + # Returns the identifier of this changeset; depending on repository backends + def identifier + if repository.class.respond_to? :changeset_identifier + repository.class.changeset_identifier self + else + revision.to_s + end + end + + def committed_on=(date) + self.commit_date = date + super + end + + # Returns the readable identifier + def format_identifier + if repository.class.respond_to? :format_changeset_identifier + repository.class.format_changeset_identifier self + else + identifier + end + end + + def project + unless repository.nil? + repository.project + end + end + + def author + user || committer.to_s.split('<').first + end + + def before_create_cs + self.committer = self.class.to_utf8(self.committer, repository.repo_log_encoding) + self.comments = self.class.normalize_comments( + self.comments, repository.repo_log_encoding) + self.user = repository.find_committer_user(self.committer) + end + + def scan_for_issues + scan_comment_for_issue_ids + end + + TIMELOG_RE = / + ( + ((\d+)(h|hours?))((\d+)(m|min)?)? + | + ((\d+)(h|hours?|m|min)) + | + (\d+):(\d+) + | + (\d+([\.,]\d+)?)h? + ) + /x + + def scan_comment_for_issue_ids + return if comments.blank? + # keywords used to reference issues + ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip) + ref_keywords_any = ref_keywords.delete('*') + # keywords used to fix issues + fix_keywords = Setting.commit_fix_keywords.downcase.split(",").collect(&:strip) + + kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|") + + referenced_issues = [] + + comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match| + action, refs = match[2], match[3] + next unless action.present? || ref_keywords_any + + refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m| + issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2] + if issue + referenced_issues << issue + fix_issue(issue) if fix_keywords.include?(action.to_s.downcase) + log_time(issue, hours) if hours && Setting.commit_logtime_enabled? + end + end + end + + referenced_issues.uniq! + self.issues = referenced_issues unless referenced_issues.empty? + end + + def short_comments + @short_comments || split_comments.first + end + + def long_comments + @long_comments || split_comments.last + end + + def text_tag(ref_project=nil) + tag = if scmid? + "commit:#{scmid}" + else + "r#{revision}" + end + if repository && repository.identifier.present? + tag = "#{repository.identifier}|#{tag}" + end + if ref_project && project && ref_project != project + tag = "#{project.identifier}:#{tag}" + end + tag + end + + # Returns the title used for the changeset in the activity/search results + def title + repo = (repository && repository.identifier.present?) ? " (#{repository.identifier})" : '' + comm = short_comments.blank? ? '' : (': ' + short_comments) + "#{l(:label_revision)} #{format_identifier}#{repo}#{comm}" + end + + # Returns the previous changeset + def previous + @previous ||= Changeset.where(["id < ? AND repository_id = ?", id, repository_id]).order('id DESC').first + end + + # Returns the next changeset + def next + @next ||= Changeset.where(["id > ? AND repository_id = ?", id, repository_id]).order('id ASC').first + end + + # Creates a new Change from it's common parameters + def create_change(change) + Change.create(:changeset => self, + :action => change[:action], + :path => change[:path], + :from_path => change[:from_path], + :from_revision => change[:from_revision]) + end + + # Finds an issue that can be referenced by the commit message + def find_referenced_issue_by_id(id) + return nil if id.blank? + issue = Issue.find_by_id(id.to_i, :include => :project) + if Setting.commit_cross_project_ref? + # all issues can be referenced/fixed + elsif issue + # issue that belong to the repository project, a subproject or a parent project only + unless issue.project && + (project == issue.project || project.is_ancestor_of?(issue.project) || + project.is_descendant_of?(issue.project)) + issue = nil + end + end + issue + end + + private + + def act_as_activity + self.acts << Activity.new(:user_id => self.user_id) + end + + def fix_issue(issue) + status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i) + if status.nil? + logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger + return issue + end + + # the issue may have been updated by the closure of another one (eg. duplicate) + issue.reload + # don't change the status is the issue is closed + return if issue.status && issue.status.is_closed? + + journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project))) + issue.status = status + unless Setting.commit_fix_done_ratio.blank? + issue.done_ratio = Setting.commit_fix_done_ratio.to_i + end + Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update, + { :changeset => self, :issue => issue }) + unless issue.save + logger.warn("Issue ##{issue.id} could not be saved by changeset #{id}: #{issue.errors.full_messages}") if logger + end + issue + end + + def log_time(issue, hours) + time_entry = TimeEntry.new( + :user => user, + :hours => hours, + :issue => issue, + :spent_on => commit_date, + :comments => l(:text_time_logged_by_changeset, :value => text_tag(issue.project), + :locale => Setting.default_language) + ) + time_entry.activity = log_time_activity unless log_time_activity.nil? + + unless time_entry.save + logger.warn("TimeEntry could not be created by changeset #{id}: #{time_entry.errors.full_messages}") if logger + end + time_entry + end + + def log_time_activity + if Setting.commit_logtime_activity_id.to_i > 0 + TimeEntryActivity.find_by_id(Setting.commit_logtime_activity_id.to_i) + end + end + + def split_comments + comments =~ /\A(.+?)\r?\n(.*)$/m + @short_comments = $1 || comments + @long_comments = $2.to_s.strip + return @short_comments, @long_comments + end + + public + + # Strips and reencodes a commit log before insertion into the database + def self.normalize_comments(str, encoding) + Changeset.to_utf8(str.to_s.strip, encoding) + end + + def self.to_utf8(str, encoding) + Redmine::CodesetUtil.to_utf8(str, encoding) + end + + private + + # update user score + def be_user_score + UserScore.project(:push_code, self.user,self, { changeset_id: self.id }) + unless self.user.nil? + #更新用户等级 + UserLevels.update_user_level(self.user) + update_changeset(self.user,1) + update_changeset(self.user,2,self.repository.project) + end + + end + + #积分刷新 + def down_user_score + UserLevels.update_user_level(self.user) + update_changeset(self.user,1) + update_changeset(self.user,2,self.repository.project) + end + + #刷新本次提交(补全相关信息如:user_id等) + def refresh_changests + unless self.repository.nil? + self.repository.fetch_changesets if Setting.autofetch_changesets? + end + end + +end diff --git a/app/models/comment.rb b/app/models/comment.rb index f261fcb9e..539c62e85 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,24 +1,24 @@ -# 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 Comment < ActiveRecord::Base - include Redmine::SafeAttributes - belongs_to :commented, :polymorphic => true, :counter_cache => true - belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' - validates_presence_of :commented, :author, :comments - safe_attributes 'comments' -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 Comment < ActiveRecord::Base + include Redmine::SafeAttributes + belongs_to :commented, :polymorphic => true, :counter_cache => true + belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' + validates_presence_of :commented, :author, :comments + safe_attributes 'comments' +end diff --git a/app/models/contest.rb b/app/models/contest.rb index 59f8ee470..ad54e8fb4 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -1,134 +1,134 @@ -class Contest < ActiveRecord::Base - attr_accessible :author_id, :budget, :commit, :deadline, :description, :name, :password - include Redmine::SafeAttributes - - belongs_to :author, :class_name => 'User', :foreign_key => :author_id - has_many :contesting_projects, :dependent => :destroy - has_many :projects, :through => :contesting_projects - has_many :contesting_softapplications, :dependent => :destroy - has_many :softapplications, :through => :contesting_softapplications, :dependent => :destroy - has_many :projects_member, :class_name => 'User', :through => :projects - has_many :journals_for_messages, :as => :jour, :dependent => :destroy - has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy - has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy - has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy - has_many :praise_tread, as: :praise_tread_object, dependent: :destroy - has_many :contestnotifications, :dependent => :destroy, :include => :author - - - - acts_as_attachable - - NAME_LENGTH_LIMIT = 60 - DESCRIPTION_LENGTH_LIMIT = 250 - validates :name, length: {maximum: NAME_LENGTH_LIMIT}, presence: true - validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT} - validates :author_id, presence: true - validates :budget, presence: true - validates :deadline, format: {:with =>/^[1-9][0-9]{3}\-0?[1-9]|1[12]\-0?[1-9]|[12]\d|3[01]$/} - validate :validate_user - after_create :act_as_activity - - scope :visible, lambda {|*args| - nil - } - - scope :like, lambda {|arg| - if arg.blank? - where(nil) - else - pattern = "%#{arg.to_s.strip.downcase}%" - where("LOWER(id) LIKE :p OR LOWER(name) LIKE :p OR LOWER(description) LIKE :p", :p => pattern) - end - } - - acts_as_watchable - acts_as_taggable - - acts_as_event :title => Proc.new {|o| "#{l(:label_requirement)} ##{o.id}: #{o.name}" }, - :description => :description, - :author => :author, - :url => Proc.new {|o| {:controller => 'contests', :action => 'show_contest', :id => o.id}} - - acts_as_activity_provider :find_options => {:include => [:projects, :author]}, - :author_key => :author_id - - safe_attributes 'name', - 'description', - 'budget', - 'deadline', - 'password' - - - def add_jour(user, notes, reference_user_id = 0, options = {}) - if options.count == 0 - self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id) - else - jfm = self.journals_for_messages.build(options) - jfm.save - jfm - end - 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 - self.budget = budget - self.deadline = deadline - self.description = description - self.save - end - end - - def delete_contests - unless self.nil? - if User.current.id == self.author_id - self.destroy - end - end - end - - # Closes open and locked project versions that are completed - def close_completed_versions_contest - 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 - - def set_commit(commit) - self.update_attribute(:commit, commit) - end - - private - - def validate_user - errors.add :author_id, :invalid if author.nil? || !author.active? - end - - - def act_as_activity - self.acts << Activity.new(:user_id => self.author_id) - end - - def validate_contest_manager(user_id) - unless user_id.nil? - if self.author_id == user_id - return true - else - return false - end - end - end -end +class Contest < ActiveRecord::Base + attr_accessible :author_id, :budget, :commit, :deadline, :description, :name, :password + include Redmine::SafeAttributes + + belongs_to :author, :class_name => 'User', :foreign_key => :author_id + has_many :contesting_projects, :dependent => :destroy + has_many :projects, :through => :contesting_projects + has_many :contesting_softapplications, :dependent => :destroy + has_many :softapplications, :through => :contesting_softapplications, :dependent => :destroy + has_many :projects_member, :class_name => 'User', :through => :projects + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy + has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy + has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy + has_many :praise_tread, as: :praise_tread_object, dependent: :destroy + has_many :contestnotifications, :dependent => :destroy, :include => :author + + + + acts_as_attachable + + NAME_LENGTH_LIMIT = 60 + DESCRIPTION_LENGTH_LIMIT = 250 + validates :name, length: {maximum: NAME_LENGTH_LIMIT}, presence: true + validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT} + validates :author_id, presence: true + validates :budget, presence: true + validates :deadline, format: {:with =>/^[1-9][0-9]{3}\-0?[1-9]|1[12]\-0?[1-9]|[12]\d|3[01]$/} + validate :validate_user + after_create :act_as_activity + + scope :visible, lambda {|*args| + nil + } + + scope :like, lambda {|arg| + if arg.blank? + where(nil) + else + pattern = "%#{arg.to_s.strip.downcase}%" + where("LOWER(id) LIKE :p OR LOWER(name) LIKE :p OR LOWER(description) LIKE :p", :p => pattern) + end + } + + acts_as_watchable + acts_as_taggable + + acts_as_event :title => Proc.new {|o| "#{l(:label_requirement)} ##{o.id}: #{o.name}" }, + :description => :description, + :author => :author, + :url => Proc.new {|o| {:controller => 'contests', :action => 'show_contest', :id => o.id}} + + acts_as_activity_provider :find_options => {:include => [:projects, :author]}, + :author_key => :author_id + + safe_attributes 'name', + 'description', + 'budget', + 'deadline', + 'password' + + + def add_jour(user, notes, reference_user_id = 0, options = {}) + if options.count == 0 + self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id) + else + jfm = self.journals_for_messages.build(options) + jfm.save + jfm + end + 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 + self.budget = budget + self.deadline = deadline + self.description = description + self.save + end + end + + def delete_contests + unless self.nil? + if User.current.id == self.author_id + self.destroy + end + end + end + + # Closes open and locked project versions that are completed + def close_completed_versions_contest + 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 + + def set_commit(commit) + self.update_attribute(:commit, commit) + end + + private + + def validate_user + errors.add :author_id, :invalid if author.nil? || !author.active? + end + + + def act_as_activity + self.acts << Activity.new(:user_id => self.author_id) + end + + def validate_contest_manager(user_id) + unless user_id.nil? + if self.author_id == user_id + return true + else + return false + end + end + end +end diff --git a/app/models/contest_notification.rb b/app/models/contest_notification.rb index 79d8bc254..1613f1378 100644 --- a/app/models/contest_notification.rb +++ b/app/models/contest_notification.rb @@ -1,4 +1,4 @@ -class ContestNotification < ActiveRecord::Base - attr_accessible :content, :title - validates :title, length: {maximum: 30} -end +class ContestNotification < ActiveRecord::Base + attr_accessible :content, :title + validates :title, length: {maximum: 30} +end diff --git a/app/models/contesting_project.rb b/app/models/contesting_project.rb index 9828bb598..ced787cbd 100644 --- a/app/models/contesting_project.rb +++ b/app/models/contesting_project.rb @@ -1,53 +1,53 @@ -class ContestingProject < ActiveRecord::Base - attr_accessible :contest_id, :description, :project_id, :user_id, :reward - - belongs_to :contest - belongs_to :project - belongs_to :user - - DESCRIPTION_LENGTH_LIMIT = 500 - validates :description, length: {maximum:DESCRIPTION_LENGTH_LIMIT } - validates :user_id, presence: true - validates :contest_id, presence: true, uniqueness: {scope: :project_id} - validates :project_id, presence: true - - validate :validate_user - validate :validate_contest - validate :validate_project - - 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 - - - def update_reward(which) - self.update_attribute(:reward,which) - end - - def get_reward - self.reward - end - - def cancel_contesting - unless self.nil? - if User.current.id == self.user_id - self.destroy - end - end - end - - private - - def validate_user - errors.add :user_id, :invalid if user.nil? || !user.active? - end - - def validate_contest - errors.add :contest_id, :invalid if contest.nil? - end - - def validate_project - errors.add :project_id, :invalid if project.nil? - end -end +class ContestingProject < ActiveRecord::Base + attr_accessible :contest_id, :description, :project_id, :user_id, :reward + + belongs_to :contest + belongs_to :project + belongs_to :user + + DESCRIPTION_LENGTH_LIMIT = 500 + validates :description, length: {maximum:DESCRIPTION_LENGTH_LIMIT } + validates :user_id, presence: true + validates :contest_id, presence: true, uniqueness: {scope: :project_id} + validates :project_id, presence: true + + validate :validate_user + validate :validate_contest + validate :validate_project + + 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 + + + def update_reward(which) + self.update_attribute(:reward,which) + end + + def get_reward + self.reward + end + + def cancel_contesting + unless self.nil? + if User.current.id == self.user_id + self.destroy + end + end + end + + private + + def validate_user + errors.add :user_id, :invalid if user.nil? || !user.active? + end + + def validate_contest + errors.add :contest_id, :invalid if contest.nil? + end + + def validate_project + errors.add :project_id, :invalid if project.nil? + end +end diff --git a/app/models/course.rb b/app/models/course.rb index 36329ccda..1f0cb0979 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -1,310 +1,310 @@ -class Course < ActiveRecord::Base - include Redmine::SafeAttributes - - STATUS_ACTIVE = 1 - STATUS_CLOSED = 5 - STATUS_ARCHIVED = 9 - - attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period - belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier - belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表 - belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school,该方法通过school_id来调用School表 - has_many :bid - has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}" - has_many :memberships, :class_name => 'Member' - has_many :member_principals, :class_name => 'Member', - :include => :principal, - :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})" - has_many :principals, :through => :member_principals, :source => :principal - has_many :users, :through => :members - has_many :homeworks, :through => :homework_for_courses, :source => :bid, :dependent => :destroy - has_many :journals_for_messages, :as => :jour, :dependent => :destroy - has_many :homework_for_courses, :dependent => :destroy - has_many :student, :class_name => 'StudentsForCourse', :source => :user - has_many :course_infos, :class_name => 'CourseInfos',:dependent => :destroy - has_many :enabled_modules, :dependent => :delete_all - has_many :boards, :dependent => :destroy, :order => "position ASC" - #has_many :course_journals_for_messages, :class_name => 'CourseJournalsForMessage', :as => :jour, :dependent => :destroy - has_many :news, :dependent => :destroy, :include => :author - has_one :course_status, :class_name => "CourseStatus", :dependent => :destroy - - acts_as_taggable - acts_as_nested_set :order => 'name', :dependent => :destroy - acts_as_attachable :view_permission => :view_files, - :delete_permission => :manage_files - - validates :password, presence: true - validates :term, presence: true - validates :name, presence: true - validates :class_period, presence: true,format: {:with =>/^\d*$/} - before_save :self_validate - after_create :create_board_sync - before_destroy :delete_all_members - - safe_attributes 'extra', - 'time', - 'name', - 'extra', - 'code', - 'location', - 'tea_id', - 'password', - 'term', - 'is_public', - 'description', - 'class_period' - - acts_as_customizable - - scope :all_course - scope :active, lambda { where(:status => STATUS_ACTIVE) } - scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) } - scope :all_public, lambda { where(:is_public => true) } - scope :visible, lambda {|*args| where(Course.visible_condition(args.shift || User.current, *args)) } - scope :allowed_to, lambda {|*args| - user = User.current - permission = nil - if args.first.is_a?(Symbol) - permission = args.shift - else - user = args.shift - permission = args.shift - end - where(Course.allowed_to_condition(user, permission, *args)) - } - scope :like, lambda {|arg| - if arg.blank? - where(nil) - else - pattern = "%#{arg.to_s.strip.downcase}%" - where(" LOWER(name) LIKE :p ", :p => pattern) - end - } - - def visible?(user=User.current) - user.allowed_to?(:view_course, self) - end - - def parent_id_changed? - false - end - - # Returns the mail adresses of users that should be always notified on project events - def recipients - notified_users.collect {|user| user.mail} - end - - # Returns the users that should be notified on project events - def notified_users - # TODO: User part should be extracted to User#notify_about? - members.select {|m| m.principal.present? && (m.mail_notification? || m.principal.mail_notification == 'all')}.collect {|m| m.principal} - end - - - # 课程的短描述信息 - def short_description(length = 255) - description.gsub(/<\/?.*?>/,"").html_safe if description - #description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description - end - - # 课程的短名称信息 - def short_name(length = 8) - name.gsub(/<\/?.*?>/,"").html_safe if name - end - - def strip_html(html) - return html if html.empty? || !html.include?('<') - output = "" - tokenizer = HTML::Tokenizer.new(html) - while token = tokenizer.next - node = HTML::Node.parse(nil, 0, 0, token, false) - output += token unless (node.kind_of? HTML::Tag) or (token =~ /^ ["#{Attachmentstype.table_name}.typeId= ?",self.attachmenttype ]) - end - - - # 获取资源后缀名列表 - def contenttypes - attachmenttypes - if @attachmenttypes.length >0 - @attachmenttypes.last().suffixArr - end - end - - def active? - self.status == STATUS_ACTIVE - end - - #课程权限判断 - def allows_to?(action) - if archived? - # No action allowed on archived projects - return false - end - unless active? || Redmine::AccessControl.read_action?(action) - # No write action allowed on closed projects - return false - end - # No action allowed on disabled modules - if action.is_a? Hash - allowed_actions.include? "#{action[:controller]}/#{action[:action]}" - else - allowed_permissions.include? action - end - end - - # 课程允许的权限集合 - def allowed_permissions - @allowed_permissions ||= begin - module_names = enabled_modules.all(:select => :name).collect {|m| m.name} - Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name} - end - end - - # 课程允许的动作集合 - def allowed_actions - @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten - end - - # 返回用户组可以访问的课程 - def users_by_role - members.includes(:user, :roles).all.inject({}) do |h, m| - m.roles.each do |r| - h[r] ||= [] - h[r] << m.user - end - h - end - end - - #自定义验证 - def self_validate - - end - - # 创建课程讨论区 - def create_board_sync - @board = self.boards.build - self.name=" #{l(:label_borad_course) }" - @board.name = self.name - @board.description = self.name.to_s - @board.project_id = -1 - if @board.save - logger.debug "[Course Model] ===> #{@board.to_json}" - else - logger.error "[Course Model] ===> Auto create board when course saved, because #{@board.full_messages}" - end - end - - # 新增课程留言 - # add by nwb - def self.add_new_jour(user, notes, id, options={}) - course = Course.find(id) - if options.count == 0 - pjfm = course.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0) - else - pjfm = course.journals_for_messages.build(options) - end - pjfm.save - pjfm - end - - # 删除课程所有成员 - def delete_all_members - if self.members && self.members.count > 0 - me, mr = Member.table_name, MemberRole.table_name - connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.course_id = #{id})") - Member.delete_all(['course_id = ?', id]) - end - end - - def get_endup_time - begin - end_time = Time.parse(self.endup_time) - rescue Exception => e - end_time = Time.parse("3000-01-01") - Rails.logger.error "[Error] course endup_time error. ===> #{e}" - ensure - return end_time - end - end - - def get_time - begin - time = Date.new(self.time).to_time - rescue Exception => e - time = Time.parse("3000-01-01") - Rails.logger.error "[Error] course time error. ===> #{e}" - ensure - return time - end - end - - def self.allowed_to_condition(user, permission, options={}) - perm = Redmine::AccessControl.permission(permission) - base_statement = (perm && perm.read? ? "#{Course.table_name}.status <> #{Course::STATUS_ARCHIVED}" : "#{Course.table_name}.status = #{Course::STATUS_ACTIVE}") - if perm && perm.course_module - base_statement << " AND #{Course.table_name}.id IN (SELECT em.course_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.course_module}')" - end - - if options[:course] - course_statement = "#{Course.table_name}.id = #{options[:course].id}" - course_statement << " OR (#{Course.table_name}.lft > #{options[:course].lft} AND #{Course.table_name}.rgt < #{options[:course].rgt})" if options[:with_subcourses] - base_statement = "(#{course_statement}) AND (#{base_statement})" - end - - if user.admin? - base_statement - else - statement_by_role = {} - unless options[:member] - role = user.logged? ? Role.non_member : Role.anonymous - if role.allowed_to?(permission) - statement_by_role[role] = "#{Course.table_name}.is_public = #{connection.quoted_true}" - end - end - if user.logged? - user.courses_by_role.each do |role, courses| - if role.allowed_to?(permission) && courses.any? - statement_by_role[role] = "#{Course.table_name}.id IN (#{courses.collect(&:id).join(',')})" - end - end - end - if statement_by_role.empty? - "1=0" - else - if block_given? - statement_by_role.each do |role, statement| - if s = yield(role, user) - statement_by_role[role] = "(#{statement} AND (#{s}))" - end - end - end - "((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))" - end - end - end - - #项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题 - #def name - # read_attribute('name') || Project.find_by_identifier(self.extra).try(:name) - #end -end +class Course < ActiveRecord::Base + include Redmine::SafeAttributes + + STATUS_ACTIVE = 1 + STATUS_CLOSED = 5 + STATUS_ARCHIVED = 9 + + attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period + belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier + belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表 + belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school,该方法通过school_id来调用School表 + has_many :bid + has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}" + has_many :memberships, :class_name => 'Member' + has_many :member_principals, :class_name => 'Member', + :include => :principal, + :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})" + has_many :principals, :through => :member_principals, :source => :principal + has_many :users, :through => :members + has_many :homeworks, :through => :homework_for_courses, :source => :bid, :dependent => :destroy + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + has_many :homework_for_courses, :dependent => :destroy + has_many :student, :class_name => 'StudentsForCourse', :source => :user + has_many :course_infos, :class_name => 'CourseInfos',:dependent => :destroy + has_many :enabled_modules, :dependent => :delete_all + has_many :boards, :dependent => :destroy, :order => "position ASC" + #has_many :course_journals_for_messages, :class_name => 'CourseJournalsForMessage', :as => :jour, :dependent => :destroy + has_many :news, :dependent => :destroy, :include => :author + has_one :course_status, :class_name => "CourseStatus", :dependent => :destroy + + acts_as_taggable + acts_as_nested_set :order => 'name', :dependent => :destroy + acts_as_attachable :view_permission => :view_files, + :delete_permission => :manage_files + + validates :password, presence: true + validates :term, presence: true + validates :name, presence: true + validates :class_period, presence: true,format: {:with =>/^\d*$/} + before_save :self_validate + after_create :create_board_sync + before_destroy :delete_all_members + + safe_attributes 'extra', + 'time', + 'name', + 'extra', + 'code', + 'location', + 'tea_id', + 'password', + 'term', + 'is_public', + 'description', + 'class_period' + + acts_as_customizable + + scope :all_course + scope :active, lambda { where(:status => STATUS_ACTIVE) } + scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) } + scope :all_public, lambda { where(:is_public => true) } + scope :visible, lambda {|*args| where(Course.visible_condition(args.shift || User.current, *args)) } + scope :allowed_to, lambda {|*args| + user = User.current + permission = nil + if args.first.is_a?(Symbol) + permission = args.shift + else + user = args.shift + permission = args.shift + end + where(Course.allowed_to_condition(user, permission, *args)) + } + scope :like, lambda {|arg| + if arg.blank? + where(nil) + else + pattern = "%#{arg.to_s.strip.downcase}%" + where(" LOWER(name) LIKE :p ", :p => pattern) + end + } + + def visible?(user=User.current) + user.allowed_to?(:view_course, self) + end + + def parent_id_changed? + false + end + + # Returns the mail adresses of users that should be always notified on project events + def recipients + notified_users.collect {|user| user.mail} + end + + # Returns the users that should be notified on project events + def notified_users + # TODO: User part should be extracted to User#notify_about? + members.select {|m| m.principal.present? && (m.mail_notification? || m.principal.mail_notification == 'all')}.collect {|m| m.principal} + end + + + # 课程的短描述信息 + def short_description(length = 255) + description.gsub(/<\/?.*?>/,"").html_safe if description + #description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description + end + + # 课程的短名称信息 + def short_name(length = 8) + name.gsub(/<\/?.*?>/,"").html_safe if name + end + + def strip_html(html) + return html if html.empty? || !html.include?('<') + output = "" + tokenizer = HTML::Tokenizer.new(html) + while token = tokenizer.next + node = HTML::Node.parse(nil, 0, 0, token, false) + output += token unless (node.kind_of? HTML::Tag) or (token =~ /^ ["#{Attachmentstype.table_name}.typeId= ?",self.attachmenttype ]) + end + + + # 获取资源后缀名列表 + def contenttypes + attachmenttypes + if @attachmenttypes.length >0 + @attachmenttypes.last().suffixArr + end + end + + def active? + self.status == STATUS_ACTIVE + end + + #课程权限判断 + def allows_to?(action) + if archived? + # No action allowed on archived projects + return false + end + unless active? || Redmine::AccessControl.read_action?(action) + # No write action allowed on closed projects + return false + end + # No action allowed on disabled modules + if action.is_a? Hash + allowed_actions.include? "#{action[:controller]}/#{action[:action]}" + else + allowed_permissions.include? action + end + end + + # 课程允许的权限集合 + def allowed_permissions + @allowed_permissions ||= begin + module_names = enabled_modules.all(:select => :name).collect {|m| m.name} + Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name} + end + end + + # 课程允许的动作集合 + def allowed_actions + @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten + end + + # 返回用户组可以访问的课程 + def users_by_role + members.includes(:user, :roles).all.inject({}) do |h, m| + m.roles.each do |r| + h[r] ||= [] + h[r] << m.user + end + h + end + end + + #自定义验证 + def self_validate + + end + + # 创建课程讨论区 + def create_board_sync + @board = self.boards.build + self.name=" #{l(:label_borad_course) }" + @board.name = self.name + @board.description = self.name.to_s + @board.project_id = -1 + if @board.save + logger.debug "[Course Model] ===> #{@board.to_json}" + else + logger.error "[Course Model] ===> Auto create board when course saved, because #{@board.full_messages}" + end + end + + # 新增课程留言 + # add by nwb + def self.add_new_jour(user, notes, id, options={}) + course = Course.find(id) + if options.count == 0 + pjfm = course.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0) + else + pjfm = course.journals_for_messages.build(options) + end + pjfm.save + pjfm + end + + # 删除课程所有成员 + def delete_all_members + if self.members && self.members.count > 0 + me, mr = Member.table_name, MemberRole.table_name + connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.course_id = #{id})") + Member.delete_all(['course_id = ?', id]) + end + end + + def get_endup_time + begin + end_time = Time.parse(self.endup_time) + rescue Exception => e + end_time = Time.parse("3000-01-01") + Rails.logger.error "[Error] course endup_time error. ===> #{e}" + ensure + return end_time + end + end + + def get_time + begin + time = Date.new(self.time).to_time + rescue Exception => e + time = Time.parse("3000-01-01") + Rails.logger.error "[Error] course time error. ===> #{e}" + ensure + return time + end + end + + def self.allowed_to_condition(user, permission, options={}) + perm = Redmine::AccessControl.permission(permission) + base_statement = (perm && perm.read? ? "#{Course.table_name}.status <> #{Course::STATUS_ARCHIVED}" : "#{Course.table_name}.status = #{Course::STATUS_ACTIVE}") + if perm && perm.course_module + base_statement << " AND #{Course.table_name}.id IN (SELECT em.course_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.course_module}')" + end + + if options[:course] + course_statement = "#{Course.table_name}.id = #{options[:course].id}" + course_statement << " OR (#{Course.table_name}.lft > #{options[:course].lft} AND #{Course.table_name}.rgt < #{options[:course].rgt})" if options[:with_subcourses] + base_statement = "(#{course_statement}) AND (#{base_statement})" + end + + if user.admin? + base_statement + else + statement_by_role = {} + unless options[:member] + role = user.logged? ? Role.non_member : Role.anonymous + if role.allowed_to?(permission) + statement_by_role[role] = "#{Course.table_name}.is_public = #{connection.quoted_true}" + end + end + if user.logged? + user.courses_by_role.each do |role, courses| + if role.allowed_to?(permission) && courses.any? + statement_by_role[role] = "#{Course.table_name}.id IN (#{courses.collect(&:id).join(',')})" + end + end + end + if statement_by_role.empty? + "1=0" + else + if block_given? + statement_by_role.each do |role, statement| + if s = yield(role, user) + statement_by_role[role] = "(#{statement} AND (#{s}))" + end + end + end + "((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))" + end + end + end + + #项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题 + #def name + # read_attribute('name') || Project.find_by_identifier(self.extra).try(:name) + #end +end diff --git a/app/models/course_status.rb b/app/models/course_status.rb index 85969e55e..2f9bdf564 100644 --- a/app/models/course_status.rb +++ b/app/models/course_status.rb @@ -1,5 +1,5 @@ -class CourseStatus < ActiveRecord::Base - attr_accessible :changesets_count, :course_ac_para, :course_id, :grade, :watchers_count - belongs_to :course - validates :course_id, presence: true,uniqueness: true -end +class CourseStatus < ActiveRecord::Base + attr_accessible :changesets_count, :course_ac_para, :course_id, :grade, :watchers_count + belongs_to :course + validates :course_id, presence: true,uniqueness: true +end diff --git a/app/models/enabled_module.rb b/app/models/enabled_module.rb index fe668e02c..e0353fa75 100644 --- a/app/models/enabled_module.rb +++ b/app/models/enabled_module.rb @@ -1,39 +1,39 @@ -# 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 EnabledModule < ActiveRecord::Base - belongs_to :project - - validates_presence_of :name - validates_uniqueness_of :name, :scope => :project_id - - after_create :module_enabled - private - - # after_create callback used to do things when a module is enabled - def module_enabled - case name - when 'wiki' - # Create a wiki with a default start page - if project && project.wiki.nil? - Wiki.create(:project => project, :start_page => 'Wiki') - end - 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 EnabledModule < ActiveRecord::Base + belongs_to :project + + validates_presence_of :name + validates_uniqueness_of :name, :scope => :project_id + + after_create :module_enabled + private + + # after_create callback used to do things when a module is enabled + def module_enabled + case name + when 'wiki' + # Create a wiki with a default start page + if project && project.wiki.nil? + Wiki.create(:project => project, :start_page => 'Wiki') + end + end + end + + +end diff --git a/app/models/softapplication.rb b/app/models/softapplication.rb index 9e469d2ac..c52d5e9aa 100644 --- a/app/models/softapplication.rb +++ b/app/models/softapplication.rb @@ -1,39 +1,39 @@ -class Softapplication < ActiveRecord::Base - attr_accessible :android_min_version_available, :app_type_id, :app_type_name, :description, :name, :user_id, :contest_id, :application_developers, :deposit_project_url, :deposit_project - acts_as_attachable :view_permission => :view_files - seems_rateable :allow_update => true, :dimensions => :quality - - - has_many :journals_for_messages, :as => :jour, :dependent => :destroy - has_many :contesting_softapplications, :dependent => :destroy - #has_many :projecting_softapplications, :dependent => :destroy - belongs_to :user - belongs_to :project - has_many :contests, :through => :contesting_softapplications - - validates_length_of :name, :maximum => 25 - validates_length_of :application_developers, :maximum => 125 - validates_length_of :android_min_version_available, :maximum => 125 - - def add_jour(user, notes, reference_user_id = 0, options = {}) - if options.count == 0 - self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id) - else - jfm = self.journals_for_messages.build(options) - jfm.save - jfm - end - end - def set_commit(commit) - self.update_attribute(:commit, commit) - end - - def editable_by? usr - usr.admin? || self.user == usr - end - - def destroyable_by? usr - self.user == usr || usr.admin? - end - -end +class Softapplication < ActiveRecord::Base + attr_accessible :android_min_version_available, :app_type_id, :app_type_name, :description, :name, :user_id, :contest_id, :application_developers, :deposit_project_url, :deposit_project + acts_as_attachable :view_permission => :view_files + seems_rateable :allow_update => true, :dimensions => :quality + + + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + has_many :contesting_softapplications, :dependent => :destroy + #has_many :projecting_softapplications, :dependent => :destroy + belongs_to :user + belongs_to :project + has_many :contests, :through => :contesting_softapplications + + validates_length_of :name, :maximum => 25 + validates_length_of :application_developers, :maximum => 125 + validates_length_of :android_min_version_available, :maximum => 125 + + def add_jour(user, notes, reference_user_id = 0, options = {}) + if options.count == 0 + self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id) + else + jfm = self.journals_for_messages.build(options) + jfm.save + jfm + end + end + def set_commit(commit) + self.update_attribute(:commit, commit) + end + + def editable_by? usr + usr.admin? || self.user == usr + end + + def destroyable_by? usr + self.user == usr || usr.admin? + end + +end diff --git a/app/models/web_footer_company.rb b/app/models/web_footer_company.rb index bca8dfb5d..0743b6a9c 100644 --- a/app/models/web_footer_company.rb +++ b/app/models/web_footer_company.rb @@ -1,8 +1,8 @@ -class WebFooterCompany < ActiveRecord::Base - attr_accessible :logo_size, :name, :url - validates :name, presence: true, length: { maximum: 500 } - validates :url, length: { maximum: 500 }, - format: { with: /(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/, - message: l(:is_not_url_error) - } -end +class WebFooterCompany < ActiveRecord::Base + attr_accessible :logo_size, :name, :url + validates :name, presence: true, length: { maximum: 500 } + validates :url, length: { maximum: 500 }, + format: { with: /(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/, + message: l(:is_not_url_error) + } +end diff --git a/app/models/web_footer_oranizer.rb b/app/models/web_footer_oranizer.rb index f47d4131f..9a014ca83 100644 --- a/app/models/web_footer_oranizer.rb +++ b/app/models/web_footer_oranizer.rb @@ -1,3 +1,3 @@ -class WebFooterOranizer < ActiveRecord::Base - attr_accessible :description, :name -end +class WebFooterOranizer < ActiveRecord::Base + attr_accessible :description, :name +end diff --git a/app/views/admin/_tab_partial.html.erb b/app/views/admin/_tab_partial.html.erb index 86191fdb5..6b8788a90 100644 --- a/app/views/admin/_tab_partial.html.erb +++ b/app/views/admin/_tab_partial.html.erb @@ -1,8 +1,8 @@ -
    -
      -
    • <%= link_to l(:label_project_first_page), {:action => 'first_page_made'}, class: "#{current_page?(first_page_made_path)? 'selected' : nil }" %>
    • -
    • <%= link_to l(:label_course_first_page), {:action => 'course_page_made'}, class: "#{current_page?(course_page_made_path)? 'selected' : nil }" %>
    • -
    • <%= link_to l(:label_contest_first_page), {:action => 'contest_page_made'}, class: "#{current_page?(contest_page_made_path)? 'selected' : nil }" %>
    • -
    • <%= link_to l(:label_web_footer_page), {:action => 'web_footer_made'}, class: "#{current_page?(web_footer_made_path)? 'selected' : nil }" %>
    • -
    +
    +
      +
    • <%= link_to l(:label_project_first_page), {:action => 'first_page_made'}, class: "#{current_page?(first_page_made_path)? 'selected' : nil }" %>
    • +
    • <%= link_to l(:label_course_first_page), {:action => 'course_page_made'}, class: "#{current_page?(course_page_made_path)? 'selected' : nil }" %>
    • +
    • <%= link_to l(:label_contest_first_page), {:action => 'contest_page_made'}, class: "#{current_page?(contest_page_made_path)? 'selected' : nil }" %>
    • +
    • <%= link_to l(:label_web_footer_page), {:action => 'web_footer_made'}, class: "#{current_page?(web_footer_made_path)? 'selected' : nil }" %>
    • +
    \ No newline at end of file diff --git a/app/views/admin/contest_page_made.html.erb b/app/views/admin/contest_page_made.html.erb index a25f149ed..77e0ce041 100644 --- a/app/views/admin/contest_page_made.html.erb +++ b/app/views/admin/contest_page_made.html.erb @@ -1,41 +1,41 @@ -

    <%=l(:label_first_page_made)%>

    - -<%= form_tag(:controller => 'admin', :action => 'contest_page_made') do%> -

    - - <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    - <%= render 'tab_partial' %> - -

    <%=l(:label_contest_first_page)%>

    -

    - -

    -
    - <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@contest_page} %> -
    -

    - - <%= text_field_tag 'image_width', params[:label_image_width],:value => @contest_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    -

    - - <%= text_field_tag 'image_height', params[:label_imgae_height], :value => @contest_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    -

    - - <%= text_field_tag 'contest_title', params[:label_site_title], :value => @contest_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    - -

    - - <%= text_area_tag 'contest_description',@contest_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    - - <%= submit_tag l(:button_save), :class => "small", :name => nil %> -<% end %> -
    - - - +

    <%=l(:label_first_page_made)%>

    + +<%= form_tag(:controller => 'admin', :action => 'contest_page_made') do%> +

    + + <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    + <%= render 'tab_partial' %> + +

    <%=l(:label_contest_first_page)%>

    +

    + +

    +
    + <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@contest_page} %> +
    +

    + + <%= text_field_tag 'image_width', params[:label_image_width],:value => @contest_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    +

    + + <%= text_field_tag 'image_height', params[:label_imgae_height], :value => @contest_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    +

    + + <%= text_field_tag 'contest_title', params[:label_site_title], :value => @contest_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    + +

    + + <%= text_area_tag 'contest_description',@contest_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    + + <%= submit_tag l(:button_save), :class => "small", :name => nil %> +<% end %> +
    + + +
    \ No newline at end of file diff --git a/app/views/admin/course_page_made.html.erb b/app/views/admin/course_page_made.html.erb index 8b91e2600..ce067eeb2 100644 --- a/app/views/admin/course_page_made.html.erb +++ b/app/views/admin/course_page_made.html.erb @@ -1,39 +1,39 @@ -

    <%=l(:label_first_page_made)%>

    - -<%= form_tag(:controller => 'admin', :action => 'course_page_made') do %> -

    - - <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    - <%= render 'tab_partial' %> -

    <%=l(:label_course_first_page)%>

    -

    - -

    -
    - <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@course_page} %> -
    -

    - - <%= text_field_tag 'image_width', params[:label_image_width],:value => @course_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    -

    - - <%= text_field_tag 'image_height', params[:label_imgae_height], :value => @course_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    -

    - - <%= text_field_tag 'course_title', params[:label_site_title], :value => @course_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    -

    - - <%= text_area_tag 'course_description',@course_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    - - <%= submit_tag l(:button_save), :class => "small", :name => nil %> -<% end %> -
    - - - +

    <%=l(:label_first_page_made)%>

    + +<%= form_tag(:controller => 'admin', :action => 'course_page_made') do %> +

    + + <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    + <%= render 'tab_partial' %> +

    <%=l(:label_course_first_page)%>

    +

    + +

    +
    + <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@course_page} %> +
    +

    + + <%= text_field_tag 'image_width', params[:label_image_width],:value => @course_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    +

    + + <%= text_field_tag 'image_height', params[:label_imgae_height], :value => @course_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    +

    + + <%= text_field_tag 'course_title', params[:label_site_title], :value => @course_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    +

    + + <%= text_area_tag 'course_description',@course_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    + + <%= submit_tag l(:button_save), :class => "small", :name => nil %> +<% end %> +
    + + +
    \ No newline at end of file diff --git a/app/views/admin/first_page_made.html.erb b/app/views/admin/first_page_made.html.erb index d8fbc0533..77bd41aa5 100644 --- a/app/views/admin/first_page_made.html.erb +++ b/app/views/admin/first_page_made.html.erb @@ -1,60 +1,60 @@ -

    <%=l(:label_first_page_made)%>

    - -<%= form_tag(:controller => 'admin', :action => 'first_page_made') do %> -

    - - <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    - <%= render 'tab_partial' %> -

    <%=l(:label_project_first_page)%>

    -

    - -

    -
    - <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@first_page} %> -
    -

    - - <%= text_field_tag 'image_width', params[:label_image_width],:value => @first_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    -

    - - <%= text_field_tag 'image_height', params[:label_imgae_height], :value => @first_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - - <%= text_area 'first_page', 'description', :value => @first_page.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %> - <%= wikitoolbar_for 'first_page_description' %> -

    - - - <%= submit_tag l(:button_save), :class => "small", :name => nil %> -<% end %> -
    - - - +

    <%=l(:label_first_page_made)%>

    + +<%= form_tag(:controller => 'admin', :action => 'first_page_made') do %> +

    + + <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    + <%= render 'tab_partial' %> +

    <%=l(:label_project_first_page)%>

    +

    + +

    +
    + <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@first_page} %> +
    +

    + + <%= text_field_tag 'image_width', params[:label_image_width],:value => @first_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    +

    + + <%= text_field_tag 'image_height', params[:label_imgae_height], :value => @first_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + + <%= text_area 'first_page', 'description', :value => @first_page.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'first_page_description' %> +

    + + + <%= submit_tag l(:button_save), :class => "small", :name => nil %> +<% end %> +
    + + +
    \ No newline at end of file diff --git a/app/views/admin/users.html.erb b/app/views/admin/users.html.erb index c70196a2f..7bbdf1c3e 100644 --- a/app/views/admin/users.html.erb +++ b/app/views/admin/users.html.erb @@ -1,69 +1,69 @@ -<% if User.current.admin? %> -
    - <%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %> -
    - -

    <%= l(:label_user_plural)%>

    - - <%= form_tag(:controller => 'admin', :action => 'search') do %> -
    - - <%= l(:label_filter_plural) %> - - - <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> - - <% if @groups.present? %> - - <%= select_tag 'group_id', content_tag('option') + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;" %> - <% end %> - - - <%= text_field_tag 'name', params[:name], :size => 30 %> - <%= submit_tag l(:label_search), :class => "small", :name => nil %> -
    - <% end %> -   - -
    - - - - <%= sort_header_tag('login', :caption => l(:field_login)) %> - <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %> - <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %> - <%= sort_header_tag('mail', :caption => l(:field_mail)) %> - - <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %> - <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %> - <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %> - - - - - <% for user in @users -%> - "> - - - - - - - - - - <% end -%> - -
    <%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %><%= h(user.firstname) %><%= h(user.lastname) %><%= checked_image user.admin? %><%= format_time(user.created_on) %> <%= change_status_link(user) %> - <%= delete_link user_path(user, :back_url => admin_users_path(params)) unless User.current == user %>
    -
    - - - <% html_title(l(:label_user_plural)) -%> -<%else %> - -<% end%> +<% if User.current.admin? %> +
    + <%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %> +
    + +

    <%= l(:label_user_plural)%>

    + + <%= form_tag(:controller => 'admin', :action => 'search') do %> +
    + + <%= l(:label_filter_plural) %> + + + <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> + + <% if @groups.present? %> + + <%= select_tag 'group_id', content_tag('option') + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;" %> + <% end %> + + + <%= text_field_tag 'name', params[:name], :size => 30 %> + <%= submit_tag l(:label_search), :class => "small", :name => nil %> +
    + <% end %> +   + +
    + + + + <%= sort_header_tag('login', :caption => l(:field_login)) %> + <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %> + <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %> + <%= sort_header_tag('mail', :caption => l(:field_mail)) %> + + <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %> + <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %> + <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %> + + + + + <% for user in @users -%> + "> + + + + + + + + + + <% end -%> + +
    <%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %><%= h(user.firstname) %><%= h(user.lastname) %><%= checked_image user.admin? %><%= format_time(user.created_on) %> <%= change_status_link(user) %> + <%= delete_link user_path(user, :back_url => admin_users_path(params)) unless User.current == user %>
    +
    + + + <% html_title(l(:label_user_plural)) -%> +<%else %> + +<% end%> diff --git a/app/views/admin/web_footer_made.html.erb b/app/views/admin/web_footer_made.html.erb index 65e77631c..90c9b5787 100644 --- a/app/views/admin/web_footer_made.html.erb +++ b/app/views/admin/web_footer_made.html.erb @@ -1,28 +1,28 @@ -

    <%=l(:label_first_page_made)%>

    - -<%= form_tag(:controller => 'admin', :action => 'web_footer_made') do%> -

    - - <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -

    - <%= render 'tab_partial' %> -
    <%= link_to l(:label_cooperation_compnay), web_footer_companies_path %>
    -

    <%=l(:label_web_footer_page)%>

    - -

    - - <%= text_field_tag 'organizer_name', params[:label_organizer_name], :value => @organizer.nil? ? "":@organizer.name,:size => 30,:style => "font-size:small;width:497px;margin-left:80px;" %> -

    -

    - - - <%= text_area 'web_footer_oranizer', 'description', :value => @organizer.nil? ? "" : @organizer.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %> - <%= wikitoolbar_for 'web_footer_oranizer_description' %> -

    - <%= submit_tag l(:button_save), :class => "small", :name => nil %> -<% end %> -
    - - - +

    <%=l(:label_first_page_made)%>

    + +<%= form_tag(:controller => 'admin', :action => 'web_footer_made') do%> +

    + + <%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> +

    + <%= render 'tab_partial' %> +
    <%= link_to l(:label_cooperation_compnay), web_footer_companies_path %>
    +

    <%=l(:label_web_footer_page)%>

    + +

    + + <%= text_field_tag 'organizer_name', params[:label_organizer_name], :value => @organizer.nil? ? "":@organizer.name,:size => 30,:style => "font-size:small;width:497px;margin-left:80px;" %> +

    +

    + + + <%= text_area 'web_footer_oranizer', 'description', :value => @organizer.nil? ? "" : @organizer.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'web_footer_oranizer_description' %> +

    + <%= submit_tag l(:button_save), :class => "small", :name => nil %> +<% end %> +
    + + +
    \ No newline at end of file diff --git a/app/views/attachments/_app_link.html.erb b/app/views/attachments/_app_link.html.erb index 263f51dc8..28a2d2c8b 100644 --- a/app/views/attachments/_app_link.html.erb +++ b/app/views/attachments/_app_link.html.erb @@ -1,17 +1,17 @@ - -<% for attachment in attachments %> - <% if attachments.count > 1 && attachment != attachments.first%> -
                     - <% end %> - <%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%> - <% if attachment.is_text? %> - <%= link_to image_tag('magnifier.png'), - :controller => 'attachments', :action => 'show', - :id => attachment, :filename => attachment.filename %> - <% end %> - - <%= h(truncate(" - #{attachment.description}", length: 20, omission: '...')) unless attachment.description.blank? %> - - (<%= number_to_human_size attachment.filesize %>) - - <% end -%> + +<% for attachment in attachments %> + <% if attachments.count > 1 && attachment != attachments.first%> +
                     + <% end %> + <%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%> + <% if attachment.is_text? %> + <%= link_to image_tag('magnifier.png'), + :controller => 'attachments', :action => 'show', + :id => attachment, :filename => attachment.filename %> + <% end %> + + <%= h(truncate(" - #{attachment.description}", length: 20, omission: '...')) unless attachment.description.blank? %> + + (<%= number_to_human_size attachment.filesize %>) + + <% end -%> diff --git a/app/views/attachments/_form_course.html.erb b/app/views/attachments/_form_course.html.erb index 0446db37d..b2089d629 100644 --- a/app/views/attachments/_form_course.html.erb +++ b/app/views/attachments/_form_course.html.erb @@ -1,63 +1,63 @@ - -<% if defined?(container) && container && container.saved_attachments %> - <% if isReply %> - <% container.saved_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;") + - link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> - <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> - <%= l(:field_is_public)%>: - <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%> - <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> - - <% end %> - <% else %> - <% 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;") + - link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> - <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> - <%= l(:field_is_public)%>: - <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%> - <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> - - <% end %> - <% end %> -<% end %> - - - -<%#= button_tag "浏览", :type=>"button", :onclick=>"CompatibleSend();" %> - -<%= button_tag "浏览", :type=>"button", :onclick=>"_file.click()" %> -<%= 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 %> + <% if isReply %> + <% container.saved_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;") + + link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> + <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> + <%= l(:field_is_public)%>: + <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%> + <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> + + <% end %> + <% else %> + <% 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;") + + link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> + <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> + <%= l(:field_is_public)%>: + <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%> + <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> + + <% end %> + <% end %> +<% end %> + + + +<%#= button_tag "浏览", :type=>"button", :onclick=>"CompatibleSend();" %> + +<%= button_tag "浏览", :type=>"button", :onclick=>"_file.click()" %> +<%= 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/_links.html.erb b/app/views/attachments/_links.html.erb index f6b7ee7dd..30e60190d 100644 --- a/app/views/attachments/_links.html.erb +++ b/app/views/attachments/_links.html.erb @@ -1,53 +1,53 @@ -
    -<% for attachment in attachments %> -

    - - <%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%> - - <% if attachment.is_text? %> - <%= link_to image_tag('magnifier.png'), - :controller => 'attachments', - :action => 'show', - :id => attachment, - :filename => attachment.filename%> - <% end %> - - <%= h(truncate(" - #{attachment.description}", length: 15, omission: '...')) unless attachment.description.blank? %> - - (<%= number_to_human_size attachment.filesize %>) - <% if options[:deletable] %> - <% if attachment.container_type == 'HomeworkAttach' %> - <%= link_to image_tag('delete.png'), {:controller => 'attachments', :action => 'delete_homework', :id => attachment.id}, - :data => {:confirm => l(:text_are_you_sure)}, - :method => :delete, - :class => 'delete', - :title => l(:button_delete) %> - <% else %> - <%= link_to image_tag('delete.png'), attachment_path(attachment), - :data => {:confirm => l(:text_are_you_sure)}, - :method => :delete, - :class => 'delete', - #:remote => true, - #:id => "attachments_" + attachment.id.to_s, - :title => l(:button_delete) %> - <% end %> - <% end %> - <% if options[:author] %> - - <%= link_to h(truncate(attachment.author.name, length: 10, omission: '...')),user_path(attachment.author) %>, - <%= format_time(attachment.created_on) %> - - <% end %> -

    -<% end %> -<% if defined?(thumbnails) && thumbnails %> - <% images = attachments.select(&:thumbnailable?) %> - <% if images.any? %> -
    - <% images.each do |attachment| %> -
    <%= thumbnail_tag(attachment) %>
    - <% end %> -
    - <% end %> -<% end %> -
    +
    +<% for attachment in attachments %> +

    + + <%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%> + + <% if attachment.is_text? %> + <%= link_to image_tag('magnifier.png'), + :controller => 'attachments', + :action => 'show', + :id => attachment, + :filename => attachment.filename%> + <% end %> + + <%= h(truncate(" - #{attachment.description}", length: 15, omission: '...')) unless attachment.description.blank? %> + + (<%= number_to_human_size attachment.filesize %>) + <% if options[:deletable] %> + <% if attachment.container_type == 'HomeworkAttach' %> + <%= link_to image_tag('delete.png'), {:controller => 'attachments', :action => 'delete_homework', :id => attachment.id}, + :data => {:confirm => l(:text_are_you_sure)}, + :method => :delete, + :class => 'delete', + :title => l(:button_delete) %> + <% else %> + <%= link_to image_tag('delete.png'), attachment_path(attachment), + :data => {:confirm => l(:text_are_you_sure)}, + :method => :delete, + :class => 'delete', + #:remote => true, + #:id => "attachments_" + attachment.id.to_s, + :title => l(:button_delete) %> + <% end %> + <% end %> + <% if options[:author] %> + + <%= link_to h(truncate(attachment.author.name, length: 10, omission: '...')),user_path(attachment.author) %>, + <%= format_time(attachment.created_on) %> + + <% end %> +

    +<% end %> +<% if defined?(thumbnails) && thumbnails %> + <% images = attachments.select(&:thumbnailable?) %> + <% if images.any? %> +
    + <% images.each do |attachment| %> +
    <%= thumbnail_tag(attachment) %>
    + <% end %> +
    + <% end %> +<% end %> +
    diff --git a/app/views/bids/_form.html.erb b/app/views/bids/_form.html.erb index 98277d315..86bac9731 100644 --- a/app/views/bids/_form.html.erb +++ b/app/views/bids/_form.html.erb @@ -1,35 +1,35 @@ - -<% else %> - -<%= error_messages_for 'bid' %> - -

    <%= l(:label_bids_form_new_description) %>

    -

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

    - -

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

    -

    <%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_new_money) %> - - - -

    -

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

    - + +<% else %> + +<%= error_messages_for 'bid' %> + +

    <%= l(:label_bids_form_new_description) %>

    +

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

    + +

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

    +

    <%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_new_money) %> + + + +

    +

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

    + diff --git a/app/views/bids/_form_contest.html.erb b/app/views/bids/_form_contest.html.erb index e2dba9271..ccd16f15e 100644 --- a/app/views/bids/_form_contest.html.erb +++ b/app/views/bids/_form_contest.html.erb @@ -1,36 +1,36 @@ - - -<%= error_messages_for 'bid' %> - -

    <%= l(:label_bids_form_contest_new_description) %>

    -

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

    - -

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

    - -

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

    - -

    - <%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_reward_what) %> - - -

    - -

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

    + + +<%= error_messages_for 'bid' %> + +

    <%= l(:label_bids_form_contest_new_description) %>

    +

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

    + +

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

    + +

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

    + +

    + <%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_reward_what) %> + + +

    + +

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

    diff --git a/app/views/bids/_history.html.erb b/app/views/bids/_history.html.erb index b67421823..784fb7ff8 100644 --- a/app/views/bids/_history.html.erb +++ b/app/views/bids/_history.html.erb @@ -1,66 +1,66 @@ -<% reply_allow = JournalsForMessage.create_by_user? User.current %> -<% tip1 = (@bid.reward_type == 3) ? l(:label_student_response) : l(:label_user_response) %> -

    <%=tip1%>

    - -
    - <%= render :partial => 'new', :locals => {:bid => @bid, :sta => @state} %> -
    -<% label = '' - case @bid.reward_type - when 1 - label = l(:label_respond_requirement) - when 2 - label = l(:label_contest_requirement) - when 3 - label = l(:label_question_requirement) - else - end -%> - - -<% if journals.size >0 %> -
      - <% for journal in journals%> -
    • - <%= image_tag(url_to_avatar(journal.user), :class => "avatar") %> - - <%= link_to journal.user, user_path(journal.user)%> - <%= label %> -
      <%= 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 => 'bids', :action => 'new', :id => bid, :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.name}: '); $('##{ids} textarea') ;return false;"} - %> - <% end %> - <% if @user==User.current|| User.current.admin? %> - <%= 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 %> - -
      -
      - <% ids = 'project_respond_form_'+ journal.id.to_s%> - <% if reply_allow %> -
      - <%= render :partial => 'words/new_respond', :locals => {:journal => journal, :m_reply_id => journal} %> -
      - <% end %> -
      -
      - <%= render :partial => "words/journal_reply", :locals => {:journal => journal } %> -
      -
    • - <% end %> -
    -<% end %> +<% reply_allow = JournalsForMessage.create_by_user? User.current %> +<% tip1 = (@bid.reward_type == 3) ? l(:label_student_response) : l(:label_user_response) %> +

    <%=tip1%>

    + +
    + <%= render :partial => 'new', :locals => {:bid => @bid, :sta => @state} %> +
    +<% label = '' + case @bid.reward_type + when 1 + label = l(:label_respond_requirement) + when 2 + label = l(:label_contest_requirement) + when 3 + label = l(:label_question_requirement) + else + end +%> + + +<% if journals.size >0 %> +
      + <% for journal in journals%> +
    • + <%= image_tag(url_to_avatar(journal.user), :class => "avatar") %> + + <%= link_to journal.user, user_path(journal.user)%> + <%= label %> +
      <%= 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 => 'bids', :action => 'new', :id => bid, :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.name}: '); $('##{ids} textarea') ;return false;"} + %> + <% end %> + <% if @user==User.current|| User.current.admin? %> + <%= 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 %> + +
      +
      + <% ids = 'project_respond_form_'+ journal.id.to_s%> + <% if reply_allow %> +
      + <%= render :partial => 'words/new_respond', :locals => {:journal => journal, :m_reply_id => journal} %> +
      + <% end %> +
      +
      + <%= render :partial => "words/journal_reply", :locals => {:journal => journal } %> +
      +
    • + <% end %> +
    +<% end %> diff --git a/app/views/bids/_homework_form.html.erb b/app/views/bids/_homework_form.html.erb index 29033ec59..3a9158349 100644 --- a/app/views/bids/_homework_form.html.erb +++ b/app/views/bids/_homework_form.html.erb @@ -1,56 +1,56 @@ - - - - -<%= error_messages_for 'bid' %> -

    - <%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :onblur => "regexName();" %> -

    -

    - -

    - -

    - <%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT %> -

    -

    - <%= f.text_field(:deadline, :required => true, :size => 60, :style => "width:150px;", :readonly => true, :onchange => "regexDeadLine();") %> - <%= calendar_for('bid_deadline')%> - - -

    -

    - <%= f.select :is_evaluation, is_evaluation_option %> -

    -

    - <%= f.select :proportion, proportion_option %> -

    -

    - <%= hidden_field_tag 'course_id', @course.id %> -

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

    - <%= render :partial => 'attachments/form', :locals => {:container => @bid} %> -

    + + + + +<%= error_messages_for 'bid' %> +

    + <%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :onblur => "regexName();" %> +

    +

    + +

    + +

    + <%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT %> +

    +

    + <%= f.text_field(:deadline, :required => true, :size => 60, :style => "width:150px;", :readonly => true, :onchange => "regexDeadLine();") %> + <%= calendar_for('bid_deadline')%> + + +

    +

    + <%= f.select :is_evaluation, is_evaluation_option %> +

    +

    + <%= f.select :proportion, proportion_option %> +

    +

    + <%= hidden_field_tag 'course_id', @course.id %> +

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

    + <%= render :partial => 'attachments/form', :locals => {:container => @bid} %> +

    \ No newline at end of file diff --git a/app/views/bids/_new_bid.html.erb b/app/views/bids/_new_bid.html.erb index db1387a00..02546e9a9 100644 --- a/app/views/bids/_new_bid.html.erb +++ b/app/views/bids/_new_bid.html.erb @@ -1,82 +1,82 @@ - - - - - -<%= form_tag({:controller => 'bids', -:action => 'new_bid', -:remote => true, -:method => :post, -:id => 'new-bid-form'}) do %> - - - - - - - - - - - - - - - - - - - - - - - - -
    <%= text_field_tag 'bid_title', "#{l(:label_requirement_name)}", :class => 'noline', :required => true, :onfocus => "clearInfo('bid_title', '#{l(:label_requirement_name)}')", :onblur => "showInfo('bid_title', '#{l(:label_requirement_name)}')"%>
    <%= text_area_tag 'bid_description', "#{l(:label_requirement_description)}", :class => 'noline', :required => true, :style => "resize: none;", :rows => 6, - :onfocus => "clearInfo('bid_description', '#{l(:label_requirement_description)}')", :onblur => "showInfo('bid_description', '#{l(:label_requirement_description)}')" %>
    <%= select_tag 'bid_reward_type', "".html_safe, :class => 'noline' %><%= text_field_tag 'bid_budget', "#{l(:label_requirement_bargain_money)}", :class => 'noline', :required => true, - :onfocus => "clearInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')", :onblur => "showInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')" %> -
    <%= text_field_tag 'bid_deadline', "#{l(:label_deadline)}", :class => 'noline', :required => true, - :onfocus => "clearInfo('bid_deadline', '#{l(:label_deadline)}')", :readonly => true, :onblur => "showInfo('bid_deadline', '#{l(:label_deadline)}')"%> - <%= calendar_for('bid_deadline')%>
    - - - - - -
    <%= submit_tag l(:button_new_bid), :name => nil , :class => "bid_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'"%>
    + + + + + +<%= form_tag({:controller => 'bids', +:action => 'new_bid', +:remote => true, +:method => :post, +:id => 'new-bid-form'}) do %> + + + + + + + + + + + + + + + + + + + + + + + + +
    <%= text_field_tag 'bid_title', "#{l(:label_requirement_name)}", :class => 'noline', :required => true, :onfocus => "clearInfo('bid_title', '#{l(:label_requirement_name)}')", :onblur => "showInfo('bid_title', '#{l(:label_requirement_name)}')"%>
    <%= text_area_tag 'bid_description', "#{l(:label_requirement_description)}", :class => 'noline', :required => true, :style => "resize: none;", :rows => 6, + :onfocus => "clearInfo('bid_description', '#{l(:label_requirement_description)}')", :onblur => "showInfo('bid_description', '#{l(:label_requirement_description)}')" %>
    <%= select_tag 'bid_reward_type', "".html_safe, :class => 'noline' %><%= text_field_tag 'bid_budget', "#{l(:label_requirement_bargain_money)}", :class => 'noline', :required => true, + :onfocus => "clearInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')", :onblur => "showInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')" %> +
    <%= text_field_tag 'bid_deadline', "#{l(:label_deadline)}", :class => 'noline', :required => true, + :onfocus => "clearInfo('bid_deadline', '#{l(:label_deadline)}')", :readonly => true, :onblur => "showInfo('bid_deadline', '#{l(:label_deadline)}')"%> + <%= calendar_for('bid_deadline')%>
    + + + + + +
    <%= submit_tag l(:button_new_bid), :name => nil , :class => "bid_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'"%>
    <%end%> \ No newline at end of file diff --git a/app/views/bids/edit.html.erb b/app/views/bids/edit.html.erb index b02898353..fd21872b0 100644 --- a/app/views/bids/edit.html.erb +++ b/app/views/bids/edit.html.erb @@ -1,60 +1,60 @@ - - -

    <%= l(:label_edit_homework) %>

    - -<%= labelled_form_for @bid do |f| %> -
    - <%#= render :partial => 'homework_form', :locals => { :f => f } %> - <%= render :partial => 'homework_form', :locals => { :f => f } %> - - <% end %> + + +

    <%= l(:label_edit_homework) %>

    + +<%= labelled_form_for @bid do |f| %> +
    + <%#= render :partial => 'homework_form', :locals => { :f => f } %> + <%= render :partial => 'homework_form', :locals => { :f => f } %> + + <% end %>
    \ No newline at end of file diff --git a/app/views/bids/show.html.erb b/app/views/bids/show.html.erb index 5545a8c14..31baac38d 100644 --- a/app/views/bids/show.html.erb +++ b/app/views/bids/show.html.erb @@ -1,36 +1,36 @@ -<% reply_allow = JournalsForMessage.create_by_user? User.current %> -
    - <%= image_tag(url_to_avatar(@bid.author), :class => "avatar")%> - -

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

    - <% if @bid.reward_type.nil? or @bid.reward_type == 1%> -

    - <%= l(:label_bids_reward_method) %><%= l(:label_call_bonus) %>  <%= l(:label_RMB_sign) %><%= @bid.budget %> -

    - <% elsif @bid.reward_type == 2%> -

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

    - <% else %> - <% end %> -
    - <%= textilizable(@bid, :description) %> - <% if @bid.attachments.any?%> - <% options = {:author => true,:deletable => (@bid.author.id == User.current.id || User.current.admin? ? true : false)} %> - <%= render :partial => 'attachments/links', :locals => {:attachments => @bid.attachments, :options => options} %> - <% end %> -
    -
    -
    -
    - -
    - <%= render :partial => 'history', :locals => { :bid => @bid, :journals => @jour, :state => false} %> -
    - - - +<% reply_allow = JournalsForMessage.create_by_user? User.current %> +
    + <%= image_tag(url_to_avatar(@bid.author), :class => "avatar")%> + +

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

    + <% if @bid.reward_type.nil? or @bid.reward_type == 1%> +

    + <%= l(:label_bids_reward_method) %><%= l(:label_call_bonus) %>  <%= l(:label_RMB_sign) %><%= @bid.budget %> +

    + <% elsif @bid.reward_type == 2%> +

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

    + <% else %> + <% end %> +
    + <%= textilizable(@bid, :description) %> + <% if @bid.attachments.any?%> + <% options = {:author => true,:deletable => (@bid.author.id == User.current.id || User.current.admin? ? true : false)} %> + <%= render :partial => 'attachments/links', :locals => {:attachments => @bid.attachments, :options => options} %> + <% end %> +
    +
    +
    +
    + +
    + <%= render :partial => 'history', :locals => { :bid => @bid, :journals => @jour, :state => false} %> +
    + + + diff --git a/app/views/calendars/show.html.erb b/app/views/calendars/show.html.erb index 65b740203..dae061251 100644 --- a/app/views/calendars/show.html.erb +++ b/app/views/calendars/show.html.erb @@ -1,40 +1,40 @@ -

    <%= @query.new_record? ? l(:label_calendar) : h(@query.name) %>

    - -<%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project}, - :method => :get, :id => 'query_form') do %> - <%= hidden_field_tag 'set_filter', '1' %> -
    "> - <%= l(:label_filter_plural) %> -
    "> - <%= render :partial => 'queries/filters', :locals => {:query => @query} %> -
    -
    -

    - <%= link_to_previous_month(@year, @month) %> | <%= link_to_next_month(@year, @month) %> -

    -

    - <%= label_tag('month', l(:label_month)) %> - <%= select_month(@month, :prefix => "month", :discard_type => true) %> - <%= label_tag('year', l(:label_year)) %> - <%= select_year(@year, :prefix => "year", :discard_type => true) %> - - <%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %> - <%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 }, :class => 'icon icon-reload' %> -

    -<% end %> - -<%= error_messages_for 'query' %> -<% if @query.valid? %> - <%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %> -

    - <%= l(:text_tip_issue_begin_day) %> - <%= l(:text_tip_issue_end_day) %> - <%= l(:text_tip_issue_begin_end_day) %> -

    -<% end %> - -<% content_for :sidebar do %> - <%= render :partial => 'issues/sidebar' %> -<% end %> - -<% html_title(l(:label_calendar)) -%> +

    <%= @query.new_record? ? l(:label_calendar) : h(@query.name) %>

    + +<%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project}, + :method => :get, :id => 'query_form') do %> + <%= hidden_field_tag 'set_filter', '1' %> +
    "> + <%= l(:label_filter_plural) %> +
    "> + <%= render :partial => 'queries/filters', :locals => {:query => @query} %> +
    +
    +

    + <%= link_to_previous_month(@year, @month) %> | <%= link_to_next_month(@year, @month) %> +

    +

    + <%= label_tag('month', l(:label_month)) %> + <%= select_month(@month, :prefix => "month", :discard_type => true) %> + <%= label_tag('year', l(:label_year)) %> + <%= select_year(@year, :prefix => "year", :discard_type => true) %> + + <%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %> + <%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 }, :class => 'icon icon-reload' %> +

    +<% end %> + +<%= error_messages_for 'query' %> +<% if @query.valid? %> + <%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %> +

    + <%= l(:text_tip_issue_begin_day) %> + <%= l(:text_tip_issue_end_day) %> + <%= l(:text_tip_issue_begin_end_day) %> +

    +<% end %> + +<% content_for :sidebar do %> + <%= render :partial => 'issues/sidebar' %> +<% end %> + +<% html_title(l(:label_calendar)) -%> diff --git a/app/views/common/403.html b/app/views/common/403.html index 826d43067..f3696c4ea 100644 --- a/app/views/common/403.html +++ b/app/views/common/403.html @@ -1,41 +1,41 @@ - - - - -没有访问权限 - - - - - -
    -
    403
    -
    -

    ERROR FORBIDDEN
    - 没有访问权限!建议您

    - -
    - -
    - - + + + + +没有访问权限 + + + + + +
    +
    403
    +
    +

    ERROR FORBIDDEN
    + 没有访问权限!建议您

    + +
    + +
    + + diff --git a/app/views/common/404.html b/app/views/common/404.html index ce92d7e4c..8453e0a41 100644 --- a/app/views/common/404.html +++ b/app/views/common/404.html @@ -1,41 +1,41 @@ - - - - -页面不见了 - - - - - -
    -
    404
    -
    -

    ERROR PAGE
    - 页面不见了!建议您

    - -
    - -
    - - + + + + +页面不见了 + + + + + +
    +
    404
    +
    +

    ERROR PAGE
    + 页面不见了!建议您

    + +
    + +
    + + diff --git a/app/views/common/_calendar.html.erb b/app/views/common/_calendar.html.erb index 83f8e217b..e4ce4da2c 100644 --- a/app/views/common/_calendar.html.erb +++ b/app/views/common/_calendar.html.erb @@ -1,38 +1,38 @@ - - - - - <% 7.times do |i| %> - - <% end %> - - - - - <% day = calendar.startdt - while day <= calendar.enddt %> - <%= ("".html_safe) if day.cwday == calendar.first_wday %> - - <%= ''.html_safe if day.cwday==calendar.last_wday and day!=calendar.enddt %> - <% day = day + 1 - end %> - - -
    <%= day_name( (calendar.first_wday+i)%7 ) %>
    #{(day+(11-day.cwday)%7).cweek} -

    <%= day.day %>

    - <% calendar.events_on(day).each do |i| %> - <% if i.is_a? Issue %> -
    - <%= h("#{i.project} -") unless @project && @project == i.project %> - <%= link_to_issue i, :truncate => 30 %> - <%= render_issue_tooltip i %> -
    - <% else %> - - <%= h("#{i.project} -") unless @project && @project == i.project %> - <%= link_to_version i%> - - <% end %> - <% end %> -
    + + + + + <% 7.times do |i| %> + + <% end %> + + + + + <% day = calendar.startdt + while day <= calendar.enddt %> + <%= ("".html_safe) if day.cwday == calendar.first_wday %> + + <%= ''.html_safe if day.cwday==calendar.last_wday and day!=calendar.enddt %> + <% day = day + 1 + end %> + + +
    <%= day_name( (calendar.first_wday+i)%7 ) %>
    #{(day+(11-day.cwday)%7).cweek} +

    <%= day.day %>

    + <% calendar.events_on(day).each do |i| %> + <% if i.is_a? Issue %> +
    + <%= h("#{i.project} -") unless @project && @project == i.project %> + <%= link_to_issue i, :truncate => 30 %> + <%= render_issue_tooltip i %> +
    + <% else %> + + <%= h("#{i.project} -") unless @project && @project == i.project %> + <%= link_to_version i%> + + <% end %> + <% end %> +
    diff --git a/app/views/common/_preview.html.erb b/app/views/common/_preview.html.erb index cf26d78ab..2d1bce459 100644 --- a/app/views/common/_preview.html.erb +++ b/app/views/common/_preview.html.erb @@ -1,3 +1,3 @@ -
    <%= l(:label_preview) %> - <%= textilizable @text, :attachments => @attachments, :object => @previewed %> -
    +
    <%= l(:label_preview) %> + <%= textilizable @text, :attachments => @attachments, :object => @previewed %> +
    diff --git a/app/views/contestnotifications/edit.html.erb b/app/views/contestnotifications/edit.html.erb index 22f484724..53536aaaf 100644 --- a/app/views/contestnotifications/edit.html.erb +++ b/app/views/contestnotifications/edit.html.erb @@ -1,18 +1,18 @@ -

    <%=l(:label_edit_contest_notice)%>

    - -<%= 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' -%> -<% end %> -
    - -<% content_for :header_tags do %> - <%= stylesheet_link_tag 'scm' %> +

    <%=l(:label_edit_contest_notice)%>

    + +<%= 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' +%> +<% end %> +
    + +<% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> <% end %> \ No newline at end of file diff --git a/app/views/contestnotifications/index.html.erb b/app/views/contestnotifications/index.html.erb index 8a4278551..526884f49 100644 --- a/app/views/contestnotifications/index.html.erb +++ b/app/views/contestnotifications/index.html.erb @@ -1,123 +1,123 @@ - - <%= l(:label_notification) %> - -<% if User.current.logged? && (User.current.admin? ||User.current == @contest.author) %> -<%= link_to(l(:bale_news_notice), - new_contest_contestnotification_path(@contest), - :class => 'icon icon-add', - :onclick => 'showAndScrollTo("add-contestnotifications", "contestnotifications_title"); return false;') %> -<% end %> -<% if @contest %> - -<% end %> -
    - -
    - - <%= image_tag(url_to_avatar(@contest.author), :class => "avatar")%> - - -

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

    -

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

    -
    - <%= @contest.description %> -
    - - <%= render :partial => "/praise_tread/praise_tread", - :locals => {:obj => @contest, - :show_flag => true, - :user_id =>User.current.id, - :horizontal => false} - %> - -
    -
    - -
    - -

    - <% @contestnotificationss.each do |contestnotifications| %> - - - - - -
    <%= link_to image_tag(url_to_avatar(contestnotifications.author), :class => "avatar"), user_path(contestnotifications.author) %> - - - - - - - - - - - - -
    - <%= link_to_user(contestnotifications.author) if contestnotifications.respond_to?(:author) %> - <%= l(:label_project_notice) %><%= link_to h(contestnotifications.title), contest_contestnotification_path(@contest, contestnotifications) %> - - <%= link_to l(:button_edit), edit_contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> - <%= delete_link contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> - -
    - <%= textilizable(contestnotifications, :description) %>
    <%= l :label_update_time %> -  <%= format_time(contestnotifications.created_at) %><%= link_to l(:label_check_comment), contest_contestnotification_path(@contest, contestnotifications) %><%#= "(#{l(:label_x_comments, :count => contestnotifications.notificationcomments_count)})" if contestnotifications.notificationcomments_count >= 0 %>
    -
    - <% end %> - -
    - -
    - - - <% content_for :header_tags do %> - <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> - <%= stylesheet_link_tag 'scm' %> - <% end %> - - <% html_title(l(:label_contest_notification)) -%> -
    - - - + + <%= l(:label_notification) %> + +<% if User.current.logged? && (User.current.admin? ||User.current == @contest.author) %> +<%= link_to(l(:bale_news_notice), + new_contest_contestnotification_path(@contest), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-contestnotifications", "contestnotifications_title"); return false;') %> +<% end %> +<% if @contest %> + +<% end %> +
    + +
    + + <%= image_tag(url_to_avatar(@contest.author), :class => "avatar")%> + + +

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

    +

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

    +
    + <%= @contest.description %> +
    + + <%= render :partial => "/praise_tread/praise_tread", + :locals => {:obj => @contest, + :show_flag => true, + :user_id =>User.current.id, + :horizontal => false} + %> + +
    +
    + +
    + +

    + <% @contestnotificationss.each do |contestnotifications| %> + + + + + +
    <%= link_to image_tag(url_to_avatar(contestnotifications.author), :class => "avatar"), user_path(contestnotifications.author) %> + + + + + + + + + + + + +
    + <%= link_to_user(contestnotifications.author) if contestnotifications.respond_to?(:author) %> + <%= l(:label_project_notice) %><%= link_to h(contestnotifications.title), contest_contestnotification_path(@contest, contestnotifications) %> + + <%= link_to l(:button_edit), edit_contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> + <%= delete_link contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> + +
    + <%= textilizable(contestnotifications, :description) %>
    <%= l :label_update_time %> +  <%= format_time(contestnotifications.created_at) %><%= link_to l(:label_check_comment), contest_contestnotification_path(@contest, contestnotifications) %><%#= "(#{l(:label_x_comments, :count => contestnotifications.notificationcomments_count)})" if contestnotifications.notificationcomments_count >= 0 %>
    +
    + <% end %> + +
    + +
    + + + <% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> + <%= stylesheet_link_tag 'scm' %> + <% end %> + + <% html_title(l(:label_contest_notification)) -%> +
    + + + \ No newline at end of file diff --git a/app/views/contests/_form_contest.html.erb b/app/views/contests/_form_contest.html.erb index ffd273db9..ec993fae8 100644 --- a/app/views/contests/_form_contest.html.erb +++ b/app/views/contests/_form_contest.html.erb @@ -1,75 +1,75 @@ - - -<%= 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)}" - %> -

    - -

    - <%= 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_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;", - :readonly => true, - :placeholder => "#{l(:label_deadline)}" - %> - <%= calendar_for('contest_deadline')%> -

    + + +<%= 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)}" + %> +

    + +

    + <%= 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_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;", + :readonly => true, + :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 b62f91146..73d71c0d0 100644 --- a/app/views/contests/_history.html.erb +++ b/app/views/contests/_history.html.erb @@ -1,79 +1,79 @@ -<% reply_allow = JournalsForMessage.create_by_user? User.current %> -<% tip1 = l(:label_user_response) %> -

    <%=tip1%>

    - -
    - <%= render :partial => 'new', :locals => {:contest => @contest, :sta => @state} %> -
    - - -<% if journals.size >0 %> -
      - <% 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), - 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}: '); $('##{ids} textarea') ;return false;" - } - %> - <% end %> - - <% if @user==User.current|| User.current.admin? %> - <%= 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} - %> -
      - <% end %> -
      -
      - <%= render :partial => "words/journal_reply", :locals => {:journal => journal } %> -
      -
    • - <% end %> -
    -<% end %> +<% reply_allow = JournalsForMessage.create_by_user? User.current %> +<% tip1 = l(:label_user_response) %> +

    <%=tip1%>

    + +
    + <%= render :partial => 'new', :locals => {:contest => @contest, :sta => @state} %> +
    + + +<% if journals.size >0 %> +
      + <% 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), + 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}: '); $('##{ids} textarea') ;return false;" + } + %> + <% end %> + + <% if @user==User.current|| User.current.admin? %> + <%= 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} + %> +
      + <% end %> +
      +
      + <%= render :partial => "words/journal_reply", :locals => {:journal => journal } %> +
      +
    • + <% end %> +
    +<% end %> diff --git a/app/views/contests/new_contest.html.erb b/app/views/contests/new_contest.html.erb index 9aa70d370..71c12fad4 100644 --- a/app/views/contests/new_contest.html.erb +++ b/app/views/contests/new_contest.html.erb @@ -1,13 +1,13 @@ - -

    <%=l(:label_newtype_contest)%>

    - -<%= 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 %> -
    + +

    <%=l(:label_newtype_contest)%>

    + +<%= 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 %> +
    <% html_title(l(:label_newtype_contest)) -%> \ No newline at end of file diff --git a/app/views/contests/show_attendingcontest.html.erb b/app/views/contests/show_attendingcontest.html.erb index 053630a8e..afdb96574 100644 --- a/app/views/contests/show_attendingcontest.html.erb +++ b/app/views/contests/show_attendingcontest.html.erb @@ -1,315 +1,315 @@ - - - -<%= render_flash_messages %> - -
    -
    - <%= 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();" - %> - -
    -
    -
    - <%= render "new_softapplication" %> -
    - -<% else %> -
    - <%= l(:label_user_login_attending_contest) %> - <%= link_to l(:label_user_login_new), signin_path %> -
    -<% end %> -
    - - - -<% if @contest.id == 2 or @contest.id == 3 or @contest.id == 6 %> - - <% @contesting_project.sort.reverse.each do |c_project| %> - <% if c_project.project %> -
    -
    -
    -
    <%= l(:label_contest_work) %> - : <%= link_to(c_project.project.name, project_path(c_project.project), :target => '_blank') %> - -
    - - - - <% if get_prize(c_project).nil? or get_prize(c_project) == "" %> - <% if @contest.deadline < Date.today %> - <%= l(:label_noawards) %> - <% else %> - <%= l(:label_noawards_current) %> - <% end %> - <% else %> - <% case get_prize(c_project) %> - <% 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 %> - - - - - - <% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %> - - <%= toggle_link l(:label_reward), c_project.id.to_s %> - - - - <% end %> -
    -
    -
    -
    -
    -
    - - <%= l(:label_profile) %>: - - <%#= c_project.project.description.truncate(90, omission: '...') %> - <%= c_project.project.description %> - - -
    -
    -
    - <%= l(:label_attendingcontest_time) %> - :<%= format_time c_project.created_at %> - <%= l(:label_attendingcontest_spoksman) %> - - <% unless c_project.nil? || c_project.user.nil? %> - :<%= link_to c_project.user.name,user_path(c_project.user) %> - <% end %> -
    - -
    - -
    -
    - <% end %> -
    - <% end %> -<% else %> - <% @contesting_softapplication.each do |c_softapplication| %> - <% if c_softapplication.softapplication %> -
    -
    - - <%= l(:label_contest_work) %>: - <%= link_to(c_softapplication.softapplication.name, softapplication_path(c_softapplication.softapplication), :target => '_blank') %> - -
    -
    - -
    - - <%= l(:label_profile) %>: - - <%#= c_softapplication.softapplication.description.truncate(90, omission: '...') %> - <%= c_softapplication.softapplication.description %> - - -
    -
    - -
    - <%= l(:label_attendingcontest_time) %> - :<%= format_time c_softapplication.created_at %> - <%= l(:label_attendingcontest_spoksman) %> - - <% unless c_softapplication.nil? || c_softapplication.softapplication.nil? || c_softapplication.softapplication.user.nil? %> - :<%= link_to c_softapplication.softapplication.user.name,user_path(c_softapplication.softapplication.user) %> - <% end %> -
    - - -
    - <% score = c_softapplication.softapplication.average(:quality).try(:avg).try(:round, 2).to_f %> - <%= l(:label_final_scores) %> - :<%= format("%.2f" , score) %> - 分 - - - - - <% if get_prize(c_softapplication).nil? or get_prize(c_softapplication) == "" %> - <% if @contest.deadline < Date.today %> - <%= l(:label_noawards) %> - <% else %> - <%= l(:label_noawards_current) %> - <% end %> - <% else %> - <% case get_prize(c_softapplication) %> - <% 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 %> - - - - - - <% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %> -
    - <%= toggle_link '评奖', c_softapplication.id.to_s %> - - -
    - <% end %> -
    -
    -
    - <% end %> -
    - <% end %> -<% end %> - - -<% html_title(l(:label_contest_joincontest)) -%> + + + +<%= render_flash_messages %> + +
    +
    + <%= 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();" + %> + +
    +
    +
    + <%= render "new_softapplication" %> +
    + +<% else %> +
    + <%= l(:label_user_login_attending_contest) %> + <%= link_to l(:label_user_login_new), signin_path %> +
    +<% end %> +
    + + + +<% if @contest.id == 2 or @contest.id == 3 or @contest.id == 6 %> + + <% @contesting_project.sort.reverse.each do |c_project| %> + <% if c_project.project %> +
    +
    +
    +
    <%= l(:label_contest_work) %> + : <%= link_to(c_project.project.name, project_path(c_project.project), :target => '_blank') %> + +
    + + + + <% if get_prize(c_project).nil? or get_prize(c_project) == "" %> + <% if @contest.deadline < Date.today %> + <%= l(:label_noawards) %> + <% else %> + <%= l(:label_noawards_current) %> + <% end %> + <% else %> + <% case get_prize(c_project) %> + <% 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 %> + + + + + + <% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %> + + <%= toggle_link l(:label_reward), c_project.id.to_s %> + + + + <% end %> +
    +
    +
    +
    +
    +
    + + <%= l(:label_profile) %>: + + <%#= c_project.project.description.truncate(90, omission: '...') %> + <%= c_project.project.description %> + + +
    +
    +
    + <%= l(:label_attendingcontest_time) %> + :<%= format_time c_project.created_at %> + <%= l(:label_attendingcontest_spoksman) %> + + <% unless c_project.nil? || c_project.user.nil? %> + :<%= link_to c_project.user.name,user_path(c_project.user) %> + <% end %> +
    + +
    + +
    +
    + <% end %> +
    + <% end %> +<% else %> + <% @contesting_softapplication.each do |c_softapplication| %> + <% if c_softapplication.softapplication %> +
    +
    + + <%= l(:label_contest_work) %>: + <%= link_to(c_softapplication.softapplication.name, softapplication_path(c_softapplication.softapplication), :target => '_blank') %> + +
    +
    + +
    + + <%= l(:label_profile) %>: + + <%#= c_softapplication.softapplication.description.truncate(90, omission: '...') %> + <%= c_softapplication.softapplication.description %> + + +
    +
    + +
    + <%= l(:label_attendingcontest_time) %> + :<%= format_time c_softapplication.created_at %> + <%= l(:label_attendingcontest_spoksman) %> + + <% unless c_softapplication.nil? || c_softapplication.softapplication.nil? || c_softapplication.softapplication.user.nil? %> + :<%= link_to c_softapplication.softapplication.user.name,user_path(c_softapplication.softapplication.user) %> + <% end %> +
    + + +
    + <% score = c_softapplication.softapplication.average(:quality).try(:avg).try(:round, 2).to_f %> + <%= l(:label_final_scores) %> + :<%= format("%.2f" , score) %> + 分 + + + + + <% if get_prize(c_softapplication).nil? or get_prize(c_softapplication) == "" %> + <% if @contest.deadline < Date.today %> + <%= l(:label_noawards) %> + <% else %> + <%= l(:label_noawards_current) %> + <% end %> + <% else %> + <% case get_prize(c_softapplication) %> + <% 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 %> + + + + + + <% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %> +
    + <%= toggle_link '评奖', c_softapplication.id.to_s %> + + +
    + <% end %> +
    +
    +
    + <% end %> +
    + <% end %> +<% end %> + + +<% html_title(l(:label_contest_joincontest)) -%> diff --git a/app/views/contests/show_contest.html.erb b/app/views/contests/show_contest.html.erb index c9ba360cc..be98c10ac 100644 --- a/app/views/contests/show_contest.html.erb +++ b/app/views/contests/show_contest.html.erb @@ -1,15 +1,15 @@ -<% reply_allow = JournalsForMessage.create_by_user? User.current %> - - -
    - <%= render :partial => 'history', - :locals => { :contest => @contest, :journals => @jour, :state => false} - %> -
    - - -<% html_title(l(:label_user_response)) -%> +<% reply_allow = JournalsForMessage.create_by_user? User.current %> + + +
    + <%= render :partial => 'history', + :locals => { :contest => @contest, :journals => @jour, :state => false} + %> +
    + + +<% html_title(l(:label_user_response)) -%> diff --git a/app/views/contests/show_participator.html.erb b/app/views/contests/show_participator.html.erb deleted file mode 100644 index c20d9dc7c..000000000 --- a/app/views/contests/show_participator.html.erb +++ /dev/null @@ -1,83 +0,0 @@ - -

    - <%=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 %> -
      -
    • - - - - - - -
      - <%= link_to image_tag(url_to_avatar(user), :class => "avatar"), - user_path(user), - :title => "#{user.show_name}" - %> - - - - - - - - - - - - - - - -
      - <%= content_tag "div", - link_to(user.show_name, user_path(user)), - :class => "project_avatar_name" , - :title => "#{user.show_name}" - %> - - <% if (im_watching_student_id? @contest) && user.user_extensions.identity.to_i.eql?(1) %> - <%= l(:label_bidding_user_studentcode) %> :<%= user.user_extensions.student_id%> - <% end %> -
      -

      - <% unless user.memberships.empty? %> - <% cond = Project.visible_condition(User.current) + "AND projects.project_type <> 1" %> - <% memberships = user.memberships.all(:conditions => cond) %> - <%= l(:label_x_contribute_to, :count => memberships.count) %> - <% - links = Array.new - memberships.collect{|member| links << link_to_project(member.project) } - %> - - <%= raw links.join(" , ") %> - <% end %> -

      - - - -
      - <%= l(:label_user_joinin) %><%= format_date(user.created_on) %> -
      -
      -
    • -
    - <% end %> -
    \ No newline at end of file diff --git a/app/views/contests/show_project.html.erb b/app/views/contests/show_project.html.erb deleted file mode 100644 index 84dfbbbc2..000000000 --- a/app/views/contests/show_project.html.erb +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - <% if User.current.logged? %> - - - - <% end %> -
    - <%= render :partial => 'project_list', - :locals => {:contesting_project => @contesting_project,:contest => @contest} - %> -
    - - diff --git a/app/views/contests/watcherlist.html.erb b/app/views/contests/watcherlist.html.erb new file mode 100644 index 000000000..4987f3616 --- /dev/null +++ b/app/views/contests/watcherlist.html.erb @@ -0,0 +1,34 @@ + +

    <%= l(:label_user_watcher)%>

    +
    + <% @contest.watcher_users.each do |user| %> +
      +
    • + + + + + +
      <%= image_tag(url_to_avatar(user), :class => "avatar") %> + + + + + + + + + +

      <%= content_tag "div", link_to_user(user), :class =>"project_avatar_name" %>

      +

      + <% unless user.memberships.empty? %> + <%= l(:label_contribute_to, :project_count => "#{user.memberships.count}") %> + <% for member in user.memberships %> + <%= link_to_project(member.project) %><%= (user.memberships.last == member) ? '' : ',' %> + <% end %> + <% end %> +

      <%= l(:label_user_joinin) %><%= format_date(user.created_on) %> +
    + <% end %> +
    +<% html_title(l(:label_followers)) -%> \ No newline at end of file diff --git a/app/views/courses/_homework_form.html.erb b/app/views/courses/_homework_form.html.erb index 7d1171116..053a9c7c4 100644 --- a/app/views/courses/_homework_form.html.erb +++ b/app/views/courses/_homework_form.html.erb @@ -1,60 +1,60 @@ - - - - -<%= error_messages_for 'bid' %> -

    - <%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", - :maxlength => Bid::NAME_LENGTH_LIMIT, - :onblur => "regexName();" %> - -

    -

    - -

    - -

    - <%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;", - :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT %> -

    -<% time = (Time.now + 3600 * 24).strftime('%Y-%m-%d') %> -

    <%= f.text_field(:deadline, :required => true, :size => 60, :style => "width:150px;",:value => "#{time}", :onchange => "regexDeadLine();", :readonly => true) %> - <%= calendar_for('bid_deadline')%> - - -

    -

    - <%= f.select :is_evaluation, is_evaluation_option %> -

    -

    - <%= f.select :proportion, proportion_option %> -

    -

    - <%= hidden_field_tag 'course_id', @course.id %> -

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

    - <%= render :partial => 'attachments/form', :locals => {:container => @homework} %> -

    + + + + +<%= error_messages_for 'bid' %> +

    + <%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", + :maxlength => Bid::NAME_LENGTH_LIMIT, + :onblur => "regexName();" %> + +

    +

    + +

    + +

    + <%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;", + :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT %> +

    +<% time = (Time.now + 3600 * 24).strftime('%Y-%m-%d') %> +

    <%= f.text_field(:deadline, :required => true, :size => 60, :style => "width:150px;",:value => "#{time}", :onchange => "regexDeadLine();", :readonly => true) %> + <%= calendar_for('bid_deadline')%> + + +

    +

    + <%= f.select :is_evaluation, is_evaluation_option %> +

    +

    + <%= f.select :proportion, proportion_option %> +

    +

    + <%= hidden_field_tag 'course_id', @course.id %> +

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

    + <%= render :partial => 'attachments/form', :locals => {:container => @homework} %> +

    \ No newline at end of file diff --git a/app/views/courses/_join_private_course.html.erb b/app/views/courses/_join_private_course.html.erb index 2d36e2ece..509173352 100644 --- a/app/views/courses/_join_private_course.html.erb +++ b/app/views/courses/_join_private_course.html.erb @@ -1,75 +1,75 @@ - - - - - 快速进入课程通道 - - - - - -
    -
    -
    -

    快速进入课程通道

    -

    只要持有课程ID和密码,就课快速加入所在课程。课程页面搜索不到的私有课程只能从此通道进入哦!

    -
    -
    - <%= form_tag({:controller => 'courses', - :action => 'join'}, - :remote => true, - :method => :post, - :id => 'new-watcher-form') do %> - - <% end%> -
    -
    -
    - - - + + + + + 快速进入课程通道 + + + + + +
    +
    +
    +

    快速进入课程通道

    +

    只要持有课程ID和密码,就课快速加入所在课程。课程页面搜索不到的私有课程只能从此通道进入哦!

    +
    +
    + <%= form_tag({:controller => 'courses', + :action => 'join'}, + :remote => true, + :method => :post, + :id => 'new-watcher-form') do %> + + <% end%> +
    +
    +
    + + + diff --git a/app/views/courses/_set_join.js.erb b/app/views/courses/_set_join.js.erb index c125e34bc..39e40d34e 100644 --- a/app/views/courses/_set_join.js.erb +++ b/app/views/courses/_set_join.js.erb @@ -1,20 +1,20 @@ -<% if object_id%> - $("#<%=object_id%>").replaceWith('<%= escape_javascript join_in_course_for_list(course, user) %>'); -<% end %> -<% if @state %> - <% if @state == 0 %> - alert("加入成功"); - <% elsif @state == 1 %> - alert("密码错误"); - <% elsif @state == 2 %> - alert("课程已过期\n请联系课程管理员重启课程。(在配置课程处)"); - <% elsif @state == 3 %> - alert("您已经加入了课程"); - <% elsif @state == 4 %> - alert("您加入的课程不存在"); - <% elsif @state == 5 %> - alert("您还未登录"); - <% else %> - alert("未知错误,请稍后再试"); - <% end %> -<% end %> +<% if object_id%> + $("#<%=object_id%>").replaceWith('<%= escape_javascript join_in_course_for_list(course, user) %>'); +<% end %> +<% if @state %> + <% if @state == 0 %> + alert("加入成功"); + <% elsif @state == 1 %> + alert("密码错误"); + <% elsif @state == 2 %> + alert("课程已过期\n请联系课程管理员重启课程。(在配置课程处)"); + <% elsif @state == 3 %> + alert("您已经加入了课程"); + <% elsif @state == 4 %> + alert("您加入的课程不存在"); + <% elsif @state == 5 %> + alert("您还未登录"); + <% else %> + alert("未知错误,请稍后再试"); + <% end %> +<% end %> diff --git a/app/views/courses/homework.html.erb b/app/views/courses/homework.html.erb index 52d97cfbf..95e26abd0 100644 --- a/app/views/courses/homework.html.erb +++ b/app/views/courses/homework.html.erb @@ -1,60 +1,60 @@ - -<%= javascript_include_tag 'attachments' %> - - -
    - <% if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.nil? && (Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.roles&Role.where(id: [3, 4, 7, 9] )).size >0))%> - <%= link_to(l(:label_course_homework_new), {:controller => 'courses', :action => 'new_homework'}, :class => 'icon icon-add') %> - <% end %> -
    -
    - <%= render :partial => 'bids/bid_homework_show', :locals => {:bids => @bids, :bid_pages => @bid_pages} %> -
    - -
    -
    -
    -

    课程: <%= @course.name%>

    -

    上传作业

    - -
    -
    - -
    -
    -
    - - + +<%= javascript_include_tag 'attachments' %> + + +
    + <% if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.nil? && (Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.roles&Role.where(id: [3, 4, 7, 9] )).size >0))%> + <%= link_to(l(:label_course_homework_new), {:controller => 'courses', :action => 'new_homework'}, :class => 'icon icon-add') %> + <% end %> +
    +
    + <%= render :partial => 'bids/bid_homework_show', :locals => {:bids => @bids, :bid_pages => @bid_pages} %> +
    + +
    +
    +
    +

    课程: <%= @course.name%>

    +

    上传作业

    + +
    +
    + +
    +
    +
    + + <% html_title(l(:label_homework)) -%> \ No newline at end of file diff --git a/app/views/courses/join_private_courses.js.erb b/app/views/courses/join_private_courses.js.erb index 14a161907..7bbb5ee99 100644 --- a/app/views/courses/join_private_courses.js.erb +++ b/app/views/courses/join_private_courses.js.erb @@ -1,4 +1,4 @@ -$('#ajax-modal').html('<%= escape_javascript(render :partial => 'join_private_course') %>'); -showModal('ajax-modal', '510px'); -$('#ajax-modal').addClass('new-watcher'); +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'join_private_course') %>'); +showModal('ajax-modal', '510px'); +$('#ajax-modal').addClass('new-watcher'); $('#ajax-modal').css('height','330px'); \ No newline at end of file diff --git a/app/views/courses/search.html.erb b/app/views/courses/search.html.erb index e25cd5349..a06e4a459 100644 --- a/app/views/courses/search.html.erb +++ b/app/views/courses/search.html.erb @@ -1,66 +1,66 @@ -<% content_for :header_tags do %> -<%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %> -<% end %> -
    - <%= form_tag(:controller => 'courses', :action => 'search', :method => :get) do %> - - - - - - <% end %> - <% end %> - - - - - - - -
    <%= l(:label_course_practice) %><%= l(:label_user_location) %> : - <% 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) %> - -
    <%= link_to request.host() + "/courses", :controller => 'courses', :action => 'index'%> <%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %>
    - <% end %> -
    - -<% if @courses.size == 0 %> -<%= render :partial => 'layouts/no_content'%> -<% else %> -
    - <%= render_course_hierarchy(@courses)%> -
    -<% end %> - - - -<% if User.current.logged? %> -

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

    -<% end %> - -<%# other_formats_links do |f| %> -<%#= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> -<%# end %> - -<% content_for :sidebar do %> -<%= form_tag({}, :method => :get) do %> -

    <%= l(:label_project_plural) %>

    - -

    - <%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %> -

    -<% end %> -<% end %> - -<% html_title(l(:label_course_all)) -%> +<% content_for :header_tags do %> +<%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %> +<% end %> +
    + <%= form_tag(:controller => 'courses', :action => 'search', :method => :get) do %> + + + + + + <% end %> + <% end %> + + + + + + + +
    <%= l(:label_course_practice) %><%= l(:label_user_location) %> : + <% 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) %> + +
    <%= link_to request.host() + "/courses", :controller => 'courses', :action => 'index'%> <%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %>
    + <% end %> +
    + +<% if @courses.size == 0 %> +<%= render :partial => 'layouts/no_content'%> +<% else %> +
    + <%= render_course_hierarchy(@courses)%> +
    +<% end %> + + + +<% if User.current.logged? %> +

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

    +<% end %> + +<%# other_formats_links do |f| %> +<%#= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<%# end %> + +<% content_for :sidebar do %> +<%= form_tag({}, :method => :get) do %> +

    <%= l(:label_project_plural) %>

    + +

    + <%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %> +

    +<% end %> +<% end %> + +<% html_title(l(:label_course_all)) -%> diff --git a/app/views/files/index.html.erb b/app/views/files/index.html.erb index e3f022e37..9d6d9f2b3 100644 --- a/app/views/files/index.html.erb +++ b/app/views/files/index.html.erb @@ -1,248 +1,248 @@ - -<% if @isproject %> - <%= render :partial => 'project_file', locals: {project: @project} %> -<% else %> - <%= render :partial => 'course_file', locals: {course: @course} %> -<% end %> - - - - - - + +<% if @isproject %> + <%= render :partial => 'project_file', locals: {project: @project} %> +<% else %> + <%= render :partial => 'course_file', locals: {course: @course} %> +<% end %> + + + + + + diff --git a/app/views/forums/new.html.erb b/app/views/forums/new.html.erb index 2e8924c90..0d51db57a 100644 --- a/app/views/forums/new.html.erb +++ b/app/views/forums/new.html.erb @@ -4,7 +4,7 @@ @nav_dispaly_main_contest_label = 1 %> <% @nav_dispaly_forum_label = 1%> -

    <%= l :label_forum_new %>

    +

    <%= l :label_forum_new %>

    <%= render 'form' %> diff --git a/app/views/homework_attach/_app_link.html.erb b/app/views/homework_attach/_app_link.html.erb index 3aba96d27..1c089dbe0 100644 --- a/app/views/homework_attach/_app_link.html.erb +++ b/app/views/homework_attach/_app_link.html.erb @@ -1,15 +1,15 @@ -<% for attachment in attachments %> - <% if attachments.count > 1 && attachment != attachments.first%> -
                     - <% end %> - <%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%> - <% if attachment.is_text? %> - <%= link_to image_tag('magnifier.png'), - :controller => 'attachments', :action => 'show', - :id => attachment, :filename => attachment.filename %> - <% end %> - - <%= h(truncate(" - #{attachment.description}", length: 20, omission: '...')) unless attachment.description.blank? %> - - (<%= number_to_human_size attachment.filesize %>) - <% end -%> +<% for attachment in attachments %> + <% if attachments.count > 1 && attachment != attachments.first%> +
                     + <% end %> + <%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%> + <% if attachment.is_text? %> + <%= link_to image_tag('magnifier.png'), + :controller => 'attachments', :action => 'show', + :id => attachment, :filename => attachment.filename %> + <% end %> + + <%= h(truncate(" - #{attachment.description}", length: 20, omission: '...')) unless attachment.description.blank? %> + + (<%= number_to_human_size attachment.filesize %>) + <% end -%> diff --git a/app/views/homework_attach/_comprehensive_evaluation.html.erb b/app/views/homework_attach/_comprehensive_evaluation.html.erb index ac1793271..2fae3f3e0 100644 --- a/app/views/homework_attach/_comprehensive_evaluation.html.erb +++ b/app/views/homework_attach/_comprehensive_evaluation.html.erb @@ -1,31 +1,31 @@ -<% is_teacher = is_course_teacher User.current,homework.bid.courses.first %> - -
    -
    - <%= l(:lable_teacher_evaluation)%>: - <% if teaher_score != "0.00" %> - <%= render :partial => 'show_score', locals: {:stars => teaher_score} %> - <% end %> -
    -
    - <%= comprehensive_evaluation.first.notes if !comprehensive_evaluation.nil? && comprehensive_evaluation.count > 0%> -
    -
    - <% if(teaher_score == "0.00" && !(!comprehensive_evaluation.nil? && comprehensive_evaluation.count > 0))%> - <% if is_teacher %> - <%#= render :partial => 'teacher_evaluation', - :locals => {:homework => homework, :comprehensive_evaluation => comprehensive_evaluation} %> - <% else %> -
    - <%= l(:lable_teacher_evaluation_no) %> -
    - <% end %> - <% end %> -
    -
    - -
    - <% if is_teacher %> - <%= render :partial => 'teacher_evaluation',:locals => {:homework => homework} %> - <% end %> +<% is_teacher = is_course_teacher User.current,homework.bid.courses.first %> + +
    +
    + <%= l(:lable_teacher_evaluation)%>: + <% if teaher_score != "0.00" %> + <%= render :partial => 'show_score', locals: {:stars => teaher_score} %> + <% end %> +
    +
    + <%= comprehensive_evaluation.first.notes if !comprehensive_evaluation.nil? && comprehensive_evaluation.count > 0%> +
    +
    + <% if(teaher_score == "0.00" && !(!comprehensive_evaluation.nil? && comprehensive_evaluation.count > 0))%> + <% if is_teacher %> + <%#= render :partial => 'teacher_evaluation', + :locals => {:homework => homework, :comprehensive_evaluation => comprehensive_evaluation} %> + <% else %> +
    + <%= l(:lable_teacher_evaluation_no) %> +
    + <% end %> + <% end %> +
    +
    + +
    + <% if is_teacher %> + <%= render :partial => 'teacher_evaluation',:locals => {:homework => homework} %> + <% end %>
    \ No newline at end of file diff --git a/app/views/homework_attach/_evaluation.html.erb b/app/views/homework_attach/_evaluation.html.erb index 40996c787..9ec926035 100644 --- a/app/views/homework_attach/_evaluation.html.erb +++ b/app/views/homework_attach/_evaluation.html.erb @@ -1,4 +1,4 @@ -
    评分: - <%= rating_for homework, dimension: :quality, class: 'rateable div_inline' %> - (您可以对作业进行多次评价,以最后一次评价为最终结果) +
    评分: + <%= rating_for homework, dimension: :quality, class: 'rateable div_inline' %> + (您可以对作业进行多次评价,以最后一次评价为最终结果)
    \ No newline at end of file diff --git a/app/views/homework_attach/_evaluation_add_jour.html.erb b/app/views/homework_attach/_evaluation_add_jour.html.erb index 5103b50ae..0c94ce29e 100644 --- a/app/views/homework_attach/_evaluation_add_jour.html.erb +++ b/app/views/homework_attach/_evaluation_add_jour.html.erb @@ -1,97 +1,97 @@ - - - - -<%= form_for('new_form', :method => :post, - :url => {:controller => 'homework_attach', - :action => 'comprehensive_evaluation_jour', - :jour_id => homework_attach.id, - :is_comprehensive_evaluation => is_comprehensive_evaluation, - :sta => sta}) do |f|%> - -
    - <%= render :partial => 'words/pre_show', :locals => {:content => @content} %> -
    - - <% if User.current.logged? %> - - - - -
    - <%= f.text_area 'user_message', :rows => 3, :cols => 65, - :value => "#{comprehensive_evaluation.nil? ? l(:label_leave_a_message) : comprehensive_evaluation}", - :onfocus => "clearInfo('new_form_user_message','#{l(:label_leave_a_message)}')", - :onblur => "showInfo('new_form_user_message','#{l(:label_leave_a_message)}')", - :style => "resize: none;", :class => 'noline'%> -
    - <%= f.text_field :reference_user_id, :style=>"display:none"%> - - - - -
    <%= submit_tag l(:button_leave_meassge), - :name => nil , :class => "enterprise", - :onmouseout => "this.style.backgroundPosition = 'left top'", - :onmouseover => "this.style.backgroundPosition = 'left -31px'"%> - <%= submit_tag l(:button_clear_meassge), :name => nil, :class => "enterprise", - :onclick => "clearMessage('new_form_user_message');", - :onmouseout => "this.style.backgroundPosition = 'left top'", - :onmouseover => "this.style.backgroundPosition = 'left -31px'" %> -
    - <% else %> -
    - <%= l(:label_user_login_tips) %> - <%= link_to l(:label_user_login_new), signin_path %> -
    - <% end %> -<% end %> + + + + +<%= form_for('new_form', :method => :post, + :url => {:controller => 'homework_attach', + :action => 'comprehensive_evaluation_jour', + :jour_id => homework_attach.id, + :is_comprehensive_evaluation => is_comprehensive_evaluation, + :sta => sta}) do |f|%> + +
    + <%= render :partial => 'words/pre_show', :locals => {:content => @content} %> +
    + + <% if User.current.logged? %> + + + + +
    + <%= f.text_area 'user_message', :rows => 3, :cols => 65, + :value => "#{comprehensive_evaluation.nil? ? l(:label_leave_a_message) : comprehensive_evaluation}", + :onfocus => "clearInfo('new_form_user_message','#{l(:label_leave_a_message)}')", + :onblur => "showInfo('new_form_user_message','#{l(:label_leave_a_message)}')", + :style => "resize: none;", :class => 'noline'%> +
    + <%= f.text_field :reference_user_id, :style=>"display:none"%> + + + + +
    <%= submit_tag l(:button_leave_meassge), + :name => nil , :class => "enterprise", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -31px'"%> + <%= submit_tag l(:button_clear_meassge), :name => nil, :class => "enterprise", + :onclick => "clearMessage('new_form_user_message');", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -31px'" %> +
    + <% else %> +
    + <%= l(:label_user_login_tips) %> + <%= link_to l(:label_user_login_new), signin_path %> +
    + <% end %> +<% end %> diff --git a/app/views/homework_attach/_teacher_evaluation.html.erb b/app/views/homework_attach/_teacher_evaluation.html.erb index 485238416..03d8567ab 100644 --- a/app/views/homework_attach/_teacher_evaluation.html.erb +++ b/app/views/homework_attach/_teacher_evaluation.html.erb @@ -1,8 +1,8 @@ -<%= render :partial => 'evaluation', :locals => {:homework => homework} %> -
    - <%= render :partial => 'evaluation_add_jour', - :locals => {:homework_attach => homework, - :sta => 0, - :is_comprehensive_evaluation => 1, - :comprehensive_evaluation => l(:label_leave_a_message)} %> +<%= render :partial => 'evaluation', :locals => {:homework => homework} %> +
    + <%= render :partial => 'evaluation_add_jour', + :locals => {:homework_attach => homework, + :sta => 0, + :is_comprehensive_evaluation => 1, + :comprehensive_evaluation => l(:label_leave_a_message)} %>
    \ No newline at end of file diff --git a/app/views/homework_attach/edit.html.erb b/app/views/homework_attach/edit.html.erb index fae1f97b5..542fe5565 100644 --- a/app/views/homework_attach/edit.html.erb +++ b/app/views/homework_attach/edit.html.erb @@ -1,91 +1,91 @@ - - - -
    - - - - - - - - - - -
    高校课程实践社区<%= l(:label_user_location) %> :
    <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index'%>

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> > - <%= link_to(@homework.bid.courses.first.name.to_s, homework_course_path(@homework.bid.courses.first)) if @homework.bid.courses.first%> > - <%=link_to(@homework.bid.name, respond_path(@homework.bid)) %> > <%= link_to "修改作业",edit_homework_attach_path(@homework)%>

    -
    - -

    <%=raw l(:label_edit_homework)%>

    - -
    - <%= form_for(@homework) do |f|%> -

    - 标      题 *  - <%= f.text_field :name, :required => true, :name => "homework_name", :size => 60, :style => "width:490px;", :maxlength => 254%> -

    -

    - 提交项目  : - <% if @homework.project.nil? %> - <%= f.select :project_id, options_for_select(user_projects_option),:name => "project_id", :required => true%> - <% else %> - <%= f.select :project_id, options_for_select(user_projects_option,@homework.project.id),:name => "project_id", :required => true%> - <% end %> - - <%= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target => '_blank' %> -

    提交项目可以为空

    -

    -

    - 描      述  :  - - <%= f.text_area :description, :rows => 8, :name => "homework_description", :class => 'wiki-edit', :maxlength => 65534, :style => "font-size:small;width:490px;margin-left:10px;" %> - -

    -

    -

    -

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

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

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

    -
    -

    -

    - - <%= submit_tag t(:label_button_ok), :sta => 0, :class => "enterprise"%> - -

    - <% end %> -
    - - + + + +
    + + + + + + + + + + +
    高校课程实践社区<%= l(:label_user_location) %> :
    <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index'%>

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> > + <%= link_to(@homework.bid.courses.first.name.to_s, homework_course_path(@homework.bid.courses.first)) if @homework.bid.courses.first%> > + <%=link_to(@homework.bid.name, respond_path(@homework.bid)) %> > <%= link_to "修改作业",edit_homework_attach_path(@homework)%>

    +
    + +

    <%=raw l(:label_edit_homework)%>

    + +
    + <%= form_for(@homework) do |f|%> +

    + 标      题 *  + <%= f.text_field :name, :required => true, :name => "homework_name", :size => 60, :style => "width:490px;", :maxlength => 254%> +

    +

    + 提交项目  : + <% if @homework.project.nil? %> + <%= f.select :project_id, options_for_select(user_projects_option),:name => "project_id", :required => true%> + <% else %> + <%= f.select :project_id, options_for_select(user_projects_option,@homework.project.id),:name => "project_id", :required => true%> + <% end %> + + <%= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target => '_blank' %> +

    提交项目可以为空

    +

    +

    + 描      述  :  + + <%= f.text_area :description, :rows => 8, :name => "homework_description", :class => 'wiki-edit', :maxlength => 65534, :style => "font-size:small;width:490px;margin-left:10px;" %> + +

    +

    +

    +

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

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

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

    +
    +

    +

    + + <%= submit_tag t(:label_button_ok), :sta => 0, :class => "enterprise"%> + +

    + <% end %> +
    + + diff --git a/app/views/homework_attach/new.html.erb b/app/views/homework_attach/new.html.erb index 29e606442..e8c820fbd 100644 --- a/app/views/homework_attach/new.html.erb +++ b/app/views/homework_attach/new.html.erb @@ -1,62 +1,62 @@ -
    - - - - - - - - - - -
    高校课程实践社区<%= l(:label_user_location) %> :
    <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index'%>

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> > - <%= link_to(@bid.courses.first.name.to_s, homework_course_path(@bid.courses.first)) if @bid.courses.first%> > - <%=link_to(@bid.name, respond_path(@bid)) %> > <%= link_to "创建作业", new_homework_attach_path(@bid)%>

    -
    - -

    <%=h l(:label_new_homework)%>

    -
    - <%= form_for('new_form', :method => :post, - :url => {:controller => 'homework_attach', - :action => 'create', - :user_id => User.current.id, - :bid_id => @bid - }) do |f|%> -

    - 标      题 * - <%= f.text_field "name", :required => true, :size => 60, :style => "width:490px;", :maxlength => 254 %> -

    -

    - 提交项目  : - <%= f.select :project_id,options_for_select(user_projects_option), {},{:style => "width:490px;"} %> - <%= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target => '_blank' %> -

    提交项目可以为空

    -

    -

    - 描      述  : - - - - <%= f.text_area "description", :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => 65534 %> - -

    -

    -

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

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

    -
    -

    - -

    - - <%= submit_tag t(:label_button_ok), :sta => 0, :class => "enterprise"%> - -

    - <% end %> -
    +
    + + + + + + + + + + +
    高校课程实践社区<%= l(:label_user_location) %> :
    <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index'%>

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> > + <%= link_to(@bid.courses.first.name.to_s, homework_course_path(@bid.courses.first)) if @bid.courses.first%> > + <%=link_to(@bid.name, respond_path(@bid)) %> > <%= link_to "创建作业", new_homework_attach_path(@bid)%>

    +
    + +

    <%=h l(:label_new_homework)%>

    +
    + <%= form_for('new_form', :method => :post, + :url => {:controller => 'homework_attach', + :action => 'create', + :user_id => User.current.id, + :bid_id => @bid + }) do |f|%> +

    + 标      题 * + <%= f.text_field "name", :required => true, :size => 60, :style => "width:490px;", :maxlength => 254 %> +

    +

    + 提交项目  : + <%= f.select :project_id,options_for_select(user_projects_option), {},{:style => "width:490px;"} %> + <%= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target => '_blank' %> +

    提交项目可以为空

    +

    +

    + 描      述  : + + + + <%= f.text_area "description", :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => 65534 %> + +

    +

    +

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

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

    +
    +

    + +

    + + <%= submit_tag t(:label_button_ok), :sta => 0, :class => "enterprise"%> + +

    + <% end %> +
    diff --git a/app/views/homework_attach/show.html.erb b/app/views/homework_attach/show.html.erb index d3fe3f334..5f631c26a 100644 --- a/app/views/homework_attach/show.html.erb +++ b/app/views/homework_attach/show.html.erb @@ -1,175 +1,175 @@ -<%= render :partial => 'layouts/base_homework_attach', :locals => {:homework_attach => @homework} %> - -<% is_student = is_cur_course_student @homework.bid.courses.first %> -<% is_teacher = is_course_teacher User.current,@homework.bid.courses.first %> -

    <%= notice %>

    -
    - - - - - - - - - - - - - - - - - - - - -
    作业基础信息<%=@count %>
    - 发布人员:<%= link_to @homework.user, user_path(@homework.user)%> - - 所属任务:<%= link_to(@homework.bid.name, course_for_bid_path(@homework.bid))%> -
    - 作业下载: - <% if @is_evaluation || is_teacher%> - <% options = {:author => true } %> - <%= render :partial => 'app_link', :locals => {:attachments => @homework.attachments, :options => options} %> - <% else %> - <%= l(:label_cant_download) %> - <% end %> - - 参与人员: - <% @homework.users.each do |homework_user| %> - <%= link_to homework_user, user_path(homework_user)%> - <% if @homework.users.count > 1 && homework_user != @homework.users.last %> -
                     - <% end %> - <% end %> -
    平均评分: - <%= render :partial => 'show_score', :locals => {:stars => @totle_score} %> - 发布时间:<%=format_time @homework.created_at %>
    - - -
    -
    - -
    - - - - - - - - - - - -
    作业描述:
    -
    - <% if @homework.description != nil && @homework.description != "" %> - <%= @homework.description %> - <% else %> -
    - 该作业无任何描述! -
    - <% end %> -
    -
    - - -
    -
    - -
    -
    - 作业得分: -
    -
    -
    -
    得分比例
    -
    - <% 100.step(20,-20) do |star| %> -
    -
    -
    -
    -
    -
    - <%= @stars_status_map["star#{(star/20).to_s}".to_sym] %> -
    - <% end %> -
    -
    -
    -
    最终得分
    -
    - <%= @totle_score %>分 -
    -
    - <%= render :partial => 'show_score', :locals => {:stars => @totle_score} %> -
    -
    -
    -
    打分总人数
    -
    - - <%= @homework.raters(:quality).count%> - -
    -
    -
    -
    -
    - - -
    - <%= render :partial => 'comprehensive_evaluation', :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework, :teaher_score => @teaher_score} %> -
    - -
    - - -<% if !users_for_homework(@homework).include?(User.current) %> -
    -
    作业评论:
    - <% if is_student %> - <% if @is_evaluation %> - <% if @has_evaluation %> -
    - <%= l(:lable_has_evaluation)%> -
    - <% else %> - <%= render :partial => 'evaluation', :locals => {:homework => @homework} %> - <% end %> - <% else %> -
    - <%= l(:lable_close_evaluation)%> -
    - <% end %> - <% end %> -
    -<% end %> - -<% if !is_teacher %> - -
    - <%= render :partial => 'addjour', :locals => {:homework_attach => @homework, :sta => 0, :is_comprehensive_evaluation => nil} %> -
    -<% end %> - - - -
    - <%= render :partial => 'showjour', :locals => {:jour => @jour,:homework => @homework} %> -
    - -
    -
    +<%= render :partial => 'layouts/base_homework_attach', :locals => {:homework_attach => @homework} %> + +<% is_student = is_cur_course_student @homework.bid.courses.first %> +<% is_teacher = is_course_teacher User.current,@homework.bid.courses.first %> +

    <%= notice %>

    +
    + + + + + + + + + + + + + + + + + + + + +
    作业基础信息<%=@count %>
    + 发布人员:<%= link_to @homework.user, user_path(@homework.user)%> + + 所属任务:<%= link_to(@homework.bid.name, course_for_bid_path(@homework.bid))%> +
    + 作业下载: + <% if @is_evaluation || is_teacher%> + <% options = {:author => true } %> + <%= render :partial => 'app_link', :locals => {:attachments => @homework.attachments, :options => options} %> + <% else %> + <%= l(:label_cant_download) %> + <% end %> + + 参与人员: + <% @homework.users.each do |homework_user| %> + <%= link_to homework_user, user_path(homework_user)%> + <% if @homework.users.count > 1 && homework_user != @homework.users.last %> +
                     + <% end %> + <% end %> +
    平均评分: + <%= render :partial => 'show_score', :locals => {:stars => @totle_score} %> + 发布时间:<%=format_time @homework.created_at %>
    + + +
    +
    + +
    + + + + + + + + + + + +
    作业描述:
    +
    + <% if @homework.description != nil && @homework.description != "" %> + <%= @homework.description %> + <% else %> +
    + 该作业无任何描述! +
    + <% end %> +
    +
    + + +
    +
    + +
    +
    + 作业得分: +
    +
    +
    +
    得分比例
    +
    + <% 100.step(20,-20) do |star| %> +
    +
    +
    +
    +
    +
    + <%= @stars_status_map["star#{(star/20).to_s}".to_sym] %> +
    + <% end %> +
    +
    +
    +
    最终得分
    +
    + <%= @totle_score %>分 +
    +
    + <%= render :partial => 'show_score', :locals => {:stars => @totle_score} %> +
    +
    +
    +
    打分总人数
    +
    + + <%= @homework.raters(:quality).count%> + +
    +
    +
    +
    +
    + + +
    + <%= render :partial => 'comprehensive_evaluation', :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework, :teaher_score => @teaher_score} %> +
    + +
    + + +<% if !users_for_homework(@homework).include?(User.current) %> +
    +
    作业评论:
    + <% if is_student %> + <% if @is_evaluation %> + <% if @has_evaluation %> +
    + <%= l(:lable_has_evaluation)%> +
    + <% else %> + <%= render :partial => 'evaluation', :locals => {:homework => @homework} %> + <% end %> + <% else %> +
    + <%= l(:lable_close_evaluation)%> +
    + <% end %> + <% end %> +
    +<% end %> + +<% if !is_teacher %> + +
    + <%= render :partial => 'addjour', :locals => {:homework_attach => @homework, :sta => 0, :is_comprehensive_evaluation => nil} %> +
    +<% end %> + + + +
    + <%= render :partial => 'showjour', :locals => {:jour => @jour,:homework => @homework} %> +
    + +
    +
    diff --git a/app/views/issues/_list.html.erb b/app/views/issues/_list.html.erb index e04f8754e..39fd3776f 100644 --- a/app/views/issues/_list.html.erb +++ b/app/views/issues/_list.html.erb @@ -1,67 +1,67 @@ -
    -
      - <% issue_list(issues) do |issue, level| -%> - <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %> - <% reset_cycle %> - <% previous_group = group %> - <% end %> -
      -
    • "> - <% column_content = ( query.inline_columns.map {|column| "#{column_content_new(column, issue)}"}) %> - - - - <%= render :partial => "/praise_tread/praise_tread",:locals => - {:obj => issue,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%> - - - <% if issue.tracker_id == 1 %> - <%= image_tag("/images/task.png", :class => "img-tag-issues") %> - <% end %> - <% if issue.tracker_id == 2 %> - <%= image_tag("/images/feature.png", :class => "img-tag-issues") %> - <% end %> - <% if issue.tracker_id == 3 %> - <%= image_tag("/images/support.png", :class => "img-tag-issues") %> - <% end %> - <% if issue.tracker_id == 4 %> - <%= image_tag("/images/issues.png", :class => "img-tag-issues") %> - <% end %> - -
        - <% unless issue.author.nil? || issue.author.name == "Anonymous" %> -
          - <%= link_to issue.author.name, user_path(issue.author), :class => "bid_user_u" %> - <%= l(:label_post_on)%> <% a = [] %> - <% a << column_content[1] %> - <%# a << "##{column_content[0]}" << "(#{raw column_content[2]}):" << column_content[4] %> - <% a << "#{issue.source_from}" << "(#{raw column_content[2]}):" << column_content[4] %> - <%= link_to a.join(' '), issue_path(issue.id), :class => "issue-link" , :target =>"_blank"%> -
        - <% end -%> -
          -
          - <%= textilizable issue, :description %> -
          -
        -
          - <% unless issue.assigned_to_id.nil? %> - - <%= l(:field_assigned_to)%>  - - <%= raw column_content[5] %>  - <% end %> - <%= l(:label_updated_time_on, format_date(issue.updated_on)).html_safe %> -
          - - <%= link_to l(:label_find_all_comments), issue_path(issue.id) %> - - <%= l(:label_comments_count, :count => issue.journals.all.count) %> -
          -
        -
      -
    • -
      - <% end -%> -
    +
    +
      + <% issue_list(issues) do |issue, level| -%> + <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %> + <% reset_cycle %> + <% previous_group = group %> + <% end %> +
      +
    • "> + <% column_content = ( query.inline_columns.map {|column| "#{column_content_new(column, issue)}"}) %> + + + + <%= render :partial => "/praise_tread/praise_tread",:locals => + {:obj => issue,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%> + + + <% if issue.tracker_id == 1 %> + <%= image_tag("/images/task.png", :class => "img-tag-issues") %> + <% end %> + <% if issue.tracker_id == 2 %> + <%= image_tag("/images/feature.png", :class => "img-tag-issues") %> + <% end %> + <% if issue.tracker_id == 3 %> + <%= image_tag("/images/support.png", :class => "img-tag-issues") %> + <% end %> + <% if issue.tracker_id == 4 %> + <%= image_tag("/images/issues.png", :class => "img-tag-issues") %> + <% end %> + +
        + <% unless issue.author.nil? || issue.author.name == "Anonymous" %> +
          + <%= link_to issue.author.name, user_path(issue.author), :class => "bid_user_u" %> + <%= l(:label_post_on)%> <% a = [] %> + <% a << column_content[1] %> + <%# a << "##{column_content[0]}" << "(#{raw column_content[2]}):" << column_content[4] %> + <% a << "#{issue.source_from}" << "(#{raw column_content[2]}):" << column_content[4] %> + <%= link_to a.join(' '), issue_path(issue.id), :class => "issue-link" , :target =>"_blank"%> +
        + <% end -%> +
          +
          + <%= textilizable issue, :description %> +
          +
        +
          + <% unless issue.assigned_to_id.nil? %> + + <%= l(:field_assigned_to)%>  + + <%= raw column_content[5] %>  + <% end %> + <%= l(:label_updated_time_on, format_date(issue.updated_on)).html_safe %> +
          + + <%= link_to l(:label_find_all_comments), issue_path(issue.id) %> + + <%= l(:label_comments_count, :count => issue.journals.all.count) %> +
          +
        +
      +
    • +
      + <% end -%> +
    \ No newline at end of file diff --git a/app/views/issues/_sidebar.html.erb b/app/views/issues/_sidebar.html.erb index 9b55ff932..c7b20cbae 100644 --- a/app/views/issues/_sidebar.html.erb +++ b/app/views/issues/_sidebar.html.erb @@ -1,16 +1,16 @@ -

    <%= l(:label_issue_plural) %>

    -<%= link_to l(:label_issue_view_all), _project_issues_path(@project, :set_filter => 1) %> -
    -<% if @project %> - <%= link_to l(:field_summary), project_issues_report_path(@project) %>
    -<% end %> -<%= call_hook(:view_issues_sidebar_issues_bottom) %> -<% if User.current.allowed_to?(:view_calendar, @project, :global => true) %> - <%= link_to l(:label_calendar), _project_calendar_path(@project) %>
    -<% end %> -<% if User.current.allowed_to?(:view_gantt, @project, :global => true) %> - <%= link_to l(:label_gantt), _project_gantt_path(@project) %>
    -<% end %> -<%= call_hook(:view_issues_sidebar_planning_bottom) %> -<%= render_sidebar_queries %> -<%= call_hook(:view_issues_sidebar_queries_bottom) %> +

    <%= l(:label_issue_plural) %>

    +<%= link_to l(:label_issue_view_all), _project_issues_path(@project, :set_filter => 1) %> +
    +<% if @project %> + <%= link_to l(:field_summary), project_issues_report_path(@project) %>
    +<% end %> +<%= call_hook(:view_issues_sidebar_issues_bottom) %> +<% if User.current.allowed_to?(:view_calendar, @project, :global => true) %> + <%= link_to l(:label_calendar), _project_calendar_path(@project) %>
    +<% end %> +<% if User.current.allowed_to?(:view_gantt, @project, :global => true) %> + <%= link_to l(:label_gantt), _project_gantt_path(@project) %>
    +<% end %> +<%= call_hook(:view_issues_sidebar_planning_bottom) %> +<%= render_sidebar_queries %> +<%= call_hook(:view_issues_sidebar_queries_bottom) %> diff --git a/app/views/issues/bulk_edit.html.erb b/app/views/issues/bulk_edit.html.erb index 2924ad927..acd2d5e3d 100644 --- a/app/views/issues/bulk_edit.html.erb +++ b/app/views/issues/bulk_edit.html.erb @@ -1,150 +1,150 @@ -

    <%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %>

    - -
      -<% @issues.each do |issue| %> - <%= content_tag 'li', link_to_issue(issue) %> -<% end %> -
    - -<%= form_tag(bulk_update_issues_path, :id => 'bulk_edit_form') do %> -<%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %> -
    -
    -<%= l(:label_change_properties) %> - -
    -<% if @allowed_projects.present? %> -

    - - <%= select_tag('issue[project_id]', content_tag('option', l(:label_no_change_option), :value => '') + project_tree_options_for_select(@allowed_projects, :selected => @target_project), - :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %> -

    -<% end %> -

    - - <%= select_tag('issue[tracker_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@trackers, :id, :name)) %> -

    -<% if @available_statuses.any? %> -

    - - <%= select_tag('issue[status_id]',content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_statuses, :id, :name)) %> -

    -<% end %> - -<% if @safe_attributes.include?('priority_id') -%> -

    - - <%= select_tag('issue[priority_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(IssuePriority.active, :id, :name)) %> -

    -<% end %> - -<% if @safe_attributes.include?('assigned_to_id') -%> -

    - - <%= select_tag('issue[assigned_to_id]', content_tag('option', l(:label_no_change_option), :value => '') + - content_tag('option', l(:label_nobody), :value => 'none') + - principals_options_for_select(@assignables)) %> -

    -<% end %> - -<% if @safe_attributes.include?('category_id') -%> -

    - - <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') + - content_tag('option', l(:label_none), :value => 'none') + - options_from_collection_for_select(@categories, :id, :name)) %> -

    -<% end %> - -<% if @safe_attributes.include?('fixed_version_id') -%> -

    - - <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') + - content_tag('option', l(:label_none), :value => 'none') + - version_options_for_select(@versions.sort)) %> -

    -<% end %> - -<% @custom_fields.each do |custom_field| %> -

    <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects) %>

    -<% end %> - -<% if @copy && @attachments_present %> -

    - - <%= check_box_tag 'copy_attachments', '1', true %> -

    -<% end %> - -<% if @copy && @subtasks_present %> -

    - - <%= check_box_tag 'copy_subtasks', '1', true %> -

    -<% end %> - -<%= call_hook(:view_issues_bulk_edit_details_bottom, { :issues => @issues }) %> -
    - -
    -<% if @safe_attributes.include?('is_private') %> -

    - - <%= select_tag('issue[is_private]', content_tag('option', l(:label_no_change_option), :value => '') + - content_tag('option', l(:general_text_Yes), :value => '1') + - content_tag('option', l(:general_text_No), :value => '0')) %> -

    -<% end %> - -<% if @safe_attributes.include?('parent_issue_id') && @project %> -

    - - <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10 %> -

    -<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %> -<% end %> - -<% if @safe_attributes.include?('start_date') %> -

    - - <%= text_field_tag 'issue[start_date]', '', :size => 10, :readonly => true %><%= calendar_for('issue_start_date') %> -

    -<% end %> - -<% if @safe_attributes.include?('due_date') %> -

    - - <%= text_field_tag 'issue[due_date]', '', :size => 10, :readonly => true %><%= calendar_for('issue_due_date') %> -

    -<% end %> - -<% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %> -

    - - <%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %> -

    -<% end %> -
    - -
    - -
    <%= l(:field_notes) %> -<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %> -<%= wikitoolbar_for 'notes' %> -
    -
    - -

    - <% if @copy %> - <%= hidden_field_tag 'copy', '1' %> - <%= submit_tag l(:button_copy) %> - <%= submit_tag l(:button_copy_and_follow), :name => 'follow' %> - <% elsif @target_project %> - <%= submit_tag l(:button_move) %> - <%= submit_tag l(:button_move_and_follow), :name => 'follow' %> - <% else %> - <%= submit_tag l(:button_submit) %> - <% end %> -

    - -<% end %> +

    <%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %>

    + +
      +<% @issues.each do |issue| %> + <%= content_tag 'li', link_to_issue(issue) %> +<% end %> +
    + +<%= form_tag(bulk_update_issues_path, :id => 'bulk_edit_form') do %> +<%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %> +
    +
    +<%= l(:label_change_properties) %> + +
    +<% if @allowed_projects.present? %> +

    + + <%= select_tag('issue[project_id]', content_tag('option', l(:label_no_change_option), :value => '') + project_tree_options_for_select(@allowed_projects, :selected => @target_project), + :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %> +

    +<% end %> +

    + + <%= select_tag('issue[tracker_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@trackers, :id, :name)) %> +

    +<% if @available_statuses.any? %> +

    + + <%= select_tag('issue[status_id]',content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_statuses, :id, :name)) %> +

    +<% end %> + +<% if @safe_attributes.include?('priority_id') -%> +

    + + <%= select_tag('issue[priority_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(IssuePriority.active, :id, :name)) %> +

    +<% end %> + +<% if @safe_attributes.include?('assigned_to_id') -%> +

    + + <%= select_tag('issue[assigned_to_id]', content_tag('option', l(:label_no_change_option), :value => '') + + content_tag('option', l(:label_nobody), :value => 'none') + + principals_options_for_select(@assignables)) %> +

    +<% end %> + +<% if @safe_attributes.include?('category_id') -%> +

    + + <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') + + content_tag('option', l(:label_none), :value => 'none') + + options_from_collection_for_select(@categories, :id, :name)) %> +

    +<% end %> + +<% if @safe_attributes.include?('fixed_version_id') -%> +

    + + <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') + + content_tag('option', l(:label_none), :value => 'none') + + version_options_for_select(@versions.sort)) %> +

    +<% end %> + +<% @custom_fields.each do |custom_field| %> +

    <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects) %>

    +<% end %> + +<% if @copy && @attachments_present %> +

    + + <%= check_box_tag 'copy_attachments', '1', true %> +

    +<% end %> + +<% if @copy && @subtasks_present %> +

    + + <%= check_box_tag 'copy_subtasks', '1', true %> +

    +<% end %> + +<%= call_hook(:view_issues_bulk_edit_details_bottom, { :issues => @issues }) %> +
    + +
    +<% if @safe_attributes.include?('is_private') %> +

    + + <%= select_tag('issue[is_private]', content_tag('option', l(:label_no_change_option), :value => '') + + content_tag('option', l(:general_text_Yes), :value => '1') + + content_tag('option', l(:general_text_No), :value => '0')) %> +

    +<% end %> + +<% if @safe_attributes.include?('parent_issue_id') && @project %> +

    + + <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10 %> +

    +<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %> +<% end %> + +<% if @safe_attributes.include?('start_date') %> +

    + + <%= text_field_tag 'issue[start_date]', '', :size => 10, :readonly => true %><%= calendar_for('issue_start_date') %> +

    +<% end %> + +<% if @safe_attributes.include?('due_date') %> +

    + + <%= text_field_tag 'issue[due_date]', '', :size => 10, :readonly => true %><%= calendar_for('issue_due_date') %> +

    +<% end %> + +<% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %> +

    + + <%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %> +

    +<% end %> +
    + +
    + +
    <%= l(:field_notes) %> +<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %> +<%= wikitoolbar_for 'notes' %> +
    +
    + +

    + <% if @copy %> + <%= hidden_field_tag 'copy', '1' %> + <%= submit_tag l(:button_copy) %> + <%= submit_tag l(:button_copy_and_follow), :name => 'follow' %> + <% elsif @target_project %> + <%= submit_tag l(:button_move) %> + <%= submit_tag l(:button_move_and_follow), :name => 'follow' %> + <% else %> + <%= submit_tag l(:button_submit) %> + <% end %> +

    + +<% end %> diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index ba6053fd6..219a0f641 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -1,135 +1,135 @@ -
    - <% if @project.enabled_modules.where("name = 'issue_tracking'").count > 0 %> -
    - <%= link_to l(:label_issue_new), {:controller => 'issues', :action => 'new', :copy_from => nil}, :param => :project_id, :caption => :label_issue_new, - :html => {:accesskey => Redmine::AccessKeys.key_for(:new_issue)}, :class => 'icon icon-add' %> - - <%= link_to l(:label_query), '#', :class => 'icon icon-help', - :onclick => '$("#custom_query").slideToggle(400); ' if true || User.current.logged? %> -
    - <% end %> -
    - -
    - <% if !@query.new_record? && @query.editable_by?(User.current) %> - <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %> - <%= delete_link query_path(@query) %> - <% end %> -
    - -<% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %> -
    - <%= form_tag({:controller => 'issues', :action => 'index', :project_id => @project}, :method => :get, :id => 'query_form', :class => 'query_form') do %> - <%= hidden_field_tag 'set_filter', '1' %> - -
    - ---<%= l :label_query_new %>--- - -
    -
    "> - - <%= l(:label_issue_query_condition) %> - -
    "> - <%= render :partial => 'queries/filters', :locals => {:query => @query} %> -
    -
    - -
    - <%= link_to_function l(:label_issue_query), 'submit_query_form("query_form")', :class => 'icon icon-checked' %> - <%= link_to l(:label_issue_cancel_query), {:set_filter => 1, :project_id => @project}, :class => 'icon icon-reload' %> -
    -
    -
    - <% end %> -
    - -<%= error_messages_for 'query' %> - -<% if @query.valid? %> - <% if @issues.empty? %> -

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

    - <% else %> - <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %> - - <% end %> -
    - <% other_formats_links do |f| %> - <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %> - <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %> - <%= f.link_to 'PDF', :url => params %> - <% end %> -
    - - - - -<% end %> - -<%= call_hook(:view_issues_index_bottom, {:issues => @issues, :project => @project, :query => @query}) %> - -<% content_for :sidebar do %> - <%= render :partial => 'issues/sidebar' %> -<% end %> - -<% content_for :header_tags do %> - <%= auto_discovery_link_tag(:atom, - {:query_id => @query, :format => 'atom', - :page => nil, :key => User.current.rss_key}, - :title => l(:label_issue_plural)) %> - <%= auto_discovery_link_tag(:atom, - {:controller => 'journals', :action => 'index', - :query_id => @query, :format => 'atom', - :page => nil, :key => User.current.rss_key}, - :title => l(:label_changes_details)) %> -<% end %> - -<%= context_menu issues_context_menu_path %> +
    + <% if @project.enabled_modules.where("name = 'issue_tracking'").count > 0 %> +
    + <%= link_to l(:label_issue_new), {:controller => 'issues', :action => 'new', :copy_from => nil}, :param => :project_id, :caption => :label_issue_new, + :html => {:accesskey => Redmine::AccessKeys.key_for(:new_issue)}, :class => 'icon icon-add' %> + + <%= link_to l(:label_query), '#', :class => 'icon icon-help', + :onclick => '$("#custom_query").slideToggle(400); ' if true || User.current.logged? %> +
    + <% end %> +
    + +
    + <% if !@query.new_record? && @query.editable_by?(User.current) %> + <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %> + <%= delete_link query_path(@query) %> + <% end %> +
    + +<% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %> +
    + <%= form_tag({:controller => 'issues', :action => 'index', :project_id => @project}, :method => :get, :id => 'query_form', :class => 'query_form') do %> + <%= hidden_field_tag 'set_filter', '1' %> + +
    + ---<%= l :label_query_new %>--- + +
    +
    "> + + <%= l(:label_issue_query_condition) %> + +
    "> + <%= render :partial => 'queries/filters', :locals => {:query => @query} %> +
    +
    + +
    + <%= link_to_function l(:label_issue_query), 'submit_query_form("query_form")', :class => 'icon icon-checked' %> + <%= link_to l(:label_issue_cancel_query), {:set_filter => 1, :project_id => @project}, :class => 'icon icon-reload' %> +
    +
    +
    + <% end %> +
    + +<%= error_messages_for 'query' %> + +<% if @query.valid? %> + <% if @issues.empty? %> +

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

    + <% else %> + <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %> + + <% end %> +
    + <% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %> + <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %> + <%= f.link_to 'PDF', :url => params %> + <% end %> +
    + + + + +<% end %> + +<%= call_hook(:view_issues_index_bottom, {:issues => @issues, :project => @project, :query => @query}) %> + +<% content_for :sidebar do %> + <%= render :partial => 'issues/sidebar' %> +<% end %> + +<% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, + {:query_id => @query, :format => 'atom', + :page => nil, :key => User.current.rss_key}, + :title => l(:label_issue_plural)) %> + <%= auto_discovery_link_tag(:atom, + {:controller => 'journals', :action => 'index', + :query_id => @query, :format => 'atom', + :page => nil, :key => User.current.rss_key}, + :title => l(:label_changes_details)) %> +<% end %> + +<%= context_menu issues_context_menu_path %> diff --git a/app/views/journals/diff.html.erb b/app/views/journals/diff.html.erb index d846b9d19..d3dfa7d34 100644 --- a/app/views/journals/diff.html.erb +++ b/app/views/journals/diff.html.erb @@ -1,10 +1,10 @@ -

    <%=h @issue.tracker %> #<%= @issue.id %>

    -

    <%= authoring @journal.created_on, @journal.user, :label => :label_updated_time_by %>

    - -
    -<%= simple_format_without_paragraph @diff.to_html %> -
    - -

    <%= link_to l(:button_back), issue_path(@issue), :onclick => 'history.back(); return false;' %>

    - -<% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %> +

    <%=h @issue.tracker %> #<%= @issue.id %>

    +

    <%= authoring @journal.created_on, @journal.user, :label => :label_updated_time_by %>

    + +
    +<%= simple_format_without_paragraph @diff.to_html %> +
    + +

    <%= link_to l(:button_back), issue_path(@issue), :onclick => 'history.back(); return false;' %>

    + +<% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %> diff --git a/app/views/layouts/_base_footer.html.erb b/app/views/layouts/_base_footer.html.erb index 012729aea..a4071e887 100644 --- a/app/views/layouts/_base_footer.html.erb +++ b/app/views/layouts/_base_footer.html.erb @@ -1,39 +1,39 @@ - -
    - -
    -
    - <%= debug(params) if Rails.env.development? %> - -
    - + +
    + +
    +
    + <%= debug(params) if Rails.env.development? %> + +
    + diff --git a/app/views/layouts/_base_header.html.erb b/app/views/layouts/_base_header.html.erb index c3b06759c..9418e07cf 100644 --- a/app/views/layouts/_base_header.html.erb +++ b/app/views/layouts/_base_header.html.erb @@ -1,128 +1,128 @@ -<% - request.headers['REQUEST_URI'] = "" if request.headers['REQUEST_URI'].nil? - realUrl = request.original_url - if (realUrl.match(/.*forge\.trustie\.net\/*/)) - #@nav_dispaly_project_label = 1 - #@nav_dispaly_forum_label = 1 - elsif (realUrl.match(/.*course\.trustie\.net\/*/)) - #@nav_dispaly_course_all_label = 1 - #@nav_dispaly_forum_label = 1 - #@nav_dispaly_course_label = nil - #@nav_dispaly_store_all_label = 1 - elsif (realUrl.match(/.*user\.trustie\.net\/*/)) - #@nav_dispaly_home_path_label = 1 - #@nav_dispaly_main_course_label = 1 - #@nav_dispaly_main_project_label = 1 - #@nav_dispaly_main_contest_label = 1 - elsif (realUrl.match(/.*contest\.trustie\.net\/*/)) - #@nav_dispaly_contest_label = 1 - #@nav_dispaly_store_all_label = 1 - else - #@nav_dispaly_project_all_label = 1 - #@nav_dispaly_course_all_label = 1 - #@nav_dispaly_forum_label = 1 - #@nav_dispaly_bid_label = 1 - #@nav_dispaly_contest_label = 1 - #@nav_dispaly_store_all_label = 1 - #@nav_dispaly_user_label = 1 - end -%> -
    - -
    - <%= render_menu :account_menu -%> -
    - <% if User.current.logged? -%> -
    -
      -
    • - <%=link_to_user(User.current)%> - -
    • -
    • - <%=link_to l(:label_my_message)+'('+User.current.count_new_jour.to_s+')', - { :controller => 'users', :action => 'user_newfeedback', id: User.current.id, host: Setting.user_domain }, - {:class => 'my-message'} if User.current.logged?%> -
    • -
    -
    - <% end -%> - <%#= render_menu :top_menu if User.current.logged? || !Setting.login_required? -%> - <%= render_dynamic_nav if User.current.logged? || !Setting.login_required? -%> - <%# 自建导航条在base页面中以 (@nav_dispaly......) 开头变量设定, 全局搜索即可发现 %> -
    -
    -
    - - +<% + request.headers['REQUEST_URI'] = "" if request.headers['REQUEST_URI'].nil? + realUrl = request.original_url + if (realUrl.match(/.*forge\.trustie\.net\/*/)) + #@nav_dispaly_project_label = 1 + #@nav_dispaly_forum_label = 1 + elsif (realUrl.match(/.*course\.trustie\.net\/*/)) + #@nav_dispaly_course_all_label = 1 + #@nav_dispaly_forum_label = 1 + #@nav_dispaly_course_label = nil + #@nav_dispaly_store_all_label = 1 + elsif (realUrl.match(/.*user\.trustie\.net\/*/)) + #@nav_dispaly_home_path_label = 1 + #@nav_dispaly_main_course_label = 1 + #@nav_dispaly_main_project_label = 1 + #@nav_dispaly_main_contest_label = 1 + elsif (realUrl.match(/.*contest\.trustie\.net\/*/)) + #@nav_dispaly_contest_label = 1 + #@nav_dispaly_store_all_label = 1 + else + #@nav_dispaly_project_all_label = 1 + #@nav_dispaly_course_all_label = 1 + #@nav_dispaly_forum_label = 1 + #@nav_dispaly_bid_label = 1 + #@nav_dispaly_contest_label = 1 + #@nav_dispaly_store_all_label = 1 + #@nav_dispaly_user_label = 1 + end +%> +
    + +
    + <%= render_menu :account_menu -%> +
    + <% if User.current.logged? -%> +
    +
      +
    • + <%=link_to_user(User.current)%> + +
    • +
    • + <%=link_to l(:label_my_message)+'('+User.current.count_new_jour.to_s+')', + { :controller => 'users', :action => 'user_newfeedback', id: User.current.id, host: Setting.user_domain }, + {:class => 'my-message'} if User.current.logged?%> +
    • +
    +
    + <% end -%> + <%#= render_menu :top_menu if User.current.logged? || !Setting.login_required? -%> + <%= render_dynamic_nav if User.current.logged? || !Setting.login_required? -%> + <%# 自建导航条在base页面中以 (@nav_dispaly......) 开头变量设定, 全局搜索即可发现 %> +
    +
    +
    + + diff --git a/app/views/layouts/_user_courses_list.html.erb b/app/views/layouts/_user_courses_list.html.erb index e5b0adb16..cb3871a9e 100644 --- a/app/views/layouts/_user_courses_list.html.erb +++ b/app/views/layouts/_user_courses_list.html.erb @@ -1,14 +1,14 @@ -<% if hasCourse %> -
  • - <%=link_to l(:label_my_course), {:controller => 'users', :action => 'user_courses', id: User.current.id} %> -
      - <% User.current.courses.each do |course| %> - <% if !course_endTime_timeout?(course) %> -
    • - <%= link_to course.name, {:controller => 'courses',:action => 'show',id:course.id} %> -
    • - <% end %> - <% end %> -
    -
  • +<% if hasCourse %> +
  • + <%=link_to l(:label_my_course), {:controller => 'users', :action => 'user_courses', id: User.current.id} %> +
      + <% User.current.courses.each do |course| %> + <% if !course_endTime_timeout?(course) %> +
    • + <%= link_to course.name, {:controller => 'courses',:action => 'show',id:course.id} %> +
    • + <% end %> + <% end %> +
    +
  • <% end %> \ No newline at end of file diff --git a/app/views/layouts/_user_project_list.html.erb b/app/views/layouts/_user_project_list.html.erb index 85eaec719..3170ff43f 100644 --- a/app/views/layouts/_user_project_list.html.erb +++ b/app/views/layouts/_user_project_list.html.erb @@ -1,12 +1,12 @@ -<% if User.current.projects.count>0 %> -
  • - <%= link_to l(:label_my_projects), {:controller => 'users', :action => 'user_projects', id: User.current.id, host: Setting.project_domain} %> -
      - <% User.current.projects.each do |project| %> -
    • - <%= link_to project.name, {:controller => 'projects', :action => 'show',id: project.id, host: Setting.project_domain } %> -
    • - <% end %> -
    -
  • +<% if User.current.projects.count>0 %> +
  • + <%= link_to l(:label_my_projects), {:controller => 'users', :action => 'user_projects', id: User.current.id, host: Setting.project_domain} %> +
      + <% User.current.projects.each do |project| %> +
    • + <%= link_to project.name, {:controller => 'projects', :action => 'show',id: project.id, host: Setting.project_domain } %> +
    • + <% end %> +
    +
  • <% end %> \ No newline at end of file diff --git a/app/views/layouts/base_admin.html.erb b/app/views/layouts/base_admin.html.erb index 5b36febaf..1cdbbd6df 100644 --- a/app/views/layouts/base_admin.html.erb +++ b/app/views/layouts/base_admin.html.erb @@ -1,60 +1,60 @@ -<% @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', :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'%> -
    -
    - -
    - <%= 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', :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'%> +
    +
    + +
    + <%= 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_homework.html.erb b/app/views/layouts/base_homework.html.erb index 92d2cc84e..ed5691314 100644 --- a/app/views/layouts/base_homework.html.erb +++ b/app/views/layouts/base_homework.html.erb @@ -1,295 +1,295 @@ -<% @nav_dispaly_course_all_label = 1 - @nav_dispaly_forum_label = 1 - @nav_dispaly_course_label = nil - @nav_dispaly_store_all_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 %> - <%= call_hook :view_layouts_base_html_head %> - - <%= yield :header_tags -%> - - - <% course = @bid.courses.first %> - <% if course %> -
    -
    -
    - <%= render :partial => 'layouts/base_header' %> -
    - -
    - - - - - - - - - -
    高校课程实践社区 - <%= l(:label_user_location) %> : -
    - <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index' %> - -

    <%= link_to "主页", home_path %> - > - <%= link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> - > - - <%= link_to(course.name.to_s, homework_course_path(course)) if course %> - - > - <%= link_to(@bid.name, respond_path(@bid)) %> -

    -
    -
    - - - -
    - -
    -
      -
    • - <%= link_to l(:label_question_student), {:controller => 'bids', :action => 'show'}, :class => link_class(:respond) %> -
    • - <% if User.current.member_of_course? course %> -
    • - <% if User.current.logged? && course && (!Member.where('user_id = ? and course_id = ?', User.current.id, course.id).first.nil? && (Member.where('user_id = ? and course_id = ?', User.current.id, course.id).first.roles&Role.where('id = ? or id = ? or id =?', 5, 10, 7)).size >0) %> - <%= link_to l(:label_homework_commit), course_for_bid_path, :class => link_class(:course) %> - <% else %> - <%= link_to l(:label_homework_info), course_for_bid_path, :class => link_class(:course) %> - <% end %> -
    • - <% end %> - - -
    -
    - - <%= yield %> - <%= call_hook :view_layouts_base_content %> -
    -
    - <%= render :partial => 'layouts/base_footer' %> -
    -
    -
    - - - - -
    - <%= call_hook :view_layouts_base_body_bottom %> - <% end %> - - +<% @nav_dispaly_course_all_label = 1 + @nav_dispaly_forum_label = 1 + @nav_dispaly_course_label = nil + @nav_dispaly_store_all_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 %> + <%= call_hook :view_layouts_base_html_head %> + + <%= yield :header_tags -%> + + + <% course = @bid.courses.first %> + <% if course %> +
    +
    +
    + <%= render :partial => 'layouts/base_header' %> +
    + +
    + + + + + + + + + +
    高校课程实践社区 + <%= l(:label_user_location) %> : +
    + <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index' %> + +

    <%= link_to "主页", home_path %> + > + <%= link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> + > + + <%= link_to(course.name.to_s, homework_course_path(course)) if course %> + + > + <%= link_to(@bid.name, respond_path(@bid)) %> +

    +
    +
    + + + +
    + +
    +
      +
    • + <%= link_to l(:label_question_student), {:controller => 'bids', :action => 'show'}, :class => link_class(:respond) %> +
    • + <% if User.current.member_of_course? course %> +
    • + <% if User.current.logged? && course && (!Member.where('user_id = ? and course_id = ?', User.current.id, course.id).first.nil? && (Member.where('user_id = ? and course_id = ?', User.current.id, course.id).first.roles&Role.where('id = ? or id = ? or id =?', 5, 10, 7)).size >0) %> + <%= link_to l(:label_homework_commit), course_for_bid_path, :class => link_class(:course) %> + <% else %> + <%= link_to l(:label_homework_info), course_for_bid_path, :class => link_class(:course) %> + <% end %> +
    • + <% end %> + + +
    +
    + + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
    +
    + <%= render :partial => 'layouts/base_footer' %> +
    +
    +
    + + + + +
    + <%= call_hook :view_layouts_base_body_bottom %> + <% end %> + + diff --git a/app/views/layouts/base_newcontest.html.erb b/app/views/layouts/base_newcontest.html.erb index a81170db3..381a6a61d 100644 --- a/app/views/layouts/base_newcontest.html.erb +++ b/app/views/layouts/base_newcontest.html.erb @@ -114,7 +114,7 @@ - <%=link_to "#{@contest.watcher_users.count}",show_project_contest_path(@contest) %> + <%=link_to "#{@contest.watcher_users.count}",watcherlist_contest_path(@contest) %> diff --git a/app/views/members/autocomplete.js.erb b/app/views/members/autocomplete.js.erb index d1e7a884b..16809de48 100644 --- a/app/views/members/autocomplete.js.erb +++ b/app/views/members/autocomplete.js.erb @@ -1,21 +1,21 @@ - <% if @project%> -$('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>'); - <% elsif @course%> - var checked = $("#principals input:checked").size(); - if(checked > 0) - { - alert('翻页或搜索后将丢失当前选择的用户数据!'); - } - $('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_course_members(@course)) %>'); - <%end%> - var collection=$("#principals_for_new_member").children("#principals").children("label"); - collection.css("text-overflow","ellipsis"); - collection.css("white-space","nowrap"); - collection.css("width","200px"); - collection.css("overflow","hidden"); - for(i=0;i +$('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>'); + <% elsif @course%> + var checked = $("#principals input:checked").size(); + if(checked > 0) + { + alert('翻页或搜索后将丢失当前选择的用户数据!'); + } + $('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_course_members(@course)) %>'); + <%end%> + var collection=$("#principals_for_new_member").children("#principals").children("label"); + collection.css("text-overflow","ellipsis"); + collection.css("white-space","nowrap"); + collection.css("width","200px"); + collection.css("overflow","hidden"); + for(i=0;i -<% @nav_dispaly_forum_label = 1%> - - - -
    - <%= link_to(l(:button_change_password), {:action => 'password'}, :class => 'icon icon-passwd') if @user.change_password_allowed? %> - <%= call_hook(:view_my_account_contextual, :user => @user) %> -
    - -

    <%= l(:label_my_account) %>

    -<%= error_messages_for 'user' %> -
    -<%= labelled_form_for :user, @user, - :url => {:action => "account"}, - :html => {:id => 'my_account_form', - :method => :post} do |f| %> - - - - - - - - - <%= submit_tag l(:button_save) %> -
    -<% end %> -<% html_title(l(:label_my_account)) -%> - - + + +
    + <%= link_to(l(:button_change_password), {:action => 'password'}, :class => 'icon icon-passwd') if @user.change_password_allowed? %> + <%= call_hook(:view_my_account_contextual, :user => @user) %> +
    + +

    <%= l(:label_my_account) %>

    +<%= error_messages_for 'user' %> +
    +<%= labelled_form_for :user, @user, + :url => {:action => "account"}, + :html => {:id => 'my_account_form', + :method => :post} do |f| %> + + + + + + + + + <%= submit_tag l(:button_save) %> +
    +<% end %> +<% html_title(l(:label_my_account)) -%> + + \ No newline at end of file diff --git a/app/views/news/edit.html.erb b/app/views/news/edit.html.erb index 3225f8031..3e9860feb 100644 --- a/app/views/news/edit.html.erb +++ b/app/views/news/edit.html.erb @@ -1,12 +1,12 @@ -

    <%=l(:label_news)%>

    - -<%= labelled_form_for @news, :html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %> -<%= render :partial => 'form', :locals => { :f => f } %> -<%= submit_tag l(:button_save) %> -<%#= preview_link preview_news_path(:project_id => @project, :id => @news), 'news-form' %> -<% end %> -
    - -<% content_for :header_tags do %> - <%= stylesheet_link_tag 'scm' %> -<% end %> +

    <%=l(:label_news)%>

    + +<%= labelled_form_for @news, :html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_save) %> +<%#= preview_link preview_news_path(:project_id => @project, :id => @news), 'news-form' %> +<% end %> +
    + +<% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> +<% end %> diff --git a/app/views/news/new.html.erb b/app/views/news/new.html.erb index 03c1d3ee7..8c9bc784a 100644 --- a/app/views/news/new.html.erb +++ b/app/views/news/new.html.erb @@ -1,17 +1,17 @@ - -<% if @project %> - <%= labelled_form_for @news, :url => project_news_index_path(@project), - :html => {:id => 'news-form', :multipart => true} do |f| %> - <%= render :partial => 'news/form', :locals => {:f => f} %> - <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> - <%#= preview_link preview_news_path(:project_id => @project), 'news-form', target='preview', {:class => 'whiteButton m3p10'} %> - <% end %> -<% elsif @course %> - <%= labelled_form_for @news, :url => course_news_index_path(@course), - :html => {:id => 'news-form', :multipart => true} do |f| %> - <%= render :partial => 'news/form', :locals => {:f => f} %> - <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> - <%#= preview_link preview_news_path(:course_id => @course), 'news-form', target='preview', {:class => 'whiteButton m3p10'} %> - <% end %> -<% end %> -
    + +<% if @project %> + <%= labelled_form_for @news, :url => project_news_index_path(@project), + :html => {:id => 'news-form', :multipart => true} do |f| %> + <%= render :partial => 'news/form', :locals => {:f => f} %> + <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> + <%#= preview_link preview_news_path(:project_id => @project), 'news-form', target='preview', {:class => 'whiteButton m3p10'} %> + <% end %> +<% elsif @course %> + <%= labelled_form_for @news, :url => course_news_index_path(@course), + :html => {:id => 'news-form', :multipart => true} do |f| %> + <%= render :partial => 'news/form', :locals => {:f => f} %> + <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> + <%#= preview_link preview_news_path(:course_id => @course), 'news-form', target='preview', {:class => 'whiteButton m3p10'} %> + <% end %> +<% end %> +
    diff --git a/app/views/projects/_new_homework.html.erb b/app/views/projects/_new_homework.html.erb index 64a76aa0f..a903741cb 100644 --- a/app/views/projects/_new_homework.html.erb +++ b/app/views/projects/_new_homework.html.erb @@ -1,81 +1,81 @@ - - - - - -<%= form_tag({:controller => 'bids', -:action => 'new_bid', -:remote => true, -:method => :post, -:id => 'new-bid-form'}) do %> - - - - - - - - - - - - - - - - - - - - - -
    <%= text_field_tag 'bid_title', "#{l(:label_requirement_name)}", :class => 'noline', :required => true, :onfocus => "clearInfo('bid_title', '#{l(:label_requirement_name)}')", :onblur => "showInfo('bid_title', '#{l(:label_requirement_name)}')"%>
    <%= text_area_tag 'bid_description', "#{l(:label_requirement_description)}", :class => 'noline', :required => true, :style => "resize: none;", :rows => 6, - :onfocus => "clearInfo('bid_description', '#{l(:label_requirement_description)}')", :onblur => "showInfo('bid_description', '#{l(:label_requirement_description)}')" %>
    <%= text_field_tag 'bid_deadline', "#{l(:label_deadline)}", :class => 'noline', :readonly => true, :required => true, - :onfocus => "clearInfo('bid_deadline', '#{l(:label_deadline)}')", :onblur => "showInfo('bid_deadline', '#{l(:label_deadline)}')"%> - <%= calendar_for('bid_deadline')%>
    - - - - -
    <%= submit_tag l(:button_new_bid), :name => nil , :class => "bid_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'"%>
    + + + + + +<%= form_tag({:controller => 'bids', +:action => 'new_bid', +:remote => true, +:method => :post, +:id => 'new-bid-form'}) do %> + + + + + + + + + + + + + + + + + + + + + +
    <%= text_field_tag 'bid_title', "#{l(:label_requirement_name)}", :class => 'noline', :required => true, :onfocus => "clearInfo('bid_title', '#{l(:label_requirement_name)}')", :onblur => "showInfo('bid_title', '#{l(:label_requirement_name)}')"%>
    <%= text_area_tag 'bid_description', "#{l(:label_requirement_description)}", :class => 'noline', :required => true, :style => "resize: none;", :rows => 6, + :onfocus => "clearInfo('bid_description', '#{l(:label_requirement_description)}')", :onblur => "showInfo('bid_description', '#{l(:label_requirement_description)}')" %>
    <%= text_field_tag 'bid_deadline', "#{l(:label_deadline)}", :class => 'noline', :readonly => true, :required => true, + :onfocus => "clearInfo('bid_deadline', '#{l(:label_deadline)}')", :onblur => "showInfo('bid_deadline', '#{l(:label_deadline)}')"%> + <%= calendar_for('bid_deadline')%>
    + + + + +
    <%= submit_tag l(:button_new_bid), :name => nil , :class => "bid_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'"%>
    <%end%> \ No newline at end of file diff --git a/app/views/projects/_new_join.html.erb b/app/views/projects/_new_join.html.erb index e74ddeba0..b1704ec32 100644 --- a/app/views/projects/_new_join.html.erb +++ b/app/views/projects/_new_join.html.erb @@ -1,62 +1,62 @@ - - - -

    请输入课程密码

    - -<%= form_tag({:controller => 'courses', - :action => 'join', - :object_id => course.id}, - :remote => true, - :method => :post, - :id => 'new-watcher-form') do %> - - - - -
    - <%= text_field_tag 'course_password', nil, :style=>'width:100%'%> -
    - -

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

    - -
    -
    -<% end %> + + + +

    请输入课程密码

    + +<%= form_tag({:controller => 'courses', + :action => 'join', + :object_id => course.id}, + :remote => true, + :method => :post, + :id => 'new-watcher-form') do %> + + + + +
    + <%= text_field_tag 'course_password', nil, :style=>'width:100%'%> +
    + +

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

    + +
    +
    +<% end %> diff --git a/app/views/projects/new.html.erb b/app/views/projects/new.html.erb index f08d8618f..b68fcb5bc 100644 --- a/app/views/projects/new.html.erb +++ b/app/views/projects/new.html.erb @@ -1,17 +1,17 @@ -<% @nav_dispaly_project_label = 1 - @nav_dispaly_forum_label = 1 %> - -<%= labelled_form_for @project do |f| %> -

    <%=l(:label_project_new)%>

    -
    -

    <%=raw l(:label_project_new_description)%>

    - <%= render :partial => 'form', :locals => { :f => f } %> - - <%= submit_tag l(:button_create), :class => "enterprise"%> - -
    - <%#= submit_tag l(:button_create_and_continue), :name => 'continue' %> - <%= javascript_tag "$('#project_name').focus();" %> -<% end %> - +<% @nav_dispaly_project_label = 1 + @nav_dispaly_forum_label = 1 %> + +<%= labelled_form_for @project do |f| %> +

    <%=l(:label_project_new)%>

    +
    +

    <%=raw l(:label_project_new_description)%>

    + <%= render :partial => 'form', :locals => { :f => f } %> + + <%= submit_tag l(:button_create), :class => "enterprise"%> + +
    + <%#= submit_tag l(:button_create_and_continue), :name => 'continue' %> + <%= javascript_tag "$('#project_name').focus();" %> +<% end %> + <% html_title(l(:label_project_new)) -%> \ No newline at end of file diff --git a/app/views/projects/settings/_repositories.html.erb b/app/views/projects/settings/_repositories.html.erb index eac6f85ce..3d9d71a56 100644 --- a/app/views/projects/settings/_repositories.html.erb +++ b/app/views/projects/settings/_repositories.html.erb @@ -1,66 +1,66 @@ -<% project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT %> -<% ip = RepositoriesHelper::REPO_IP_ADDRESS %> -<% if @project.repositories.any? %> - - - - - - - - - - - - <% @project.repositories.sort.each do |repository| %> - - - - - <%if repository.scm_name=="Git"%> - - <%else %> - - <% end %> - - - - <% end %> - -
    <%= l(:field_identifier) %><%= l(:field_repository_is_default) %><%= l(:label_scm) %><%= l(:label_repository_path) %>
    - <%= link_to repository.identifier, - {:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier.present? %> - <%= checked_image repository.is_default? %><%=h repository.scm_name %>http://<%= repository.login.to_s %>_<%= repository.identifier.to_s%>@<%= ip %><%=h repository.url.slice(project_path_cut, repository.url.length) %><%=h repository.url %> - <% if repository.scm_name=="Subversion"%> - <%if User.current.allowed_to?(:manage_repository, @project) %> - <%= link_to(l(:label_user_plural), committers_repository_path(repository), - :class => 'icon icon-user') %> - <%= link_to(l(:button_edit), edit_repository_path(repository), - :class => 'icon icon-edit') %> - <%= delete_link repository_path(repository) %> - <% end %> - <% elsif repository.scm_name=="Git"%> - <%if User.current.allowed_to?(:manage_repository, @project) %> - - <%= link_to(l(:label_user_plural), committers_repository_path(repository), - :class => 'icon icon-user') %> - <% if repository.login.to_s==User.current.login.to_s %> - <%= delete_link repository_path(repository) %> - <% end %> - <% end %> - <% end %> -
    -<% else %> -

    <%= l(:label_no_data) %>

    -<% end %> - -<% course_tag = @project.project_type %> -<% if User.current.allowed_to?(:manage_repository, @project) %> -

    <%= link_to l(:label_repository_new), new_project_repository_path(@project, :course => course_tag), :class => 'icon icon-add' %>

    -<% end %> - -<% if User.current.allowed_to?(:manage_repository, @project) %> -

    <%= l(:label_repository_no) %> - <%= link_to l(:label_repository_new_repos), newrepo_project_repository_path(@project, :course => course_tag), :class => 'icon icon-add' %>

    +<% project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT %> +<% ip = RepositoriesHelper::REPO_IP_ADDRESS %> +<% if @project.repositories.any? %> + + + + + + + + + + + + <% @project.repositories.sort.each do |repository| %> + + + + + <%if repository.scm_name=="Git"%> + + <%else %> + + <% end %> + + + + <% end %> + +
    <%= l(:field_identifier) %><%= l(:field_repository_is_default) %><%= l(:label_scm) %><%= l(:label_repository_path) %>
    + <%= link_to repository.identifier, + {:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier.present? %> + <%= checked_image repository.is_default? %><%=h repository.scm_name %>http://<%= repository.login.to_s %>_<%= repository.identifier.to_s%>@<%= ip %><%=h repository.url.slice(project_path_cut, repository.url.length) %><%=h repository.url %> + <% if repository.scm_name=="Subversion"%> + <%if User.current.allowed_to?(:manage_repository, @project) %> + <%= link_to(l(:label_user_plural), committers_repository_path(repository), + :class => 'icon icon-user') %> + <%= link_to(l(:button_edit), edit_repository_path(repository), + :class => 'icon icon-edit') %> + <%= delete_link repository_path(repository) %> + <% end %> + <% elsif repository.scm_name=="Git"%> + <%if User.current.allowed_to?(:manage_repository, @project) %> + + <%= link_to(l(:label_user_plural), committers_repository_path(repository), + :class => 'icon icon-user') %> + <% if repository.login.to_s==User.current.login.to_s %> + <%= delete_link repository_path(repository) %> + <% end %> + <% end %> + <% end %> +
    +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> + +<% course_tag = @project.project_type %> +<% if User.current.allowed_to?(:manage_repository, @project) %> +

    <%= link_to l(:label_repository_new), new_project_repository_path(@project, :course => course_tag), :class => 'icon icon-add' %>

    +<% end %> + +<% if User.current.allowed_to?(:manage_repository, @project) %> +

    <%= l(:label_repository_no) %> + <%= link_to l(:label_repository_new_repos), newrepo_project_repository_path(@project, :course => course_tag), :class => 'icon icon-add' %>

    <% end %> \ No newline at end of file diff --git a/app/views/projects/watcherlist.html.erb b/app/views/projects/watcherlist.html.erb index 6a44a4d86..b85705de8 100644 --- a/app/views/projects/watcherlist.html.erb +++ b/app/views/projects/watcherlist.html.erb @@ -1,34 +1,34 @@ - -

    <%= l(:label_user_watcher)%>

    -
    - <% for user in @project.watcher_users %> -
      -
    • - - - - - -
      <%= image_tag(url_to_avatar(user), :class => "avatar") %> - - - - - - - - - -

      <%= content_tag "div", link_to_user(user), :class =>"project_avatar_name" %>

      -

      - <% unless user.memberships.empty? %> - <%= l(:label_contribute_to, :project_count => "#{user.memberships.count}") %> - <% for member in user.memberships %> - <%= link_to_project(member.project) %><%= (user.memberships.last == member) ? '' : ',' %> - <% end %> - <% end %> -

      <%= l(:label_user_joinin) %><%= format_date(user.created_on) %> -
    -<% end %> -
    + +

    <%= l(:label_user_watcher)%>

    +
    + <% for user in @project.watcher_users %> +
      +
    • + + + + + +
      <%= image_tag(url_to_avatar(user), :class => "avatar") %> + + + + + + + + + +

      <%= content_tag "div", link_to_user(user), :class =>"project_avatar_name" %>

      +

      + <% unless user.memberships.empty? %> + <%= l(:label_contribute_to, :project_count => "#{user.memberships.count}") %> + <% for member in user.memberships %> + <%= link_to_project(member.project) %><%= (user.memberships.last == member) ? '' : ',' %> + <% end %> + <% end %> +

      <%= l(:label_user_joinin) %><%= format_date(user.created_on) %> +
    +<% end %> +
    <% html_title(l(:label_followers)) -%> \ No newline at end of file diff --git a/app/views/repositories/diff.html.erb b/app/views/repositories/diff.html.erb index 97630153a..3d206854d 100644 --- a/app/views/repositories/diff.html.erb +++ b/app/views/repositories/diff.html.erb @@ -1,27 +1,27 @@ -

    <%= l(:label_revision) %> <%= @diff_format_revisions %> <%=h @path %>

    - - -<%= form_tag({:action => 'diff', :id => @project, - :repository_id => @repository.identifier_param, - :path => to_path_param(@path), :rev=> @rev}, :method => 'get') do %> - <%= hidden_field_tag('rev_to', params[:rev_to]) if params[:rev_to] %> -

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

    -<% end %> - -<% cache(@cache_key) do -%> -<%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type, :diff_style => @repository.class.scm_name} %> -<% end -%> - -<%# other_formats_links do |f| %> - <%#= f.link_to 'Diff', :url => params, :caption => 'Unified diff' %> -<%# end %> - -<% html_title(with_leading_slash(@path), 'Diff') -%> - -<% content_for :header_tags do %> -<%= stylesheet_link_tag "scm" %> -<% end %> +

    <%= l(:label_revision) %> <%= @diff_format_revisions %> <%=h @path %>

    + + +<%= form_tag({:action => 'diff', :id => @project, + :repository_id => @repository.identifier_param, + :path => to_path_param(@path), :rev=> @rev}, :method => 'get') do %> + <%= hidden_field_tag('rev_to', params[:rev_to]) if params[:rev_to] %> +

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

    +<% end %> + +<% cache(@cache_key) do -%> +<%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type, :diff_style => @repository.class.scm_name} %> +<% end -%> + +<%# other_formats_links do |f| %> + <%#= f.link_to 'Diff', :url => params, :caption => 'Unified diff' %> +<%# end %> + +<% html_title(with_leading_slash(@path), 'Diff') -%> + +<% content_for :header_tags do %> +<%= stylesheet_link_tag "scm" %> +<% end %> diff --git a/app/views/settings/_display.html.erb b/app/views/settings/_display.html.erb index 1ae5a351a..e5056261a 100644 --- a/app/views/settings/_display.html.erb +++ b/app/views/settings/_display.html.erb @@ -1,26 +1,26 @@ -<%= form_tag({:action => 'edit', :tab => 'display'}) do %> - -
    -

    <%= setting_select :ui_theme, Redmine::Themes.themes.collect {|t| [t.name, t.id]}, :blank => :label_default, :label => :label_theme %>

    - -

    <%= setting_select :default_language, lang_options_for_select(false) %>

    - -

    <%= setting_select :start_of_week, [[day_name(1),'1'], [day_name(6),'6'], [day_name(7),'7']], :blank => :label_language_based %>

    -<% locale = User.current.language.blank? ? ::I18n.locale : User.current.language %> -

    <%= setting_select :date_format, Setting::DATE_FORMATS.collect {|f| [::I18n.l(Date.today, :locale => locale, :format => f), f]}, :blank => :label_language_based %>

    - -

    <%= setting_select :time_format, Setting::TIME_FORMATS.collect {|f| [::I18n.l(Time.now, :locale => locale, :format => f), f]}, :blank => :label_language_based %>

    - -

    <%= setting_select :user_format, @options[:user_format] %>

    - -

    <%= setting_check_box :gravatar_enabled %>

    - -

    <%= setting_select :gravatar_default, [["Wavatars", 'wavatar'], ["Identicons", 'identicon'], ["Monster ids", 'monsterid'], ["Retro", 'retro'], ["Mystery man", 'mm']], :blank => :label_none %>

    - -

    <%= setting_check_box :thumbnails_enabled %>

    - -

    <%= setting_text_field :thumbnails_size, :size => 6 %>

    -
    - -<%= submit_tag l(:button_save) %> -<% end %> +<%= form_tag({:action => 'edit', :tab => 'display'}) do %> + +
    +

    <%= setting_select :ui_theme, Redmine::Themes.themes.collect {|t| [t.name, t.id]}, :blank => :label_default, :label => :label_theme %>

    + +

    <%= setting_select :default_language, lang_options_for_select(false) %>

    + +

    <%= setting_select :start_of_week, [[day_name(1),'1'], [day_name(6),'6'], [day_name(7),'7']], :blank => :label_language_based %>

    +<% locale = User.current.language.blank? ? ::I18n.locale : User.current.language %> +

    <%= setting_select :date_format, Setting::DATE_FORMATS.collect {|f| [::I18n.l(Date.today, :locale => locale, :format => f), f]}, :blank => :label_language_based %>

    + +

    <%= setting_select :time_format, Setting::TIME_FORMATS.collect {|f| [::I18n.l(Time.now, :locale => locale, :format => f), f]}, :blank => :label_language_based %>

    + +

    <%= setting_select :user_format, @options[:user_format] %>

    + +

    <%= setting_check_box :gravatar_enabled %>

    + +

    <%= setting_select :gravatar_default, [["Wavatars", 'wavatar'], ["Identicons", 'identicon'], ["Monster ids", 'monsterid'], ["Retro", 'retro'], ["Mystery man", 'mm']], :blank => :label_none %>

    + +

    <%= setting_check_box :thumbnails_enabled %>

    + +

    <%= setting_text_field :thumbnails_size, :size => 6 %>

    +
    + +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/app/views/softapplications/_list.html.erb b/app/views/softapplications/_list.html.erb index 860b157c3..b31cfa9f9 100644 --- a/app/views/softapplications/_list.html.erb +++ b/app/views/softapplications/_list.html.erb @@ -1,35 +1,35 @@ - - <% @softapplications.each do |softapplication| %> -
    - <%= link_to softapplication.name, softapplication, :target => "_blank" %> - <%= rating_for softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %> - -
    -
    <%= image_tag('/images/app1.png')%>
    -
    -
    - <%contest = softapplication.contests.first%> - <%=l(:label_attendingcontestwork_belongs_contest)%>:<%= contest ? link_to(contest.name.truncate(14, omission: '...'), show_attendingcontest_contest_path(contest), title: contest.name.to_s ) : '尚未加入竞赛'%> -

    - <%= l(:label_profile) %>:<%= softapplication.description.truncate(95, omission: '...') %> - -
    - -
    - <% strTitle = softapplication.android_min_version_available %> -

    <%=l(:label_attendingcontestwork_adaptive_system)%>:<%= strTitle ? strTitle.truncate(10,omisiion:'...') : "" %>

    - - - -

    <%=l(:label_attendingcontestwork_belongs_type)%>:<%= softapplication.app_type_name ? softapplication.app_type_name.truncate(14, omission: '...') : "" %>

    -
    -
    - - <%=l(:label_attendingcontestwork_developers)%>:<%= softapplication.application_developers %> - <%=l(:label_attendingcontestwork_release_time)%>:<%=format_time softapplication.created_at %> -
    -
    -
    - <% end %> - + + <% @softapplications.each do |softapplication| %> +
    + <%= link_to softapplication.name, softapplication, :target => "_blank" %> + <%= rating_for softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %> + +
    +
    <%= image_tag('/images/app1.png')%>
    +
    +
    + <%contest = softapplication.contests.first%> + <%=l(:label_attendingcontestwork_belongs_contest)%>:<%= contest ? link_to(contest.name.truncate(14, omission: '...'), show_attendingcontest_contest_path(contest), title: contest.name.to_s ) : '尚未加入竞赛'%> +

    + <%= l(:label_profile) %>:<%= softapplication.description.truncate(95, omission: '...') %> + +
    + +
    + <% strTitle = softapplication.android_min_version_available %> +

    <%=l(:label_attendingcontestwork_adaptive_system)%>:<%= strTitle ? strTitle.truncate(10,omisiion:'...') : "" %>

    + + + +

    <%=l(:label_attendingcontestwork_belongs_type)%>:<%= softapplication.app_type_name ? softapplication.app_type_name.truncate(14, omission: '...') : "" %>

    +
    +
    + + <%=l(:label_attendingcontestwork_developers)%>:<%= softapplication.application_developers %> + <%=l(:label_attendingcontestwork_release_time)%>:<%=format_time softapplication.created_at %> +
    +
    +
    + <% end %> + \ No newline at end of file diff --git a/app/views/softapplications/show.html.erb b/app/views/softapplications/show.html.erb index 1d6d46e9e..5aa40bf90 100644 --- a/app/views/softapplications/show.html.erb +++ b/app/views/softapplications/show.html.erb @@ -1,143 +1,143 @@ -<%= render :partial => 'layouts/base_softapplication_top_content' %> -
    - - - - - - - - - - - - <% contest = @softapplication.contests.first %> - - - - - - - - - - - - - - - - - -
    <%= @softapplication.name %> - <%= link_to '删除', softapplication_path(@softapplication), method: :delete, data: {confirm: '您确定要删除吗?'} if @softapplication.destroyable_by? User.current %>  - <%= link_to '编辑', edit_softapplication_path(@softapplication), method: :get if @softapplication.destroyable_by? User.current %> -
    - <%=l(:label_attendingcontestwork_belongs_type)%>: - <%= @softapplication.app_type_name %> - <%=l(:label_attendingcontestwork_belongs_contest)%>: - <%= contest ? link_to(contest.name, show_attendingcontest_contest_path(contest)) : '尚未加入竞赛' %> -
    - <%=l(:label_attendingcontestwork_release_person)%>: - <%= @softapplication.user.name %> - - <%=l(:label_attendingcontestwork_adaptive_system)%>: - <%= @softapplication.android_min_version_available %> -
    - <%=l(:label_attendingcontestwork_download)%>: - - <% options = {:author => true, :deletable => @softapplication.user.eql?(User.current)} %><%= render :partial => 'attachments/app_link', :locals => {:attachments => @app_items, :options => options} %> - - <%=l(:label_attendingcontestwork_developers)%>:<%= @softapplication.application_developers %>
    <%=l(:label_attendingcontestwork_average_scores)%>: <%= rating_for @softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %><%=l(:label_attendingcontestwork_release_time)%>:<%=format_time @softapplication.created_at %>
    - <% if @project %> - <%=l(:label_attendingcontestwork_deposit_project)%>:<%= link_to "#@project", project_path(@project) %> - <% end %> -
    - - -
    -
    - -
    - -
    <%=l(:label_work_description)%>:
    -
    -
    <%= @softapplication.description %>
    -
    -
    - -
    -
    <%=l(:label_work_scores)%>:
    - -
    -
    -
    <%=l(:label_work_scores_proportion)%>
    -
    - <% 100.step(20, -20) do |star| %> -
    -
    -
    -
    -
    -
    - <%= @stars_status_map["star#{(star/20).to_s}".to_sym] %> -
    - <% end %> -
    -
    -
    -
    <%=l(:label_final_scores)%>
    -
    <%= @softapplication.average(:quality).try(:avg).try(:round, 2).to_i.to_s %>分
    -
    <%= rating_for @softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %>
    -
    -
    -
    <%=l(:label_rating_person_amount)%>
    -
    - <%= @softapplication.raters(:quality).count %>
    -
    -
    -
    -
    - -
    - -
    <%=l(:label_work_photo)%>:
    -
    - -
    -
      - <% @image_results.take(4).each do |attachment| %> -
    • - - <%= link_to_attachment_img attachment, :class => "soft-application", :download => "true"%> -
    • - <% end %> -
    -
    -
    -
    - -
    - -
    -
    - <%=l(:label_work_comment)%>: -
    - <% if (User.current.logged? and User.current.id != @softapplication.user_id) %> -
    <%=l(:label_work_rating)%>: <%= rating_for @softapplication, dimension: :quality, class: 'rateable div_inline' %> - (<%=l(:label_attendingcontestwork_sorting_intimation)%>)
    - <% end %> -
    - -
    - <%= render :partial => 'message_history', :locals => {:contest => @softapplication, :journals => @jour, :state => false} %> -
    - - - +<%= render :partial => 'layouts/base_softapplication_top_content' %> +
    + + + + + + + + + + + + <% contest = @softapplication.contests.first %> + + + + + + + + + + + + + + + + + +
    <%= @softapplication.name %> + <%= link_to '删除', softapplication_path(@softapplication), method: :delete, data: {confirm: '您确定要删除吗?'} if @softapplication.destroyable_by? User.current %>  + <%= link_to '编辑', edit_softapplication_path(@softapplication), method: :get if @softapplication.destroyable_by? User.current %> +
    + <%=l(:label_attendingcontestwork_belongs_type)%>: + <%= @softapplication.app_type_name %> + <%=l(:label_attendingcontestwork_belongs_contest)%>: + <%= contest ? link_to(contest.name, show_attendingcontest_contest_path(contest)) : '尚未加入竞赛' %> +
    + <%=l(:label_attendingcontestwork_release_person)%>: + <%= @softapplication.user.name %> + + <%=l(:label_attendingcontestwork_adaptive_system)%>: + <%= @softapplication.android_min_version_available %> +
    + <%=l(:label_attendingcontestwork_download)%>: + + <% options = {:author => true, :deletable => @softapplication.user.eql?(User.current)} %><%= render :partial => 'attachments/app_link', :locals => {:attachments => @app_items, :options => options} %> + + <%=l(:label_attendingcontestwork_developers)%>:<%= @softapplication.application_developers %>
    <%=l(:label_attendingcontestwork_average_scores)%>: <%= rating_for @softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %><%=l(:label_attendingcontestwork_release_time)%>:<%=format_time @softapplication.created_at %>
    + <% if @project %> + <%=l(:label_attendingcontestwork_deposit_project)%>:<%= link_to "#@project", project_path(@project) %> + <% end %> +
    + + +
    +
    + +
    + +
    <%=l(:label_work_description)%>:
    +
    +
    <%= @softapplication.description %>
    +
    +
    + +
    +
    <%=l(:label_work_scores)%>:
    + +
    +
    +
    <%=l(:label_work_scores_proportion)%>
    +
    + <% 100.step(20, -20) do |star| %> +
    +
    +
    +
    +
    +
    + <%= @stars_status_map["star#{(star/20).to_s}".to_sym] %> +
    + <% end %> +
    +
    +
    +
    <%=l(:label_final_scores)%>
    +
    <%= @softapplication.average(:quality).try(:avg).try(:round, 2).to_i.to_s %>分
    +
    <%= rating_for @softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %>
    +
    +
    +
    <%=l(:label_rating_person_amount)%>
    +
    + <%= @softapplication.raters(:quality).count %>
    +
    +
    +
    +
    + +
    + +
    <%=l(:label_work_photo)%>:
    +
    + +
    +
      + <% @image_results.take(4).each do |attachment| %> +
    • + + <%= link_to_attachment_img attachment, :class => "soft-application", :download => "true"%> +
    • + <% end %> +
    +
    +
    +
    + +
    + +
    +
    + <%=l(:label_work_comment)%>: +
    + <% if (User.current.logged? and User.current.id != @softapplication.user_id) %> +
    <%=l(:label_work_rating)%>: <%= rating_for @softapplication, dimension: :quality, class: 'rateable div_inline' %> + (<%=l(:label_attendingcontestwork_sorting_intimation)%>)
    + <% end %> +
    + +
    + <%= render :partial => 'message_history', :locals => {:contest => @softapplication, :journals => @jour, :state => false} %> +
    + + + diff --git a/app/views/stores/index.html.erb b/app/views/stores/index.html.erb index afd2244af..1b86bbd64 100644 --- a/app/views/stores/index.html.erb +++ b/app/views/stores/index.html.erb @@ -1,72 +1,72 @@ -<% content_for :top_field do%> - <%= render 'search_bar' %> -<% end %> - -
    -<% @attach_array.each do |k|%> -
    -

    - <%= @str_arr.shift %> -

    - -
    -
    -
    <%=l(:label_attachment)%>
    -
    <%=l(:field_downloads)%>
    -
    <%=l(:button_download)%>
    -
    -
    - -
    - <% k.each do |c1|%> -
    -
    - <%= link_to c1.filename, (attachFromUrl c1), {:title => c1.filename, :target => "_blank"} %> -
    -
    - <%= c1.downloads %> -
    -
    - <%= link_to_attachment c1, {:download => true, :text => image_tag("/images/button/download.png", width: "22px", alt: l(:button_download)) }%> -
    -
    - <% end -%> -
    - -
    -<% end; reset_cycle %> -
    - +<% content_for :top_field do%> + <%= render 'search_bar' %> +<% end %> + +
    +<% @attach_array.each do |k|%> +
    +

    + <%= @str_arr.shift %> +

    + +
    +
    +
    <%=l(:label_attachment)%>
    +
    <%=l(:field_downloads)%>
    +
    <%=l(:button_download)%>
    +
    +
    + +
    + <% k.each do |c1|%> +
    +
    + <%= link_to c1.filename, (attachFromUrl c1), {:title => c1.filename, :target => "_blank"} %> +
    +
    + <%= c1.downloads %> +
    +
    + <%= link_to_attachment c1, {:download => true, :text => image_tag("/images/button/download.png", width: "22px", alt: l(:button_download)) }%> +
    +
    + <% end -%> +
    + +
    +<% end; reset_cycle %> +
    + <% html_title(l(:label_stores_index)) -%> \ No newline at end of file diff --git a/app/views/tags/_show_attachments.html.erb b/app/views/tags/_show_attachments.html.erb index 4accf4f64..fac2a4584 100644 --- a/app/views/tags/_show_attachments.html.erb +++ b/app/views/tags/_show_attachments.html.erb @@ -1,34 +1,34 @@ -
    -<% if attachments_results.nil? || attachments_results.try(:size).to_i < 0 %> -<% else %> -
    - <% attachments_results.each do |file| %> -

    - - - - - - -
    -
    - <%= l(:label_attachment) %>:  <%= file.filename %> - - <%= link_to_attachment file, {:download => true, :text => image_tag("/images/button/dl.png", width: "70px", alt: l(:button_download), :class => 'download_icon')}%> - -
    - <%= l(:field_description) %>:  <%= file.description %> -
    所属分类:<%=result_come_from file%>
    - - 下载:<%= file.downloads%>| - 大小:<%= number_to_human_size(file.filesize) %>| - 共享者:<%= link_to file.author, user_path(file.author), target: "_blank" unless file.author.blank? %>| - 上传时间:<%= format_time(file.created_on) %> - -
    -
    -

    -
    - <% end %> -<% end %> -
    +
    +<% if attachments_results.nil? || attachments_results.try(:size).to_i < 0 %> +<% else %> +
    + <% attachments_results.each do |file| %> +

    + + + + + + +
    +
    + <%= l(:label_attachment) %>:  <%= file.filename %> + + <%= link_to_attachment file, {:download => true, :text => image_tag("/images/button/dl.png", width: "70px", alt: l(:button_download), :class => 'download_icon')}%> + +
    + <%= l(:field_description) %>:  <%= file.description %> +
    所属分类:<%=result_come_from file%>
    + + 下载:<%= file.downloads%>| + 大小:<%= number_to_human_size(file.filesize) %>| + 共享者:<%= link_to file.author, user_path(file.author), target: "_blank" unless file.author.blank? %>| + 上传时间:<%= format_time(file.created_on) %> + +
    +
    +

    +
    + <% end %> +<% end %> +
    diff --git a/app/views/tags/_show_bids.html.erb b/app/views/tags/_show_bids.html.erb index ef6c5ad52..445bc4e40 100644 --- a/app/views/tags/_show_bids.html.erb +++ b/app/views/tags/_show_bids.html.erb @@ -1,15 +1,15 @@ -
    - <% if bids_results.try(:size).to_i > 0 %> -
    - <% bids_results.each do |bid| %> -

    - <%= l(:label_tags_bid) %>:<%= link_to "#{bid.name}", - :controller => "bids",:action => "show",:id => bid.id %> -
    - <%= l(:label_tags_bid_description) %>:<%= textilizable bid.description %> - <%= bid.updated_on %> -

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

    + <%= l(:label_tags_bid) %>:<%= link_to "#{bid.name}", + :controller => "bids",:action => "show",:id => bid.id %> +
    + <%= l(:label_tags_bid_description) %>:<%= textilizable bid.description %> + <%= bid.updated_on %> +

    +
    + <% end %> + <% end %> +
    diff --git a/app/views/tags/_show_courses.html.erb b/app/views/tags/_show_courses.html.erb index 1e118541b..32bd55f2c 100644 --- a/app/views/tags/_show_courses.html.erb +++ b/app/views/tags/_show_courses.html.erb @@ -1,14 +1,14 @@ -
    - <% if courses_results.try(:size).to_i > 0 %> -
    - <% courses_results.each do |course| %> -

    - <%= l(:label_course) %>:<%= link_to "#{course.name}",course_path(course) %> -
    - <%= l(:label_new_course_description) %>:<%= textilizable course.description %> - <%= course.updated_at %> -

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

    + <%= l(:label_course) %>:<%= link_to "#{course.name}",course_path(course) %> +
    + <%= l(:label_new_course_description) %>:<%= textilizable course.description %> + <%= course.updated_at %> +

    +
    + <% end %> + <% end %> +
    diff --git a/app/views/tags/_show_forums.html.erb b/app/views/tags/_show_forums.html.erb index 3caba4903..4f6db4ae1 100644 --- a/app/views/tags/_show_forums.html.erb +++ b/app/views/tags/_show_forums.html.erb @@ -1,15 +1,15 @@ -
    - <% if forums_results.try(:size).to_i > 0 %> -
    - <% forums_results.each do |forum| %> -

    - <%= l(:label_tags_forum) %>:<%= link_to "#{forum.name}", - :controller => "forums",:action => "show",:id => forum.id %> -
    - <%= l(:label_tags_forum_description) %>:<%= textAreailizable forum.description %> - <%= forum.updated_at %> -

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

    + <%= l(:label_tags_forum) %>:<%= link_to "#{forum.name}", + :controller => "forums",:action => "show",:id => forum.id %> +
    + <%= l(:label_tags_forum_description) %>:<%= textAreailizable forum.description %> + <%= forum.updated_at %> +

    +
    + <% end %> + <% end %> +
    diff --git a/app/views/tags/_show_issues.html.erb b/app/views/tags/_show_issues.html.erb index ea35dbff5..d02737e21 100644 --- a/app/views/tags/_show_issues.html.erb +++ b/app/views/tags/_show_issues.html.erb @@ -1,15 +1,15 @@ -
    - <% if issues_results.try(:size).to_i > 0 %> -
    - <% issues_results.each do |issue| %> -

    - <%= l(:label_tags_issue) %><%= link_to "#{issue.subject}",:controller => "issues",:action => "show",:id => issue.id %> -
    - <%= l(:label_tags_issue_description) %>:<%= textilizable issue.description %> -

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

    + <%= l(:label_tags_issue) %><%= link_to "#{issue.subject}",:controller => "issues",:action => "show",:id => issue.id %> +
    + <%= l(:label_tags_issue_description) %>:<%= textilizable issue.description %> +

    +
    + <% end %> + + <% end %> +
    + diff --git a/app/views/tags/_show_open_source_projects.html.erb b/app/views/tags/_show_open_source_projects.html.erb index 5f9dae299..311863885 100644 --- a/app/views/tags/_show_open_source_projects.html.erb +++ b/app/views/tags/_show_open_source_projects.html.erb @@ -1,15 +1,15 @@ -
    -<% if projects_results.try(:size).to_i > 0 %> -
    -<% projects_results.each do |prj| %> -
    -

    - <%= l(:label_tags_project_name) %><%= link_to "#{prj.name}",:controller => "open_source_projects",:action => "show",:id => prj.id %> -
    - <%= l(:label_tags_project_description) %><%= textilizable prj.short_description %> -

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

    + <%= l(:label_tags_project_name) %><%= link_to "#{prj.name}",:controller => "open_source_projects",:action => "show",:id => prj.id %> +
    + <%= l(:label_tags_project_description) %><%= textilizable prj.short_description %> +

    +
    +
    +<% end %> +<% end %> +
    diff --git a/app/views/tags/_show_projects.html.erb b/app/views/tags/_show_projects.html.erb index 7ed32cba1..2b6b42189 100644 --- a/app/views/tags/_show_projects.html.erb +++ b/app/views/tags/_show_projects.html.erb @@ -1,15 +1,15 @@ -
    -<% if projects_results.try(:size).to_i > 0 %> -
    -<% projects_results.each do |prj| %> -
    -

    - <%= l(:label_tags_project_name) %><%= link_to "#{prj.name}",:controller => "projects",:action => "show",:id => prj.id %> -
    - <%= l(:label_tags_project_description) %><%= textilizable prj.description %> -

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

    + <%= l(:label_tags_project_name) %><%= link_to "#{prj.name}",:controller => "projects",:action => "show",:id => prj.id %> +
    + <%= l(:label_tags_project_description) %><%= textilizable prj.description %> +

    +
    +
    +<% end %> +<% end %> +
    diff --git a/app/views/tags/_tag.html.erb b/app/views/tags/_tag.html.erb index 405f8f2e3..4d3414a1f 100644 --- a/app/views/tags/_tag.html.erb +++ b/app/views/tags/_tag.html.erb @@ -1,84 +1,84 @@ -
    - <%#begin - 1 代表是user类型 - 2 代表是project类型 - 3 代表是issue类型 - 4 代表是bid类型 - 5 代表是forum类型 - 6 代表是Attachment类型 - 7 代表是contest类型 - 8 代表是OpenSourceProject类型 - 9 代表是RelativeMemo类型 - #end%> - - <% if object_flag == '3' %> - - <%= image_tag("/images/sidebar/tags.png") %> - - - <%= l(:label_tag) %>: - - <% if User.current.logged? %> - - <%= toggle_link (image_tag "/images/sidebar/add.png"), 'put-tag-form-issue', {:focus => 'name-issue'} %> - - <% end %> - -
    - <%= render :partial => "tags/tag_name",:locals => {:obj => obj,:non_list_all => false ,:object_flag => object_flag} %> -
    - - - <% elsif object_flag == '6' %> - <%#= image_tag("/images/sidebar/tags.png") %> - - <%= link_to (image_tag "/images/sidebar/add.png"), 'javascript:void(0);', - :class => "tags_icona", - :onclick=>"$('#put-tag-form-#{obj.class}-#{obj.id}').toggle(); readmore(this);" if User.current.logged? %> - <%#= toggle_link (image_tag "/images/sidebar/add.png"), "put-tag-form-#{obj.class}-#{obj.id}", {:focus => "put-tag-form-#{obj.class}-#{obj.id} #name"} if User.current.logged? %> - -    -
    - <%= render :partial => "tags/tag_name",:locals => {:obj => obj,:non_list_all => false ,:object_flag => object_flag} %> -
    - - <% else %> - - <%= image_tag("/images/sidebar/tags.png") %> - - - <%= l(:label_tag) %>: - - <% if User.current.logged? %> - - <%= toggle_link (image_tag "/images/sidebar/add.png"), 'put-tag-form', {:focus => 'tags_name'} %> - - <% end %> -
    - <%= render :partial => "tags/tag_name",:locals => {:obj => obj,:non_list_all => false ,:object_flag => object_flag} %> -
    - -<% end %> -
    +
    + <%#begin + 1 代表是user类型 + 2 代表是project类型 + 3 代表是issue类型 + 4 代表是bid类型 + 5 代表是forum类型 + 6 代表是Attachment类型 + 7 代表是contest类型 + 8 代表是OpenSourceProject类型 + 9 代表是RelativeMemo类型 + #end%> + + <% if object_flag == '3' %> + + <%= image_tag("/images/sidebar/tags.png") %> + + + <%= l(:label_tag) %>: + + <% if User.current.logged? %> + + <%= toggle_link (image_tag "/images/sidebar/add.png"), 'put-tag-form-issue', {:focus => 'name-issue'} %> + + <% end %> + +
    + <%= render :partial => "tags/tag_name",:locals => {:obj => obj,:non_list_all => false ,:object_flag => object_flag} %> +
    + + + <% elsif object_flag == '6' %> + <%#= image_tag("/images/sidebar/tags.png") %> + + <%= link_to (image_tag "/images/sidebar/add.png"), 'javascript:void(0);', + :class => "tags_icona", + :onclick=>"$('#put-tag-form-#{obj.class}-#{obj.id}').toggle(); readmore(this);" if User.current.logged? %> + <%#= toggle_link (image_tag "/images/sidebar/add.png"), "put-tag-form-#{obj.class}-#{obj.id}", {:focus => "put-tag-form-#{obj.class}-#{obj.id} #name"} if User.current.logged? %> + +    +
    + <%= render :partial => "tags/tag_name",:locals => {:obj => obj,:non_list_all => false ,:object_flag => object_flag} %> +
    + + <% else %> + + <%= image_tag("/images/sidebar/tags.png") %> + + + <%= l(:label_tag) %>: + + <% if User.current.logged? %> + + <%= toggle_link (image_tag "/images/sidebar/add.png"), 'put-tag-form', {:focus => 'tags_name'} %> + + <% end %> +
    + <%= render :partial => "tags/tag_name",:locals => {:obj => obj,:non_list_all => false ,:object_flag => object_flag} %> +
    + +<% end %> +
    diff --git a/app/views/tags/_tag_search_results.html.erb b/app/views/tags/_tag_search_results.html.erb index 3ed4ba112..84a672617 100644 --- a/app/views/tags/_tag_search_results.html.erb +++ b/app/views/tags/_tag_search_results.html.erb @@ -1,46 +1,46 @@ -
      - <% unless show_flag.nil? %> - <% case %> - <% when show_flag == '1' %> - <%=l(:label_user)%>(<%= @results_count %>) - <%= render :partial => "show_users",:locals => {:users_results => users_results}%> - <% when show_flag == '2'%> - <%=l(:label_project)%>(<%= @results_count %>) - <%= render :partial => "show_projects",:locals => {:projects_results => projects_results }%> - <% when show_flag == '3'%> - <%=l(:label_issue)%>(<%= @results_count %>) - <%= render :partial => "show_issues",:locals => {:issues_results => issues_results }%> - <% when show_flag == '4'%> - <%= l(:label_requirement)%>(<%= @results_count %>) - <%= render :partial => "show_bids",:locals => {:bids_results => bids_results}%> - <% when show_flag == '5'%> - <%= l(:label_forum)%>(<%= @results_count %>) - <%= render :partial => "show_forums",:locals => {:forums_results => forums_results}%> - <% when show_flag == '6'%> - <%= l(:label_attachment)%>(<%= @results_count %>) - <%= render :partial => "show_attachments",:locals => {:attachments_results => attachments_results}%> - <% when show_flag == '7'%> - <%= l(:label_contest_innovate)%>(<%= @results_count %>) - <%= render :partial => "show_contests",:locals => {:contests_results => contests_results}%> - <% when show_flag == '8'%> - <%#= l(:label_attachment)%> - 开源项目:(<%= @results_count %>) - <%= render :partial => "show_open_source_projects",:locals => {:projects_results => open_source_projects_results}%> - <% when show_flag == '9'%> - <%= l(:label_course)%>(<%= @results_count %>) - <%= render :partial => "show_courses",:locals => {:courses_results => courses_results}%> - <% else %> - <%= l(:label_tags_all_objects)%> - - <%= render :partial => "show_issues",:locals => {:issues_results => issues_results }%> - <%= render :partial => "show_users",:locals => {:users_results => users_results }%> - <%= render :partial => "show_projects",:locals => {:projects_results => projects_results }%> - <%= render :partial => "show_bids",:locals => {:bids_results => bids_results}%> - <%= render :partial => "show_contests",:locals => {:contests_results => contests_results}%> - <% end %> - - <% else %> - no data... - <% end %> -
    -<%= render :partial => "pagination",:locals => {:obj_pages => @obj_pages} %> +
      + <% unless show_flag.nil? %> + <% case %> + <% when show_flag == '1' %> + <%=l(:label_user)%>(<%= @results_count %>) + <%= render :partial => "show_users",:locals => {:users_results => users_results}%> + <% when show_flag == '2'%> + <%=l(:label_project)%>(<%= @results_count %>) + <%= render :partial => "show_projects",:locals => {:projects_results => projects_results }%> + <% when show_flag == '3'%> + <%=l(:label_issue)%>(<%= @results_count %>) + <%= render :partial => "show_issues",:locals => {:issues_results => issues_results }%> + <% when show_flag == '4'%> + <%= l(:label_requirement)%>(<%= @results_count %>) + <%= render :partial => "show_bids",:locals => {:bids_results => bids_results}%> + <% when show_flag == '5'%> + <%= l(:label_forum)%>(<%= @results_count %>) + <%= render :partial => "show_forums",:locals => {:forums_results => forums_results}%> + <% when show_flag == '6'%> + <%= l(:label_attachment)%>(<%= @results_count %>) + <%= render :partial => "show_attachments",:locals => {:attachments_results => attachments_results}%> + <% when show_flag == '7'%> + <%= l(:label_contest_innovate)%>(<%= @results_count %>) + <%= render :partial => "show_contests",:locals => {:contests_results => contests_results}%> + <% when show_flag == '8'%> + <%#= l(:label_attachment)%> + 开源项目:(<%= @results_count %>) + <%= render :partial => "show_open_source_projects",:locals => {:projects_results => open_source_projects_results}%> + <% when show_flag == '9'%> + <%= l(:label_course)%>(<%= @results_count %>) + <%= render :partial => "show_courses",:locals => {:courses_results => courses_results}%> + <% else %> + <%= l(:label_tags_all_objects)%> + + <%= render :partial => "show_issues",:locals => {:issues_results => issues_results }%> + <%= render :partial => "show_users",:locals => {:users_results => users_results }%> + <%= render :partial => "show_projects",:locals => {:projects_results => projects_results }%> + <%= render :partial => "show_bids",:locals => {:bids_results => bids_results}%> + <%= render :partial => "show_contests",:locals => {:contests_results => contests_results}%> + <% end %> + + <% else %> + no data... + <% end %> +
    +<%= render :partial => "pagination",:locals => {:obj_pages => @obj_pages} %> diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index bf2c8c31c..47a2ba1d2 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -1,48 +1,48 @@ -<% content_for :sidebar do %> -
    -

    <%= l(:label_tags_selected) %>

    -
    - <%= render :partial => "selected_tags",:locals => { - :selected_tags => @selected_tags,:obj_flag => @obj_flag,:obj_id => @obj_id }%> -
    - -

    <%= l(:label_tags_related) %>

    - -
    -<% end %> -<% content_for :content do %> -
    -

    <%= l(:label_tags_search_result) %>

    -
    - <%= l(:label_tags_numbers) %> - <%= l(:label_issue_plural) %>(<%= @issues_tags_num %>) | - <%= l(:label_project_plural) %>(<%= @projects_tags_num %>) | - <%= l(:label_user_plural) %>(<%= @users_tags_num %>) | - <%= l(:label_tags_call)%>(<%= @bids_tags_num %>) | - <%= l(:field_filename)%>(<%= @attachments_tags_num %>) | - 开源项目(<%= @open_source_projects_num %>) | - <%= l(:label_tags_contest)%>(<%= @contests_tags_num %>) | -
    -
    - <%# 求工厂模式重构 %> - <%= render :partial => "tag_search_results", - :locals => {:issues_results => @issues_results, - :projects_results => @projects_results, - :users_results => @users_results, - :bids_results => @bids_results, - :forums_results => @forums_results, - :attachments_results=> @attachments_results, - :contests_results => @contests_results, - :open_source_projects_results => @open_source_projects_results, - :courses_results => @courses_results, - :show_flag => @obj_flag} - %> -
    - -
    - -<% end %> - +<% content_for :sidebar do %> +
    +

    <%= l(:label_tags_selected) %>

    +
    + <%= render :partial => "selected_tags",:locals => { + :selected_tags => @selected_tags,:obj_flag => @obj_flag,:obj_id => @obj_id }%> +
    + +

    <%= l(:label_tags_related) %>

    + +
    +<% end %> +<% content_for :content do %> +
    +

    <%= l(:label_tags_search_result) %>

    +
    + <%= l(:label_tags_numbers) %> + <%= l(:label_issue_plural) %>(<%= @issues_tags_num %>) | + <%= l(:label_project_plural) %>(<%= @projects_tags_num %>) | + <%= l(:label_user_plural) %>(<%= @users_tags_num %>) | + <%= l(:label_tags_call)%>(<%= @bids_tags_num %>) | + <%= l(:field_filename)%>(<%= @attachments_tags_num %>) | + 开源项目(<%= @open_source_projects_num %>) | + <%= l(:label_tags_contest)%>(<%= @contests_tags_num %>) | +
    +
    + <%# 求工厂模式重构 %> + <%= render :partial => "tag_search_results", + :locals => {:issues_results => @issues_results, + :projects_results => @projects_results, + :users_results => @users_results, + :bids_results => @bids_results, + :forums_results => @forums_results, + :attachments_results=> @attachments_results, + :contests_results => @contests_results, + :open_source_projects_results => @open_source_projects_results, + :courses_results => @courses_results, + :show_flag => @obj_flag} + %> +
    + +
    + +<% end %> + diff --git a/app/views/timelog/_form.html.erb b/app/views/timelog/_form.html.erb index a3c0fa81b..a448e63c6 100644 --- a/app/views/timelog/_form.html.erb +++ b/app/views/timelog/_form.html.erb @@ -1,32 +1,32 @@ -<%= error_messages_for 'time_entry' %> -<%= back_url_hidden_field_tag %> - -
    - <% if @time_entry.new_record? %> - <% if params[:project_id] || @time_entry.issue %> - <%= f.hidden_field :project_id %> - <% else %> -

    <%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %>

    - <% end %> - <% end %> -

    - <%= f.text_field :issue_id, :size => 6 %> - <%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %> -

    -

    <%= f.text_field :spent_on, :size => 10, :required => true, :readonly => true %><%= calendar_for('time_entry_spent_on') %>

    -

    <%= f.text_field :hours, :size => 6, :required => true %>

    -

    <%= f.text_field :comments, :size => 100, :maxlength => 255 %>

    -

    <%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %>

    - <% @time_entry.custom_field_values.each do |value| %> -

    <%= custom_field_tag_with_label :time_entry, value %>

    - <% end %> - <%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %> -
    - -<%= javascript_tag do %> - observeAutocompleteField('time_entry_issue_id', '<%= escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))%>', { - select: function(event, ui) { - $('#time_entry_issue').text(ui.item.label); - } - }); -<% end %> +<%= error_messages_for 'time_entry' %> +<%= back_url_hidden_field_tag %> + +
    + <% if @time_entry.new_record? %> + <% if params[:project_id] || @time_entry.issue %> + <%= f.hidden_field :project_id %> + <% else %> +

    <%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %>

    + <% end %> + <% end %> +

    + <%= f.text_field :issue_id, :size => 6 %> + <%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %> +

    +

    <%= f.text_field :spent_on, :size => 10, :required => true, :readonly => true %><%= calendar_for('time_entry_spent_on') %>

    +

    <%= f.text_field :hours, :size => 6, :required => true %>

    +

    <%= f.text_field :comments, :size => 100, :maxlength => 255 %>

    +

    <%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %>

    + <% @time_entry.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :time_entry, value %>

    + <% end %> + <%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %> +
    + +<%= javascript_tag do %> + observeAutocompleteField('time_entry_issue_id', '<%= escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))%>', { + select: function(event, ui) { + $('#time_entry_issue').text(ui.item.label); + } + }); +<% end %> diff --git a/app/views/timelog/bulk_edit.html.erb b/app/views/timelog/bulk_edit.html.erb index a7ccc36fc..649c7b0d9 100644 --- a/app/views/timelog/bulk_edit.html.erb +++ b/app/views/timelog/bulk_edit.html.erb @@ -1,50 +1,50 @@ -

    <%= l(:label_bulk_edit_selected_time_entries) %>

    - -
      -<% @time_entries.each do |entry| %> - <%= content_tag 'li', - link_to("#{format_date(entry.spent_on)} - #{entry.project}: #{l(:label_f_hour_plural, :value => entry.hours)}", edit_time_entry_path(entry)) %> -<% end %> -
    - -<%= form_tag(bulk_update_time_entries_path, :id => 'bulk_edit_form') do %> -<%= @time_entries.collect {|i| hidden_field_tag('ids[]', i.id)}.join.html_safe %> -
    -
    -

    - - <%= text_field :time_entry, :issue_id, :size => 6 %> -

    - -

    - - <%= text_field :time_entry, :spent_on, :size => 10, :readonly => true %><%= calendar_for('time_entry_spent_on') %> -

    - -

    - - <%= text_field :time_entry, :hours, :size => 6 %> -

    - - <% if @available_activities.any? %> -

    - - <%= select_tag('time_entry[activity_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_activities, :id, :name)) %> -

    - <% end %> - -

    - - <%= text_field(:time_entry, :comments, :size => 100) %> -

    - - <% @custom_fields.each do |custom_field| %> -

    <%= custom_field_tag_for_bulk_edit('time_entry', custom_field, @projects) %>

    - <% end %> - - <%= call_hook(:view_time_entries_bulk_edit_details_bottom, { :time_entries => @time_entries }) %> -
    -
    - -

    <%= submit_tag l(:button_submit) %>

    -<% end %> +

    <%= l(:label_bulk_edit_selected_time_entries) %>

    + +
      +<% @time_entries.each do |entry| %> + <%= content_tag 'li', + link_to("#{format_date(entry.spent_on)} - #{entry.project}: #{l(:label_f_hour_plural, :value => entry.hours)}", edit_time_entry_path(entry)) %> +<% end %> +
    + +<%= form_tag(bulk_update_time_entries_path, :id => 'bulk_edit_form') do %> +<%= @time_entries.collect {|i| hidden_field_tag('ids[]', i.id)}.join.html_safe %> +
    +
    +

    + + <%= text_field :time_entry, :issue_id, :size => 6 %> +

    + +

    + + <%= text_field :time_entry, :spent_on, :size => 10, :readonly => true %><%= calendar_for('time_entry_spent_on') %> +

    + +

    + + <%= text_field :time_entry, :hours, :size => 6 %> +

    + + <% if @available_activities.any? %> +

    + + <%= select_tag('time_entry[activity_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_activities, :id, :name)) %> +

    + <% end %> + +

    + + <%= text_field(:time_entry, :comments, :size => 100) %> +

    + + <% @custom_fields.each do |custom_field| %> +

    <%= custom_field_tag_for_bulk_edit('time_entry', custom_field, @projects) %>

    + <% end %> + + <%= call_hook(:view_time_entries_bulk_edit_details_bottom, { :time_entries => @time_entries }) %> +
    +
    + +

    <%= submit_tag l(:button_submit) %>

    +<% end %> diff --git a/app/views/users/tag_save.js.erb b/app/views/users/tag_save.js.erb index 8c44fe19c..f83b17450 100644 --- a/app/views/users/tag_save.js.erb +++ b/app/views/users/tag_save.js.erb @@ -1,18 +1,18 @@ -<% if @obj_flag == '3'%> - $('#tags_show_issue').html('<%= escape_javascript(render :partial => 'tags/tag_name', - :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); -//$('#put-tag-form-issue').hide(); - $('#name-issue').val(""); -<% elsif @obj_flag == '6'%> - $("#tags_show-<%=@obj.class%>-<%=@obj.id%>").empty(); - $("#tags_show-<%=@obj.class%>-<%=@obj.id%>").html('<%= escape_javascript(render :partial => 'tags/tag_name', - :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); - //$("#put-tag-form-<%#=@obj.class%>-<%#=@obj.id%>").hide(); - $("#put-tag-form-<%=@obj.class%>-<%=@obj.id%> #name").val(""); -<% else %> - $('#tags_show').html('<%= escape_javascript(render :partial => 'tags/tag_name', - :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); - $('#tags_name').val(""); -//$('#put-tag-form').hide(); -<% end %> - +<% if @obj_flag == '3'%> + $('#tags_show_issue').html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +//$('#put-tag-form-issue').hide(); + $('#name-issue').val(""); +<% elsif @obj_flag == '6'%> + $("#tags_show-<%=@obj.class%>-<%=@obj.id%>").empty(); + $("#tags_show-<%=@obj.class%>-<%=@obj.id%>").html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); + //$("#put-tag-form-<%#=@obj.class%>-<%#=@obj.id%>").hide(); + $("#put-tag-form-<%=@obj.class%>-<%=@obj.id%> #name").val(""); +<% else %> + $('#tags_show').html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); + $('#tags_name').val(""); +//$('#put-tag-form').hide(); +<% end %> + diff --git a/app/views/users/user_newfeedback.html.erb b/app/views/users/user_newfeedback.html.erb index 6086c0242..c20d9717d 100644 --- a/app/views/users/user_newfeedback.html.erb +++ b/app/views/users/user_newfeedback.html.erb @@ -1,18 +1,18 @@ -
    -
    - <%= render :partial => 'words/new', :locals => {:user => @user, :sta => @state} %> -
    -
    -<%= l(:label_newfeedback_message) %>(<%= @feedback_count%>) -
    - -
    - <%= render :partial => 'words/message', :locals => {:jour => @jour, :state => @state, :user => @user, :feedback_pages => @feedback_pages} %> -
    - -
    +
    +
    + <%= render :partial => 'words/new', :locals => {:user => @user, :sta => @state} %> +
    +
    +<%= l(:label_newfeedback_message) %>(<%= @feedback_count%>) +
    + +
    + <%= render :partial => 'words/message', :locals => {:jour => @jour, :state => @state, :user => @user, :feedback_pages => @feedback_pages} %> +
    + +
    <% html_title(l(:label_responses)) -%> \ No newline at end of file diff --git a/app/views/users/user_projects.html.erb b/app/views/users/user_projects.html.erb index 1129af514..ff580cf71 100644 --- a/app/views/users/user_projects.html.erb +++ b/app/views/users/user_projects.html.erb @@ -1,66 +1,66 @@ - - - - -
    - -<%#= watch_projects @state %> -<% unless @memberships.empty? %> -
    -
      - <% for membership in @memberships %> -
    • - - - - - - -
      <%= image_tag(url_to_avatar(membership.project), :class => 'avatar') %> - - - - - - - - - - - -
      <%= link_to_user(membership.user) if membership.respond_to?(:user) %> - <%= l(:label_peoject_take_in) %> <%= link_to_project(membership.project) %>
      -

      - <%= membership.project.short_description%> -

      <%= l(:label_create_time) %> : <%= format_time(membership.created_on) %><%= h membership.roles.sort.collect(&:to_s).join(', ') %>
      - -
    • - <% end %> -
    -<% else %> -<% if @user != User.current %> -

    <%= l(:label_project_un) %>

    -<% else %> -

    <%= l(:label_project_unadd) %>

    -<% end %> - -<% end %> -<%= call_hook :view_account_left_bottom, :user => @user %> -
    - + + + + +
    + +<%#= watch_projects @state %> +<% unless @memberships.empty? %> +
    +
      + <% for membership in @memberships %> +
    • + + + + + + +
      <%= image_tag(url_to_avatar(membership.project), :class => 'avatar') %> + + + + + + + + + + + +
      <%= link_to_user(membership.user) if membership.respond_to?(:user) %> + <%= l(:label_peoject_take_in) %> <%= link_to_project(membership.project) %>
      +

      + <%= membership.project.short_description%> +

      <%= l(:label_create_time) %> : <%= format_time(membership.created_on) %><%= h membership.roles.sort.collect(&:to_s).join(', ') %>
      + +
    • + <% end %> +
    +<% else %> +<% if @user != User.current %> +

    <%= l(:label_project_un) %>

    +<% else %> +

    <%= l(:label_project_unadd) %>

    +<% end %> + +<% end %> +<%= call_hook :view_account_left_bottom, :user => @user %> +
    + <% html_title(l(:label_user_project)) -%> \ No newline at end of file diff --git a/app/views/versions/_form.html.erb b/app/views/versions/_form.html.erb index d0729c720..286e85188 100644 --- a/app/views/versions/_form.html.erb +++ b/app/views/versions/_form.html.erb @@ -1,41 +1,41 @@ -<%= back_url_hidden_field_tag %> -<%= error_messages_for 'version' %> - -
    -

    - <%= f.text_field :name, :size => 60, :required => true %> -

    -

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

    -

    - - <%= f.select :status, Version::VERSION_STATUSES.collect {|s| [l("version_status_#{s}"), s]} %> - -

    -

    - - <%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %> - -

    -

    - - <%= f.text_field :effective_date, :size => 10, :readonly => true %> - <%= calendar_for('version_effective_date') %> - -

    -

    - - <%= f.select :sharing, @version.allowed_sharings.collect {|v| [format_version_sharing(v), v]} %> - -

    - -<% @version.custom_field_values.each do |value| %> -

    - - <%= custom_field_tag_with_label :version, value %> - -

    -<% end %> - -
    +<%= back_url_hidden_field_tag %> +<%= error_messages_for 'version' %> + +
    +

    + <%= f.text_field :name, :size => 60, :required => true %> +

    +

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

    +

    + + <%= f.select :status, Version::VERSION_STATUSES.collect {|s| [l("version_status_#{s}"), s]} %> + +

    +

    + + <%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %> + +

    +

    + + <%= f.text_field :effective_date, :size => 10, :readonly => true %> + <%= calendar_for('version_effective_date') %> + +

    +

    + + <%= f.select :sharing, @version.allowed_sharings.collect {|v| [format_version_sharing(v), v]} %> + +

    + +<% @version.custom_field_values.each do |value| %> +

    + + <%= custom_field_tag_with_label :version, value %> + +

    +<% end %> + +
    diff --git a/app/views/web_footer_companies/edit.html.erb b/app/views/web_footer_companies/edit.html.erb index 033a97c30..3561cf347 100644 --- a/app/views/web_footer_companies/edit.html.erb +++ b/app/views/web_footer_companies/edit.html.erb @@ -1,19 +1,19 @@ -

    <%= link_to l(:label_cooperation_compnay), web_footer_companies_path %> » <%=l(:label_edit_company)%>

    -<%= labelled_form_for @company do |f| %> - <%= error_messages_for 'tracker' %> - -
    -
    -

    <%= f.text_field :name, :required => true %>

    -

    <%= f.text_field :url, :required => true %>

    -

    <%= l(:label_url_prompt) %>

    -

    - -

    -
    - <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@company} %> -
    -
    - <%= submit_tag l(:button_save) %> -
    +

    <%= link_to l(:label_cooperation_compnay), web_footer_companies_path %> » <%=l(:label_edit_company)%>

    +<%= labelled_form_for @company do |f| %> + <%= error_messages_for 'tracker' %> + +
    +
    +

    <%= f.text_field :name, :required => true %>

    +

    <%= f.text_field :url, :required => true %>

    +

    <%= l(:label_url_prompt) %>

    +

    + +

    +
    + <%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@company} %> +
    +
    + <%= submit_tag l(:button_save) %> +
    <% end %> \ No newline at end of file diff --git a/app/views/web_footer_companies/index.html.erb b/app/views/web_footer_companies/index.html.erb index 19a6aea48..4ab6fde8f 100644 --- a/app/views/web_footer_companies/index.html.erb +++ b/app/views/web_footer_companies/index.html.erb @@ -1,11 +1,11 @@ -
    <%= link_to l(:label_new_company), new_web_footer_company_path,:class => "icon icon-add" %>
    -

    <%=l(:label_web_footer_cooperation_compnay)%>

    - -