# frozen_string_literal: true class Wizard attr_reader :steps, :user attr_accessor :max_topics_to_require_completion @@excluded_steps = [] def initialize(user) @steps = [] @user = user @first_step = nil @max_topics_to_require_completion = 15 end def create_step(step_name) Step.new(step_name) end def append_step(step, after: nil) return if @@excluded_steps.include?(step) step = create_step(step) if step.is_a?(String) yield step if block_given? if after before_step = @steps.detect { |s| s.id == after } if before_step step.previous = before_step step.index = before_step.index + 1 if before_step.next step.next = before_step.next before_step.next.previous = step end before_step.next = step @steps.insert(before_step.index + 1, step) step.index += 1 while (step = step.next) return end end last_step = @steps.last @steps << step # If it's the first step if @steps.size == 1 @first_step = step step.index = 0 elsif last_step.present? last_step.next = step step.previous = last_step step.index = last_step.index + 1 end end def remove_step(step_id) i = @steps.index { |step| step.id == step_id } return if i.nil? step = @steps.delete_at(i) step.previous.next = step.next if step.previous while step = step.next step.index -= 1 if step.index == 0 step.previous = nil @first_step = step else step.previous = @steps[step.index - 1] end end end def self.exclude_step(step) @@excluded_steps << step end def steps_with_fields @steps_with_fields ||= @steps.select(&:has_fields?) end def start completed = UserHistory .where(action: UserHistory.actions[:wizard_step], context: steps_with_fields.map(&:id)) .uniq .pluck(:context) # First uncompleted step steps_with_fields.each { |s| return s if completed.exclude?(s.id) } @first_step end def create_updater(step_id, fields) step = @steps.find { |s| s.id == step_id.dasherize } Wizard::StepUpdater.new(@user, step, fields) end def completed? completed_steps?(steps_with_fields.map(&:id)) end def completed_steps?(steps) steps = [steps].flatten.uniq completed = UserHistory .where(action: UserHistory.actions[:wizard_step], context: steps) .distinct .order(:context) .pluck(:context) steps.sort == completed end def requires_completion? return false unless SiteSetting.wizard_enabled? return false if SiteSetting.bypass_wizard_check? if Topic.limit(@max_topics_to_require_completion + 1).count > @max_topics_to_require_completion SiteSetting.bypass_wizard_check = true return false end if @user&.id && User.first_login_admin_id == @user.id !Wizard::Builder.new(@user).build.completed? else false end end def self.user_requires_completion?(user) self.new(user).requires_completion? end end