To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / b0 / b08b8359ba61a19a3531e1766fc73fb2077273a2.svn-base @ 1297:0a574315af3e

History | View | Annotate | Download (5.87 KB)

1 1296:038ba2d95de8 Chris
# Redmine - project management software
2
# Copyright (C) 2006-2012  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17
18
module Redmine
19
  module Acts
20
    module Customizable
21
      def self.included(base)
22
        base.extend ClassMethods
23
      end
24
25
      module ClassMethods
26
        def acts_as_customizable(options = {})
27
          return if self.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
28
          cattr_accessor :customizable_options
29
          self.customizable_options = options
30
          has_many :custom_values, :as => :customized,
31
                                   :include => :custom_field,
32
                                   :order => "#{CustomField.table_name}.position",
33
                                   :dependent => :delete_all,
34
                                   :validate => false
35
          send :include, Redmine::Acts::Customizable::InstanceMethods
36
          validate :validate_custom_field_values
37
          after_save :save_custom_field_values
38
        end
39
      end
40
41
      module InstanceMethods
42
        def self.included(base)
43
          base.extend ClassMethods
44
        end
45
46
        def available_custom_fields
47
          CustomField.find(:all, :conditions => "type = '#{self.class.name}CustomField'",
48
                                 :order => 'position')
49
        end
50
51
        # Sets the values of the object's custom fields
52
        # values is an array like [{'id' => 1, 'value' => 'foo'}, {'id' => 2, 'value' => 'bar'}]
53
        def custom_fields=(values)
54
          values_to_hash = values.inject({}) do |hash, v|
55
            v = v.stringify_keys
56
            if v['id'] && v.has_key?('value')
57
              hash[v['id']] = v['value']
58
            end
59
            hash
60
          end
61
          self.custom_field_values = values_to_hash
62
        end
63
64
        # Sets the values of the object's custom fields
65
        # values is a hash like {'1' => 'foo', 2 => 'bar'}
66
        def custom_field_values=(values)
67
          values = values.stringify_keys
68
69
          custom_field_values.each do |custom_field_value|
70
            key = custom_field_value.custom_field_id.to_s
71
            if values.has_key?(key)
72
              value = values[key]
73
              if value.is_a?(Array)
74
                value = value.reject(&:blank?).uniq
75
                if value.empty?
76
                  value << ''
77
                end
78
              end
79
              custom_field_value.value = value
80
            end
81
          end
82
          @custom_field_values_changed = true
83
        end
84
85
        def custom_field_values
86
          @custom_field_values ||= available_custom_fields.collect do |field|
87
            x = CustomFieldValue.new
88
            x.custom_field = field
89
            x.customized = self
90
            if field.multiple?
91
              values = custom_values.select { |v| v.custom_field == field }
92
              if values.empty?
93
                values << custom_values.build(:customized => self, :custom_field => field, :value => nil)
94
              end
95
              x.value = values.map(&:value)
96
            else
97
              cv = custom_values.detect { |v| v.custom_field == field }
98
              cv ||= custom_values.build(:customized => self, :custom_field => field, :value => nil)
99
              x.value = cv.value
100
            end
101
            x
102
          end
103
        end
104
105
        def visible_custom_field_values
106
          custom_field_values.select(&:visible?)
107
        end
108
109
        def custom_field_values_changed?
110
          @custom_field_values_changed == true
111
        end
112
113
        def custom_value_for(c)
114
          field_id = (c.is_a?(CustomField) ? c.id : c.to_i)
115
          custom_values.detect {|v| v.custom_field_id == field_id }
116
        end
117
118
        def custom_field_value(c)
119
          field_id = (c.is_a?(CustomField) ? c.id : c.to_i)
120
          custom_field_values.detect {|v| v.custom_field_id == field_id }.try(:value)
121
        end
122
123
        def validate_custom_field_values
124
          if new_record? || custom_field_values_changed?
125
            custom_field_values.each(&:validate_value)
126
          end
127
        end
128
129
        def save_custom_field_values
130
          target_custom_values = []
131
          custom_field_values.each do |custom_field_value|
132
            if custom_field_value.value.is_a?(Array)
133
              custom_field_value.value.each do |v|
134
                target = custom_values.detect {|cv| cv.custom_field == custom_field_value.custom_field && cv.value == v}
135
                target ||= custom_values.build(:customized => self, :custom_field => custom_field_value.custom_field, :value => v)
136
                target_custom_values << target
137
              end
138
            else
139
              target = custom_values.detect {|cv| cv.custom_field == custom_field_value.custom_field}
140
              target ||= custom_values.build(:customized => self, :custom_field => custom_field_value.custom_field)
141
              target.value = custom_field_value.value
142
              target_custom_values << target
143
            end
144
          end
145
          self.custom_values = target_custom_values
146
          custom_values.each(&:save)
147
          @custom_field_values_changed = false
148
          true
149
        end
150
151
        def reset_custom_values!
152
          @custom_field_values = nil
153
          @custom_field_values_changed = true
154
        end
155
156
        module ClassMethods
157
        end
158
      end
159
    end
160
  end
161
end