Class: Decidim::FileValidatorHumanizer

Inherits:
Object
  • Object
show all
Defined in:
decidim-core/lib/decidim/file_validator_humanizer.rb

Overview

This class fetches the file validation conditions from the active record model objects which have specific validators and uploaders attached to them. This class is used to convert these validation conditions to a human readable format in the front-end and to simplify the code where these are needed from.

This considers if the validation conditions and the uploader have been set directly to the record being validated or if they should be read from another object in case the PassthruValidator is in charge of the validations.

Instance Method Summary collapse

Constructor Details

#initialize(record, attribute) ⇒ FileValidatorHumanizer

record - Form object (e.g. Decidim::AccountForm) attribute - Form field (e.g. :avatar)


17
18
19
20
21
22
23
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 17

def initialize(record, attribute)
  @record = record
  @attribute = attribute
  @passthru_validator ||= record.singleton_class.validators_on(
    attribute
  ).find { |validator| validator.is_a?(PassthruValidator) }
end

Instance Method Details

#extension_allowlistObject


92
93
94
95
96
97
98
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 92

def extension_allowlist
  return unless uploader.respond_to?(:extension_allowlist, true)

  # It may be a private method in some uploaders which is why we need to use
  # `#send`.
  uploader.send(:extension_allowlist)
end

#max_file_dimensionsObject

rubocop: enable Metrics/CyclomaticComplexity


86
87
88
89
90
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 86

def max_file_dimensions
  return unless uploader.respond_to?(:max_image_height_or_width)

  "#{uploader.max_image_height_or_width}x#{uploader.max_image_height_or_width}"
end

#max_file_sizeObject

rubocop: disable Metrics/CyclomaticComplexity


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 61

def max_file_size
  # First try if the record itself has a file size validator defined.
  validator = record.singleton_class.validators_on(attribute).find do |v|
    v.is_a?(::ActiveModel::Validations::FileSizeValidator)
  end
  if validator
    lte = validator.options[:less_than_or_equal_to]
    return lte if lte.is_a?(Numeric)
    return lte.call(record) if lte.respond_to?(:call)
  end
  return unless passthru_validator

  # If not, check for the same validator from the pass through record.
  validator = passthru_validator.target_validators(attribute).find do |v|
    v.is_a?(::ActiveModel::Validations::FileSizeValidator)
  end
  return unless validator

  lte = validator.options[:less_than_or_equal_to]
  return lte if lte.is_a?(Numeric)

  lte.call(passthru_record) if lte.respond_to?(:call)
end

#messagesObject


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 29

def messages
  messages = []

  if (file_size = max_file_size)
    file_size_mb = (((file_size / 1024 / 1024) * 100) / 100).round
    messages << I18n.t(
      "max_file_size",
      megabytes: file_size_mb,
      scope: "decidim.forms.file_validation"
    )
  end

  if (file_dimensions = max_file_dimensions)
    messages << I18n.t(
      "max_file_dimension",
      resolution: file_dimensions,
      scope: "decidim.forms.file_validation"
    )
  end

  if (extensions = extension_allowlist)
    messages << I18n.t(
      "allowed_file_extensions",
      extensions: extensions.join(" "),
      scope: "decidim.forms.file_validation"
    )
  end

  messages
end

#uploaderObject


25
26
27
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 25

def uploader
  @uploader ||= fetch_uploader
end