Initial commit of foodsoft 2
This commit is contained in:
commit
5b9a7e05df
657 changed files with 70444 additions and 0 deletions
497
vendor/plugins/acts_as_configurable/lib/acts_as_configurable.rb
vendored
Normal file
497
vendor/plugins/acts_as_configurable/lib/acts_as_configurable.rb
vendored
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
|
||||
module Nkryptic # :nodoc:
|
||||
module ActsAsConfigurable #:nodoc:
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
# These methods will be available to any ActiveRecord::Base descended model.
|
||||
module ClassMethods
|
||||
|
||||
# == Acts As Configurable
|
||||
# requirements::
|
||||
# model descended from ActiveRecord::Base
|
||||
# configurable_settings table has been created
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# acts_as_configurable
|
||||
# end
|
||||
#
|
||||
# This mixin will provide your model with a large variety of configuration options.
|
||||
#
|
||||
# see:: settings and settins_for
|
||||
#
|
||||
def acts_as_configurable(options = {})
|
||||
|
||||
# don't allow multiple calls
|
||||
return if self.included_modules.include?(Nkryptic::ActsAsConfigurable::InstanceMethods)
|
||||
send :include, Nkryptic::ActsAsConfigurable::InstanceMethods
|
||||
|
||||
cattr_accessor :defaults
|
||||
self.defaults = (options.class == Hash ? options : {}).with_indifferent_access
|
||||
|
||||
has_many :_configurable_settings,
|
||||
:as => :configurable,
|
||||
:class_name => 'ConfigurableSetting',
|
||||
:dependent => :destroy
|
||||
|
||||
end
|
||||
|
||||
# == Acts As Configurable Target
|
||||
# requirements::
|
||||
# model descended from ActiveRecord::Base
|
||||
# configurable_settings table has been created
|
||||
#
|
||||
# class User < ActiveRecord::Base
|
||||
# acts_as_configurable_target
|
||||
# end
|
||||
#
|
||||
# This mixin will provide your model with the ability to see where it is used as a target of acts_as_configurable
|
||||
#
|
||||
# see:: targetable_settings and targetable_settings_for
|
||||
#
|
||||
def acts_as_configurable_target(options = {})
|
||||
return if self.included_modules.include?(Nkryptic::ActsAsConfigurable::TargetInstanceMethods)
|
||||
send :include, Nkryptic::ActsAsConfigurable::TargetInstanceMethods
|
||||
|
||||
has_many :_targetable_settings,
|
||||
:as => :targetable,
|
||||
:class_name => 'ConfigurableSetting',
|
||||
:dependent => :destroy
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend Nkryptic::ActsAsConfigurable::InstanceMethods::ClassMethods
|
||||
end
|
||||
|
||||
# * specify any setting you want for an instance of a model
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# user = User.create(:name => 'joe')
|
||||
# user.settings # => []
|
||||
#
|
||||
# user.settings[:friends] = ['jane','sam','karl']
|
||||
# user.settings[:friends] # => ['jane','sam','karl']
|
||||
# user.settings[:age] = 25
|
||||
# user.settings[:age] # => 25
|
||||
#
|
||||
def settings
|
||||
@general_settings ||= ConfigurableSettings.new(self)
|
||||
end
|
||||
|
||||
# * specify any setting you want for an instance of a model targeting another object
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# user = User.create(:name => 'joe')
|
||||
# post = Post.find(:first)
|
||||
#
|
||||
# user.settings_for(post) # => []
|
||||
# user.settings_for(post)[:show_headlines] = true
|
||||
#
|
||||
# user.settings_for(post)[:show_headlines] # => true
|
||||
# user.settings_for(post).size # => 1
|
||||
#
|
||||
# # but the user's untargeted settings are still empty
|
||||
# user.settings # => []
|
||||
#
|
||||
def settings_for(obj)
|
||||
if obj.is_a? Class
|
||||
# wire the settings object to only deal with settings targeting this class obj
|
||||
variable_name = "settings_for_class_#{obj.name}"
|
||||
else
|
||||
# wire the settings object to only deal with settings targeting this instance obj
|
||||
variable_name = "settings_for_#{obj.class}_#{obj.id}"
|
||||
end
|
||||
settings_obj = instance_variable_get("@#{variable_name}")
|
||||
settings_obj = instance_variable_set("@#{variable_name}",ConfigurableSettings.new(self, obj)) if settings_obj.nil?
|
||||
settings_obj
|
||||
end
|
||||
|
||||
# These are class methods that are mixed in with the model class.
|
||||
module ClassMethods # :nodoc:
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
module TargetInstanceMethods
|
||||
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend Nkryptic::ActsAsConfigurable::TargetInstanceMethods::ClassMethods
|
||||
end
|
||||
|
||||
# * specify any setting you want for an instance of a model targeting another object
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# user = User.create(:name => 'joe')
|
||||
# post = Post.find(:first)
|
||||
#
|
||||
# user.settings_for(post) # => []
|
||||
# user.settings_for(post)[:num_lines] = 15
|
||||
#
|
||||
# user.settings_for(post)[:num_lines] # => 15
|
||||
# post.targeted_settings[:num_lines].size # => 1
|
||||
# post.targeted_settings[:num_lines].first # => 15
|
||||
# post.targeted_settings[:num_lines].first.owner # => user
|
||||
#
|
||||
def targeted_settings
|
||||
@targeted_settings ||= TargetedSettings.new(self)
|
||||
end
|
||||
|
||||
# * specify any setting you want for an instance of a model targeting another object
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# user = User.create(:name => 'joe')
|
||||
# post = Post.find(:first)
|
||||
#
|
||||
# user.settings_for(post) # => []
|
||||
# user.settings_for(post)[:num_lines] = 15
|
||||
#
|
||||
# user.settings_for(post)[:num_lines] # => 15
|
||||
# user.settings_for(post)[:hide_comments] # => true
|
||||
# post.targeted_settings_for(user)[:num_lines] # => 15
|
||||
# post.targeted_settings_for(user) # => [15,true]
|
||||
# post.targeted_settings_for(user).collect {|x| x.name} # => ['num_lines','hide_comments']
|
||||
#
|
||||
def targeted_settings_for(obj)
|
||||
if obj.is_a? Class
|
||||
# wire the targeted_settings object to only deal with settings targeting this class obj
|
||||
variable_name = "targeted_settings_for_class_#{obj.name}"
|
||||
else
|
||||
# wire the targeted_settings object to only deal with settings targeting this instance obj
|
||||
variable_name = "targeted_settings_for_#{obj.class}_#{obj.id}"
|
||||
end
|
||||
settings_obj = instance_variable_get("@#{variable_name}")
|
||||
settings_obj = instance_variable_set("@#{variable_name}",TargetedSettings.new(self, obj)) if settings_obj.nil?
|
||||
settings_obj
|
||||
end
|
||||
|
||||
# These are class methods that are mixed in with the model class.
|
||||
module ClassMethods # :nodoc:
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class ProxySettings # :nodoc:
|
||||
alias_method '__class', 'class'
|
||||
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$)/ }
|
||||
|
||||
#class_inheritable_accessor(:sql_word)
|
||||
|
||||
def initialize(source, reference=nil)
|
||||
@source = source
|
||||
@reference = reference
|
||||
true
|
||||
end
|
||||
|
||||
def real_class
|
||||
__class
|
||||
end
|
||||
|
||||
def settings
|
||||
@source.send(@settings)
|
||||
end
|
||||
|
||||
def to_ary
|
||||
find_settings.collect do |x|
|
||||
ProxySetting.new(x)
|
||||
end
|
||||
end
|
||||
|
||||
def responds_to?(what)
|
||||
settings.responds_to?(what)
|
||||
end
|
||||
|
||||
def ==(what)
|
||||
find_settings == what
|
||||
end
|
||||
|
||||
def size
|
||||
find_settings.size
|
||||
end
|
||||
|
||||
def inspect
|
||||
find_settings.inspect
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
find_settings.each do |x|
|
||||
yield ProxySetting.new(x)
|
||||
end
|
||||
end
|
||||
|
||||
def each_with_key(&block)
|
||||
find_settings.each do |x|
|
||||
yield(x.name, ProxySetting.new(x))
|
||||
end
|
||||
end
|
||||
|
||||
def select(&block)
|
||||
find_settings.select do |x|
|
||||
yield ProxySetting.new(x)
|
||||
end
|
||||
end
|
||||
|
||||
def reject(&block)
|
||||
find_settings.reject do |x|
|
||||
yield ProxySetting.new(x)
|
||||
end
|
||||
end
|
||||
|
||||
def collect(&block)
|
||||
find_settings.collect do |x|
|
||||
yield ProxySetting.new(x)
|
||||
end
|
||||
end
|
||||
|
||||
def has_key?(name)
|
||||
name = name.to_s
|
||||
setting = find_setting(name)
|
||||
if setting.nil?
|
||||
false
|
||||
else
|
||||
if setting.is_a? Array
|
||||
setting.size == 0 ? false : true
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def [](name)
|
||||
name = name.to_s
|
||||
setting = find_setting(name)
|
||||
return nil if setting.nil?
|
||||
if setting.is_a? Array
|
||||
setting.collect {|x| ProxySetting.new(x)}
|
||||
else
|
||||
ProxySetting.new(setting)
|
||||
end
|
||||
end
|
||||
|
||||
def []=(name, value)
|
||||
name = name.to_s
|
||||
setting = find_setting(name)
|
||||
if setting.is_a? Array
|
||||
setting.collect do |x|
|
||||
x.value_type = value.class.to_s
|
||||
x.value = value.to_yaml
|
||||
x.save
|
||||
ProxySetting.new(x)
|
||||
end
|
||||
else
|
||||
if setting.nil?
|
||||
setting = create_setting(name)
|
||||
end
|
||||
setting.value_type = value.class.to_s
|
||||
setting.value = value.to_yaml
|
||||
setting.save
|
||||
ProxySetting.new(setting)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_settings; nil end
|
||||
|
||||
def find_setting(name); nil end
|
||||
|
||||
def create_setting(name); nil end
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
settings.send(method, *args, &block)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ConfigurableSettings < ProxySettings # :nodoc:
|
||||
|
||||
def initialize(source, reference=nil)
|
||||
super
|
||||
@settings = '_configurable_settings'
|
||||
@@sql_word = "targetable"
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_settings
|
||||
if @reference.is_a? Class
|
||||
settings.find( :all,
|
||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", @reference.to_s ] )
|
||||
elsif @reference
|
||||
settings.find( :all,
|
||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id = ?", @reference.class.to_s, @reference.id ] )
|
||||
else
|
||||
settings.find( :all,
|
||||
:conditions => [ "#{@@sql_word}_type is null and #{@@sql_word}_id is null" ] )
|
||||
end
|
||||
end
|
||||
|
||||
def find_setting(name)
|
||||
if @reference.is_a? Class
|
||||
settings.find( :first,
|
||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", name, @reference.to_s ] )
|
||||
elsif @reference
|
||||
settings.find( :first,
|
||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id = ?", name, @reference.class.to_s, @reference.id ] )
|
||||
else
|
||||
settings.find( :first,
|
||||
:conditions => [ "name = ? and #{@@sql_word}_type is null and #{@@sql_word}_id is null", name ] )
|
||||
end
|
||||
end
|
||||
|
||||
def create_setting(name)
|
||||
if @reference.is_a? Class
|
||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.to_s )
|
||||
elsif @reference
|
||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.class.to_s, "#{@@sql_word}_id" => @reference.id )
|
||||
else
|
||||
settings.create( :name => name )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class TargetedSettings < ProxySettings # :nodoc:
|
||||
|
||||
def initialize(target, owner=nil)
|
||||
super
|
||||
@settings = '_targetable_settings'
|
||||
@@sql_word = "configurable"
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_settings
|
||||
if @reference.is_a? Class
|
||||
settings.find( :all,
|
||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", @reference.to_s ] )
|
||||
elsif @reference
|
||||
settings.find( :all,
|
||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id = ?", @reference.class.to_s, @reference.id ] )
|
||||
else
|
||||
settings.find( :all )
|
||||
end
|
||||
end
|
||||
|
||||
def find_setting(name)
|
||||
if @reference.is_a? Class
|
||||
settings.find( :first,
|
||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", name, @reference.to_s ] )
|
||||
elsif @reference
|
||||
settings.find( :first,
|
||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id = ?", name, @reference.class.to_s, @reference.id ] )
|
||||
else
|
||||
settings.find( :all,
|
||||
:conditions => [ "name = ?", name ] )
|
||||
end
|
||||
end
|
||||
|
||||
def create_setting(name)
|
||||
if @reference.is_a? Class
|
||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.to_s )
|
||||
elsif @reference
|
||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.class.to_s, "#{@@sql_word}_id" => @reference.id )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ProxySetting # :nodoc:
|
||||
|
||||
alias_method '__class', 'class'
|
||||
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$)/ }
|
||||
|
||||
def initialize(setting)
|
||||
@_setting = setting
|
||||
true
|
||||
end
|
||||
|
||||
def real_class
|
||||
ProxySetting
|
||||
end
|
||||
|
||||
def target
|
||||
unless @_setting.targetable_type.blank? or @_setting.targetable_id.blank?
|
||||
ConfigurableSetting.find_targetable(@_setting.targetable_type, @_setting.targetable_id)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def owner
|
||||
unless @_setting.configurable_type.blank? or @_setting.configurable_id.blank?
|
||||
ConfigurableSetting.find_configurable(@_setting.configurable_type, @_setting.configurable_id)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def []=(name, val)
|
||||
obj = self.value
|
||||
if obj.responds_to? '[]='
|
||||
obj[name] = val
|
||||
self.value = obj
|
||||
self.save
|
||||
else
|
||||
method_missing('[]=', [name,val])
|
||||
end
|
||||
end
|
||||
|
||||
def delete(name)
|
||||
obj = self.value
|
||||
if obj.responds_to? 'delete'
|
||||
obj.delete(name)
|
||||
self.value = obj
|
||||
self.save
|
||||
else
|
||||
method_missing('delete', [name,val])
|
||||
end
|
||||
end
|
||||
|
||||
def save
|
||||
@_setting.save
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def value
|
||||
@value ||= YAML.load(@_setting.value)
|
||||
end
|
||||
|
||||
def value=(val)
|
||||
@value = val
|
||||
self.set_value
|
||||
end
|
||||
|
||||
def set_value
|
||||
@_setting.value_type = @value.class.to_s
|
||||
@_setting.value = @value.to_yaml
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
return_value = self.value.send(method, *args, &block)
|
||||
if @value != YAML.load(@_setting.value)
|
||||
STDERR.puts "#{method} called with args #{args} for ProxySetting"
|
||||
self.set_value
|
||||
end
|
||||
return_value
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
50
vendor/plugins/acts_as_configurable/lib/configurable_setting.rb
vendored
Normal file
50
vendor/plugins/acts_as_configurable/lib/configurable_setting.rb
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# this is the base class of all configurable settings
|
||||
class ConfigurableSetting < ActiveRecord::Base
|
||||
belongs_to :configurable, :polymorphic => true
|
||||
belongs_to :targetable, :polymorphic => true
|
||||
|
||||
# ==For migration up
|
||||
# in your migration self.up method:
|
||||
# <tt>ConfigurableSetting.create_table</tt>
|
||||
def self.create_table
|
||||
self.connection.create_table :configurable_settings, :options => 'ENGINE=InnoDB' do |t|
|
||||
t.column :configurable_id, :integer
|
||||
t.column :configurable_type, :string
|
||||
t.column :targetable_id, :integer
|
||||
t.column :targetable_type, :string
|
||||
t.column :name, :string, :null => false
|
||||
t.column :value_type, :string
|
||||
t.column :value, :text, :null => true
|
||||
end
|
||||
self.connection.add_index :configurable_settings, :name
|
||||
end
|
||||
|
||||
# ==For migration down
|
||||
# in your migration self.down method:
|
||||
# <tt>ConfigurableSetting.drop_table</tt>
|
||||
def self.drop_table
|
||||
self.connection.remove_index :configurable_settings, :name
|
||||
self.connection.drop_table :configurable_settings
|
||||
end
|
||||
|
||||
# returns a string with the classname of configurable
|
||||
def self.configurable_class(configurable) # :nodoc:
|
||||
ActiveRecord::Base.send(:class_name_of_active_record_descendant, configurable.class).to_s
|
||||
end
|
||||
|
||||
# returns a string with the classname of configurable
|
||||
def self.targetable_class(targetable) # :nodoc:
|
||||
ActiveRecord::Base.send(:class_name_of_active_record_descendant, targetable.class).to_s
|
||||
end
|
||||
|
||||
# returns the instance of the "owner" of the setting
|
||||
def self.find_configurable(configured_class, configured_id) # :nodoc:
|
||||
configured_class.constantize.find(configured_id)
|
||||
end
|
||||
|
||||
# returns the instance of the "target" of the setting
|
||||
def self.find_targetable(targeted_class, targeted_id) # :nodoc:
|
||||
targeted_class.constantize.find(targeted_id)
|
||||
end
|
||||
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue