Class: Redmine::FieldFormat::Base

Inherits:
Object
  • Object
show all
Includes:
ERB::Util, Helpers::URL, I18n, Singleton
Defined in:
lib/redmine/field_format.rb

Direct Known Subclasses

AttachmentFormat, List, Unbounded

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers::URL

#uri_with_link_safe_scheme?, #uri_with_safe_scheme?

Methods included from I18n

#abbr_day_name, #current_language, #day_letter, #day_name, #find_language, #format_date, #format_hours, #format_time, included, #l, #l_hours, #l_hours_short, #l_or_humanize, #languages_options, #ll, #lu, #month_name, #normalize_float, #set_language_if_valid, #valid_languages

Class Method Details

.field_attributesObject



113
114
115
# File 'lib/redmine/field_format.rb', line 113

def self.field_attributes(*)
  CustomField.store_accessor(:format_store, *)
end

Instance Method Details

#after_save_custom_value(custom_field, custom_value) ⇒ Object

CustomValue after_save callback



244
245
# File 'lib/redmine/field_format.rb', line 244

def after_save_custom_value(custom_field, custom_value)
end

#before_custom_field_save(custom_field) ⇒ Object



341
342
# File 'lib/redmine/field_format.rb', line 341

def before_custom_field_save(custom_field)
end

#bulk_edit_tag(view, tag_id, tag_name, custom_field, objects, value, options = {}) ⇒ Object



316
317
318
319
# File 'lib/redmine/field_format.rb', line 316

def bulk_edit_tag(view, tag_id, tag_name, custom_field, objects, value, options={})
  view.text_field_tag(tag_name, value, options.merge(:id => tag_id)) +
    bulk_clear_tag(view, tag_id, tag_name, custom_field, value)
end

#cast_custom_value(custom_value) ⇒ Object



142
143
144
# File 'lib/redmine/field_format.rb', line 142

def cast_custom_value(custom_value)
  cast_value(custom_value.custom_field, custom_value.value, custom_value.customized)
end

#cast_single_value(custom_field, value, customized = nil) ⇒ Object



159
160
161
# File 'lib/redmine/field_format.rb', line 159

def cast_single_value(custom_field, value, customized=nil)
  value.to_s
end

#cast_value(custom_field, value, customized = nil) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/redmine/field_format.rb', line 146

def cast_value(custom_field, value, customized=nil)
  if value.blank?
    nil
  elsif value.is_a?(Array)
    casted = value.map do |v|
      cast_single_value(custom_field, v, customized)
    end
    casted.compact.sort
  else
    cast_single_value(custom_field, value, customized)
  end
end

#edit_tag(view, tag_id, tag_name, custom_value, options = {}) ⇒ Object



312
313
314
# File 'lib/redmine/field_format.rb', line 312

def edit_tag(view, tag_id, tag_name, custom_value, options={})
  view.text_field_tag(tag_name, custom_value.value, options.merge(:id => tag_id))
end

#formatted_custom_value(view, custom_value, html = false) ⇒ Object



247
248
249
# File 'lib/redmine/field_format.rb', line 247

def formatted_custom_value(view, custom_value, html=false)
  formatted_value(view, custom_value.custom_field, custom_value.value, custom_value.customized, html)
end

#formatted_value(view, custom_field, value, customized = nil, html = false) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/redmine/field_format.rb', line 251

def formatted_value(view, custom_field, value, customized=nil, html=false)
  casted = cast_value(custom_field, value, customized)
  if html && custom_field.url_pattern.present?
    texts_and_urls = Array.wrap(casted).map do |single_value|
      text = view.format_object(single_value, html: false).to_s
      url = url_from_pattern(custom_field, single_value, customized)
      [text, url]
    end
    links = texts_and_urls.sort_by(&:first).map do |text, url|
      view.link_to text, url
    end
    sanitize_html links.join(', ')
  else
    casted
  end
end

#group_statement(custom_field) ⇒ Object

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.



354
355
356
# File 'lib/redmine/field_format.rb', line 354

def group_statement(custom_field)
  nil
end

#join_for_order_statement(custom_field) ⇒ Object

Returns a JOIN clause that is added to the query when sorting by custom values



359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/redmine/field_format.rb', line 359

def join_for_order_statement(custom_field)
  alias_name = join_alias(custom_field)

  "LEFT OUTER JOIN #{CustomValue.table_name} #{alias_name}" +
    " ON #{alias_name}.customized_type = '#{custom_field.class.customized_class.base_class.name}'" +
    " AND #{alias_name}.customized_id = #{custom_field.class.customized_class.table_name}.id" +
    " AND #{alias_name}.custom_field_id = #{custom_field.id}" +
    " AND (#{custom_field.visibility_by_project_condition})" +
    " AND #{alias_name}.value <> ''" +
    " AND #{alias_name}.id = (SELECT max(#{alias_name}_2.id) FROM #{CustomValue.table_name} #{alias_name}_2" +
      " WHERE #{alias_name}_2.customized_type = #{alias_name}.customized_type" +
      " AND #{alias_name}_2.customized_id = #{alias_name}.customized_id" +
      " AND #{alias_name}_2.custom_field_id = #{alias_name}.custom_field_id)"
end

#labelObject



123
124
125
# File 'lib/redmine/field_format.rb', line 123

def label
  "label_#{name}"
end

#nameObject



119
120
121
# File 'lib/redmine/field_format.rb', line 119

def name
  self.class.format_name
end

#order_statement(custom_field) ⇒ Object

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.



347
348
349
350
# File 'lib/redmine/field_format.rb', line 347

def order_statement(custom_field)
  # COALESCE is here to make sure that blank and NULL values are sorted equally
  Arel.sql "COALESCE(#{join_alias custom_field}.value, '')"
end

#possible_custom_value_options(custom_value) ⇒ Object



167
168
169
# File 'lib/redmine/field_format.rb', line 167

def possible_custom_value_options(custom_value)
  possible_values_options(custom_value.custom_field, custom_value.customized)
end

#possible_values_options(custom_field, object = nil) ⇒ Object



171
172
173
# File 'lib/redmine/field_format.rb', line 171

def possible_values_options(custom_field, object=nil)
  []
end

#query_filter_options(custom_field, query) ⇒ Object



337
338
339
# File 'lib/redmine/field_format.rb', line 337

def query_filter_options(custom_field, query)
  {:type => :string}
end

#sanitize_html(html) ⇒ Object



268
269
270
# File 'lib/redmine/field_format.rb', line 268

def sanitize_html(html)
  Redmine::WikiFormatting::HtmlSanitizer.call(html).html_safe
end

#set_custom_field_value(custom_field, custom_field_value, value) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/redmine/field_format.rb', line 127

def set_custom_field_value(custom_field, custom_field_value, value)
  if value.is_a?(Array)
    value = value.map(&:to_s).reject{|v| v==''}.uniq
    if value.empty?
      value << ''
    end
  elsif custom_field.field_format == 'float'
    value = normalize_float(value)
  else
    value = value.to_s
  end

  value
end

#target_classObject



163
164
165
# File 'lib/redmine/field_format.rb', line 163

def target_class
  nil
end

#validate_custom_field(custom_field) ⇒ Object

Returns the validation errors for custom_field Should return an empty array if custom_field is valid



219
220
221
222
223
224
225
226
# File 'lib/redmine/field_format.rb', line 219

def validate_custom_field(custom_field)
  errors = []
  pattern = custom_field.url_pattern
  if pattern.present? && !uri_with_safe_scheme?(url_pattern_without_tokens(pattern))
    errors << [:url_pattern, :invalid]
  end
  errors
end

#validate_custom_value(custom_value) ⇒ Object

Returns the validation error messages for custom_value Should return an empty array if custom_value is valid custom_value is a CustomFieldValue.



231
232
233
234
235
236
237
# File 'lib/redmine/field_format.rb', line 231

def validate_custom_value(custom_value)
  values = Array.wrap(custom_value.value).reject {|value| value.to_s == ''}
  errors = values.map do |value|
    validate_single_value(custom_value.custom_field, value, custom_value.customized)
  end
  errors.flatten.uniq
end

#validate_single_value(custom_field, value, customized = nil) ⇒ Object



239
240
241
# File 'lib/redmine/field_format.rb', line 239

def validate_single_value(custom_field, value, customized=nil)
  []
end

#value_from_keyword(custom_field, keyword, object) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/redmine/field_format.rb', line 175

def value_from_keyword(custom_field, keyword, object)
  possible_values_options = possible_values_options(custom_field, object)
  if possible_values_options.present?
    parse_keyword(custom_field, keyword) do |k|
      if v = possible_values_options.detect {|text, id| k.casecmp(text) == 0}
        if v.is_a?(Array)
          v.last
        else
          v
        end
      end
    end
  else
    keyword
  end
end