summaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/attachment.rb180
-rw-r--r--app/models/auth_source_ldap.rb154
-rw-r--r--app/models/custom_field.rb118
-rw-r--r--app/models/custom_value.rb72
-rw-r--r--app/models/document.rb44
-rw-r--r--app/models/enumeration.rb90
-rw-r--r--app/models/issue.rb202
-rw-r--r--app/models/issue_category.rb54
-rw-r--r--app/models/issue_custom_field.rb52
-rw-r--r--app/models/issue_history.rb44
-rw-r--r--app/models/issue_status.rb98
-rw-r--r--app/models/mailer.rb158
-rw-r--r--app/models/member.rb54
-rw-r--r--app/models/news.rb54
-rw-r--r--app/models/permission.rb126
-rw-r--r--app/models/project.rb138
-rw-r--r--app/models/project_custom_field.rb44
-rw-r--r--app/models/role.rb62
-rw-r--r--app/models/svn_repos.rb430
-rw-r--r--app/models/tracker.rb62
-rw-r--r--app/models/user.rb280
-rw-r--r--app/models/user_custom_field.rb44
-rw-r--r--app/models/version.rb62
-rw-r--r--app/models/workflow.rb46
24 files changed, 1334 insertions, 1334 deletions
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index 773f2ebe9..82fcdadf5 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -1,92 +1,92 @@
-# redMine - project management software
-# Copyright (C) 2006-2007 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"
-
-class Attachment < ActiveRecord::Base
- belongs_to :container, :polymorphic => true
- belongs_to :author, :class_name => "User", :foreign_key => "author_id"
-
- validates_presence_of :container, :filename
-
- cattr_accessor :storage_path
- @@storage_path = "#{RAILS_ROOT}/files"
-
- def validate
- errors.add_to_base :too_long if self.filesize > Setting.attachment_max_size.to_i.kilobytes
- end
-
- def file=(incomming_file)
- unless incomming_file.nil?
- @temp_file = incomming_file
- if @temp_file.size > 0
- self.filename = sanitize_filename(@temp_file.original_filename)
- self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
- self.content_type = @temp_file.content_type
- self.filesize = @temp_file.size
- end
- end
- end
-
- def file
- nil
- end
-
- # Copy temp file to its final location
- def before_save
- if @temp_file && (@temp_file.size > 0)
- logger.debug("saving '#{self.diskfile}'")
- File.open(diskfile, "wb") do |f|
- f.write(@temp_file.read)
- end
- self.digest = Digest::MD5.hexdigest(File.read(diskfile))
- end
- end
-
- # Deletes file on the disk
- def after_destroy
- if self.filename?
- File.delete(diskfile) if File.exist?(diskfile)
- end
- end
-
- # Returns file's location on disk
- def diskfile
- "#{@@storage_path}/#{self.disk_filename}"
- end
-
- def increment_download
- increment!(:downloads)
- end
-
- # returns last created projects
- def self.most_downloaded
- find(:all, :limit => 5, :order => "downloads DESC")
- end
-
-private
- def sanitize_filename(value)
- # get only the filename, not the whole path
- just_filename = value.gsub(/^.*(\\|\/)/, '')
- # NOTE: File.basename doesn't work right with Windows paths on Unix
- # INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
-
- # Finally, replace all non alphanumeric, underscore or periods with underscore
- @filename = just_filename.gsub(/[^\w\.\-]/,'_')
- end
+# redMine - project management software
+# Copyright (C) 2006-2007 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"
+
+class Attachment < ActiveRecord::Base
+ belongs_to :container, :polymorphic => true
+ belongs_to :author, :class_name => "User", :foreign_key => "author_id"
+
+ validates_presence_of :container, :filename
+
+ cattr_accessor :storage_path
+ @@storage_path = "#{RAILS_ROOT}/files"
+
+ def validate
+ errors.add_to_base :too_long if self.filesize > Setting.attachment_max_size.to_i.kilobytes
+ end
+
+ def file=(incomming_file)
+ unless incomming_file.nil?
+ @temp_file = incomming_file
+ if @temp_file.size > 0
+ self.filename = sanitize_filename(@temp_file.original_filename)
+ self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
+ self.content_type = @temp_file.content_type
+ self.filesize = @temp_file.size
+ end
+ end
+ end
+
+ def file
+ nil
+ end
+
+ # Copy temp file to its final location
+ def before_save
+ if @temp_file && (@temp_file.size > 0)
+ logger.debug("saving '#{self.diskfile}'")
+ File.open(diskfile, "wb") do |f|
+ f.write(@temp_file.read)
+ end
+ self.digest = Digest::MD5.hexdigest(File.read(diskfile))
+ end
+ end
+
+ # Deletes file on the disk
+ def after_destroy
+ if self.filename?
+ File.delete(diskfile) if File.exist?(diskfile)
+ end
+ end
+
+ # Returns file's location on disk
+ def diskfile
+ "#{@@storage_path}/#{self.disk_filename}"
+ end
+
+ def increment_download
+ increment!(:downloads)
+ end
+
+ # returns last created projects
+ def self.most_downloaded
+ find(:all, :limit => 5, :order => "downloads DESC")
+ end
+
+private
+ def sanitize_filename(value)
+ # get only the filename, not the whole path
+ just_filename = value.gsub(/^.*(\\|\/)/, '')
+ # NOTE: File.basename doesn't work right with Windows paths on Unix
+ # INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
+
+ # Finally, replace all non alphanumeric, underscore or periods with underscore
+ @filename = just_filename.gsub(/[^\w\.\-]/,'_')
+ end
end
diff --git a/app/models/auth_source_ldap.rb b/app/models/auth_source_ldap.rb
index 895cf1c63..31259afc9 100644
--- a/app/models/auth_source_ldap.rb
+++ b/app/models/auth_source_ldap.rb
@@ -1,79 +1,79 @@
-# redMine - project management software
-# Copyright (C) 2006 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 'iconv'
-
-class AuthSourceLdap < AuthSource
- validates_presence_of :host, :port, :attr_login
-
- def after_initialize
- self.port = 389 if self.port == 0
- end
-
- def authenticate(login, password)
- attrs = []
- # get user's DN
- ldap_con = initialize_ldap_con(self.account, self.account_password)
- login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
- object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
- dn = String.new
- ldap_con.search( :base => self.base_dn,
- :filter => object_filter & login_filter,
- :attributes=> ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]) do |entry|
- dn = entry.dn
- attrs = [: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 nil if dn.empty?
- logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
- # authenticate user
- ldap_con = initialize_ldap_con(dn, password)
- return nil unless ldap_con.bind
- # return user's attributes
- logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
- attrs
- rescue Net::LDAP::LdapError => text
- raise "LdapError: " + text
- end
-
- # test the connection to the LDAP
- def test_connection
- ldap_con = initialize_ldap_con(self.account, self.account_password)
- ldap_con.open { }
- rescue Net::LDAP::LdapError => text
- raise "LdapError: " + text
- end
-
- def auth_method_name
- "LDAP"
- end
-
-private
- def initialize_ldap_con(ldap_user, ldap_password)
- Net::LDAP.new( {:host => self.host,
- :port => self.port,
- :auth => { :method => :simple, :username => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_user), :password => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_password) }}
- )
- end
-
- def self.get_attr(entry, attr_name)
- entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
+# redMine - project management software
+# Copyright (C) 2006 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 'iconv'
+
+class AuthSourceLdap < AuthSource
+ validates_presence_of :host, :port, :attr_login
+
+ def after_initialize
+ self.port = 389 if self.port == 0
+ end
+
+ def authenticate(login, password)
+ attrs = []
+ # get user's DN
+ ldap_con = initialize_ldap_con(self.account, self.account_password)
+ login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
+ object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
+ dn = String.new
+ ldap_con.search( :base => self.base_dn,
+ :filter => object_filter & login_filter,
+ :attributes=> ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]) do |entry|
+ dn = entry.dn
+ attrs = [: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 nil if dn.empty?
+ logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
+ # authenticate user
+ ldap_con = initialize_ldap_con(dn, password)
+ return nil unless ldap_con.bind
+ # return user's attributes
+ logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
+ attrs
+ rescue Net::LDAP::LdapError => text
+ raise "LdapError: " + text
+ end
+
+ # test the connection to the LDAP
+ def test_connection
+ ldap_con = initialize_ldap_con(self.account, self.account_password)
+ ldap_con.open { }
+ rescue Net::LDAP::LdapError => text
+ raise "LdapError: " + text
+ end
+
+ def auth_method_name
+ "LDAP"
+ end
+
+private
+ def initialize_ldap_con(ldap_user, ldap_password)
+ Net::LDAP.new( {:host => self.host,
+ :port => self.port,
+ :auth => { :method => :simple, :username => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_user), :password => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_password) }}
+ )
+ end
+
+ def self.get_attr(entry, attr_name)
+ entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
end
end
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
index ea11edc46..554504a9f 100644
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -1,60 +1,60 @@
-# redMine - project management software
-# Copyright (C) 2006 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 CustomField < ActiveRecord::Base
- has_many :custom_values, :dependent => :delete_all
- serialize :possible_values
-
- FIELD_FORMATS = { "string" => { :name => :label_string, :order => 1 },
- "text" => { :name => :label_text, :order => 2 },
- "int" => { :name => :label_integer, :order => 3 },
- "list" => { :name => :label_list, :order => 4 },
- "date" => { :name => :label_date, :order => 5 },
- "bool" => { :name => :label_boolean, :order => 6 }
- }.freeze
-
- validates_presence_of :name, :field_format
- validates_uniqueness_of :name
- validates_format_of :name, :with => /^[\w\s\'\-]*$/i
- validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
-
- def initialize(attributes = nil)
- super
- self.possible_values ||= []
- end
-
- def before_validation
- # remove empty values
- self.possible_values = self.possible_values.collect{|v| v unless v.empty?}.compact
- end
-
- def validate
- if self.field_format == "list"
- errors.add(:possible_values, :activerecord_error_blank) if self.possible_values.nil? || self.possible_values.empty?
- errors.add(:possible_values, :activerecord_error_invalid) unless self.possible_values.is_a? Array
- end
- end
-
- # to move in project_custom_field
- def self.for_all
- find(:all, :conditions => ["is_for_all=?", true])
- end
-
- def type_name
- nil
+# redMine - project management software
+# Copyright (C) 2006 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 CustomField < ActiveRecord::Base
+ has_many :custom_values, :dependent => :delete_all
+ serialize :possible_values
+
+ FIELD_FORMATS = { "string" => { :name => :label_string, :order => 1 },
+ "text" => { :name => :label_text, :order => 2 },
+ "int" => { :name => :label_integer, :order => 3 },
+ "list" => { :name => :label_list, :order => 4 },
+ "date" => { :name => :label_date, :order => 5 },
+ "bool" => { :name => :label_boolean, :order => 6 }
+ }.freeze
+
+ validates_presence_of :name, :field_format
+ validates_uniqueness_of :name
+ validates_format_of :name, :with => /^[\w\s\'\-]*$/i
+ validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
+
+ def initialize(attributes = nil)
+ super
+ self.possible_values ||= []
end
-end
+
+ def before_validation
+ # remove empty values
+ self.possible_values = self.possible_values.collect{|v| v unless v.empty?}.compact
+ end
+
+ def validate
+ if self.field_format == "list"
+ errors.add(:possible_values, :activerecord_error_blank) if self.possible_values.nil? || self.possible_values.empty?
+ errors.add(:possible_values, :activerecord_error_invalid) unless self.possible_values.is_a? Array
+ end
+ end
+
+ # to move in project_custom_field
+ def self.for_all
+ find(:all, :conditions => ["is_for_all=?", true])
+ end
+
+ def type_name
+ nil
+ end
+end
diff --git a/app/models/custom_value.rb b/app/models/custom_value.rb
index e93dfb4f3..a1b2c9c40 100644
--- a/app/models/custom_value.rb
+++ b/app/models/custom_value.rb
@@ -1,38 +1,38 @@
-# redMine - project management software
-# Copyright (C) 2006 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 CustomValue < ActiveRecord::Base
- belongs_to :custom_field
- belongs_to :customized, :polymorphic => true
-
-protected
- def validate
- errors.add(:value, :activerecord_error_blank) and return if custom_field.is_required? and value.empty?
- errors.add(:value, :activerecord_error_invalid) unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
- errors.add(:value, :activerecord_error_too_short) if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
- errors.add(:value, :activerecord_error_too_long) if custom_field.max_length > 0 and value.length > custom_field.max_length
- case custom_field.field_format
- when "int"
- errors.add(:value, :activerecord_error_not_a_number) unless value =~ /^[0-9]*$/
- when "date"
- errors.add(:value, :activerecord_error_not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/ or value.empty?
- when "list"
- errors.add(:value, :activerecord_error_inclusion) unless custom_field.possible_values.include? value or value.empty?
- end
+# redMine - project management software
+# Copyright (C) 2006 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 CustomValue < ActiveRecord::Base
+ belongs_to :custom_field
+ belongs_to :customized, :polymorphic => true
+
+protected
+ def validate
+ errors.add(:value, :activerecord_error_blank) and return if custom_field.is_required? and value.empty?
+ errors.add(:value, :activerecord_error_invalid) unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
+ errors.add(:value, :activerecord_error_too_short) if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
+ errors.add(:value, :activerecord_error_too_long) if custom_field.max_length > 0 and value.length > custom_field.max_length
+ case custom_field.field_format
+ when "int"
+ errors.add(:value, :activerecord_error_not_a_number) unless value =~ /^[0-9]*$/
+ when "date"
+ errors.add(:value, :activerecord_error_not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/ or value.empty?
+ when "list"
+ errors.add(:value, :activerecord_error_inclusion) unless custom_field.possible_values.include? value or value.empty?
+ end
end
-end
+end
diff --git a/app/models/document.rb b/app/models/document.rb
index 40a9765a4..141489a79 100644
--- a/app/models/document.rb
+++ b/app/models/document.rb
@@ -1,24 +1,24 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Document < ActiveRecord::Base
- belongs_to :project
- belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
- has_many :attachments, :as => :container, :dependent => :destroy
-
+# redMine - project management software
+# Copyright (C) 2006 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 Document < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
+ has_many :attachments, :as => :container, :dependent => :destroy
+
validates_presence_of :project, :title, :category
end
diff --git a/app/models/enumeration.rb b/app/models/enumeration.rb
index 0d6554f82..251f00fbe 100644
--- a/app/models/enumeration.rb
+++ b/app/models/enumeration.rb
@@ -1,47 +1,47 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Enumeration < ActiveRecord::Base
- before_destroy :check_integrity
-
- validates_presence_of :opt, :name
- validates_uniqueness_of :name, :scope => [:opt]
- validates_format_of :name, :with => /^[\w\s\'\-]*$/i
-
- OPTIONS = {
- "IPRI" => :enumeration_issue_priorities,
- "DCAT" => :enumeration_doc_categories
- }.freeze
-
- def self.get_values(option)
- find(:all, :conditions => ['opt=?', option])
- end
-
- def option_name
- OPTIONS[self.opt]
- end
-
-private
- def check_integrity
- case self.opt
- when "IPRI"
- raise "Can't delete enumeration" if Issue.find(:first, :conditions => ["priority_id=?", self.id])
- when "DCAT"
- raise "Can't delete enumeration" if Document.find(:first, :conditions => ["category_id=?", self.id])
- end
+# redMine - project management software
+# Copyright (C) 2006 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 Enumeration < ActiveRecord::Base
+ before_destroy :check_integrity
+
+ validates_presence_of :opt, :name
+ validates_uniqueness_of :name, :scope => [:opt]
+ validates_format_of :name, :with => /^[\w\s\'\-]*$/i
+
+ OPTIONS = {
+ "IPRI" => :enumeration_issue_priorities,
+ "DCAT" => :enumeration_doc_categories
+ }.freeze
+
+ def self.get_values(option)
+ find(:all, :conditions => ['opt=?', option])
+ end
+
+ def option_name
+ OPTIONS[self.opt]
+ end
+
+private
+ def check_integrity
+ case self.opt
+ when "IPRI"
+ raise "Can't delete enumeration" if Issue.find(:first, :conditions => ["priority_id=?", self.id])
+ when "DCAT"
+ raise "Can't delete enumeration" if Document.find(:first, :conditions => ["category_id=?", self.id])
+ end
end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 6f77bef30..140071872 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -1,102 +1,102 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Issue < ActiveRecord::Base
-
- belongs_to :project
- belongs_to :tracker
- belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
- belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
- belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
- belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
- belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
- belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
-
- has_many :journals, :as => :journalized, :dependent => :destroy
- has_many :attachments, :as => :container, :dependent => :destroy
-
- has_many :custom_values, :dependent => :delete_all, :as => :customized
- has_many :custom_fields, :through => :custom_values
-
- validates_presence_of :subject, :description, :priority, :tracker, :author, :status
- validates_inclusion_of :done_ratio, :in => 0..100
- validates_associated :custom_values, :on => :update
-
- # set default status for new issues
- def before_validation
- self.status = IssueStatus.default if new_record?
- end
-
- def validate
- if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
- errors.add :due_date, :activerecord_error_not_a_date
- end
-
- if self.due_date and self.start_date and self.due_date < self.start_date
- errors.add :due_date, :activerecord_error_greater_than_start_date
- end
- end
-
- #def before_create
- # build_history
- #end
-
- def before_save
- if @current_journal
- # attributes changes
- (Issue.column_names - %w(id description)).each {|c|
- @current_journal.details << JournalDetail.new(:property => 'attr',
- :prop_key => c,
- :old_value => @issue_before_change.send(c),
- :value => send(c)) unless send(c)==@issue_before_change.send(c)
- }
- # custom fields changes
- custom_values.each {|c|
- @current_journal.details << JournalDetail.new(:property => 'cf',
- :prop_key => c.custom_field_id,
- :old_value => @custom_values_before_change[c.custom_field_id],
- :value => c.value) unless @custom_values_before_change[c.custom_field_id]==c.value
- }
- @current_journal.save unless @current_journal.details.empty? and @current_journal.notes.empty?
- end
- end
-
- def long_id
- "%05d" % self.id
- end
-
- def custom_value_for(custom_field)
- self.custom_values.each {|v| return v if v.custom_field_id == custom_field.id }
- return nil
- end
-
- def init_journal(user, notes = "")
- @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
- @issue_before_change = self.clone
- @custom_values_before_change = {}
- self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
- @current_journal
- end
-
-private
- # Creates an history for the issue
- #def build_history
- # @history = self.histories.build
- # @history.status = self.status
- # @history.author = self.author
- #end
+# redMine - project management software
+# Copyright (C) 2006 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 Issue < ActiveRecord::Base
+
+ belongs_to :project
+ belongs_to :tracker
+ belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
+ belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+ belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
+ belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
+ belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
+ belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
+
+ has_many :journals, :as => :journalized, :dependent => :destroy
+ has_many :attachments, :as => :container, :dependent => :destroy
+
+ has_many :custom_values, :dependent => :delete_all, :as => :customized
+ has_many :custom_fields, :through => :custom_values
+
+ validates_presence_of :subject, :description, :priority, :tracker, :author, :status
+ validates_inclusion_of :done_ratio, :in => 0..100
+ validates_associated :custom_values, :on => :update
+
+ # set default status for new issues
+ def before_validation
+ self.status = IssueStatus.default if new_record?
+ end
+
+ def validate
+ if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
+ errors.add :due_date, :activerecord_error_not_a_date
+ end
+
+ if self.due_date and self.start_date and self.due_date < self.start_date
+ errors.add :due_date, :activerecord_error_greater_than_start_date
+ end
+ end
+
+ #def before_create
+ # build_history
+ #end
+
+ def before_save
+ if @current_journal
+ # attributes changes
+ (Issue.column_names - %w(id description)).each {|c|
+ @current_journal.details << JournalDetail.new(:property => 'attr',
+ :prop_key => c,
+ :old_value => @issue_before_change.send(c),
+ :value => send(c)) unless send(c)==@issue_before_change.send(c)
+ }
+ # custom fields changes
+ custom_values.each {|c|
+ @current_journal.details << JournalDetail.new(:property => 'cf',
+ :prop_key => c.custom_field_id,
+ :old_value => @custom_values_before_change[c.custom_field_id],
+ :value => c.value) unless @custom_values_before_change[c.custom_field_id]==c.value
+ }
+ @current_journal.save unless @current_journal.details.empty? and @current_journal.notes.empty?
+ end
+ end
+
+ def long_id
+ "%05d" % self.id
+ end
+
+ def custom_value_for(custom_field)
+ self.custom_values.each {|v| return v if v.custom_field_id == custom_field.id }
+ return nil
+ end
+
+ def init_journal(user, notes = "")
+ @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
+ @issue_before_change = self.clone
+ @custom_values_before_change = {}
+ self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
+ @current_journal
+ end
+
+private
+ # Creates an history for the issue
+ #def build_history
+ # @history = self.histories.build
+ # @history.status = self.status
+ # @history.author = self.author
+ #end
end
diff --git a/app/models/issue_category.rb b/app/models/issue_category.rb
index 74adb8f52..1a1daffb2 100644
--- a/app/models/issue_category.rb
+++ b/app/models/issue_category.rb
@@ -1,29 +1,29 @@
-# redMine - project management software
-# Copyright (C) 2006 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 IssueCategory < ActiveRecord::Base
- before_destroy :check_integrity
- belongs_to :project
-
- validates_presence_of :name
- validates_uniqueness_of :name, :scope => [:project_id]
-
-private
- def check_integrity
- raise "Can't delete category" if Issue.find(:first, :conditions => ["category_id=?", self.id])
+# redMine - project management software
+# Copyright (C) 2006 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 IssueCategory < ActiveRecord::Base
+ before_destroy :check_integrity
+ belongs_to :project
+
+ validates_presence_of :name
+ validates_uniqueness_of :name, :scope => [:project_id]
+
+private
+ def check_integrity
+ raise "Can't delete category" if Issue.find(:first, :conditions => ["category_id=?", self.id])
end
end
diff --git a/app/models/issue_custom_field.rb b/app/models/issue_custom_field.rb
index 209ae206b..7759c9059 100644
--- a/app/models/issue_custom_field.rb
+++ b/app/models/issue_custom_field.rb
@@ -1,27 +1,27 @@
-# redMine - project management software
-# Copyright (C) 2006 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 IssueCustomField < CustomField
- has_and_belongs_to_many :projects, :join_table => "custom_fields_projects", :foreign_key => "custom_field_id"
- has_and_belongs_to_many :trackers, :join_table => "custom_fields_trackers", :foreign_key => "custom_field_id"
- has_many :issues, :through => :issue_custom_values
-
- def type_name
- :label_issue_plural
- end
-end
+# redMine - project management software
+# Copyright (C) 2006 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 IssueCustomField < CustomField
+ has_and_belongs_to_many :projects, :join_table => "custom_fields_projects", :foreign_key => "custom_field_id"
+ has_and_belongs_to_many :trackers, :join_table => "custom_fields_trackers", :foreign_key => "custom_field_id"
+ has_many :issues, :through => :issue_custom_values
+
+ def type_name
+ :label_issue_plural
+ end
+end
diff --git a/app/models/issue_history.rb b/app/models/issue_history.rb
index 4b6682600..38366bbc3 100644
--- a/app/models/issue_history.rb
+++ b/app/models/issue_history.rb
@@ -1,24 +1,24 @@
-# redMine - project management software
-# Copyright (C) 2006 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.
-
+# redMine - project management software
+# Copyright (C) 2006 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 IssueHistory < ActiveRecord::Base
- belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
- belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
- belongs_to :issue
-
- validates_presence_of :status
+ belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
+ belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+ belongs_to :issue
+
+ validates_presence_of :status
end
diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb
index 1a690b449..fd6194c9a 100644
--- a/app/models/issue_status.rb
+++ b/app/models/issue_status.rb
@@ -1,51 +1,51 @@
-# redMine - project management software
-# Copyright (C) 2006 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 IssueStatus < ActiveRecord::Base
- before_destroy :check_integrity
- has_many :workflows, :foreign_key => "old_status_id"
- acts_as_list
-
- validates_presence_of :name
- validates_uniqueness_of :name
- validates_format_of :name, :with => /^[\w\s\'\-]*$/i
- validates_length_of :html_color, :is => 6
- validates_format_of :html_color, :with => /^[a-f0-9]*$/i
-
- def before_save
- IssueStatus.update_all "is_default=#{connection.quoted_false}" if self.is_default?
- end
-
- # Returns the default status for new issues
- def self.default
- find(:first, :conditions =>["is_default=?", true])
- end
-
- # Returns an array of all statuses the given role can switch to
- def new_statuses_allowed_to(role, tracker)
- statuses = []
- for workflow in self.workflows
- statuses << workflow.new_status if workflow.role_id == role.id and workflow.tracker_id == tracker.id
- end unless role.nil? or tracker.nil?
- statuses
- end
-
-private
- def check_integrity
- raise "Can't delete status" if Issue.find(:first, :conditions => ["status_id=?", self.id])
+# redMine - project management software
+# Copyright (C) 2006 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 IssueStatus < ActiveRecord::Base
+ before_destroy :check_integrity
+ has_many :workflows, :foreign_key => "old_status_id"
+ acts_as_list
+
+ validates_presence_of :name
+ validates_uniqueness_of :name
+ validates_format_of :name, :with => /^[\w\s\'\-]*$/i
+ validates_length_of :html_color, :is => 6
+ validates_format_of :html_color, :with => /^[a-f0-9]*$/i
+
+ def before_save
+ IssueStatus.update_all "is_default=#{connection.quoted_false}" if self.is_default?
+ end
+
+ # Returns the default status for new issues
+ def self.default
+ find(:first, :conditions =>["is_default=?", true])
+ end
+
+ # Returns an array of all statuses the given role can switch to
+ def new_statuses_allowed_to(role, tracker)
+ statuses = []
+ for workflow in self.workflows
+ statuses << workflow.new_status if workflow.role_id == role.id and workflow.tracker_id == tracker.id
+ end unless role.nil? or tracker.nil?
+ statuses
+ end
+
+private
+ def check_integrity
+ raise "Can't delete status" if Issue.find(:first, :conditions => ["status_id=?", self.id])
end
end
diff --git a/app/models/mailer.rb b/app/models/mailer.rb
index 42d20ecac..36bcddc2a 100644
--- a/app/models/mailer.rb
+++ b/app/models/mailer.rb
@@ -1,88 +1,88 @@
-# redMine - project management software
-# Copyright (C) 2006-2007 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 Mailer < ActionMailer::Base
+# redMine - project management software
+# Copyright (C) 2006-2007 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 Mailer < ActionMailer::Base
helper IssuesHelper
- def issue_add(issue)
+ def issue_add(issue)
+ set_language_if_valid(Setting.default_language)
+ # Sends to all project members
+ @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
+ @from = Setting.mail_from
+ @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
+ @body['issue'] = issue
+ end
+
+ def issue_edit(journal)
set_language_if_valid(Setting.default_language)
# Sends to all project members
+ issue = journal.journalized
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
@from = Setting.mail_from
@subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
- @body['issue'] = issue
- end
-
- def issue_edit(journal)
- set_language_if_valid(Setting.default_language)
- # Sends to all project members
- issue = journal.journalized
- @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
- @from = Setting.mail_from
- @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
- @body['issue'] = issue
- @body['journal']= journal
- end
-
- def document_add(document)
- set_language_if_valid(Setting.default_language)
- @recipients = document.project.users.collect { |u| u.mail if u.mail_notification }.compact
- @from = Setting.mail_from
- @subject = "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
- @body['document'] = document
- end
-
- def attachments_add(attachments)
- set_language_if_valid(Setting.default_language)
- container = attachments.first.container
- url = "http://#{Setting.host_name}/"
- added_to = ""
- case container.class.to_s
- when 'Version'
- url << "projects/list_files/#{container.project_id}"
- added_to = "#{l(:label_version)}: #{container.name}"
- when 'Document'
- url << "documents/show/#{container.id}"
- added_to = "#{l(:label_document)}: #{container.title}"
- when 'Issue'
- url << "issues/show/#{container.id}"
- added_to = "#{container.tracker.name} ##{container.id}: #{container.subject}"
- end
- @recipients = container.project.users.collect { |u| u.mail if u.mail_notification }.compact
- @from = Setting.mail_from
- @subject = "[#{container.project.name}] #{l(:label_attachment_new)}"
- @body['attachments'] = attachments
- @body['url'] = url
- @body['added_to'] = added_to
- end
-
- def lost_password(token)
- set_language_if_valid(token.user.language)
- @recipients = token.user.mail
- @from = Setting.mail_from
- @subject = l(:mail_subject_lost_password)
- @body['token'] = token
+ @body['issue'] = issue
+ @body['journal']= journal
+ end
+
+ def document_add(document)
+ set_language_if_valid(Setting.default_language)
+ @recipients = document.project.users.collect { |u| u.mail if u.mail_notification }.compact
+ @from = Setting.mail_from
+ @subject = "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
+ @body['document'] = document
+ end
+
+ def attachments_add(attachments)
+ set_language_if_valid(Setting.default_language)
+ container = attachments.first.container
+ url = "http://#{Setting.host_name}/"
+ added_to = ""
+ case container.class.to_s
+ when 'Version'
+ url << "projects/list_files/#{container.project_id}"
+ added_to = "#{l(:label_version)}: #{container.name}"
+ when 'Document'
+ url << "documents/show/#{container.id}"
+ added_to = "#{l(:label_document)}: #{container.title}"
+ when 'Issue'
+ url << "issues/show/#{container.id}"
+ added_to = "#{container.tracker.name} ##{container.id}: #{container.subject}"
+ end
+ @recipients = container.project.users.collect { |u| u.mail if u.mail_notification }.compact
+ @from = Setting.mail_from
+ @subject = "[#{container.project.name}] #{l(:label_attachment_new)}"
+ @body['attachments'] = attachments
+ @body['url'] = url
+ @body['added_to'] = added_to
+ end
+
+ def lost_password(token)
+ set_language_if_valid(token.user.language)
+ @recipients = token.user.mail
+ @from = Setting.mail_from
+ @subject = l(:mail_subject_lost_password)
+ @body['token'] = token
end
-
- def register(token)
- set_language_if_valid(token.user.language)
- @recipients = token.user.mail
- @from = Setting.mail_from
- @subject = l(:mail_subject_register)
- @body['token'] = token
- end
+
+ def register(token)
+ set_language_if_valid(token.user.language)
+ @recipients = token.user.mail
+ @from = Setting.mail_from
+ @subject = l(:mail_subject_register)
+ @body['token'] = token
+ end
end
diff --git a/app/models/member.rb b/app/models/member.rb
index 1214b6443..9814faa51 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -1,29 +1,29 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Member < ActiveRecord::Base
- belongs_to :user
- belongs_to :role
- belongs_to :project
-
- validates_presence_of :role, :user, :project
- validates_uniqueness_of :user_id, :scope => :project_id
-
- def name
- self.user.display_name
+# redMine - project management software
+# Copyright (C) 2006 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 Member < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :role
+ belongs_to :project
+
+ validates_presence_of :role, :user, :project
+ validates_uniqueness_of :user_id, :scope => :project_id
+
+ def name
+ self.user.display_name
end
end
diff --git a/app/models/news.rb b/app/models/news.rb
index 89e94f1ce..848517302 100644
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -1,29 +1,29 @@
-# redMine - project management software
-# Copyright (C) 2006 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 News < ActiveRecord::Base
- belongs_to :project
- belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
- has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
-
- validates_presence_of :title, :description
-
- # returns latest news for projects visible by user
- def self.latest(user=nil, count=5)
- find(:all, :limit => count, :conditions => Project.visible_by(user), :include => [ :author, :project ], :order => "news.created_on DESC")
+# redMine - project management software
+# Copyright (C) 2006 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 News < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+ has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
+
+ validates_presence_of :title, :description
+
+ # returns latest news for projects visible by user
+ def self.latest(user=nil, count=5)
+ find(:all, :limit => count, :conditions => Project.visible_by(user), :include => [ :author, :project ], :order => "news.created_on DESC")
end
end
diff --git a/app/models/permission.rb b/app/models/permission.rb
index 65b9253c7..3ce40d116 100644
--- a/app/models/permission.rb
+++ b/app/models/permission.rb
@@ -1,65 +1,65 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Permission < ActiveRecord::Base
- has_and_belongs_to_many :roles
-
- validates_presence_of :controller, :action, :description
-
- GROUPS = {
- 100 => :label_project,
- 200 => :label_member_plural,
- 300 => :label_version_plural,
- 400 => :label_issue_category_plural,
- 600 => :label_query_plural,
- 1000 => :label_issue_plural,
- 1100 => :label_news_plural,
- 1200 => :label_document_plural,
- 1300 => :label_attachment_plural,
- 1400 => :label_repository
- }.freeze
-
- @@cached_perms_for_public = nil
- @@cached_perms_for_roles = nil
-
- def name
- self.controller + "/" + self.action
- end
-
- def group_id
- (self.sort / 100)*100
- end
-
- def self.allowed_to_public(action)
- @@cached_perms_for_public ||= find(:all, :conditions => ["is_public=?", true]).collect {|p| "#{p.controller}/#{p.action}"}
- @@cached_perms_for_public.include? action
- end
-
- def self.allowed_to_role(action, role)
- @@cached_perms_for_roles ||=
- begin
- perms = {}
- find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } }
- perms
- end
- allowed_to_public(action) or (@@cached_perms_for_roles[action] and @@cached_perms_for_roles[action].include? role)
- end
-
- def self.allowed_to_role_expired
- @@cached_perms_for_roles = nil
+# redMine - project management software
+# Copyright (C) 2006 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 Permission < ActiveRecord::Base
+ has_and_belongs_to_many :roles
+
+ validates_presence_of :controller, :action, :description
+
+ GROUPS = {
+ 100 => :label_project,
+ 200 => :label_member_plural,
+ 300 => :label_version_plural,
+ 400 => :label_issue_category_plural,
+ 600 => :label_query_plural,
+ 1000 => :label_issue_plural,
+ 1100 => :label_news_plural,
+ 1200 => :label_document_plural,
+ 1300 => :label_attachment_plural,
+ 1400 => :label_repository
+ }.freeze
+
+ @@cached_perms_for_public = nil
+ @@cached_perms_for_roles = nil
+
+ def name
+ self.controller + "/" + self.action
+ end
+
+ def group_id
+ (self.sort / 100)*100
+ end
+
+ def self.allowed_to_public(action)
+ @@cached_perms_for_public ||= find(:all, :conditions => ["is_public=?", true]).collect {|p| "#{p.controller}/#{p.action}"}
+ @@cached_perms_for_public.include? action
+ end
+
+ def self.allowed_to_role(action, role)
+ @@cached_perms_for_roles ||=
+ begin
+ perms = {}
+ find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } }
+ perms
+ end
+ allowed_to_public(action) or (@@cached_perms_for_roles[action] and @@cached_perms_for_roles[action].include? role)
+ end
+
+ def self.allowed_to_role_expired
+ @@cached_perms_for_roles = nil
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 3f9ec1680..3cf5a816a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1,71 +1,71 @@
-# redMine - project management software
-# Copyright (C) 2006 Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-class Project < ActiveRecord::Base
- has_many :versions, :dependent => :destroy, :order => "versions.effective_date DESC, versions.name DESC"
- has_many :members, :dependent => :delete_all, :include => :user, :conditions => "users.status=#{User::STATUS_ACTIVE}"
- has_many :users, :through => :members
- has_many :custom_values, :dependent => :delete_all, :as => :customized
- has_many :issues, :dependent => :destroy, :order => "issues.created_on DESC", :include => [:status, :tracker]
- has_many :queries, :dependent => :delete_all
- has_many :documents, :dependent => :destroy
- has_many :news, :dependent => :delete_all, :include => :author
- has_many :issue_categories, :dependent => :delete_all, :order => "issue_categories.name"
- has_one :repository, :dependent => :destroy
- has_one :wiki, :dependent => :destroy
- has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
- acts_as_tree :order => "name", :counter_cache => true
-
- validates_presence_of :name, :description
- validates_uniqueness_of :name
- validates_associated :custom_values, :on => :update
- validates_associated :repository, :wiki
- validates_format_of :name, :with => /^[\w\s\'\-]*$/i
-
- # returns latest created projects
- # non public projects will be returned only if user is a member of those
- def self.latest(user=nil, count=5)
- find(:all, :limit => count, :conditions => visible_by(user), :order => "projects.created_on DESC")
- end
-
- def self.visible_by(user=nil)
- if user && !user.memberships.empty?
- return ["projects.is_public = ? or projects.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')})", true]
- else
- return ["projects.is_public = ?", true]
- end
- end
-
- # Returns an array of all custom fields enabled for project issues
- # (explictly associated custom fields and custom fields enabled for all projects)
- def custom_fields_for_issues(tracker)
- tracker.custom_fields.find(:all, :include => :projects,
- :conditions => ["is_for_all=? or project_id=?", true, self.id])
- #(CustomField.for_all + custom_fields).uniq
- end
-
- def all_custom_fields
- @all_custom_fields ||= IssueCustomField.find(:all, :include => :projects,
- :conditions => ["is_for_all=? or project_id=?", true, self.id])
- end
-
-protected
- def validate
- errors.add(parent_id, " must be a root project") if parent and parent.parent
- errors.add_to_base("A project with subprojects can't be a subproject") if parent and children.size > 0
+# redMine - project management software
+# Copyright (C) 2006 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class Project < ActiveRecord::Base
+ has_many :versions, :dependent => :destroy, :order => "versions.effective_date DESC, versions.name DESC"
+ has_many :members, :dependent => :delete_all, :include => :user, :conditions => "users.status=#{User::STATUS_ACTIVE}"
+ has_many :users, :through => :members
+ has_many :custom_values, :dependent => :delete_all, :as => :customized
+ has_many :issues, :dependent => :destroy, :order => "issues.created_on DESC", :include => [:status, :tracker]
+ has_many :queries, :dependent => :delete_all
+ has_many :documents, :dependent => :destroy
+ has_many :news, :dependent => :delete_all, :include => :author
+ has_many :issue_categories, :dependent => :delete_all, :order => "issue_categories.name"
+ has_one :repository, :dependent => :destroy
+ has_one :wiki, :dependent => :destroy
+ has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
+ acts_as_tree :order => "name", :counter_cache => true
+
+ validates_presence_of :name, :description
+ validates_uniqueness_of :name
+ validates_associated :custom_values, :on => :update
+ validates_associated :repository, :wiki
+ validates_format_of :name, :with => /^[\w\s\'\-]*$/i
+
+ # returns latest created projects
+ # non public projects will be returned only if user is a member of those
+ def self.latest(user=nil, count=5)
+ find(:all, :limit => count, :conditions => visible_by(user), :order => "projects.created_on DESC")
+ end
+
+ def self.visible_by(user=nil)
+ if user && !user.memberships.empty?
+ return ["projects.is_public = ? or projects.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')})", true]
+ else
+ return ["projects.is_public = ?", true]
+ end
+ end
+
+ # Returns an array of all custom fields enabled for project issues
+ # (explictly associated custom fields and custom fields enabled for all projects)
+ def custom_fields_for_issues(tracker)
+ tracker.custom_fields.find(:all, :include => :projects,
+ :conditions => ["is_for_all=? or project_id=?", true, self.id])
+ #(CustomField.for_all + custom_fields).uniq
+ end
+
+ def all_custom_fields
+ @all_custom_fields ||= IssueCustomField.find(:all, :include => :projects,
+ :conditions => ["is_for_all=? or project_id=?", true, self.id])
+ end
+
+protected
+ def validate
+ errors.add(parent_id, " must be a root project") if parent and parent.parent
+ errors.add_to_base("A project with subprojects can't be a subproject") if parent and children.size > 0
end
end
diff --git a/app/models/project_custom_field.rb b/app/models/project_custom_field.rb
index baa533812..f0dab6913 100644
--- a/app/models/project_custom_field.rb
+++ b/app/models/project_custom_field.rb
@@ -1,22 +1,22 @@
-# redMine - project management software
-# Copyright (C) 2006 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 ProjectCustomField < CustomField
- def type_name
- :label_project_plural
- end
-end
+# redMine - project management software
+# Copyright (C) 2006 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 ProjectCustomField < CustomField
+ def type_name
+ :label_project_plural
+ end
+end
diff --git a/app/models/role.rb b/app/models/role.rb
index d00a2b218..7798f3bc6 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -1,33 +1,33 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Role < ActiveRecord::Base
- before_destroy :check_integrity
- has_and_belongs_to_many :permissions
- has_many :workflows, :dependent => :delete_all
- has_many :members
- acts_as_list
-
- validates_presence_of :name
- validates_uniqueness_of :name
- validates_format_of :name, :with => /^[\w\s\'\-]*$/i
-
-private
- def check_integrity
- raise "Can't delete role" if Member.find(:first, :conditions =>["role_id=?", self.id])
+# redMine - project management software
+# Copyright (C) 2006 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 Role < ActiveRecord::Base
+ before_destroy :check_integrity
+ has_and_belongs_to_many :permissions
+ has_many :workflows, :dependent => :delete_all
+ has_many :members
+ acts_as_list
+
+ validates_presence_of :name
+ validates_uniqueness_of :name
+ validates_format_of :name, :with => /^[\w\s\'\-]*$/i
+
+private
+ def check_integrity
+ raise "Can't delete role" if Member.find(:first, :conditions =>["role_id=?", self.id])
end
end
diff --git a/app/models/svn_repos.rb b/app/models/svn_repos.rb
index aed9f1b58..3ed81403d 100644
--- a/app/models/svn_repos.rb
+++ b/app/models/svn_repos.rb
@@ -1,216 +1,216 @@
-# redMine - project management software
-# Copyright (C) 2006 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 'rexml/document'
-
-module SvnRepos
-
- class CommandFailed < StandardError #:nodoc:
- end
-
- class Base
-
- def initialize(url, login=nil, password=nil)
- @url = url
- @login = login if login && !login.empty?
- @password = (password || "") if @login
- end
-
- # Returns the entry identified by path and revision identifier
- # or nil if entry doesn't exist in the repository
- def entry(path=nil, identifier=nil)
- e = entries(path, identifier)
- e ? e.first : nil
- end
-
- # Returns an Entries collection
- # or nil if the given path doesn't exist in the repository
- def entries(path=nil, identifier=nil)
- path ||= ''
- identifier = 'HEAD' unless identifier and identifier > 0
- entries = Entries.new
- cmd = "svn list --xml #{target(path)}@#{identifier}"
- cmd << " --username #{@login} --password #{@password}" if @login
- shellout(cmd) do |io|
- begin
- doc = REXML::Document.new(io)
- doc.elements.each("lists/list/entry") do |entry|
- entries << Entry.new({:name => entry.elements['name'].text,
- :path => ((path.empty? ? "" : "#{path}/") + entry.elements['name'].text),
- :kind => entry.attributes['kind'],
- :size => (entry.elements['size'] and entry.elements['size'].text).to_i,
- :lastrev => Revision.new({
- :identifier => entry.elements['commit'].attributes['revision'],
- :time => Time.parse(entry.elements['commit'].elements['date'].text),
- :author => (entry.elements['commit'].elements['author'] ? entry.elements['commit'].elements['author'].text : "anonymous")
- })
- })
- end
- rescue
- end
- end
- return nil if $? && $?.exitstatus != 0
- entries.sort_by_name
- rescue Errno::ENOENT => e
- raise CommandFailed
- end
-
- def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
- path ||= ''
- identifier_from = 'HEAD' unless identifier_from and identifier_from.to_i > 0
- identifier_to = 1 unless identifier_to and identifier_to.to_i > 0
- revisions = Revisions.new
- cmd = "svn log --xml -r #{identifier_from}:#{identifier_to}"
- cmd << " --username #{@login} --password #{@password}" if @login
- cmd << " --verbose " if options[:with_paths]
- cmd << target(path)
- shellout(cmd) do |io|
- begin
- doc = REXML::Document.new(io)
- doc.elements.each("log/logentry") do |logentry|
- paths = []
- logentry.elements.each("paths/path") do |path|
- paths << {:action => path.attributes['action'],
- :path => path.text
- }
- end
- paths.sort! { |x,y| x[:path] <=> y[:path] }
-
- revisions << Revision.new({:identifier => logentry.attributes['revision'],
- :author => (logentry.elements['author'] ? logentry.elements['author'].text : "anonymous"),
- :time => Time.parse(logentry.elements['date'].text),
- :message => logentry.elements['msg'].text,
- :paths => paths
- })
- end
- rescue
- end
- end
- return nil if $? && $?.exitstatus != 0
- revisions
- rescue Errno::ENOENT => e
- raise CommandFailed
- end
-
- def diff(path, identifier_from, identifier_to=nil)
- path ||= ''
- if identifier_to and identifier_to.to_i > 0
- identifier_to = identifier_to.to_i
- else
- identifier_to = identifier_from.to_i - 1
- end
- cmd = "svn diff -r "
- cmd << "#{identifier_to}:"
- cmd << "#{identifier_from}"
- cmd << "#{target(path)}@#{identifier_from}"
- cmd << " --username #{@login} --password #{@password}" if @login
- diff = []
- shellout(cmd) do |io|
- io.each_line do |line|
- diff << line
- end
- end
- return nil if $? && $?.exitstatus != 0
- diff
- rescue Errno::ENOENT => e
- raise CommandFailed
- end
-
- def cat(path, identifier=nil)
- identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
- cmd = "svn cat #{target(path)}@#{identifier}"
- cmd << " --username #{@login} --password #{@password}" if @login
- cat = nil
- shellout(cmd) do |io|
- cat = io.read
- end
- return nil if $? && $?.exitstatus != 0
- cat
- rescue Errno::ENOENT => e
- raise CommandFailed
- end
-
- private
- def target(path)
- " \"" << "#{@url}/#{path}".gsub(/["'?<>\*]/, '') << "\""
- end
-
- def logger
- RAILS_DEFAULT_LOGGER
- end
-
- def shellout(cmd, &block)
- logger.debug "Shelling out: #{cmd}" if logger && logger.debug?
- IO.popen(cmd, "r+") do |io|
- io.close_write
- block.call(io) if block_given?
- end
- end
- end
-
- class Entries < Array
- def sort_by_name
- sort {|x,y|
- if x.kind == y.kind
- x.name <=> y.name
- else
- x.kind <=> y.kind
- end
- }
- end
-
- def revisions
- revisions ||= Revisions.new(collect{|entry| entry.lastrev})
- end
- end
-
- class Entry
- attr_accessor :name, :path, :kind, :size, :lastrev
- def initialize(attributes={})
- self.name = attributes[:name] if attributes[:name]
- self.path = attributes[:path] if attributes[:path]
- self.kind = attributes[:kind] if attributes[:kind]
- self.size = attributes[:size].to_i if attributes[:size]
- self.lastrev = attributes[:lastrev]
- end
-
- def is_file?
- 'file' == self.kind
- end
-
- def is_dir?
- 'dir' == self.kind
- end
- end
-
- class Revisions < Array
- def latest
- sort {|x,y| x.time <=> y.time}.last
- end
- end
-
- class Revision
- attr_accessor :identifier, :author, :time, :message, :paths
- def initialize(attributes={})
- self.identifier = attributes[:identifier]
- self.author = attributes[:author]
- self.time = attributes[:time]
- self.message = attributes[:message] || ""
- self.paths = attributes[:paths]
- end
- end
+# redMine - project management software
+# Copyright (C) 2006 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 'rexml/document'
+
+module SvnRepos
+
+ class CommandFailed < StandardError #:nodoc:
+ end
+
+ class Base
+
+ def initialize(url, login=nil, password=nil)
+ @url = url
+ @login = login if login && !login.empty?
+ @password = (password || "") if @login
+ end
+
+ # Returns the entry identified by path and revision identifier
+ # or nil if entry doesn't exist in the repository
+ def entry(path=nil, identifier=nil)
+ e = entries(path, identifier)
+ e ? e.first : nil
+ end
+
+ # Returns an Entries collection
+ # or nil if the given path doesn't exist in the repository
+ def entries(path=nil, identifier=nil)
+ path ||= ''
+ identifier = 'HEAD' unless identifier and identifier > 0
+ entries = Entries.new
+ cmd = "svn list --xml #{target(path)}@#{identifier}"
+ cmd << " --username #{@login} --password #{@password}" if @login
+ shellout(cmd) do |io|
+ begin
+ doc = REXML::Document.new(io)
+ doc.elements.each("lists/list/entry") do |entry|
+ entries << Entry.new({:name => entry.elements['name'].text,
+ :path => ((path.empty? ? "" : "#{path}/") + entry.elements['name'].text),
+ :kind => entry.attributes['kind'],
+ :size => (entry.elements['size'] and entry.elements['size'].text).to_i,
+ :lastrev => Revision.new({
+ :identifier => entry.elements['commit'].attributes['revision'],
+ :time => Time.parse(entry.elements['commit'].elements['date'].text),
+ :author => (entry.elements['commit'].elements['author'] ? entry.elements['commit'].elements['author'].text : "anonymous")
+ })
+ })
+ end
+ rescue
+ end
+ end
+ return nil if $? && $?.exitstatus != 0
+ entries.sort_by_name
+ rescue Errno::ENOENT => e
+ raise CommandFailed
+ end
+
+ def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
+ path ||= ''
+ identifier_from = 'HEAD' unless identifier_from and identifier_from.to_i > 0
+ identifier_to = 1 unless identifier_to and identifier_to.to_i > 0
+ revisions = Revisions.new
+ cmd = "svn log --xml -r #{identifier_from}:#{identifier_to}"
+ cmd << " --username #{@login} --password #{@password}" if @login
+ cmd << " --verbose " if options[:with_paths]
+ cmd << target(path)
+ shellout(cmd) do |io|
+ begin
+ doc = REXML::Document.new(io)
+ doc.elements.each("log/logentry") do |logentry|
+ paths = []
+ logentry.elements.each("paths/path") do |path|
+ paths << {:action => path.attributes['action'],
+ :path => path.text
+ }
+ end
+ paths.sort! { |x,y| x[:path] <=> y[:path] }
+
+ revisions << Revision.new({:identifier => logentry.attributes['revision'],
+ :author => (logentry.elements['author'] ? logentry.elements['author'].text : "anonymous"),
+ :time => Time.parse(logentry.elements['date'].text),
+ :message => logentry.elements['msg'].text,
+ :paths => paths
+ })
+ end
+ rescue
+ end
+ end
+ return nil if $? && $?.exitstatus != 0
+ revisions
+ rescue Errno::ENOENT => e
+ raise CommandFailed
+ end
+
+ def diff(path, identifier_from, identifier_to=nil)
+ path ||= ''
+ if identifier_to and identifier_to.to_i > 0
+ identifier_to = identifier_to.to_i
+ else
+ identifier_to = identifier_from.to_i - 1
+ end
+ cmd = "svn diff -r "
+ cmd << "#{identifier_to}:"
+ cmd << "#{identifier_from}"
+ cmd << "#{target(path)}@#{identifier_from}"
+ cmd << " --username #{@login} --password #{@password}" if @login
+ diff = []
+ shellout(cmd) do |io|
+ io.each_line do |line|
+ diff << line
+ end
+ end
+ return nil if $? && $?.exitstatus != 0
+ diff
+ rescue Errno::ENOENT => e
+ raise CommandFailed
+ end
+
+ def cat(path, identifier=nil)
+ identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
+ cmd = "svn cat #{target(path)}@#{identifier}"
+ cmd << " --username #{@login} --password #{@password}" if @login
+ cat = nil
+ shellout(cmd) do |io|
+ cat = io.read
+ end
+ return nil if $? && $?.exitstatus != 0
+ cat
+ rescue Errno::ENOENT => e
+ raise CommandFailed
+ end
+
+ private
+ def target(path)
+ " \"" << "#{@url}/#{path}".gsub(/["'?<>\*]/, '') << "\""
+ end
+
+ def logger
+ RAILS_DEFAULT_LOGGER
+ end
+
+ def shellout(cmd, &block)
+ logger.debug "Shelling out: #{cmd}" if logger && logger.debug?
+ IO.popen(cmd, "r+") do |io|
+ io.close_write
+ block.call(io) if block_given?
+ end
+ end
+ end
+
+ class Entries < Array
+ def sort_by_name
+ sort {|x,y|
+ if x.kind == y.kind
+ x.name <=> y.name
+ else
+ x.kind <=> y.kind
+ end
+ }
+ end
+
+ def revisions
+ revisions ||= Revisions.new(collect{|entry| entry.lastrev})
+ end
+ end
+
+ class Entry
+ attr_accessor :name, :path, :kind, :size, :lastrev
+ def initialize(attributes={})
+ self.name = attributes[:name] if attributes[:name]
+ self.path = attributes[:path] if attributes[:path]
+ self.kind = attributes[:kind] if attributes[:kind]
+ self.size = attributes[:size].to_i if attributes[:size]
+ self.lastrev = attributes[:lastrev]
+ end
+
+ def is_file?
+ 'file' == self.kind
+ end
+
+ def is_dir?
+ 'dir' == self.kind
+ end
+ end
+
+ class Revisions < Array
+ def latest
+ sort {|x,y| x.time <=> y.time}.last
+ end
+ end
+
+ class Revision
+ attr_accessor :identifier, :author, :time, :message, :paths
+ def initialize(attributes={})
+ self.identifier = attributes[:identifier]
+ self.author = attributes[:author]
+ self.time = attributes[:time]
+ self.message = attributes[:message] || ""
+ self.paths = attributes[:paths]
+ end
+ end
end \ No newline at end of file
diff --git a/app/models/tracker.rb b/app/models/tracker.rb
index b584704c2..51ae73d1c 100644
--- a/app/models/tracker.rb
+++ b/app/models/tracker.rb
@@ -1,33 +1,33 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Tracker < ActiveRecord::Base
- before_destroy :check_integrity
- has_many :issues
- has_many :workflows, :dependent => :delete_all
- has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_trackers', :association_foreign_key => 'custom_field_id'
- acts_as_list
-
- validates_presence_of :name
- validates_uniqueness_of :name
- validates_format_of :name, :with => /^[\w\s\'\-]*$/i
-
-private
- def check_integrity
- raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
+# redMine - project management software
+# Copyright (C) 2006 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 Tracker < ActiveRecord::Base
+ before_destroy :check_integrity
+ has_many :issues
+ has_many :workflows, :dependent => :delete_all
+ has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_trackers', :association_foreign_key => 'custom_field_id'
+ acts_as_list
+
+ validates_presence_of :name
+ validates_uniqueness_of :name
+ validates_format_of :name, :with => /^[\w\s\'\-]*$/i
+
+private
+ def check_integrity
+ raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index bf2930a0f..3a315239c 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,142 +1,142 @@
-# redMine - project management software
-# Copyright (C) 2006-2007 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/sha1"
-
-class User < ActiveRecord::Base
- has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => :delete_all
- has_many :projects, :through => :memberships
- has_many :custom_values, :dependent => :delete_all, :as => :customized
- has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
- belongs_to :auth_source
-
- attr_accessor :password, :password_confirmation
- attr_accessor :last_before_login_on
- # Prevents unauthorized assignments
- attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
-
- validates_presence_of :login, :firstname, :lastname, :mail
- validates_uniqueness_of :login, :mail
- # Login must contain lettres, numbers, underscores only
- validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i
- validates_format_of :login, :with => /^[a-z0-9_\-@\.]+$/i
- validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
- # Password length between 4 and 12
- validates_length_of :password, :in => 4..12, :allow_nil => true
- validates_confirmation_of :password, :allow_nil => true
- validates_associated :custom_values, :on => :update
-
- # Account statuses
- STATUS_ACTIVE = 1
- STATUS_REGISTERED = 2
- STATUS_LOCKED = 3
-
- def before_save
- # update hashed_password if password was set
- self.hashed_password = User.hash_password(self.password) if self.password
- end
-
- def self.active
- with_scope :find => { :conditions => [ "status = ?", STATUS_ACTIVE ] } do
- yield
- end
- end
-
- def self.find_active(*args)
- active do
- find(*args)
- end
- end
-
- # Returns the user that matches provided login and password, or nil
- def self.try_to_login(login, password)
- user = find(:first, :conditions => ["login=?", login])
- if user
- # user is already in local database
- return nil if !user.active?
- if user.auth_source
- # user has an external authentication method
- return nil unless user.auth_source.authenticate(login, password)
- else
- # authentication with local password
- return nil unless User.hash_password(password) == user.hashed_password
- end
- else
- # user is not yet registered, try to authenticate with available sources
- attrs = AuthSource.authenticate(login, password)
- if attrs
- onthefly = new(*attrs)
- onthefly.login = login
- onthefly.language = Setting.default_language
- if onthefly.save
- user = find(:first, :conditions => ["login=?", login])
- logger.info("User '#{user.login}' created on the fly.") if logger
- end
- end
- end
- user.update_attribute(:last_login_on, Time.now) if user
- user
-
- rescue => text
- raise text
- end
-
- # Return user's full name for display
- def display_name
- firstname + " " + lastname
- end
-
- def name
- display_name
- end
-
- def active?
- self.status == STATUS_ACTIVE
- end
-
- def registered?
- self.status == STATUS_REGISTERED
- end
-
- def locked?
- self.status == STATUS_LOCKED
- end
-
- def check_password?(clear_password)
- User.hash_password(clear_password) == self.hashed_password
- end
-
- def role_for_project(project_id)
- @role_for_projects ||=
- begin
- roles = {}
- self.memberships.each { |m| roles.store m.project_id, m.role_id }
- roles
- end
- @role_for_projects[project_id]
- end
-
- def pref
- self.preference ||= UserPreference.new(:user => self)
- end
-
-private
- # Return password digest
- def self.hash_password(clear_password)
- Digest::SHA1.hexdigest(clear_password || "")
+# redMine - project management software
+# Copyright (C) 2006-2007 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/sha1"
+
+class User < ActiveRecord::Base
+ has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => :delete_all
+ has_many :projects, :through => :memberships
+ has_many :custom_values, :dependent => :delete_all, :as => :customized
+ has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
+ belongs_to :auth_source
+
+ attr_accessor :password, :password_confirmation
+ attr_accessor :last_before_login_on
+ # Prevents unauthorized assignments
+ attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
+
+ validates_presence_of :login, :firstname, :lastname, :mail
+ validates_uniqueness_of :login, :mail
+ # Login must contain lettres, numbers, underscores only
+ validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i
+ validates_format_of :login, :with => /^[a-z0-9_\-@\.]+$/i
+ validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
+ # Password length between 4 and 12
+ validates_length_of :password, :in => 4..12, :allow_nil => true
+ validates_confirmation_of :password, :allow_nil => true
+ validates_associated :custom_values, :on => :update
+
+ # Account statuses
+ STATUS_ACTIVE = 1
+ STATUS_REGISTERED = 2
+ STATUS_LOCKED = 3
+
+ def before_save
+ # update hashed_password if password was set
+ self.hashed_password = User.hash_password(self.password) if self.password
+ end
+
+ def self.active
+ with_scope :find => { :conditions => [ "status = ?", STATUS_ACTIVE ] } do
+ yield
+ end
+ end
+
+ def self.find_active(*args)
+ active do
+ find(*args)
+ end
+ end
+
+ # Returns the user that matches provided login and password, or nil
+ def self.try_to_login(login, password)
+ user = find(:first, :conditions => ["login=?", login])
+ if user
+ # user is already in local database
+ return nil if !user.active?
+ if user.auth_source
+ # user has an external authentication method
+ return nil unless user.auth_source.authenticate(login, password)
+ else
+ # authentication with local password
+ return nil unless User.hash_password(password) == user.hashed_password
+ end
+ else
+ # user is not yet registered, try to authenticate with available sources
+ attrs = AuthSource.authenticate(login, password)
+ if attrs
+ onthefly = new(*attrs)
+ onthefly.login = login
+ onthefly.language = Setting.default_language
+ if onthefly.save
+ user = find(:first, :conditions => ["login=?", login])
+ logger.info("User '#{user.login}' created on the fly.") if logger
+ end
+ end
+ end
+ user.update_attribute(:last_login_on, Time.now) if user
+ user
+
+ rescue => text
+ raise text
+ end
+
+ # Return user's full name for display
+ def display_name
+ firstname + " " + lastname
+ end
+
+ def name
+ display_name
+ end
+
+ def active?
+ self.status == STATUS_ACTIVE
+ end
+
+ def registered?
+ self.status == STATUS_REGISTERED
+ end
+
+ def locked?
+ self.status == STATUS_LOCKED
+ end
+
+ def check_password?(clear_password)
+ User.hash_password(clear_password) == self.hashed_password
+ end
+
+ def role_for_project(project_id)
+ @role_for_projects ||=
+ begin
+ roles = {}
+ self.memberships.each { |m| roles.store m.project_id, m.role_id }
+ roles
+ end
+ @role_for_projects[project_id]
+ end
+
+ def pref
+ self.preference ||= UserPreference.new(:user => self)
+ end
+
+private
+ # Return password digest
+ def self.hash_password(clear_password)
+ Digest::SHA1.hexdigest(clear_password || "")
end
end
diff --git a/app/models/user_custom_field.rb b/app/models/user_custom_field.rb
index 866234a7f..99e76eea5 100644
--- a/app/models/user_custom_field.rb
+++ b/app/models/user_custom_field.rb
@@ -1,23 +1,23 @@
-# redMine - project management software
-# Copyright (C) 2006 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 UserCustomField < CustomField
- def type_name
- :label_user_plural
- end
-end
+# redMine - project management software
+# Copyright (C) 2006 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 UserCustomField < CustomField
+ def type_name
+ :label_user_plural
+ end
+end
diff --git a/app/models/version.rb b/app/models/version.rb
index 71a8a8807..611500c8c 100644
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -1,32 +1,32 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Version < ActiveRecord::Base
- before_destroy :check_integrity
- belongs_to :project
- has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id'
- has_many :attachments, :as => :container, :dependent => :destroy
-
- validates_presence_of :name
- validates_uniqueness_of :name, :scope => [:project_id]
- validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :activerecord_error_not_a_date
-
-private
- def check_integrity
- raise "Can't delete version" if self.fixed_issues.find(:first)
- end
+# redMine - project management software
+# Copyright (C) 2006 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 Version < ActiveRecord::Base
+ before_destroy :check_integrity
+ belongs_to :project
+ has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id'
+ has_many :attachments, :as => :container, :dependent => :destroy
+
+ validates_presence_of :name
+ validates_uniqueness_of :name, :scope => [:project_id]
+ validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :activerecord_error_not_a_date
+
+private
+ def check_integrity
+ raise "Can't delete version" if self.fixed_issues.find(:first)
+ end
end
diff --git a/app/models/workflow.rb b/app/models/workflow.rb
index 22c873fc7..89322aa58 100644
--- a/app/models/workflow.rb
+++ b/app/models/workflow.rb
@@ -1,24 +1,24 @@
-# redMine - project management software
-# Copyright (C) 2006 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 Workflow < ActiveRecord::Base
- belongs_to :role
- belongs_to :old_status, :class_name => 'IssueStatus', :foreign_key => 'old_status_id'
- belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
-
- validates_presence_of :role, :old_status, :new_status
+# redMine - project management software
+# Copyright (C) 2006 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 Workflow < ActiveRecord::Base
+ belongs_to :role
+ belongs_to :old_status, :class_name => 'IssueStatus', :foreign_key => 'old_status_id'
+ belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
+
+ validates_presence_of :role, :old_status, :new_status
end