# frozen_string_literal: true module Decidim module DecidimAwesome # The current awesome config for the organization. class Config def initialize(organization) @organization = organization @vars = AwesomeConfig.for_organization(organization).includes(:constraints) @context = { participatory_space_manifest: nil, participatory_slug: nil, component_id: nil, component_manifest: nil } end attr_reader :context attr_writer :defaults def defaults @defaults || Decidim::DecidimAwesome.config end def context=(context) @config = nil @context = context end # convert context to manifest, slug and id def context_from_request(request) @config = nil @context = Decidim::DecidimAwesome::ContextAnalyzers::RequestAnalyzer.context_for request end # convert component to manifest, slug and id def context_from_component(component) @config = nil @context = Decidim::DecidimAwesome::ContextAnalyzers::ComponentAnalyzer.context_for component end # convert participatory space to manifest, slug and id def context_from_participatory_space(space) @config = nil @context = Decidim::DecidimAwesome::ContextAnalyzers::ParticipatorySpaceAnalyzer.context_for space end # config processed in context def config @config ||= calculate_config end # config processed for the organization config, without context def organization_config @organization_config ||= unfiltered_config.map do |key, value| value = defaults[key] unless enabled_for_organization? key [key, value] end.to_h end # config normalized according default values, without context, without organization config def unfiltered_config valid = @vars.map { |v| [v.var.to_sym, v.value] }.to_h map_defaults do |key| valid[key].presence end end def setting_for(var) @vars.find_or_initialize_by( organization: @organization, var: var ) end # Checks if some config option es enabled in a certain context def enabled_for?(setting) config[setting] end # checks if some constraint blocks the validity fot the current context def valid_in_context?(constraints) # if no constraints defined, applies to everything return true if constraints.blank? # check if current context matches some constraint constraints.detect do |constraint| # if some setting is different, rejects invalid = constraint.settings.detect { |key, val| context[key.to_sym].to_s != val.to_s } invalid.blank? end end private def map_defaults defaults.map do |key, val| value = false unless val == :disabled value = yield(key) || val value = val.merge(value.transform_keys(&:to_sym)) if val.is_a? Hash end [key, value] end.to_h end def calculate_config # filter vars compliant with current context valid = @vars.filter { |item| enabled_for_organization?(item.var) && valid_in_context?(item.constraints) } .map { |v| [v.var.to_sym, v.value] }.to_h map_defaults do |key| valid[key].presence end end # extra checks that may be relevant for the key def enabled_for_organization?(key) case key.to_sym when :allow_images_in_proposals if @organization.respond_to? :rich_text_editor_in_public_views return false if @organization.rich_text_editor_in_public_views end end true end end end end