Class: CustomField

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Redmine::SafeAttributes, Redmine::SubclassFactory
Defined in:
app/models/custom_field.rb

Overview

Redmine - project management software Copyright (C) 2006-2017 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.

Since:

  • 0.4.0

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Redmine::SafeAttributes

#delete_unsafe_attributes, #safe_attribute?, #safe_attribute_names, #safe_attributes=

Class Method Details

.customized_classObject

Since:

  • 0.9.0



250
251
252
253
# File 'app/models/custom_field.rb', line 250

def self.customized_class
  self.name =~ /^(.+)CustomField$/
  $1.constantize rescue nil
end

.for_allObject

to move in project_custom_field



256
257
258
# File 'app/models/custom_field.rb', line 256

def self.for_all
  where(:is_for_all => true).order(:position).to_a
end

.human_attribute_name(attribute_key_name, *args) ⇒ Object

Since:

  • 3.2.3



306
307
308
309
310
311
312
# File 'app/models/custom_field.rb', line 306

def self.human_attribute_name(attribute_key_name, *args)
  attr_name = attribute_key_name.to_s
  if attr_name == 'url_pattern'
    attr_name = "url"
  end
  super(attr_name, *args)
end

.visibility_conditionObject

Deprecated.

Removed at 4.0.0

Since:

  • 2.4.0



228
229
230
231
232
233
234
235
236
237
238
239
# File 'app/models/custom_field.rb', line 228

def self.visibility_condition
  if user.admin?
    "1=1"
  elsif user.anonymous?
    "#{table_name}.visible"
  else
    "#{project_key} IN (SELECT DISTINCT m.project_id FROM #{Member.table_name} m" +
      " INNER JOIN #{MemberRole.table_name} mr ON mr.member_id = m.id" +
      " INNER JOIN #{table_name_prefix}custom_fields_roles#{table_name_suffix} cfr ON cfr.role_id = mr.role_id" +
      " WHERE m.user_id = #{user.id} AND cfr.custom_field_id = #{id})"
  end
end

Instance Method Details

#<=>(field) ⇒ Object

Since:

  • 0.6.1



241
242
243
# File 'app/models/custom_field.rb', line 241

def <=>(field)
  position <=> field.position
end

#after_save_custom_value(custom_value) ⇒ Object

Since:

  • 3.4.0



298
299
300
# File 'app/models/custom_field.rb', line 298

def after_save_custom_value(custom_value)
  format.after_save_custom_value(self, custom_value)
end

#cast_value(value) ⇒ Object

Since:

  • 0.9.0



173
174
175
# File 'app/models/custom_field.rb', line 173

def cast_value(value)
  format.cast_value(self, value)
end

#field_format=(arg) ⇒ Object

Since:

  • 2.2.0



99
100
101
102
103
104
105
# File 'app/models/custom_field.rb', line 99

def field_format=(arg)
  # cannot change format of a saved custom field
  if new_record?
    @format = nil
    super
  end
end

#formatObject

Since:

  • 2.5.0



95
96
97
# File 'app/models/custom_field.rb', line 95

def format
  @format ||= Redmine::FieldFormat.find(field_format)
end

#format_in?(*args) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 2.1.0



302
303
304
# File 'app/models/custom_field.rb', line 302

def format_in?(*args)
  args.include?(field_format)
end

#full_width_layout?Boolean

Returns:

  • (Boolean)

Since:

  • 3.4.0



190
191
192
# File 'app/models/custom_field.rb', line 190

def full_width_layout?
  full_width_layout == '1'
end

#group_statementObject

Returns a GROUP BY clause that can used to group by custom value Returns nil if the custom field can not be used for grouping.

Since:

  • 2.1.0



204
205
206
207
# File 'app/models/custom_field.rb', line 204

def group_statement
  return nil if multiple?
  format.group_statement(self)
end

#join_for_order_statementObject

Since:

  • 2.1.0



209
210
211
# File 'app/models/custom_field.rb', line 209

def join_for_order_statement
  format.join_for_order_statement(self)
end

#order_statementObject

Returns a ORDER BY clause that can used to sort customized objects by their value of the custom field. Returns nil if the custom field can not be used for sorting.

Since:

  • 0.9.0



197
198
199
200
# File 'app/models/custom_field.rb', line 197

def order_statement
  return nil if multiple?
  format.order_statement(self)
end

#possible_custom_value_options(custom_value) ⇒ Object

Since:

  • 2.5.0



135
136
137
# File 'app/models/custom_field.rb', line 135

def possible_custom_value_options(custom_value)
  format.possible_custom_value_options(custom_value)
end

#possible_valuesObject

Since:

  • 1.2.0



147
148
149
150
151
152
153
154
155
156
157
# File 'app/models/custom_field.rb', line 147

def possible_values
  values = read_attribute(:possible_values)
  if values.is_a?(Array)
    values.each do |value|
      value.to_s.force_encoding('UTF-8')
    end
    values
  else
    []
  end
end

#possible_values=(arg) ⇒ Object

Makes possible_values accept a multiline string

Since:

  • 0.9.0



160
161
162
163
164
165
166
167
# File 'app/models/custom_field.rb', line 160

def possible_values=(arg)
  if arg.is_a?(Array)
    values = arg.compact.map {|a| a.to_s.strip}.reject(&:blank?)
    write_attribute(:possible_values, values)
  else
    self.possible_values = arg.to_s.split(/[\n\r]+/)
  end
end

#possible_values_options(object = nil) ⇒ Object

Since:

  • 1.2.0



139
140
141
142
143
144
145
# File 'app/models/custom_field.rb', line 139

def possible_values_options(object=nil)
  if object.is_a?(Array)
    object.map {|o| format.possible_values_options(self, o)}.reduce(:&) || []
  else
    format.possible_values_options(self, object) || []
  end
end

#query_filter_options(query) ⇒ Object

Returns the options hash used to build a query filter for the field

Since:

  • 3.2.0



182
183
184
# File 'app/models/custom_field.rb', line 182

def query_filter_options(query)
  format.query_filter_options(self, query)
end

#set_custom_field_value(custom_field_value, value) ⇒ Object

Since:

  • 3.4.0



169
170
171
# File 'app/models/custom_field.rb', line 169

def set_custom_field_value(custom_field_value, value)
  format.set_custom_field_value(self, custom_field_value, value)
end

#set_searchableObject

Since:

  • 1.4.0



107
108
109
110
111
112
113
# File 'app/models/custom_field.rb', line 107

def set_searchable
  # make sure these fields are not searchable
  self.searchable = false unless format.class.searchable_supported
  # make sure only these fields can have multiple values
  self.multiple = false unless format.class.multiple_supported
  true
end

#totalable?Boolean

Returns:

  • (Boolean)

Since:

  • 3.2.0



186
187
188
# File 'app/models/custom_field.rb', line 186

def totalable?
  format.totalable_supported
end

#type_nameObject



260
261
262
# File 'app/models/custom_field.rb', line 260

def type_name
  nil
end

#valid_field_value?(value) ⇒ Boolean

Returns true if value is a valid value for the custom field

Returns:

  • (Boolean)

Since:

  • 1.4.0



294
295
296
# File 'app/models/custom_field.rb', line 294

def valid_field_value?(value)
  validate_field_value(value).empty?
end

#validate_custom_fieldObject

Since:

  • 1.4.0



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'app/models/custom_field.rb', line 115

def validate_custom_field
  format.validate_custom_field(self).each do |attribute, message|
    errors.add attribute, message
  end

  if regexp.present?
    begin
      Regexp.new(regexp)
    rescue
      errors.add(:regexp, :invalid)
    end
  end

  if default_value.present?
    validate_field_value(default_value).each do |message|
      errors.add :default_value, message
    end
  end
end

#validate_custom_value(custom_value) ⇒ Object

Returns the error messages for the given value or an empty array if value is a valid value for the custom field

Since:

  • 2.5.0



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'app/models/custom_field.rb', line 266

def validate_custom_value(custom_value)
  value = custom_value.value
  errs = format.validate_custom_value(custom_value)

  unless errs.any?
    if value.is_a?(Array)
      if !multiple?
        errs << ::I18n.t('activerecord.errors.messages.invalid')
      end
      if is_required? && value.detect(&:present?).nil?
        errs << ::I18n.t('activerecord.errors.messages.blank')
      end
    else
      if is_required? && value.blank?
        errs << ::I18n.t('activerecord.errors.messages.blank')
      end
    end
  end

  errs
end

#validate_field_value(value) ⇒ Object

Returns the error messages for the default custom field value

Since:

  • 1.4.0



289
290
291
# File 'app/models/custom_field.rb', line 289

def validate_field_value(value)
  validate_custom_value(CustomFieldValue.new(:custom_field => self, :value => value))
end

#value_classObject

Returns the class that values represent

Since:

  • 2.1.0



246
247
248
# File 'app/models/custom_field.rb', line 246

def value_class
  format.target_class if format.respond_to?(:target_class)
end

#value_from_keyword(keyword, customized) ⇒ Object

Since:

  • 2.1.0



177
178
179
# File 'app/models/custom_field.rb', line 177

def value_from_keyword(keyword, customized)
  format.value_from_keyword(self, keyword, customized)
end

#visibility_by_project_condition(project_key = nil, user = User.current, id_column = nil) ⇒ Object

Since:

  • 2.4.0



213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'app/models/custom_field.rb', line 213

def visibility_by_project_condition(project_key=nil, user=User.current, id_column=nil)
  if visible? || user.admin?
    "1=1"
  elsif user.anonymous?
    "1=0"
  else
    project_key ||= "#{self.class.customized_class.table_name}.project_id"
    id_column ||= id
    "#{project_key} IN (SELECT DISTINCT m.project_id FROM #{Member.table_name} m" +
      " INNER JOIN #{MemberRole.table_name} mr ON mr.member_id = m.id" +
      " INNER JOIN #{table_name_prefix}custom_fields_roles#{table_name_suffix} cfr ON cfr.role_id = mr.role_id" +
      " WHERE m.user_id = #{user.id} AND cfr.custom_field_id = #{id_column})"
  end
end

#visible_by?(project, user = User.current) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 2.4.0



66
67
68
# File 'app/models/custom_field.rb', line 66

def visible_by?(project, user=User.current)
  visible? || user.admin?
end