diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 5f39bfed..14293d44 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -208,8 +208,10 @@ def options @options = self.class.module_options(params[:options]) if request.post? && @options.valid? - Configuration.set_config_model(@options) - flash[:notice] = "Updated Everyone options".t + if params[:commit] + Configuration.set_config_model(@options) + flash[:notice] = "Updated Everyone options".t + end redirect_to :action => 'index' return end @@ -241,9 +243,13 @@ def segments def create_segment cms_page_path ['People', 'Segments'], 'Create a Segment' + @builder = UserSegment::OperationBuilder.new nil + @segment = UserSegment.new :main_page => true if request.post? && params[:segment] + return redirect_to :action => 'index' unless params[:commit] + if @segment.update_attributes params[:segment] @segment.refresh redirect_to :action => 'segments' @@ -256,7 +262,11 @@ def edit_segment cms_page_path ['People', 'Segments'], '%s Segment' / @segment.name + @builder = UserSegment::OperationBuilder.new nil + if request.post? && params[:segment] + return redirect_to :action => 'index', :path => @segment.id unless params[:commit] + if @segment.update_attributes params[:segment] if @segment.should_refresh? @segment.refresh @@ -273,10 +283,14 @@ def copy_segment cms_page_path ['People', 'Segments'], 'Copy %s Segment' / segment_to_copy.name + @builder = UserSegment::OperationBuilder.new nil + @segment = UserSegment.new segment_to_copy.attributes.symbolize_keys.slice(:name, :description, :fields, :main_page, :segment_options_text, :order_by) @segment.name += ' (Copy)' unless request.post? if request.post? && params[:segment] + return redirect_to :action => 'index', :path => segment_to_copy.id unless params[:commit] + if @segment.update_attributes params[:segment] @segment.refresh redirect_to :action => 'segments' @@ -290,6 +304,16 @@ def refresh_segment redirect_to :action => 'segments' end + def builder + cms_page_path ['People'], 'Operation Builder' + + @builder = UserSegment::OperationBuilder.new nil + + if request.post? && params[:builder] + @builder.build(params[:builder]) + end + end + def create cms_page_path ['People'],'Create Contact' diff --git a/app/models/end_user_segment_field.rb b/app/models/end_user_segment_field.rb index b5442962..8efd6e93 100644 --- a/app/models/end_user_segment_field.rb +++ b/app/models/end_user_segment_field.rb @@ -9,12 +9,11 @@ def self.user_segment_fields_handler_info } end - register_field :email, UserSegment::CoreType::StringType - register_field :gender, UserSegment::CoreType::StringType - register_field :created, UserSegment::CoreType::DateTimeType, :field => :created_at - register_field :registered, UserSegment::CoreType::BooleanType - register_field :activated, UserSegment::CoreType::BooleanType - register_field :id, UserSegment::CoreType::NumberType - register_field :user_level, UserSegment::CoreType::NumberType + register_field :email, UserSegment::CoreType::StringType, :name => 'User: Email' + register_field :gender, UserSegment::CoreType::StringType, :name => 'User: Gender' + register_field :created, UserSegment::CoreType::DateTimeType, :field => :created_at, :name => 'User: Created' + register_field :registered, UserSegment::CoreType::BooleanType, :name => 'User: Registered' + register_field :activated, UserSegment::CoreType::BooleanType, :name => 'User: Activated' + register_field :user_level, UserSegment::CoreType::NumberType, :name => 'User: User Level' end diff --git a/app/models/user_segment/field.rb b/app/models/user_segment/field.rb index 70b03153..d8aebf93 100644 --- a/app/models/user_segment/field.rb +++ b/app/models/user_segment/field.rb @@ -1,7 +1,5 @@ class UserSegment::Field < HashModel - include HandlerActions - attributes :field => nil, :operation => nil, :arguments => [], :child => nil validates_presence_of :field @@ -67,6 +65,10 @@ def operation_argument_options self.operation_info[:argument_options] if self.operation_info end + def operation_argument_names + self.operation_info[:argument_names] if self.operation_info + end + def operation_info @operation_info ||= self.type_class.user_segment_field_type_operations[self.operation.to_sym] if self.type_class end diff --git a/app/models/user_segment/operation.rb b/app/models/user_segment/operation.rb index 720426b8..de6eebf4 100644 --- a/app/models/user_segment/operation.rb +++ b/app/models/user_segment/operation.rb @@ -41,7 +41,7 @@ def to_a def to_expr output = @operator == 'not' ? 'not ' : '' - output = @fields.collect { |fld| fld.to_expr }.join(' + ') + output += @fields.collect { |fld| fld.to_expr }.join(' + ') output end end diff --git a/app/models/user_segment/operation_builder.rb b/app/models/user_segment/operation_builder.rb new file mode 100644 index 00000000..02885376 --- /dev/null +++ b/app/models/user_segment/operation_builder.rb @@ -0,0 +1,87 @@ + +class UserSegment::OperationBuilder < HashModel + attributes :operator => nil, :field => 'created', :operation => 'since', :arguments => [] + + def operator_options + [['Not', 'not'], ['', nil]] + end + + def build(opts={}) + self.operator = opts[:operator] + self.field = opts[:field] + self.operation = opts[:operation] + unless self.operation_options.rassoc(self.operation) + self.operation = self.operation_options[0][1] + @user_segment_field = nil + end + + self.operation_arguments.each_with_index do |type, idx| + arg = "argument#{idx}" + self.send("#{arg}=", opts[arg.to_sym]) if opts[arg.to_sym] + end + end + + def field_options + return @field_options if @field_options + @field_options = [] + UserSegment::FieldHandler.handlers.each do |handler| + handler[:class].user_segment_fields.each do |field, values| + @field_options << [values[:name], field.to_s] unless @field_options.rassoc(field.to_s) + end + end + @field_options.sort! { |a, b| a[0] <=> b[0] } + end + + def user_segment_field + return @user_segment_field if @user_segment_field + @user_segment_field = UserSegment::Field.new :field => self.field, :operation => self.operation, :arguments => self.arguments + @user_segment_field + end + + def operation_options + return @operation_options if @operation_options + @operation_options = [] + + if self.user_segment_field.type_class + @operation_options = self.user_segment_field.type_class.user_segment_field_type_operations.collect do |operation, values| + [values[:name], operation.to_s] + end + end + + @operation_options.sort! { |a, b| a[0] <=> b[0] } + end + + def operation_arguments + self.user_segment_field.operation_arguments || [] + end + + def operation_argument_names + self.user_segment_field.operation_argument_names + end + + def operation_argument_options + self.user_segment_field.operation_argument_options + end + + def convert_to(value, idx) + UserSegment::FieldType.convert_to(value, self.operation_arguments[idx], self.operation_argument_options[idx]) + end + + def method_missing(arg, *args) + arg = arg.to_s + if arg =~ /^argument(\d+)$/ + self.arguments[$1.to_i] + elsif arg =~ /^argument(\d+)=$/ + self.arguments[$1.to_i] = self.convert_to(args[0], $1.to_i) if $1.to_i < self.operation_arguments.length + else + super + end + end + + def to_expr + return '' unless self.user_segment_field.valid? + output = self.operator == 'not' ? 'not ' : '' + output += self.user_segment_field.to_expr + output + end +end diff --git a/app/views/members/_operation_form.html.erb b/app/views/members/_operation_form.html.erb new file mode 100644 index 00000000..ed19bd63 --- /dev/null +++ b/app/views/members/_operation_form.html.erb @@ -0,0 +1,30 @@ + +
+<% admin_form_for :builder, @builder do |f| -%> +<%= f.check_boxes :operator, [['not', 'not']], :single => true, :label => 'I am' %> +<%= f.select :field, @builder.field_options, :label => 'looking for' %> +<%= f.select :operation, @builder.operation_options %> + + <% @builder.operation_arguments.each_with_index do |arg, idx| -%> + <% arg_options = @builder.operation_argument_options[idx] + label = @builder.operation_argument_names[idx] + if arg_options[:options] -%> + <%= f.select "argument#{idx}", arg_options[:options], :label => label %> + <% else -%> + <%= f.text_field "argument#{idx}", :label => label %> + <% end -%> + <% end -%> + +<%= f.submit 'Build' %> +<% end -%> + +
+Expression:
+ +
+ +
+ + diff --git a/app/views/members/_segment_form.html.erb b/app/views/members/_segment_form.html.erb index 49d96b0a..7c757e98 100644 --- a/app/views/members/_segment_form.html.erb +++ b/app/views/members/_segment_form.html.erb @@ -9,3 +9,4 @@ <%= f.spacer %> <%= f.cancel_submit_buttons 'Cancel', (@segment.id ? 'Save' : 'Create') %> <% end -%> + diff --git a/app/views/members/builder.html.erb b/app/views/members/builder.html.erb new file mode 100644 index 00000000..49c6cf10 --- /dev/null +++ b/app/views/members/builder.html.erb @@ -0,0 +1,3 @@ + +<%= render :partial => 'operation_form' %> +