module Rtml::Controller::State def find_or_build_state headers = request.headers if params[:terminal] && params[:terminal][:itid] itid = params[:terminal][:itid] elsif request.terminal? itid = headers['ITID'] || headers['HTTP_ITID'] || params['itid'] else itid = headers['ITID'] || headers['HTTP_ITID'] || params['itid'] || 'web-browser' end @terminal_state = Rtml::State.find_by_itid(itid) || Rtml::State.new(:itid => itid, :model => params[:model]) set_state_values verify_state unless request.post? || params.key?(:ignore_state) || !request.rtml? end def set_state_values state_variable_mapping.each do |tmlvar, state_attribute| if params[:terminal] && params[:terminal][state_attribute] value = params[:terminal][state_attribute] else code = "params['#{tmlvar.to_s.gsub(/\./, '\'][\'')}']" begin value = eval(code, binding, __FILE__, __LINE__) rescue NoMethodError value = nil end end state[state_attribute] = value if value end end def verify_state if @terminal_state.new_record? Rails.logger.debug "Terminal state for ITID #{@terminal_state[:itid]} needs to be created" render :rtml => 'get_state' elsif @terminal_state.updated_at < 1.day.ago Rails.logger.debug "Terminal state for ITID #{@terminal_state[:itid]} needs to be updated" render :rtml => 'get_state' end end def state @terminal_state end def save_state if @terminal_state.changed? @terminal_state.save # can fail silently end true end def state_variable_mapping self.class.state_variable_mapping end class << self def included(base) base.instance_eval do hide_action :find_or_build_state, :set_state_values, :verify_state, :save_state, :state, :state_variable_mapping before_filter :find_or_build_state after_filter :save_state helper_method :state def state_variable_mapping @state_variable_mapping ||= Rtml::State::VariableMapping.new end end end end end