Module: SimpleWorkflow::Controller

Included in:
ActionController::Base
Defined in:
lib/simple_workflow/controller.rb

Instance Method Summary collapse

Instance Method Details

#back(response_status_and_flash) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/simple_workflow/controller.rb', line 58

def back(response_status_and_flash)
  return false if session[:detours].nil?
  detour = pop_detour
  post = detour.delete(:request_method) == :post
  if post
    set_flash(response_status_and_flash)
    redirect_to_post(detour)
  else
    redirect_to detour, response_status_and_flash
  end
  true
end

#back_or_redirect_to(options = {}, response_status_and_flash = {}) ⇒ Object



71
72
73
# File 'lib/simple_workflow/controller.rb', line 71

def back_or_redirect_to(options = {}, response_status_and_flash = {})
  back(response_status_and_flash) or redirect_to(options, response_status_and_flash)
end

#detour_to(options) ⇒ Object

Like ActionController::Base#redirect_to, but stores the location we come from, enabling returning here later.



3
4
5
6
# File 'lib/simple_workflow/controller.rb', line 3

def detour_to(options)
  store_detour(params)
  redirect_to(options)
end

#pop_detourObject



90
91
92
93
94
95
96
97
# File 'lib/simple_workflow/controller.rb', line 90

def pop_detour
  detours = session[:detours]
  return nil unless detours
  detour = detours.pop
  logger.debug "popped detour: #{detour.inspect} #{session[:detours].size} more"
  reset_workflow if detours.empty?
  detour
end

#redirect_to_post(options) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/simple_workflow/controller.rb', line 103

def redirect_to_post(options)
  url = url_for options
  render :text => <<EOF, :layout => false
<html>
<body onload="document.getElementById('form').submit()">
  <form id="form" action="#{url}" method="POST">
  </form>
</body>
</html>
EOF
end

#reset_workflowObject



99
100
101
# File 'lib/simple_workflow/controller.rb', line 99

def reset_workflow
  session.delete(:detours)
end

#rjs_detour_to(options) ⇒ Object



8
9
10
11
# File 'lib/simple_workflow/controller.rb', line 8

def rjs_detour_to(options)
  store_detour(params, request.post?)
  rjs_redirect_to(options)
end

#rjs_redirect_to(options) ⇒ Object



13
14
15
16
# File 'lib/simple_workflow/controller.rb', line 13

def rjs_redirect_to(options)
  @options = options
  render :template => 'redirect', :layout => false, :formats => :js
end

#store_detour(options, post = false) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/simple_workflow/controller.rb', line 18

def store_detour(options, post = false)
  options = options.dup.permit!.to_h if options.is_a?(ActionController::Parameters)
  options[:request_method] = :post if post
  if session[:detours] && session[:detours].last == options
    logger.debug "Ignored duplicate detour: #{options.inspect}"
    return
  end
  session[:detours] ||= []
  session[:detours] << options

  if Rails.application.config.session_store == ActionDispatch::Session::CookieStore
    encryptor = cookies.signed_or_encrypted.instance_variable_get(:@encryptor)
    ss = ws = nil
    loop do
      ser_val = cookies.signed_or_encrypted.send(:serialize, nil, session.to_hash)
      new_value = encryptor.encrypt_and_sign(ser_val)
      ss = new_value.size
      wf_ser_val = cookies.signed_or_encrypted.send(:serialize, nil, session[:detours])
      wf_crypt_val = encryptor.encrypt_and_sign(wf_ser_val)
      ws = wf_crypt_val.size
      break unless ws >= 2048 || (ss >= 3072 && session[:detours] && session[:detours].size > 0)
      logger.warn "Workflow too large (#{ws}).  Dropping oldest detour."
      session[:detours].shift
      reset_workflow if session[:detours].empty?
    end
    logger.debug "session: #{ss} bytes, workflow(#{session[:detours].try(:size) || 0}): #{ws} bytes"
  end

  logger.debug "Added detour (#{session[:detours].try(:size) || 0}): #{options.inspect}"
end

#store_detour_from_paramsObject



49
50
51
52
53
54
55
56
# File 'lib/simple_workflow/controller.rb', line 49

def store_detour_from_params
  if params[:detour]
    store_detour(params[:detour])
  end
  if params[:return_from_detour] && session[:detours]
    pop_detour
  end
end