module Formidable

Constants

CONFIG_PATH
HOST
VERSION

Public Class Methods

clear_filtered_parameters() click to toggle source
# File lib/formidable.rb, line 139
def clear_filtered_parameters
  @@filtered_params = []
end
configure(args) click to toggle source
# File lib/formidable.rb, line 131
def configure(args)
  Config.load(args)
end
filter_parameters(*params) click to toggle source
# File lib/formidable.rb, line 135
def filter_parameters(*params)
  @@filtered_params = @@filtered_params | params.flatten
end
track(args) click to toggle source
# File lib/formidable.rb, line 38
def track(args)
  return if Config.api_key.empty?

  raise "Must define a form." unless args[:form]

  errors = args[:errors] || {}
  errors = {:base => errors} if errors.any? and errors.kind_of?(Array)

  # values will be nil if errors and no args[:values]
  # we want this for later
  values =
  if Config.track_values and errors.any?
    args[:values]
  else
    {}
  end

  times = args[:times]
  total_time = args[:total_time]
  attempt = args[:attempt]

  if args[:timing_data]
    tt, t = Timer.parse(args[:timing_data])
    total_time ||= tt
    times ||= t
  end

  # get as much data as we can from the request object
  # don't override anything that was set
  request = Thread.current[:formidable_request]
  if request
    # Rails 3
    if request.env["action_dispatch.parameter_filter"]
      filter_parameters(request.env["action_dispatch.parameter_filter"])
    end

    # if values aren't set, get them from request and delete
    values ||= request.params.reject{|k, v| [:utf8, :action, :controller, :authenticity_token, :commit, :formidable].include?(k.to_sym) }

    if timing_data = request.params[:formidable]
      tt, t = Timer.parse(request.params[:formidable])
      total_time ||= tt
      times ||= t
    end
  end

  times ||= {}
  values ||= {}

  cookies = Thread.current[:formidable_cookies]
  if cookies
    attempt ||= Attempt.parse(cookies, args[:form], errors.empty?)
  end

  # filter values
  values.delete_if{|k,v| filter?(k)}

  # flatten everything
  flatten(errors, true)
  flatten(values)
  flatten(times)

  # delete values if no errors for field
  values.delete_if{|k,v| !errors[k] or errors[k].empty?}

  # time to strip the prefix
  prefix = args[:prefix]
  if prefix
    regex = Regexp.new('\A' + prefix.to_s + '\[([^\]]+)\]')
    remove_prefix(errors, regex)
    remove_prefix(values, regex)
    remove_prefix(times, regex)
  end

  data = {
    :form => args[:form],
    :errors => errors,
    :values => values,
    :times => times,
    :total_time => total_time,
    :attempt => attempt
  }

  if Config.thread
    Thread.new do
      Remote.send(data)
    end
    true
  else
    Remote.send(data)
  end
end

Private Class Methods

filter?(k) click to toggle source
# File lib/formidable.rb, line 154
def filter?(k)
  @@filtered_params.each do |param|
    if Regexp.new(param.to_s).match(k)
      return true
    end
  end
  false
end
flatten(ret, arr=false, name=nil, values=nil) click to toggle source
# File lib/formidable.rb, line 163
def flatten(ret, arr=false, name=nil, values=nil)
  values = ret.dup unless values
  values.each do |k, v|
    k = "#{name}[#{k}]" if name
    unless v.kind_of?(Hash)
      if !arr or v.kind_of?(Array)
        ret[k] = v
      else
        ret[k] = [] unless v.kind_of?(Array)
        ret[k] << v
      end
    else
      flatten(ret, arr, k, v)
      ret.delete(k) unless name
    end
  end
  ret
end
remove_prefix(data, regex) click to toggle source
# File lib/formidable.rb, line 145
def remove_prefix(data, regex)
  return unless data
  data.dup.each do |k, v|
    key = k.to_s.gsub(regex, '\1')
    data[key] = v
    data.delete(k)
  end
end