Skip to content
Browse files

Merged rails-3.2 branch.

git-svn-id: svn://rubyforge.org/var/svn/redmine/trunk@9528 e93f8b46-1217-0410-a6f0-8f06a7374b81
  • Loading branch information...
1 parent cd0596e commit d9b292e791fc589fec0c600cf7649f1654213d36 jplang committed
Showing with 6,058 additions and 1,332 deletions.
  1. +1 −0 .gitignore
  2. +1 −0 .hgignore
  3. +9 −5 Gemfile
  4. +4 −12 Rakefile
  5. +14 −30 app/controllers/application_controller.rb
  6. +2 −1 app/controllers/messages_controller.rb
  7. +9 −9 app/controllers/repositories_controller.rb
  8. +1 −1 app/controllers/watchers_controller.rb
  9. +2 −0 app/controllers/wiki_controller.rb
  10. +5 −2 app/helpers/application_helper.rb
  11. +3 −3 app/helpers/wiki_helper.rb
  12. +9 −13 app/models/custom_field.rb
  13. +6 −6 app/models/issue.rb
  14. +11 −2 app/models/mail_handler.rb
  15. +135 −172 app/models/mailer.rb
  16. +4 −0 app/models/project.rb
  17. +2 −2 app/models/repository.rb
  18. +1 −1 app/models/role.rb
  19. +1 −1 app/models/tracker.rb
  20. +1 −1 app/views/account/login.html.erb
  21. +1 −1 app/views/account/lost_password.html.erb
  22. +1 −1 app/views/account/password_recovery.html.erb
  23. +1 −1 app/views/account/register.html.erb
  24. +1 −1 app/views/activities/index.html.erb
  25. +1 −1 app/views/admin/_no_data.html.erb
  26. +1 −1 app/views/admin/projects.html.erb
  27. +1 −1 app/views/attachments/diff.html.erb
  28. +1 −1 app/views/auth_sources/edit.html.erb
  29. +1 −1 app/views/auth_sources/new.html.erb
  30. +1 −1 app/views/boards/edit.html.erb
  31. +1 −1 app/views/boards/new.html.erb
  32. +1 −1 app/views/boards/show.html.erb
  33. +2 −1 app/views/calendars/show.html.erb
  34. +2 −2 app/views/common/feed.atom.builder
  35. +1 −1 app/views/custom_fields/edit.html.erb
  36. +1 −1 app/views/custom_fields/new.html.erb
  37. +1 −1 app/views/documents/edit.html.erb
  38. +1 −1 app/views/documents/index.html.erb
  39. +1 −1 app/views/documents/new.html.erb
  40. +1 −1 app/views/documents/show.html.erb
  41. +1 −1 app/views/enumerations/destroy.html.erb
  42. +1 −1 app/views/enumerations/edit.html.erb
  43. +1 −1 app/views/enumerations/new.html.erb
  44. +1 −1 app/views/files/new.html.erb
  45. +4 −1 app/views/gantts/show.html.erb
  46. +1 −1 app/views/groups/_general.html.erb
  47. +4 −3 app/views/groups/_memberships.html.erb
  48. +2 −1 app/views/groups/_users.html.erb
  49. +1 −1 app/views/groups/new.html.erb
  50. +1 −1 app/views/issue_categories/destroy.html.erb
  51. +1 −1 app/views/issue_statuses/edit.html.erb
  52. +1 −1 app/views/issue_statuses/new.html.erb
  53. +1 −1 app/views/issues/_action_menu.html.erb
  54. +1 −1 app/views/issues/_attributes.html.erb
  55. +2 −2 app/views/issues/_edit.html.erb
  56. +2 −2 app/views/issues/_form.html.erb
  57. +3 −3 app/views/issues/_list.html.erb
  58. +1 −1 app/views/issues/_list_simple.html.erb
  59. +1 −1 app/views/issues/bulk_edit.html.erb
  60. +1 −1 app/views/issues/destroy.html.erb
  61. +2 −2 app/views/issues/index.html.erb
  62. +1 −1 app/views/issues/new.html.erb
  63. +1 −1 app/views/journals/_notes_form.html.erb
  64. +6 −6 app/views/layouts/base.html.erb
  65. +7 −5 app/views/messages/edit.html.erb
  66. +1 −1 app/views/messages/new.html.erb
  67. +1 −1 app/views/messages/show.html.erb
  68. +1 −1 app/views/my/account.html.erb
  69. +1 −1 app/views/my/destroy.html.erb
  70. +1 −1 app/views/my/page_layout.html.erb
  71. +1 −1 app/views/my/password.html.erb
  72. +1 −1 app/views/news/edit.html.erb
  73. +1 −1 app/views/news/index.html.erb
  74. +1 −1 app/views/news/new.html.erb
  75. +2 −2 app/views/news/show.html.erb
  76. +1 −1 app/views/projects/_edit.html.erb
  77. +1 −1 app/views/projects/copy.html.erb
  78. +1 −1 app/views/projects/destroy.html.erb
  79. +1 −1 app/views/projects/index.html.erb
  80. +1 −1 app/views/projects/new.html.erb
  81. +2 −2 app/views/projects/settings/_activities.html.erb
  82. +1 −1 app/views/projects/settings/_modules.html.erb
  83. +3 −3 app/views/projects/show.html.erb
  84. +1 −1 app/views/queries/_filters.html.erb
  85. +1 −1 app/views/queries/edit.html.erb
  86. +1 −1 app/views/queries/new.html.erb
  87. +1 −1 app/views/repositories/_navigation.html.erb
  88. +1 −1 app/views/repositories/_revisions.html.erb
  89. +1 −1 app/views/repositories/committers.html.erb
  90. +1 −1 app/views/repositories/diff.html.erb
  91. +1 −1 app/views/repositories/edit.html.erb
  92. +1 −1 app/views/repositories/new.html.erb
  93. +1 −1 app/views/repositories/revision.html.erb
  94. +2 −2 app/views/repositories/revisions.html.erb
  95. +1 −1 app/views/roles/edit.html.erb
  96. +1 −1 app/views/roles/new.html.erb
  97. +1 −1 app/views/roles/permissions.html.erb
  98. +1 −1 app/views/search/index.html.erb
  99. +1 −1 app/views/settings/_authentication.html.erb
  100. +1 −1 app/views/settings/_display.html.erb
  101. +1 −1 app/views/settings/_general.html.erb
  102. +1 −1 app/views/settings/_issues.html.erb
  103. +1 −1 app/views/settings/_mail_handler.html.erb
  104. +1 −1 app/views/settings/_notifications.html.erb
  105. +1 −1 app/views/settings/_projects.html.erb
  106. +1 −1 app/views/settings/_repositories.html.erb
  107. +1 −1 app/views/settings/plugin.html.erb
  108. +2 −2 app/views/timelog/_date_range.html.erb
  109. +1 −1 app/views/timelog/_list.html.erb
  110. +1 −1 app/views/timelog/bulk_edit.html.erb
  111. +1 −1 app/views/timelog/edit.html.erb
  112. +1 −1 app/views/timelog/index.html.erb
  113. +1 −1 app/views/timelog/new.html.erb
  114. +3 −1 app/views/timelog/report.html.erb
  115. +1 −1 app/views/trackers/edit.html.erb
  116. +1 −1 app/views/trackers/new.html.erb
  117. +1 −1 app/views/users/_general.html.erb
  118. +1 −1 app/views/users/_groups.html.erb
  119. +5 −3 app/views/users/_memberships.html.erb
  120. +1 −1 app/views/users/_preferences.html.erb
  121. +1 −1 app/views/users/index.html.erb
  122. +1 −1 app/views/users/new.html.erb
  123. +1 −1 app/views/versions/_issue_counts.html.erb
  124. +1 −1 app/views/versions/_new_modal.html.erb
  125. +1 −1 app/views/versions/edit.html.erb
  126. +2 −2 app/views/versions/index.html.erb
  127. +1 −1 app/views/versions/new.html.erb
  128. +1 −1 app/views/versions/show.html.erb
  129. +1 −1 app/views/watchers/_new.html.erb
  130. +1 −1 app/views/wiki/_sidebar.html.erb
  131. +1 −1 app/views/wiki/destroy.html.erb
  132. +3 −3 app/views/wiki/edit.html.erb
  133. +3 −1 app/views/wiki/history.html.erb
  134. +2 −2 app/views/wiki/rename.html.erb
  135. +4 −1 app/views/wiki/show.html.erb
  136. +1 −1 app/views/wikis/destroy.html.erb
  137. +1 −1 app/views/workflows/copy.html.erb
  138. +2 −2 app/views/workflows/edit.html.erb
  139. +4 −0 config.ru
  140. +56 −0 config/application.rb
  141. +4 −122 config/boot.rb
  142. +4 −58 config/environment.rb
  143. +14 −11 config/environments/development.rb
  144. +25 −23 config/environments/production.rb
  145. +18 −18 config/environments/test.rb
  146. +16 −18 config/initializers/10-patches.rb
  147. +1 −2 config/initializers/20-mime_types.rb
  148. +2 −0 config/initializers/30-redmine.rb
  149. +296 −374 config/routes.rb
  150. +17 −0 db/migrate/20120422150750_change_repositories_to_full_sti.rb
  151. +4 −3 extra/sample_plugin/README
  152. +3 −1 extra/sample_plugin/app/views/example/say_goodbye.html.erb
  153. +8 −2 extra/sample_plugin/app/views/example/say_hello.html.erb
  154. +7 −0 extra/sample_plugin/config/routes.rb
  155. +1 −4 extra/sample_plugin/init.rb
  156. +5 −16 lib/generators/redmine_plugin/USAGE
  157. +24 −23 lib/generators/redmine_plugin/redmine_plugin_generator.rb
  158. +0 −2 lib/generators/redmine_plugin/templates/init.rb.erb
  159. +2 −0 lib/generators/redmine_plugin/templates/routes.rb
  160. +1 −1 lib/generators/redmine_plugin_controller/USAGE
  161. +18 −46 lib/generators/redmine_plugin_controller/redmine_plugin_controller_generator.rb
  162. +1 −1 lib/generators/redmine_plugin_controller/templates/controller.rb.erb
  163. +1 −1 lib/generators/redmine_plugin_controller/templates/functional_test.rb.erb
  164. +1 −1 lib/generators/redmine_plugin_controller/templates/helper.rb.erb
  165. +1 −1 lib/generators/redmine_plugin_controller/templates/view.html.erb
  166. +1 −1 lib/generators/redmine_plugin_model/USAGE
  167. +12 −38 lib/generators/redmine_plugin_model/redmine_plugin_model_generator.rb
  168. +0 −11 lib/generators/redmine_plugin_model/templates/fixtures.yml
  169. +0 −13 lib/generators/redmine_plugin_model/templates/migration.rb.erb
  170. +1 −1 lib/generators/redmine_plugin_model/templates/model.rb.erb
  171. +1 −2 lib/generators/redmine_plugin_model/templates/unit_test.rb.erb
  172. +1 −1 lib/redmine.rb
  173. +3 −3 lib/redmine/ciphering.rb
  174. +15 −28 lib/redmine/core_ext/active_record.rb
  175. +4 −0 lib/redmine/core_ext/string.rb
  176. +12 −4 lib/redmine/hook.rb
  177. +136 −1 lib/redmine/plugin.rb
  178. +2 −2 lib/redmine/scm/adapters/cvs_adapter.rb
  179. +8 −0 lib/redmine/themes.rb
  180. +3 −3 lib/redmine/utils.rb
  181. +3 −3 lib/redmine/version.rb
  182. +2 −4 lib/redmine/views/api_template_handler.rb
  183. +3 −1 lib/redmine/views/builders/xml.rb
  184. +2 −2 lib/redmine/views/labelled_form_builder.rb
  185. +1 −1 lib/redmine/views/my_page/block.rb
  186. +4 −3 lib/redmine/wiki_formatting.rb
  187. +1 −0 lib/tasks/deprecated.rake
  188. +10 −20 lib/tasks/initializers.rake
  189. +0 −15 lib/tasks/migrate_plugins.rake
  190. +0 −38 lib/tasks/plugins.rake
  191. +24 −0 lib/tasks/redmine.rake
  192. +6 −0 lib/vendor/tmail-1.2.7/tmail.rb
  193. +18 −0 lib/vendor/tmail-1.2.7/tmail/Makefile
  194. +392 −0 lib/vendor/tmail-1.2.7/tmail/address.rb
  195. +65 −0 lib/vendor/tmail-1.2.7/tmail/attachments.rb
  196. +46 −0 lib/vendor/tmail-1.2.7/tmail/base64.rb
  197. +41 −0 lib/vendor/tmail-1.2.7/tmail/compat.rb
  198. +67 −0 lib/vendor/tmail-1.2.7/tmail/config.rb
  199. +63 −0 lib/vendor/tmail-1.2.7/tmail/core_extensions.rb
  200. +590 −0 lib/vendor/tmail-1.2.7/tmail/encode.rb
  201. +962 −0 lib/vendor/tmail-1.2.7/tmail/header.rb
  202. +9 −0 lib/vendor/tmail-1.2.7/tmail/index.rb
  203. +1,162 −0 lib/vendor/tmail-1.2.7/tmail/interface.rb
  204. +3 −0 lib/vendor/tmail-1.2.7/tmail/loader.rb
  205. +578 −0 lib/vendor/tmail-1.2.7/tmail/mail.rb
  206. +496 −0 lib/vendor/tmail-1.2.7/tmail/mailbox.rb
  207. +6 −0 lib/vendor/tmail-1.2.7/tmail/main.rb
  208. +3 −0 lib/vendor/tmail-1.2.7/tmail/mbox.rb
  209. +250 −0 lib/vendor/tmail-1.2.7/tmail/net.rb
  210. +132 −0 lib/vendor/tmail-1.2.7/tmail/obsolete.rb
Sorry, we could not display the entire diff because too many files (457) changed.
View
1 .gitignore
@@ -5,6 +5,7 @@
/config/database.yml
/config/email.yml
/config/initializers/session_store.rb
+/config/initializers/secret_token.rb
/coverage
/db/*.db
/db/*.sqlite3
View
1 .hgignore
@@ -7,6 +7,7 @@ config/configuration.yml
config/database.yml
config/email.yml
config/initializers/session_store.rb
+config/initializers/secret_token.rb
coverage
db/*.db
db/*.sqlite3
View
14 Gemfile
@@ -1,10 +1,12 @@
-source :rubygems
+source 'http://rubygems.org'
-gem "rails", "2.3.14"
-gem "i18n", "~> 0.4.2"
+gem 'rails', '3.2.3'
+gem 'prototype-rails', '3.2.1'
+gem "i18n", "~> 0.6.0"
gem "coderay", "~> 1.0.6"
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
gem "tzinfo", "~> 0.3.31"
+gem "builder"
# Optional gem for LDAP authentication
group :ldap do
@@ -14,6 +16,7 @@ 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
@@ -45,7 +48,7 @@ end
platforms :mri_19, :mingw_19 do
group :mysql do
- gem "mysql2", "~> 0.2.7"
+ gem "mysql2", "~> 0.3.11"
end
end
@@ -69,8 +72,9 @@ group :development do
gem "rdoc", ">= 2.4.2"
end
+
group :test do
- gem "shoulda", "~> 2.10.3"
+ gem "shoulda"
gem "mocha"
end
View
16 Rakefile
@@ -1,15 +1,7 @@
+#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
-# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
-require(File.join(File.dirname(__FILE__), 'config', 'boot'))
+require File.expand_path('../config/application', __FILE__)
-require 'rake'
-require 'rake/testtask'
-
-begin
- require 'rdoc/task'
-rescue LoadError
- # RDoc is not available
-end
-
-require 'tasks/rails'
+RedmineApp::Application.load_tasks
View
44 app/controllers/application_controller.rb
@@ -22,9 +22,12 @@ class Unauthorized < Exception; end
class ApplicationController < ActionController::Base
include Redmine::I18n
+
+ class_attribute :accept_api_auth_actions
+ class_attribute :accept_rss_auth_actions
+ class_attribute :model_object
layout 'base'
- exempt_from_layout 'builder', 'rsb'
protect_from_forgery
def handle_unverified_request
@@ -68,7 +71,6 @@ def utf8nize!(obj)
end
before_filter :user_setup, :check_if_login_required, :set_localization
- filter_parameter_logging :password
rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
rescue_from ::Unauthorized, :with => :deny_access
@@ -77,10 +79,6 @@ def utf8nize!(obj)
include Redmine::MenuManager::MenuController
helper Redmine::MenuManager::MenuHelper
- Redmine::Scm::Base.all.each do |scm|
- require_dependency "repository/#{scm.underscore}"
- end
-
def user_setup
# Check the settings cache for each request
Setting.check_cache
@@ -242,7 +240,7 @@ def find_project_from_association
end
def find_model_object
- model = self.class.read_inheritable_attribute('model_object')
+ model = self.class.model_object
if model
@object = model.find(params[:id])
self.instance_variable_set('@' + controller_name.singularize, @object) if @object
@@ -252,7 +250,7 @@ def find_model_object
end
def self.model_object(model)
- write_inheritable_attribute('model_object', model)
+ self.model_object = model
end
# Filter for bulk issue operations
@@ -388,9 +386,9 @@ def render_feed(items, options={})
def self.accept_rss_auth(*actions)
if actions.any?
- write_inheritable_attribute('accept_rss_auth_actions', actions)
+ self.accept_rss_auth_actions = actions
else
- read_inheritable_attribute('accept_rss_auth_actions') || []
+ self.accept_rss_auth_actions || []
end
end
@@ -400,9 +398,9 @@ def accept_rss_auth?(action=action_name)
def self.accept_api_auth(*actions)
if actions.any?
- write_inheritable_attribute('accept_api_auth_actions', actions)
+ self.accept_api_auth_actions = actions
else
- read_inheritable_attribute('accept_api_auth_actions') || []
+ self.accept_api_auth_actions || []
end
end
@@ -523,26 +521,12 @@ def render_validation_errors(objects)
else
@error_messages = objects.errors.full_messages
end
- render :template => 'common/error_messages.api', :status => :unprocessable_entity, :layout => false
- end
-
- # Overrides #default_template so that the api template
- # is used automatically if it exists
- def default_template(action_name = self.action_name)
- if api_request?
- begin
- return self.view_paths.find_template(default_template_name(action_name), 'api')
- rescue ::ActionView::MissingTemplate
- # the api template was not found
- # fallback to the default behaviour
- end
- end
- super
+ render :template => 'common/error_messages.api', :status => :unprocessable_entity, :layout => nil
end
- # Overrides #pick_layout so that #render with no arguments
+ # Overrides #_include_layout? so that #render with no arguments
# doesn't use the layout for api requests
- def pick_layout(*args)
- api_request? ? nil : super
+ def _include_layout?(*args)
+ api_request? ? false : super
end
end
View
3 app/controllers/messages_controller.rb
@@ -95,10 +95,11 @@ def edit
# Delete a messages
def destroy
(render_403; return false) unless @message.destroyable_by?(User.current)
+ r = @message.to_param
@message.destroy
redirect_to @message.parent.nil? ?
{ :controller => 'boards', :action => 'show', :project_id => @project, :id => @board } :
- { :action => 'show', :id => @message.parent, :r => @message }
+ { :action => 'show', :id => @message.parent, :r => r }
end
def quote
View
18 app/controllers/repositories_controller.rb
@@ -18,6 +18,7 @@
require 'SVG/Graph/Bar'
require 'SVG/Graph/BarHorizontal'
require 'digest/sha1'
+require 'redmine/scm/adapters/abstract_adapter'
class ChangesetNotFound < Exception; end
class InvalidRevisionParam < Exception; end
@@ -307,8 +308,7 @@ def find_project_repository
@repository = @project.repository
end
(render_404; return false) unless @repository
- @path = params[:path].join('/') unless params[:path].nil?
- @path ||= ''
+ @path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s
@rev = params[:rev].blank? ? @repository.default_branch : params[:rev].to_s.strip
@rev_to = params[:rev_to]
@@ -343,15 +343,15 @@ def graph_commits_per_month(repository)
@date_to = Date.today
@date_from = @date_to << 11
@date_from = Date.civil(@date_from.year, @date_from.month, 1)
- commits_by_day = repository.changesets.count(
+ commits_by_day = Changeset.count(
:all, :group => :commit_date,
- :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
+ :conditions => ["repository_id = ? AND commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to])
commits_by_month = [0] * 12
commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last }
- changes_by_day = repository.changes.count(
- :all, :group => :commit_date,
- :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
+ changes_by_day = Change.count(
+ :all, :group => :commit_date, :include => :changeset,
+ :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to])
changes_by_month = [0] * 12
changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last }
@@ -384,10 +384,10 @@ def graph_commits_per_month(repository)
end
def graph_commits_per_author(repository)
- commits_by_author = repository.changesets.count(:all, :group => :committer)
+ commits_by_author = Changeset.count(:all, :group => :committer, :conditions => ["repository_id = ?", repository.id])
commits_by_author.to_a.sort! {|x, y| x.last <=> y.last}
- changes_by_author = repository.changes.count(:all, :group => :committer)
+ changes_by_author = Change.count(:all, :group => :committer, :include => :changeset, :conditions => ["#{Changeset.table_name}.repository_id = ?", repository.id])
h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
fields = commits_by_author.collect {|r| r.first}
View
2 app/controllers/watchers_controller.rb
@@ -109,7 +109,7 @@ def find_project
@watched = klass.find(params[:object_id])
@project = @watched.project
elsif params[:project_id]
- @project = Project.visible.find(params[:project_id])
+ @project = Project.visible.find_by_param(params[:project_id])
end
rescue
render_404
View
2 app/controllers/wiki_controller.rb
@@ -163,6 +163,8 @@ def update
# Optimistic locking exception
flash.now[:error] = l(:notice_locking_conflict)
render :action => 'edit'
+ rescue ActiveRecord::RecordNotSaved
+ render :action => 'edit'
end
# rename a page
View
7 app/helpers/application_helper.rb
@@ -930,6 +930,9 @@ def labelled_tabular_form_for(*args, &proc)
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
@@ -1060,7 +1063,7 @@ def email_delivery_enabled?
# +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
def avatar(user, options = { })
if Setting.gravatar_enabled?
- options.merge!({:ssl => (defined?(request) && request.ssl?), :default => Setting.gravatar_default})
+ options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default})
email = nil
if user.respond_to?(:mail)
email = user.mail
@@ -1079,7 +1082,7 @@ def sanitize_anchor_name(anchor)
# Returns the javascript tags that are included in the html layout head
def javascript_heads
- tags = javascript_include_tag(:defaults)
+ tags = javascript_include_tag('prototype', 'effects', 'dragdrop', 'controls', 'rails', 'application')
unless User.current.pref.warn_on_leaving_unsaved == '0'
tags << "\n".html_safe + javascript_tag("Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('#{escape_javascript( l(:text_warn_on_leaving_unsaved) )}'); });")
end
View
6 app/helpers/wiki_helper.rb
@@ -21,14 +21,14 @@ module WikiHelper
def wiki_page_options_for_select(pages, selected = nil, parent = nil, level = 0)
pages = pages.group_by(&:parent) unless pages.is_a?(Hash)
- s = ''
+ s = ''.html_safe
if pages.has_key?(parent)
pages[parent].each do |page|
attrs = "value='#{page.id}'"
attrs << " selected='selected'" if selected == page
- indent = (level > 0) ? ('&nbsp;' * level * 2 + '&#187; ') : nil
+ indent = (level > 0) ? ('&nbsp;' * level * 2 + '&#187; ') : ''
- s << "<option #{attrs}>#{indent}#{h page.pretty_title}</option>\n" +
+ s << content_tag('option', (indent + h(page.pretty_title)).html_safe, :value => page.id.to_s, :selected => selected == page) +
wiki_page_options_for_select(pages, selected, page, level + 1)
end
end
View
22 app/models/custom_field.rb
@@ -80,7 +80,7 @@ def possible_values_options(obj=nil)
when 'bool'
[[l(:general_text_Yes), '1'], [l(:general_text_No), '0']]
else
- read_possible_values_utf8_encoded || []
+ possible_values || []
end
end
@@ -91,14 +91,20 @@ def possible_values(obj=nil)
when 'bool'
['1', '0']
else
- read_possible_values_utf8_encoded
+ values = super()
+ if values.is_a?(Array)
+ values.each do |value|
+ value.force_encoding('UTF-8') if value.respond_to?(:force_encoding)
+ end
+ end
+ values
end
end
# Makes possible_values accept a multiline string
def possible_values=(arg)
if arg.is_a?(Array)
- write_attribute(:possible_values, arg.compact.collect(&:strip).select {|v| !v.blank?})
+ super(arg.compact.collect(&:strip).select {|v| !v.blank?})
else
self.possible_values = arg.to_s.split(/[\n\r]+/)
end
@@ -218,14 +224,4 @@ def validate_field_value_format(value)
end
errs
end
-
- def read_possible_values_utf8_encoded
- values = read_attribute(:possible_values)
- if values.is_a?(Array)
- values.each do |value|
- value.force_encoding('UTF-8') if value.respond_to?(:force_encoding)
- end
- end
- values
- end
end
View
12 app/models/issue.rb
@@ -246,8 +246,8 @@ def description=(arg)
write_attribute(:description, arg)
end
- # Overrides attributes= so that project and tracker get assigned first
- def attributes_with_project_and_tracker_first=(new_attributes, *args)
+ # Overrides assign_attributes so that project and tracker get assigned first
+ def assign_attributes_with_project_and_tracker_first(new_attributes, *args)
return if new_attributes.nil?
attrs = new_attributes.dup
attrs.stringify_keys!
@@ -257,10 +257,10 @@ def attributes_with_project_and_tracker_first=(new_attributes, *args)
send "#{attr}=", attrs.delete(attr)
end
end
- send :attributes_without_project_and_tracker_first=, attrs, *args
+ send :assign_attributes_without_project_and_tracker_first, attrs, *args
end
# Do not redefine alias chain on reload (see #4838)
- alias_method_chain(:attributes=, :project_and_tracker_first) unless method_defined?(:attributes_without_project_and_tracker_first=)
+ alias_method_chain(:assign_attributes, :project_and_tracker_first) unless method_defined?(:assign_attributes_without_project_and_tracker_first)
def estimated_hours=(h)
write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
@@ -350,7 +350,7 @@ def safe_attributes=(attrs, user=User.current)
end
# mass-assignment security bypass
- self.send :attributes=, attrs, false
+ assign_attributes attrs, :without_protection => true
end
def done_ratio
@@ -921,7 +921,7 @@ def recalculate_attributes_for(issue_id)
p.estimated_hours = nil if p.estimated_hours == 0.0
# ancestors will be recursively updated
- p.save(false)
+ p.save(:validate => false)
end
end
View
13 app/models/mail_handler.rb
@@ -15,7 +15,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-class MailHandler < ActionMailer::Base
+require 'vendor/tmail'
+
+class MailHandler
include ActionView::Helpers::SanitizeHelper
include Redmine::I18n
@@ -39,7 +41,14 @@ def self.receive(email, options={})
@@handler_options[:allow_override] << 'status' unless @@handler_options[:issue].has_key?(:status)
@@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1' ? true : false)
- super email
+
+ mail = TMail::Mail.parse(email)
+ mail.base64_decode
+ new.receive(mail)
+ end
+
+ def logger
+ Rails.logger
end
cattr_accessor :ignored_emails_headers
View
307 app/models/mailer.rb
@@ -21,13 +21,10 @@ class Mailer < ActionMailer::Base
helper :issues
helper :custom_fields
- include ActionController::UrlWriter
include Redmine::I18n
def self.default_url_options
- h = Setting.host_name
- h = h.to_s.gsub(%r{\/.*$}, '') unless Redmine::Utils.relative_url_root.blank?
- { :host => h, :protocol => Setting.protocol }
+ { :host => Setting.host_name, :protocol => Setting.protocol }
end
# Builds a tmail object used to email recipients of the added issue.
@@ -42,12 +39,13 @@ def issue_add(issue)
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
message_id issue
@author = issue.author
- recipients issue.recipients
- cc(issue.watcher_recipients - @recipients)
- subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
- body :issue => issue,
- :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
- render_multipart('issue_add', body)
+ @issue = issue
+ @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
+ recipients = issue.recipients
+ cc = issue.watcher_recipients - recipients
+ mail :to => recipients,
+ :cc => cc,
+ :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
end
# Builds a tmail object used to email recipients of the edited issue.
@@ -64,30 +62,29 @@ def issue_edit(journal)
message_id journal
references issue
@author = journal.user
- recipients issue.recipients
+ recipients = issue.recipients
# Watchers in cc
- cc(issue.watcher_recipients - @recipients)
+ cc = issue.watcher_recipients - recipients
s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
s << issue.subject
- subject s
- body :issue => issue,
- :journal => journal,
- :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
-
- render_multipart('issue_edit', body)
+ @issue = issue
+ @journal = journal
+ @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
+ mail :to => recipients,
+ :cc => cc,
+ :subject => s
end
def reminder(user, issues, days)
set_language_if_valid user.language
- recipients user.mail
- subject l(:mail_subject_reminder, :count => issues.size, :days => days)
- body :issues => issues,
- :days => days,
- :issues_url => url_for(:controller => 'issues', :action => 'index',
+ @issues = issues
+ @days = days
+ @issues_url = url_for(:controller => 'issues', :action => 'index',
:set_filter => 1, :assigned_to_id => user.id,
:sort => 'due_date:asc')
- render_multipart('reminder', body)
+ mail :to => user.mail,
+ :subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
end
# Builds a tmail object used to email users belonging to the added document's project.
@@ -97,12 +94,11 @@ def reminder(user, issues, days)
# Mailer.deliver_document_added(document) => sends an email to the document's project recipients
def document_added(document)
redmine_headers 'Project' => document.project.identifier
- recipients document.recipients
@author = User.current
- subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
- body :document => document,
- :document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
- render_multipart('document_added', body)
+ @document = document
+ @document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
+ mail :to => document.recipients,
+ :subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
end
# Builds a tmail object used to email recipients of a project when an attachements are added.
@@ -119,22 +115,22 @@ def attachments_added(attachments)
when 'Project'
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
added_to = "#{l(:label_project)}: #{container}"
- recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
+ recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
when 'Version'
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
added_to = "#{l(:label_version)}: #{container.name}"
- recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
+ recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
when 'Document'
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
added_to = "#{l(:label_document)}: #{container.title}"
- recipients container.recipients
+ recipients = container.recipients
end
redmine_headers 'Project' => container.project.identifier
- subject "[#{container.project.name}] #{l(:label_attachment_new)}"
- body :attachments => attachments,
- :added_to => added_to,
- :added_to_url => added_to_url
- render_multipart('attachments_added', body)
+ @attachments = attachments
+ @added_to = added_to
+ @added_to_url = added_to_url
+ mail :to => recipients,
+ :subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
end
# Builds a tmail object used to email recipients of a news' project when a news item is added.
@@ -146,11 +142,10 @@ def news_added(news)
redmine_headers 'Project' => news.project.identifier
@author = news.author
message_id news
- recipients news.recipients
- subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
- body :news => news,
- :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
- render_multipart('news_added', body)
+ @news = news
+ @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
+ mail :to => news.recipients,
+ :subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
end
# Builds a tmail object used to email recipients of a news' project when a news comment is added.
@@ -163,13 +158,12 @@ def news_comment_added(comment)
redmine_headers 'Project' => news.project.identifier
@author = comment.author
message_id comment
- recipients news.recipients
- cc news.watcher_recipients
- subject "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
- body :news => news,
- :comment => comment,
- :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
- render_multipart('news_comment_added', body)
+ @news = news
+ @comment = comment
+ @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
+ mail :to => news.recipients,
+ :cc => news.watcher_recipients,
+ :subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
end
# Builds a tmail object used to email the recipients of the specified message that was posted.
@@ -183,12 +177,13 @@ def message_posted(message)
@author = message.author
message_id message
references message.parent unless message.parent.nil?
- recipients(message.recipients)
- cc((message.root.watcher_recipients + message.board.watcher_recipients).uniq - @recipients)
- subject "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
- body :message => message,
- :message_url => url_for(message.event_url)
- render_multipart('message_posted', body)
+ recipients = message.recipients
+ cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients)
+ @message = message
+ @message_url = url_for(message.event_url)
+ mail :to => recipients,
+ :cc => cc,
+ :subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
end
# Builds a tmail object used to email the recipients of a project of the specified wiki content was added.
@@ -201,14 +196,15 @@ def wiki_content_added(wiki_content)
'Wiki-Page-Id' => wiki_content.page.id
@author = wiki_content.author
message_id wiki_content
- recipients wiki_content.recipients
- cc(wiki_content.page.wiki.watcher_recipients - recipients)
- subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
- body :wiki_content => wiki_content,
- :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
+ recipients = wiki_content.recipients
+ cc = wiki_content.page.wiki.watcher_recipients - recipients
+ @wiki_content = wiki_content
+ @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
:project_id => wiki_content.project,
:id => wiki_content.page.title)
- render_multipart('wiki_content_added', body)
+ mail :to => recipients,
+ :cc => cc,
+ :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
end
# Builds a tmail object used to email the recipients of a project of the specified wiki content was updated.
@@ -221,17 +217,18 @@ def wiki_content_updated(wiki_content)
'Wiki-Page-Id' => wiki_content.page.id
@author = wiki_content.author
message_id wiki_content
- recipients wiki_content.recipients
- cc(wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients)
- subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
- body :wiki_content => wiki_content,
- :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
+ recipients = wiki_content.recipients
+ cc = wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients
+ @wiki_content = wiki_content
+ @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
:project_id => wiki_content.project,
- :id => wiki_content.page.title),
- :wiki_diff_url => url_for(:controller => 'wiki', :action => 'diff',
+ :id => wiki_content.page.title)
+ @wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff',
:project_id => wiki_content.project, :id => wiki_content.page.title,
:version => wiki_content.version)
- render_multipart('wiki_content_updated', body)
+ mail :to => recipients,
+ :cc => cc,
+ :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
end
# Builds a tmail object used to email the specified user their account information.
@@ -241,12 +238,11 @@ def wiki_content_updated(wiki_content)
# Mailer.deliver_account_information(user, password) => sends account information to the user
def account_information(user, password)
set_language_if_valid user.language
- recipients user.mail
- subject l(:mail_subject_register, Setting.app_title)
- body :user => user,
- :password => password,
- :login_url => url_for(:controller => 'account', :action => 'login')
- render_multipart('account_information', body)
+ @user = user
+ @password = password
+ @login_url = url_for(:controller => 'account', :action => 'login')
+ mail :to => user.mail,
+ :subject => l(:mail_subject_register, Setting.app_title)
end
# Builds a tmail object used to email all active administrators of an account activation request.
@@ -256,13 +252,13 @@ def account_information(user, password)
# Mailer.deliver_account_activation_request(user)=> sends an email to all active administrators
def account_activation_request(user)
# Send the email to all active administrators
- recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
- subject l(:mail_subject_account_activation_request, Setting.app_title)
- body :user => user,
- :url => url_for(:controller => 'users', :action => 'index',
+ recipients = User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
+ @user = user
+ @url = url_for(:controller => 'users', :action => 'index',
:status => User::STATUS_REGISTERED,
:sort_key => 'created_on', :sort_order => 'desc')
- render_multipart('account_activation_request', body)
+ mail :to => recipients,
+ :subject => l(:mail_subject_account_activation_request, Setting.app_title)
end
# Builds a tmail object used to email the specified user that their account was activated by an administrator.
@@ -272,37 +268,33 @@ def account_activation_request(user)
# Mailer.deliver_account_activated(user) => sends an email to the registered user
def account_activated(user)
set_language_if_valid user.language
- recipients user.mail
- subject l(:mail_subject_register, Setting.app_title)
- body :user => user,
- :login_url => url_for(:controller => 'account', :action => 'login')
- render_multipart('account_activated', body)
+ @user = user
+ @login_url = url_for(:controller => 'account', :action => 'login')
+ mail :to => user.mail,
+ :subject => l(:mail_subject_register, Setting.app_title)
end
def lost_password(token)
set_language_if_valid(token.user.language)
- recipients token.user.mail
- subject l(:mail_subject_lost_password, Setting.app_title)
- body :token => token,
- :url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
- render_multipart('lost_password', body)
+ @token = token
+ @url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
+ mail :to => token.user.mail,
+ :subject => l(:mail_subject_lost_password, Setting.app_title)
end
def register(token)
set_language_if_valid(token.user.language)
- recipients token.user.mail
- subject l(:mail_subject_register, Setting.app_title)
- body :token => token,
- :url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
- render_multipart('register', body)
+ @token = token
+ @url = url_for(:controller => 'account', :action => 'activate', :token => token.value)
+ mail :to => token.user.mail,
+ :subject => l(:mail_subject_register, Setting.app_title)
end
def test_email(user)
set_language_if_valid(user.language)
- recipients user.mail
- subject 'Redmine test'
- body :url => url_for(:controller => 'welcome')
- render_multipart('test_email', body)
+ @url = url_for(:controller => 'welcome')
+ mail :to => user.mail,
+ :subject => 'Redmine test'
end
# Overrides default deliver! method to prevent from sending an email
@@ -313,13 +305,6 @@ def deliver!(mail = @mail)
(cc.nil? || cc.empty?) &&
(bcc.nil? || bcc.empty?)
- # Set Message-Id and References
- if @message_id_object
- mail.message_id = self.class.message_id_for(@message_id_object)
- end
- if @references_objects
- mail.references = @references_objects.collect {|o| self.class.message_id_for(o)}
- end
# Log errors when raise_delivery_errors is set to false, Rails does not
raise_errors = self.class.raise_delivery_errors
@@ -383,83 +368,72 @@ def self.with_synched_deliveries(&block)
ActionMailer::Base.delivery_method = saved_method
end
- private
- def initialize_defaults(method_name)
- super
- @initial_language = current_language
- set_language_if_valid Setting.default_language
- from Setting.mail_from
-
- # Common headers
- headers 'X-Mailer' => 'Redmine',
+ def mail(headers={})
+ headers.merge! 'X-Mailer' => 'Redmine',
'X-Redmine-Host' => Setting.host_name,
'X-Redmine-Site' => Setting.app_title,
'X-Auto-Response-Suppress' => 'OOF',
- 'Auto-Submitted' => 'auto-generated'
- end
+ 'Auto-Submitted' => 'auto-generated',
+ 'From' => Setting.mail_from
- # Appends a Redmine header field (name is prepended with 'X-Redmine-')
- def redmine_headers(h)
- h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
- end
-
- # Overrides the create_mail method
- def create_mail
# Removes the author from the recipients and cc
# if he doesn't want to receive notifications about what he does
if @author && @author.logged? && @author.pref[:no_self_notified]
- if recipients
- recipients((recipients.is_a?(Array) ? recipients : [recipients]) - [@author.mail])
- end
- if cc
- cc((cc.is_a?(Array) ? cc : [cc]) - [@author.mail])
- end
+ headers[:to].delete(@author.mail) if headers[:to].is_a?(Array)
+ headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array)
end
if @author && @author.logged?
redmine_headers 'Sender' => @author.login
end
- notified_users = [recipients, cc].flatten.compact.uniq
- # Rails would log recipients only, not cc and bcc
- mylogger.info "Sending email notification to: #{notified_users.join(', ')}" if mylogger
-
# Blind carbon copy recipients
if Setting.bcc_recipients?
- bcc(notified_users)
- recipients []
- cc []
+ headers[:bcc] = [headers[:to], headers[:cc]].flatten.uniq.reject(&:blank?)
+ headers[:to] = nil
+ headers[:cc] = nil
+ end
+
+ if @message_id_object
+ headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
+ end
+ if @references_objects
+ headers[:references] = @references_objects.collect {|o| "<#{self.class.message_id_for(o)}>"}.join(' ')
+ end
+
+ super headers do |format|
+ format.text
+ format.html unless Setting.plain_text_mail?
end
+
+ set_language_if_valid @initial_language
+ end
+
+ def initialize(*args)
+ @initial_language = current_language
+ set_language_if_valid Setting.default_language
+ super
+ end
+
+ def self.deliver_mail(mail)
+ return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank?
super
end
- # Rails 2.3 has problems rendering implicit multipart messages with
- # layouts so this method will wrap an multipart messages with
- # explicit parts.
- #
- # https://rails.lighthouseapp.com/projects/8994/tickets/2338-actionmailer-mailer-views-and-content-type
- # https://rails.lighthouseapp.com/projects/8994/tickets/1799-actionmailer-doesnt-set-template_format-when-rendering-layouts
-
- def render_multipart(method_name, body)
- if Setting.plain_text_mail?
- content_type "text/plain"
- body render(:file => "#{method_name}.text.erb",
- :body => body,
- :layout => 'mailer.text.erb')
+ def self.method_missing(method, *args, &block)
+ if m = method.to_s.match(%r{^deliver_(.+)$})
+ send(m[1], *args).deliver
else
- content_type "multipart/alternative"
- part :content_type => "text/plain",
- :body => render(:file => "#{method_name}.text.erb",
- :body => body, :layout => 'mailer.text.erb')
- part :content_type => "text/html",
- :body => render_message("#{method_name}.html.erb", body)
+ super
end
end
- # Makes partial rendering work with Rails 1.2 (retro-compatibility)
- def self.controller_path
- ''
- end unless respond_to?('controller_path')
+ private
+
+ # Appends a Redmine header field (name is prepended with 'X-Redmine-')
+ def redmine_headers(h)
+ h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
+ end
# Returns a predictable Message-Id for the given object
def self.message_id_for(object)
@@ -469,11 +443,9 @@ def self.message_id_for(object)
hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
host = "#{::Socket.gethostname}.redmine" if host.empty?
- "<#{hash}@#{host}>"
+ "#{hash}@#{host}"
end
- private
-
def message_id(object)
@message_id_object = object
end
@@ -487,12 +459,3 @@ def mylogger
Rails.logger
end
end
-
-# Patch TMail so that message_id is not overwritten
-module TMail
- class Mail
- def add_message_id( fqdn = nil )
- self.message_id ||= ::TMail::new_message_id(fqdn)
- end
- end
-end
View
4 app/models/project.rb
@@ -272,6 +272,10 @@ def self.find(*args)
end
end
+ def self.find_by_param(*args)
+ self.find(*args)
+ end
+
def reload(*args)
@shared_versions = nil
@rolled_up_versions = nil
View
4 app/models/repository.rb
@@ -57,7 +57,7 @@ def self.human_attribute_name(attribute_key_name, *args)
end
alias :attributes_without_extra_info= :attributes=
- def attributes=(new_attributes, guard_protected_attributes = true)
+ def attributes=(new_attributes)
return if new_attributes.nil?
attributes = new_attributes.dup
attributes.stringify_keys!
@@ -72,7 +72,7 @@ def attributes=(new_attributes, guard_protected_attributes = true)
end
end
- send :attributes_without_extra_info=, p, guard_protected_attributes
+ send :attributes_without_extra_info=, p
if p_extra.keys.any?
merge_extra_info(p_extra)
end
View
2 app/models/role.rb
@@ -36,7 +36,7 @@ class Role < ActiveRecord::Base
before_destroy :check_deletable
has_many :workflows, :dependent => :delete_all do
def copy(source_role)
- Workflow.copy(nil, source_role, nil, proxy_owner)
+ Workflow.copy(nil, source_role, nil, proxy_association.owner)
end
end
View
2 app/models/tracker.rb
@@ -20,7 +20,7 @@ class Tracker < ActiveRecord::Base
has_many :issues
has_many :workflows, :dependent => :delete_all do
def copy(source_tracker)
- Workflow.copy(source_tracker, nil, proxy_owner, nil)
+ Workflow.copy(source_tracker, nil, proxy_association.owner, nil)
end
end
View
2 app/views/account/login.html.erb
@@ -1,6 +1,6 @@
<%= call_hook :view_account_login_top %>
<div id="login-form">
-<% form_tag({:action=> "login"}) do %>
+<%= form_tag({:action=> "login"}) do %>
<%= back_url_hidden_field_tag %>
<table>
<tr>
View
2 app/views/account/lost_password.html.erb
@@ -1,7 +1,7 @@
<h2><%=l(:label_password_lost)%></h2>
<div class="box">
-<% form_tag({:action=> "lost_password"}, :class => "tabular") do %>
+<%= form_tag({:action=> "lost_password"}, :class => "tabular") do %>
<p><label for="mail"><%=l(:field_mail)%> <span class="required">*</span></label>
<%= text_field_tag 'mail', nil, :size => 40 %>
View
2 app/views/account/password_recovery.html.erb
@@ -2,7 +2,7 @@
<%= error_messages_for 'user' %>
-<% form_tag({:token => @token.value}) do %>
+<%= form_tag({:token => @token.value}) do %>
<div class="box tabular">
<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
<%= password_field_tag 'new_password', nil, :size => 25 %>
View
2 app/views/account/register.html.erb
@@ -1,6 +1,6 @@
<h2><%=l(:label_register)%> <%=link_to l(:label_login_with_open_id_option), signin_url if Setting.openid? %></h2>
-<% labelled_form_for @user, :url => {:action => 'register'} do |f| %>
+<%= labelled_form_for @user, :url => {:action => 'register'} do |f| %>
<%= error_messages_for 'user' %>
<div class="box tabular">
View
2 app/views/activities/index.html.erb
@@ -40,7 +40,7 @@
<% end %>
<% content_for :sidebar do %>
-<% form_tag({}, :method => :get) do %>
+<%= form_tag({}, :method => :get) do %>
<h3><%= l(:label_activity) %></h3>
<p><% @activity.event_types.each do |t| %>
<%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %>
View
2 app/views/admin/_no_data.html.erb
@@ -1,5 +1,5 @@
<div class="nodata">
-<% form_tag({:action => 'default_configuration'}) do %>
+<%= form_tag({:action => 'default_configuration'}) do %>
<%= simple_format(l(:text_no_configuration_data)) %>
<p><%= l(:field_language) %>:
<%= select_tag 'lang', options_for_select(lang_options_for_select(false), current_language.to_s) %>
View
2 app/views/admin/projects.html.erb
@@ -4,7 +4,7 @@
<h2><%=l(:label_project_plural)%></h2>
-<% form_tag({}, :method => :get) do %>
+<%= form_tag({}, :method => :get) do %>
<fieldset><legend><%= l(:label_filter_plural) %></legend>
<label for='status'><%= l(:field_status) %> :</label>
<%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
View
2 app/views/attachments/diff.html.erb
@@ -7,7 +7,7 @@
<span class="size">(<%= number_to_human_size @attachment.filesize %>)</span></p>
</div>
<p>
-<% form_tag({}, :method => 'get') do %>
+<%= form_tag({}, :method => 'get') do %>
<label><%= l(:label_view_diff) %></label>
<%= select_tag 'type',
options_for_select(
View
2 app/views/auth_sources/edit.html.erb
@@ -1,6 +1,6 @@
<h2><%=l(:label_auth_source)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
-<% form_tag({:action => 'update', :id => @auth_source}, :method => :put, :class => "tabular") do %>
+<%= form_tag({:action => 'update', :id => @auth_source}, :method => :put, :class => "tabular") do %>
<%= render :partial => auth_source_partial_name(@auth_source) %>
<%= submit_tag l(:button_save) %>
<% end %>
View
2 app/views/auth_sources/new.html.erb
@@ -1,6 +1,6 @@
<h2><%=l(:label_auth_source_new)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
-<% form_tag({:action => 'create'}, :class => "tabular") do %>
+<%= form_tag({:action => 'create'}, :class => "tabular") do %>
<%= hidden_field_tag 'type', @auth_source.type %>
<%= render :partial => auth_source_partial_name(@auth_source) %>
<%= submit_tag l(:button_create) %>
View
2 app/views/boards/edit.html.erb
@@ -1,6 +1,6 @@
<h2><%= l(:label_board) %></h2>
-<% labelled_form_for @board, :url => project_board_path(@project, @board) do |f| %>
+<%= labelled_form_for @board, :url => project_board_path(@project, @board) do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_save) %>
<% end %>
View
2 app/views/boards/new.html.erb
@@ -1,6 +1,6 @@
<h2><%= l(:label_board_new) %></h2>
-<% labelled_form_for @board, :url => project_boards_path(@project) do |f| %>
+<%= labelled_form_for @board, :url => project_boards_path(@project) do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_create) %>
<% end %>
View
2 app/views/boards/show.html.erb
@@ -11,7 +11,7 @@
<div id="add-message" style="display:none;">
<% if authorize_for('messages', 'new') %>
<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%= l(:label_message_new) %></h2>
-<% form_for :message, @message, :url => {:controller => 'messages', :action => 'new', :board_id => @board}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
+<%= form_for @message, :url => {:controller => 'messages', :action => 'new', :board_id => @board}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
<%= render :partial => 'messages/form', :locals => {:f => f} %>
<p><%= submit_tag l(:button_create) %>
<%= link_to_remote l(:label_preview),
View
3 app/views/calendars/show.html.erb
@@ -1,6 +1,7 @@
<h2><%= @query.new_record? ? l(:label_calendar) : h(@query.name) %></h2>
-<% form_tag({:controller => 'calendars', :action => 'show', :project_id => @project}, :method => :get, :id => 'query_form') do %>
+<%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project},
+ :method => :get, :id => 'query_form') do %>
<%= hidden_field_tag 'set_filter', '1' %>
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
<legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
View
4 app/views/common/feed.atom.builder
@@ -1,8 +1,8 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.title truncate_single_line(@title, :length => 100)
- xml.link "rel" => "self", "href" => url_for(params.merge(:only_path => false, :escape => false))
- xml.link "rel" => "alternate", "href" => url_for(params.merge(:only_path => false, :format => nil, :key => nil, :escape => false))
+ xml.link "rel" => "self", "href" => url_for(params.merge(:only_path => false))
+ xml.link "rel" => "alternate", "href" => url_for(params.merge(:only_path => false, :format => nil, :key => nil))
xml.id url_for(:controller => 'welcome', :only_path => false)
xml.updated((@items.first ? @items.first.event_datetime : Time.now).xmlschema)
xml.author { xml.name "#{Setting.app_title}" }
View
2 app/views/custom_fields/edit.html.erb
@@ -2,7 +2,7 @@
&#187; <%= link_to l(@custom_field.type_name), :controller => 'custom_fields', :action => 'index', :tab => @custom_field.class.name %>
&#187; <%=h @custom_field.name %></h2>
-<% labelled_form_for :custom_field, @custom_field, :url => custom_field_path(@custom_field), :html => {:method => :put} do |f| %>
+<%= labelled_form_for :custom_field, @custom_field, :url => custom_field_path(@custom_field), :html => {:method => :put} do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<%= submit_tag l(:button_save) %>
<% end %>
View
2 app/views/custom_fields/new.html.erb
@@ -2,7 +2,7 @@
&#187; <%= link_to l(@custom_field.type_name), :controller => 'custom_fields', :action => 'index', :tab => @custom_field.class.name %>
&#187; <%= l(:label_custom_field_new) %></h2>
-<% labelled_form_for :custom_field, @custom_field, :url => custom_fields_path do |f| %>
+<%= labelled_form_for :custom_field, @custom_field, :url => custom_fields_path do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<%= hidden_field_tag 'type', @custom_field.type %>
<%= submit_tag l(:button_save) %>
View
2 app/views/documents/edit.html.erb
@@ -1,6 +1,6 @@
<h2><%=l(:label_document)%></h2>
-<% labelled_form_for @document do |f| %>
+<%= labelled_form_for @document do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<p><%= submit_tag l(:button_save) %></p>
<% end %>
View
2 app/views/documents/index.html.erb
@@ -5,7 +5,7 @@
<div id="add-document" style="display:none;">
<h2><%=l(:label_document_new)%></h2>
-<% labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
+<%= labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<p>
<%= submit_tag l(:button_create) %>
View
2 app/views/documents/new.html.erb
@@ -1,6 +1,6 @@
<h2><%=l(:label_document_new)%></h2>
-<% labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
+<%= labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<p><%= submit_tag l(:button_create) %></p>
<% end %>
View
2 app/views/documents/show.html.erb
@@ -19,7 +19,7 @@
<% if authorize_for('documents', 'add_attachment') %>
<p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
:id => 'attach_files_link' %></p>
- <% form_tag({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
+ <%= form_tag({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
<div class="box">
<p><%= render :partial => 'attachments/form' %></p>
</div>
View
2 app/views/enumerations/destroy.html.erb
@@ -1,6 +1,6 @@
<h2><%= l(@enumeration.option_name) %>: <%=h @enumeration %></h2>
-<% form_tag({}, :method => :delete) do %>
+<%= form_tag({}, :method => :delete) do %>
<div class="box">
<p><strong><%= l(:text_enumeration_destroy_question, @enumeration.objects_count) %></strong></p>
<p><label for='reassign_to_id'><%= l(:text_enumeration_category_reassign_to) %></label>
View
2 app/views/enumerations/edit.html.erb
@@ -1,6 +1,6 @@
<h2><%= link_to l(@enumeration.option_name), enumerations_path %> &#187; <%=h @enumeration %></h2>
-<% labelled_form_for :enumeration, @enumeration, :url => enumeration_path(@enumeration), :html => {:method => :put} do |f| %>
+<%= labelled_form_for :enumeration, @enumeration, :url => enumeration_path(@enumeration), :html => {:method => :put} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_save) %>
<% end %>
View
2 app/views/enumerations/new.html.erb
@@ -1,6 +1,6 @@
<h2><%= link_to l(@enumeration.option_name), enumerations_path %> &#187; <%=l(:label_enumeration_new)%></h2>
-<% labelled_form_for :enumeration, @enumeration, :url => enumerations_path do |f| %>
+<%= labelled_form_for :enumeration, @enumeration, :url => enumerations_path do |f| %>
<%= f.hidden_field :type %>
<%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_create) %>
View
2 app/views/files/new.html.erb
@@ -1,7 +1,7 @@
<h2><%=l(:label_attachment_new)%></h2>
<%= error_messages_for 'attachment' %>
-<% form_tag(project_files_path(@project), :multipart => true, :class => "tabular") do %>
+<%= form_tag(project_files_path(@project), :multipart => true, :class => "tabular") do %>
<div class="box">
<% if @versions.any? %>
View
5 app/views/gantts/show.html.erb
@@ -1,7 +1,10 @@
<% @gantt.view = self %>
<h2><%= @query.new_record? ? l(:label_gantt) : h(@query.name) %></h2>
-<% form_tag({:controller => 'gantts', :action => 'show', :project_id => @project, :month => params[:month], :year => params[:year], :months => params[:months]}, :method => :get, :id => 'query_form') do %>
+<%= form_tag({:controller => 'gantts', :action => 'show',
+ :project_id => @project, :month => params[:month],
+ :year => params[:year], :months => params[:months]},
+ :method => :get, :id => 'query_form') do %>
<%= hidden_field_tag 'set_filter', '1' %>
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
<legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
View
2 app/views/groups/_general.html.erb
@@ -1,4 +1,4 @@
-<% labelled_form_for @group do |f| %>
+<%= labelled_form_for @group do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<%= submit_tag l(:button_save) %>
<% end %>
View
7 app/views/groups/_memberships.html.erb
@@ -16,8 +16,9 @@
<td class="project"><%=h membership.project %></td>
<td class="roles">
<span id="member-<%= membership.id %>-roles"><%=h membership.roles.sort.collect(&:to_s).join(', ') %></span>
- <% remote_form_for(:membership, :url => { :action => 'edit_membership', :id => @group, :membership_id => membership },
- :html => { :id => "member-#{membership.id}-roles-form", :style => 'display:none;'}) do %>
+ <%= form_for(:membership, :remote => true,
+ :url => { :action => 'edit_membership', :id => @group, :membership_id => membership },
+ :html => { :id => "member-#{membership.id}-roles-form", :style => 'display:none;'}) do %>
<p><% roles.each do |role| %>
<label><%= check_box_tag 'membership[role_ids][]', role.id, membership.roles.include?(role) %> <%=h role %></label><br />
<% end %></p>
@@ -55,7 +56,7 @@
<div class="splitcontentright">
<% if projects.any? %>
<fieldset><legend><%=l(:label_project_new)%></legend>
-<% remote_form_for(:membership, :url => { :action => 'edit_membership', :id => @group }) do %>
+<%= form_for(:membership, :remote => true, :url => { :action => 'edit_membership', :id => @group }) do %>
<%= label_tag "membership_project_id", l(:description_choose_project), :class => "hidden-for-sighted" %>
<%= select_tag 'membership[project_id]', options_for_membership_project_select(@group, projects) %>
<p><%= l(:label_role_plural) %>:
View
3 app/views/groups/_users.html.erb
@@ -29,7 +29,8 @@
<div class="splitcontentright">
<% users = User.active.not_in_group(@group).all(:limit => 100) %>
<% if users.any? %>
- <% remote_form_for(@group, :url => group_users_path(@group), :html => {:method => :post}) do |f| %>
+ <%= form_for(@group, :remote => true, :url => group_users_path(@group),
+ :html => {:method => :post}) do |f| %>
<fieldset><legend><%=l(:label_user_new)%></legend>
<p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
View
2 app/views/groups/new.html.erb
@@ -1,6 +1,6 @@
<h2><%= link_to l(:label_group_plural), groups_path %> &#187; <%= l(:label_group_new) %></h2>
-<% labelled_form_for @group do |f| %>
+<%= labelled_form_for @group do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<p>
<%= f.submit l(:button_create) %>
View
2 app/views/issue_categories/destroy.html.erb
@@ -1,6 +1,6 @@
<h2><%=