spree_mail 0.40.0.3 → 0.40.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -14,7 +14,7 @@ To create a spree mail demo app, run the following:
14
14
  rails new spree_mail_example
15
15
  cd spree_mail_example
16
16
  echo "gem 'spree', '0.40.2'" >> Gemfile
17
- echo "gem 'spree_mail', '0.40.0.3'" >> Gemfile
17
+ echo "gem 'spree_mail', '0.40.0.4'" >> Gemfile
18
18
  rm public/index.html
19
19
  bundle install
20
20
  rake spree:install spree_mail:install db:migrate db:seed
@@ -22,9 +22,9 @@ To create a spree mail demo app, run the following:
22
22
 
23
23
  Or all at once:
24
24
 
25
- rails new spree_mail_example; cd spree_mail_example; echo "gem 'spree', '0.40.2'" >> Gemfile; echo "gem 'spree_mail', '0.40.0.3'" >> Gemfile; rm public/index.html; bundle install; rake spree:install spree_mail:install db:migrate db:seed
25
+ rails new spree_mail_example; cd spree_mail_example; echo "gem 'spree', '0.40.2'" >> Gemfile; echo "gem 'spree_mail', '0.40.0.4'" >> Gemfile; rm public/index.html; bundle install; rake spree:install spree_mail:install db:migrate db:seed
26
26
 
27
- `rake db:sample` if you want to...
27
+ `rake spree_sample:install db:sample` if you want to...
28
28
 
29
29
  Then start the server with `rails s`
30
30
 
@@ -42,7 +42,7 @@ Before sending, you may need to create an action_mailer initializer.
42
42
  To Do
43
43
  -----
44
44
 
45
- * Write real tests
45
+ * Write more tests
46
46
  * Write a rake task that converts current users to subscribers
47
47
  * Add checkbox on user signup: 'sign up for our mailing list'
48
48
  * Add user help to email form
data/Rakefile CHANGED
@@ -1,94 +1,30 @@
1
- require 'bundler'
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rake'
10
+ require 'rake/rdoctask'
2
11
  require 'rake/testtask'
12
+
3
13
  Bundler::GemHelper.install_tasks
4
14
 
5
- Rake::TestTask.new do |t|
6
- t.libs << "lib"
15
+ Rake::TestTask.new(:test) do |t|
16
+ t.libs << 'lib'
17
+ t.libs << 'test'
7
18
  t.pattern = 'test/**/*_test.rb'
8
- t.verbose = true
19
+ t.verbose = false
9
20
  end
10
21
 
22
+ task :default => :test
11
23
 
12
- #task :test do
13
- #
14
- # root = ENV["RAILS_ROOT"] || File.expand_path('../spec/test_app', __FILE__)
15
- # env = File.join(root, 'config', 'environment.rb')
16
- # puts "(Rails Root: #{root})"
17
- #
18
- # require env
19
- # require File.expand_path('../test/test_helper', __FILE__)
20
- # Dir["test/**/*.rb"].reject{|file| file.match(/test_helper/) != nil }.each do |file|
21
- # puts "Loading #{file}"
22
- # load file
23
- # end
24
- #
25
- #end
26
- #
27
-
28
-
29
-
30
- desc "Default Task"
31
- task :default => [ :test ]
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
- # TODO: pull in the spree/core/Rakefile bits that set up for testing
41
- desc "Regenerates a Rails 3 app for testing"
42
- task :test_app do
43
- # TODO - this path requires a certain directory structure -- need
44
- # to think about how to refactor
45
-
46
-
47
- files = `gem contents spree`.split("\n").select{|file| file.match("test_app_generator")}
48
- if files.length == 1
49
- require files.first
50
- class SpreeMailTestAppGenerator < Spree::Generators::TestAppGenerator
51
- def tweak_gemfile
52
- append_file "Gemfile" ,
53
- <<-gems
54
- gem 'activemerchant'
55
- gem 'spree_core', '>=0.40.2'
56
- gem 'spree_auth', '>=0.40.2'
57
- gem 'spree_mail', :path => "#{File.dirname(__FILE__)}"
58
- gems
59
- end
60
-
61
- def install_spree_gems
62
-
63
- puts "-----------------------------------------"
64
- puts "Installing gems..."
65
- `bundle install --gemfile=spec/test_app/Gemfile`
66
- puts "-----------------------------------------"
67
-
68
- inside "test_app" do
69
- run 'rake spree_core:install'
70
- run 'rake spree_auth:install'
71
- run 'rake spree_mail:install'
72
- end
73
- end
74
-
75
- def migrate_db
76
- run_migrations
77
- end
78
- end
79
-
80
- SpreeMailTestAppGenerator.start
81
-
82
- puts "spec/test_app created. "
83
-
84
- else
85
- puts "Failed: Could not find lib/generators/spree/test_app_generator.rb"
86
- end
87
- end
88
-
89
- namespace :test_app do
90
- desc 'Rebuild test database'
91
- task :rebuild_db do
92
- system("cd spec/test_app && rake db:drop db:migrate RAILS_ENV=test")
93
- end
94
- end
24
+ Rake::RDocTask.new(:rdoc) do |rdoc|
25
+ rdoc.rdoc_dir = 'rdoc'
26
+ rdoc.title = 'SpreeMail'
27
+ rdoc.options << '--line-numbers' << '--inline-source'
28
+ rdoc.rdoc_files.include('README.rdoc')
29
+ rdoc.rdoc_files.include('lib/**/*.rb')
30
+ end
@@ -2,18 +2,12 @@ class Admin::EmailsController < Admin::BaseController
2
2
 
3
3
  resource_controller
4
4
 
5
- before_filter :check_json_authenticity, :only => :index
6
5
  before_filter :get_subscribers, :only => [:new, :create, :edit, :update]
7
6
 
8
- index.response do |wants|
9
- wants.html { render :action => :index }
10
- wants.json { render :json => json_data }
11
- end
12
7
  destroy.success.wants.js { render_js_for_destroy }
13
8
 
14
-
15
9
  def deliver
16
- @email = Email.find(params[:id])
10
+ @email = object
17
11
  sent, count = @email.deliver!
18
12
  if sent
19
13
  flash[:notice] = t('delivery_success', count)
@@ -23,39 +17,21 @@ class Admin::EmailsController < Admin::BaseController
23
17
  redirect_to admin_email_path(@email)
24
18
  end
25
19
 
26
-
27
-
28
20
  private
29
-
30
- ## Allow different formats of json data to suit different ajax calls
31
- #def json_data
32
- # json_format = params[:json_format] or 'default'
33
- # case json_format
34
- # when 'basic'
35
- # collection.map {|u| {'id' => u.id, 'name' => u.email}}.to_json
36
- # else
37
- # collection.to_json(:include =>
38
- # {:bill_address => {:include => [:state, :country]},
39
- # :ship_address => {:include => [:state, :country]}})
40
- # end
41
- #end
42
-
43
- def get_subscribers
44
- @subscribers = Subscriber.active
45
- end
46
21
 
47
- def collection
48
- return @collection if @collection.present?
49
- unless request.xhr?
50
- @search = Email.searchlogic(params[:search])
51
-
52
- #set order by to default or form result
53
- @search.order ||= "ascend_by_name"
54
-
55
- @collection = @search.do_search.paginate(:per_page => Spree::Config[:admin_products_per_page], :page => params[:page])
56
-
57
- else
58
- @collection = Email.where("wholesalers.name like :search", {:search => "#{params[:q].strip}%"}).limit(params[:limit] || 100)
22
+ def get_subscribers
23
+ @subscribers = Subscriber.active
24
+ end
25
+
26
+ def object
27
+ @object ||= Email.find_by_token(params[:id])
28
+ end
29
+
30
+ def collection
31
+ params[:search] ||= {}
32
+ params[:search][:meta_sort] ||= "subject.asc"
33
+ @search = end_of_association_chain.metasearch(params[:search])
34
+ @collection = @search.paginate(:per_page => Spree::Config[:admin_products_per_page], :page => params[:page])
59
35
  end
60
- end
36
+
61
37
  end
@@ -2,13 +2,6 @@ class Admin::SubscribersController < Admin::BaseController
2
2
 
3
3
  resource_controller
4
4
 
5
- before_filter :check_json_authenticity, :only => :index
6
-
7
- #index.response do |wants|
8
- # wants.html { render :action => :index }
9
- # wants.json { render :json => json_data }
10
- #end
11
-
12
5
  destroy.success.wants.js { render_js_for_destroy }
13
6
 
14
7
  create.response do |wants|
@@ -22,9 +15,9 @@ class Admin::SubscribersController < Admin::BaseController
22
15
  def resubscribe
23
16
  @subscriber = object
24
17
  if @subscriber.resubscribe!
25
- flash[:notice] = t("resubscribe_success")
18
+ flash[:notice] = t('resubscribe_success')
26
19
  else
27
- flash[:error] = t("resubscribe_failed")
20
+ flash[:error] = t('resubscribe_failed')
28
21
  end
29
22
  redirect_to request.referer
30
23
  end
@@ -32,47 +25,34 @@ class Admin::SubscribersController < Admin::BaseController
32
25
  def unsubscribe
33
26
  @subscriber = object
34
27
  if @subscriber.unsubscribe!
35
- flash[:notice] = t("unsubscribe_success")
28
+ flash[:notice] = t('unsubscribe_success')
36
29
  else
37
- flash[:error] = t("unsubscribe_failed")
30
+ flash[:error] = t('unsubscribe_failed')
38
31
  end
39
32
  redirect_to request.referer
40
33
  end
41
34
 
42
35
  def unsubscribed
43
- @search = Subscriber.searchlogic(params[:search])
44
-
45
- #set order by to default or form result
46
- @search.order ||= "ascend_by_name"
47
-
48
- @subscribers = @collection = @search.do_search.unsubscribed.paginate(:per_page => Spree::Config[:admin_products_per_page], :page => params[:page])
36
+ params[:search] ||= {}
37
+ params[:search][:unsubscribed_at_is_not_null] = true
38
+ @subscribers = collection
49
39
  render :template => 'admin/subscribers/index'
50
40
  end
51
41
 
52
-
53
42
  private
54
-
55
- # Allow different formats of json data to suit different ajax calls
56
- #def json_data
57
- # json_format = params[:json_format] or 'default'
58
- # case json_format
59
- # when 'basic'
60
- # collection.map {|u| {'id' => u.id, 'name' => u.email}}.to_json
61
- # else
62
- # collection.to_json(:include =>
63
- # {:bill_address => {:include => [:state, :country]},
64
- # :ship_address => {:include => [:state, :country]}})
65
- # end
66
- #end
67
-
68
- def collection
69
- return @collection if @collection.present?
70
- @search = Subscriber.searchlogic(params[:search])
43
+
44
+ def object
45
+ @object ||= Subscriber.find_by_token(params[:id])
46
+ end
71
47
 
72
- #set order by to default or form result
73
- @search.order ||= "ascend_by_name"
74
-
75
- @collection = @search.do_search.active.paginate(:per_page => Spree::Config[:admin_products_per_page], :page => params[:page])
48
+ def collection
49
+ params[:search] ||= {}
50
+ params[:search][:meta_sort] ||= "name.asc"
51
+ unless params[:search].has_key?(:unsubscribed_at_is_not_null)
52
+ params[:search][:unsubscribed_at_is_null] = true
53
+ end
54
+ @search = end_of_association_chain.metasearch(params[:search])
55
+ @collection = @search.paginate(:per_page => Spree::Config[:admin_products_per_page], :page => params[:page])
56
+ end
76
57
 
77
- end
78
- end
58
+ end
@@ -4,16 +4,17 @@ class EmailsController < Spree::BaseController
4
4
  include ActionView::Helpers::TextHelper
5
5
 
6
6
  def show
7
- @subscriber = Subscriber.find_by_token(params[:token])
8
- @email = Email.find_by_token(params[:id])
9
-
10
- return redirect_to new_subscriber_path unless @email.recipients.include?(@subscriber.email)
11
-
12
- @email_subject = @email.render(:subject, @subscriber)
13
- @text = @email.render(:body, @subscriber)
14
- @base_url = "http://#{Spree::Config[:site_url]}"
15
-
16
- render :layout => 'email', :text => simple_format(@text)
7
+ @subscriber = Subscriber.find_by_token(params[:subscriber])
8
+ @email = Email.find_by_token(params[:email])
9
+ if @email.recipients.include?(@subscriber.email)
10
+ @email_subject = @email.render(:subject, @subscriber)
11
+ @text = @email.render(:body, @subscriber)
12
+ @base_url = "http://#{Spree::Config[:site_url]}"
13
+ render :layout => 'email', :text => simple_format(@text)
14
+ else
15
+ flash[:error] = t('unintened_email_view')
16
+ redirect_to new_subscriber_path
17
+ end
17
18
  end
18
19
 
19
20
  end
@@ -16,21 +16,22 @@ class SubscribersController < Spree::BaseController
16
16
  def create
17
17
  @subscriber = Subscriber.new(params[:subscriber])
18
18
  if @subscriber.valid? && @subscriber.save
19
- flash[:notice] = I18n.t( :subscribe_thanks)
19
+ flash[:notice] = t('subscribe_thanks')
20
20
  redirect_to new_subscriber_path
21
21
  else
22
- flash[:error] = I18n.t( :subscribe_failed)
22
+ flash[:error] = t('subscribe_failed')
23
23
  render :action => 'new'
24
24
  end
25
25
  end
26
26
 
27
27
  def unsubscribe
28
28
  if @subscriber.email == params[:subscriber][:email] && @subscriber.unsubscribe!
29
- flash[:notice] = I18n.t(:unsubscribe_success_public)
29
+ flash[:notice] = t('unsubscribe_success_public')
30
+ redirect_to new_subscriber_path
30
31
  else
31
- flash[:error] = I18n.t(:unsubscribe_failed_public)
32
+ flash[:error] = t('unsubscribe_failed_public')
33
+ redirect_to subscriber_path(@subscriber)
32
34
  end
33
- redirect_to new_subscriber_path
34
35
  end
35
36
 
36
37
  private
@@ -1,11 +1,11 @@
1
1
  class Email < ActiveRecord::Base
2
-
2
+
3
+ include SpreeMail::HasToken
4
+
3
5
  validates :to, :presence => true
4
6
  validates :subject, :presence => true
5
7
  validates :body, :presence => true
6
8
 
7
- before_create :set_token
8
-
9
9
  def to=(value)
10
10
  value = {} unless value.is_a? Hash
11
11
  value.delete("0")
@@ -25,6 +25,10 @@ class Email < ActiveRecord::Base
25
25
  def recipient_list
26
26
  recipients.join(", ")
27
27
  end
28
+
29
+ def render(attribute, subscriber)
30
+ Mustache.render(self.send(attribute), subscriber.attributes)
31
+ end
28
32
 
29
33
  def deliver!
30
34
  count = 0
@@ -37,20 +41,7 @@ class Email < ActiveRecord::Base
37
41
  end
38
42
  return 0 < count, count
39
43
  end
40
-
41
-
42
-
43
- def render(attribute, subscriber)
44
- Mustache.render(self.send(attribute), subscriber.attributes)
45
- end
46
-
47
- private
48
-
49
- def set_token
50
- write_attribute :token, Digest::SHA1.hexdigest(Time.now.to_s)
51
- end
52
-
53
-
44
+
54
45
  class << self
55
46
 
56
47
  def new(parameters={})
@@ -1,15 +1,15 @@
1
1
  class Subscriber < ActiveRecord::Base
2
2
 
3
- attr_protected :token
3
+ include SpreeMail::HasToken
4
4
 
5
+ # ?? Do we need these scopes anywhere else
6
+ # -> DRY (Later task)
5
7
  scope :active, where("unsubscribed_at IS NULL").order(:name)
6
8
  scope :unsubscribed, where("unsubscribed_at IS NOT NULL").order(:name)
7
9
 
8
10
  validates :name, :presence => true
9
11
  validates :email, :email => true, :uniqueness => true
10
-
11
- before_create :set_token
12
-
12
+
13
13
  def active?
14
14
  unsubscribed_at.to_s.empty?
15
15
  end
@@ -29,11 +29,5 @@ class Subscriber < ActiveRecord::Base
29
29
  def email=(value)
30
30
  write_attribute :email, value.strip.downcase
31
31
  end
32
-
33
- private
34
-
35
- def set_token
36
- write_attribute :token, Digest::SHA1.hexdigest(Time.now.to_s)
37
- end
38
-
32
+
39
33
  end
@@ -15,6 +15,6 @@ class EmailValidator < ActiveModel::EachValidator
15
15
  rescue Exception => e
16
16
  r = false
17
17
  end
18
- record.errors[attribute] << (options[:message] || I18n.t(:invalid_email, :scope => [:activerecord, :errors, :messages])) unless r
18
+ record.errors[attribute] << (options[:message] || I18n.t('invalid_email', :scope => [:activerecord, :errors, :messages])) unless r
19
19
  end
20
20
  end
@@ -1,13 +1,10 @@
1
1
  <%- locals = {:f => f} %>
2
2
 
3
3
  <% content_for :head do %>
4
- <%= stylesheet_link_tag 'admin/spree_mail' %>
5
-
4
+ <%= stylesheet_link_tag 'admin/spree_mail' %>
6
5
  <script type="text/javascript">
7
- //<![CDATA[
8
-
6
+ //<![CDATA[
9
7
  $(document).ready(function() {
10
-
11
8
  $('div.selection a').click(function(evt) {
12
9
  evt.preventDefault();
13
10
  var a = $(this);
@@ -22,20 +19,15 @@
22
19
  break;
23
20
  }
24
21
  });
25
-
26
22
  $('div.selection li').click(function(evt) {
27
23
  if (evt.target.type == 'checkbox') return true;
28
24
  evt.preventDefault();
29
25
  var cb = $(this).find('input[type=checkbox]');
30
26
  cb.attr('checked', cb.is(':checked') ? false : true);
31
27
  });
32
-
33
28
  });
34
-
35
-
36
29
  //]]>
37
- </script>
38
-
30
+ </script>
39
31
  <% end %>
40
32
 
41
33
  <%= hook :admin_email_form_fields, locals do %>
@@ -44,9 +36,9 @@
44
36
 
45
37
  <div class="selection left">
46
38
 
47
- <h3><%= t("select_subscribers") %>:</h3>
48
- <%= link_to t("select_all"), "#select-all" %> /
49
- <%= link_to t("deselect_all"), "#deselect-all" %>
39
+ <h3><%= t('select_subscribers') %>:</h3>
40
+ <%= link_to t('select_all'), "#select-all" %> /
41
+ <%= link_to t('deselect_all'), "#deselect-all" %>
50
42
  <ul class="select">
51
43
  <% @subscribers.each do |subscriber| %>
52
44
  <li class="checkbox">
@@ -60,7 +52,7 @@
60
52
 
61
53
  <div class="right">
62
54
 
63
- <h3><%= t("message_details")%></h3>
55
+ <h3><%= t('message_details')%></h3>
64
56
  <%= f.field_container :subject do %>
65
57
  <%= f.label :subject, t("subject") %><br />
66
58
  <%= f.text_field :subject, :class => "title" %>
@@ -68,7 +60,7 @@
68
60
  <% end %>
69
61
 
70
62
  <%= f.field_container :body do %>
71
- <%= f.label :body, t("message_body") %><br />
63
+ <%= f.label :body, t('message_body') %><br />
72
64
  <%= f.text_area :body %>
73
65
  <%= error_message_on :email, :body %>
74
66
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%= render 'admin/shared/spree_mail_sub_nav' %>
2
2
 
3
3
  <%= hook :admin_email_edit_form_header do %>
4
- <h1><%= t("editing_email") %></h1>
4
+ <h1><%= t('editing_email') %></h1>
5
5
  <% end %>
6
6
 
7
7
  <%= hook :admin_email_edit_form do %>
@@ -3,22 +3,22 @@
3
3
  <div class='toolbar'>
4
4
  <ul class='actions'>
5
5
  <li>
6
- <p><%= button_link_to t("new_email"), new_object_url, :icon => 'add' %></p>
6
+ <p><%= button_link_to t('new_email'), new_object_url, :icon => 'add' %></p>
7
7
  </li>
8
8
  </ul>
9
9
  <br class='clear' />
10
10
  </div>
11
11
 
12
12
 
13
- <h1><%= t("listing_emails") %></h1>
13
+ <h1><%= t('listing_emails') %></h1>
14
14
 
15
15
 
16
16
  <table class="index">
17
17
  <thead>
18
18
  <tr>
19
19
  <%= hook :admin_emails_index_headers do %>
20
- <th><%= order @search, :by => :subject, :as => t("subject") %></th>
21
- <th><%= order @search, :by => :body, :as => t("message_body") %></th>
20
+ <th><%= sort_link @search, :subject, t('subject') %></th>
21
+ <th><%= sort_link @search, :body, t('message_body') %></th>
22
22
  <th><%= hook :admin_emails_index_header_actions %></th>
23
23
  <% end %>
24
24
  </tr>
@@ -44,21 +44,26 @@
44
44
 
45
45
  <%= will_paginate(:previous_label => "&#171; #{t('previous')}", :next_label => "#{t('next')} &#187;") %>
46
46
 
47
-
48
47
  <% content_for :sidebar do %>
49
- <div class="box">
50
- <h3><%= t(:search) %></h3>
51
- <%= form_for @search do |f| %>
52
- <%- locals = {:f => f} %>
53
- <%= hook :admin_emails_index_search, locals do %>
54
- <p>
55
- <%= t("to") %><br />
56
- <%= f.text_field :to_contains, :size=>18 %>
57
- </p>
58
- <% end %>
59
- <%= hook :admin_emails_index_search_buttons, locals do %>
60
- <p><%= button t("search") %></p>
61
- <% end %>
48
+ <div class="box">
49
+ <h3><%= t('search') %></h3>
50
+
51
+ <% @email = Email.metasearch %>
52
+ <%= form_for [:admin, @email] do |f| %>
53
+ <%- locals = {:f => f} %>
54
+ <%= hook :admin_emails_index_search, locals do %>
55
+ <p>
56
+ <label><%= t 'to' %></label><br />
57
+ <%= f.text_field :to_like, :size => 25 %>
58
+ </p>
59
+ <p>
60
+ <label><%= t 'subject' %></label><br />
61
+ <%= f.text_field :subject_like, :size => 25 %>
62
+ </p>
62
63
  <% end %>
63
- </div>
64
- <% end %>
64
+ <%= hook :admin_emails_index_search_buttons, locals do %>
65
+ <p><%= button t('search') %></p>
66
+ <% end %>
67
+ <% end %>
68
+ </div>
69
+ <% end %>
@@ -1,7 +1,7 @@
1
1
  <%= render 'admin/shared/spree_mail_sub_nav' %>
2
2
 
3
3
  <%= hook :admin_email_new_form_header do %>
4
- <h1><%= t("new_email") %></h1>
4
+ <h1><%= t('new_email') %></h1>
5
5
  <% end %>
6
6
 
7
7
  <%= hook :admin_email_new_form do %>
@@ -1,20 +1,20 @@
1
1
  <%= render 'admin/shared/spree_mail_sub_nav' %>
2
2
 
3
- <h1><%= t("show_email") %></h1>
3
+ <h1><%= t('show_email') %></h1>
4
4
 
5
- <h5><%= t("to") %>: (<%= @email.recipients.length %>)</h5>
5
+ <h5><%= t('to') %>: (<%= @email.recipients.length %>)</h5>
6
6
  <p><%= @email.recipient_list %></p>
7
7
 
8
- <h5><%= t("subject") %>:</h5>
8
+ <h5><%= t('subject') %>:</h5>
9
9
  <p><%= @email.subject %></p>
10
10
 
11
- <h5><%= t("body") %>:</h5>
11
+ <h5><%= t('body') %>:</h5>
12
12
  <%= simple_format @email.body %>
13
13
 
14
14
  <hr/>
15
15
 
16
16
  <p>
17
- <%= link_to (image_tag("admin/icons/email.png") + " " + t("send")), deliver_admin_email_path(@email) %> &nbsp;
17
+ <%= link_to (image_tag("admin/icons/email.png") + " " + t('send')), deliver_admin_email_path(@email) %> &nbsp;
18
18
  <%= link_to_edit @email %> <%= t('or') %>
19
19
  <%= link_to t('back'), collection_url %>
20
20
  </p>
@@ -5,13 +5,13 @@
5
5
  <%= render "shared/error_messages", :target => @subscriber %>
6
6
 
7
7
  <%= f.field_container :name do %>
8
- <%= f.label :name, t("name") %><br />
8
+ <%= f.label :name, t('name') %><br />
9
9
  <%= f.text_field :name, :class => 'title' %>
10
10
  <%= error_message_on :subscriber, :name %>
11
11
  <% end %>
12
12
 
13
13
  <%= f.field_container :email do %>
14
- <%= f.label :email, t("email") %><br />
14
+ <%= f.label :email, t('email') %><br />
15
15
  <%= f.text_field :email, :class => 'title' %>
16
16
  <%= error_message_on :subscriber, :email %>
17
17
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <% if subscriber.active? %>
2
- <%= link_to t("unsubscribe"), unsubscribe_admin_subscriber_path(subscriber) %>
2
+ <%= link_to t('unsubscribe'), unsubscribe_admin_subscriber_path(subscriber) %>
3
3
  <% else %>
4
- <%= link_to t("resubscribe"), resubscribe_admin_subscriber_path(subscriber) %>
4
+ <%= link_to t('resubscribe'), resubscribe_admin_subscriber_path(subscriber) %>
5
5
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%= render 'admin/shared/spree_mail_sub_nav' %>
2
2
 
3
3
  <%= hook :admin_subscriber_edit_form_header do %>
4
- <h1><%= t("editing_subscriber") %></h1>
4
+ <h1><%= t('editing_subscriber') %></h1>
5
5
  <% end %>
6
6
 
7
7
  <%= hook :admin_subscriber_edit_form do %>
@@ -5,11 +5,11 @@
5
5
  <li>
6
6
  <p>
7
7
  <% if controller.action_name == 'unsubscribed' %>
8
- <%= button_link_to t("view_all_subscribers"), admin_subscribers_path %>
8
+ <%= button_link_to t('view_all_subscribers'), admin_subscribers_path %>
9
9
  <% else %>
10
- <%= button_link_to t("view_unsubscribed"), unsubscribed_admin_subscribers_path %>
10
+ <%= button_link_to t('view_unsubscribed'), unsubscribed_admin_subscribers_path %>
11
11
  <% end %>
12
- <%= button_link_to t("new_subscriber"), new_object_url, :icon => 'add' %>
12
+ <%= button_link_to t('new_subscriber'), new_object_url, :icon => 'add' %>
13
13
  </p>
14
14
  </li>
15
15
  </ul>
@@ -17,15 +17,15 @@
17
17
  </div>
18
18
 
19
19
 
20
- <h1><%= t("listing_subscribers") %></h1>
20
+ <h1><%= t('listing_subscribers') %></h1>
21
21
 
22
22
 
23
23
  <table class="index">
24
24
  <thead>
25
25
  <tr>
26
26
  <%= hook :admin_subscribers_index_headers do %>
27
- <th><%= order @search, :by => :name, :as => t("name") %></th>
28
- <th><%= order @search, :by => :email, :as => t("email") %></th>
27
+ <th><%= sort_link @search, :name, t('name') %></th>
28
+ <th><%= sort_link @search, :email, t('email') %></th>
29
29
  <th><%= hook :admin_subscribers_index_header_actions %></th>
30
30
  <% end %>
31
31
  </tr>
@@ -54,23 +54,25 @@
54
54
 
55
55
 
56
56
  <% content_for :sidebar do %>
57
- <div class="box">
58
- <h3><%= t(:search) %></h3>
59
- <%= form_for @search do |f| %>
60
- <%- locals = {:f => f} %>
61
- <%= hook :admin_subscribers_index_search, locals do %>
62
- <p>
63
- <%= t("name") %><br />
64
- <%= f.text_field :name_contains, :size=>18 %>
65
- <p>
66
- <%= t("email") %><br />
67
- <%= f.text_field :email_contains, :size=>18 %>
68
- </p>
69
-
70
- <% end %>
71
- <%= hook :admin_subscribers_index_search_buttons, locals do %>
72
- <p><%= button t("search") %></p>
73
- <% end %>
57
+ <div class="box">
58
+ <h3><%= t('search') %></h3>
59
+
60
+ <% @subscriber = Subscriber.metasearch %>
61
+ <%= form_for [:admin, @subscriber] do |f| %>
62
+ <%- locals = {:f => f} %>
63
+ <%= hook :admin_subscribers_index_search, locals do %>
64
+ <p>
65
+ <label><%= t 'name' %></label><br />
66
+ <%= f.text_field :name_like, :size => 25 %>
67
+ </p>
68
+ <p>
69
+ <label><%= t 'email' %></label><br />
70
+ <%= f.text_field :email_like, :size => 25 %>
71
+ </p>
72
+ <% end %>
73
+ <%= hook :admin_subscribers_index_search_buttons, locals do %>
74
+ <p><%= button t('search') %></p>
74
75
  <% end %>
75
- </div>
76
- <% end %>
76
+ <% end %>
77
+ </div>
78
+ <% end %>
@@ -1,7 +1,7 @@
1
1
  <%= render 'admin/shared/spree_mail_sub_nav' %>
2
2
 
3
3
  <%= hook :admin_subscriber_new_form_header do %>
4
- <h1><%= t("new_subscriber") %></h1>
4
+ <h1><%= t('new_subscriber') %></h1>
5
5
  <% end %>
6
6
 
7
7
  <%= hook :admin_subscriber_new_form do %>
@@ -1,6 +1,6 @@
1
1
  <%= render 'admin/shared/spree_mail_sub_nav' %>
2
2
 
3
- <h1><%= t("show_subscriber") %></h1>
3
+ <h1><%= t('show_subscriber') %></h1>
4
4
 
5
5
  <h5>Name:</h5>
6
6
  <h3><%= @subscriber.name %></h3>
@@ -1 +1 @@
1
- <%= link_to t("sign_up_for_our_newsletter"), new_subscriber_path %>
1
+ <%= link_to t('sign_up_for_our_newsletter'), new_subscriber_path %>
@@ -1,3 +1,3 @@
1
1
  <h1><%= t('newsletter_sign_up') %></h1>
2
2
 
3
- <p><%= t("newsletter_text_signup") %></p>
3
+ <p><%= t('newsletter_text_signup') %></p>
@@ -23,7 +23,7 @@
23
23
  <td><%= link_to image_tag(@base_url + Spree::Config[:logo], :alt => Spree::Config[:site_name], :style => "border: 0"), root_url %></td>
24
24
  <td align="right">
25
25
  <p><%= l @email.created_at, :format => "%B %d, %Y" %></p>
26
- <p><b><%= t("subject") %>:</b> <%= @email_subject %></p>
26
+ <p><b><%= t('subject') %>:</b> <%= @email_subject %></p>
27
27
  </td>
28
28
  </tr>
29
29
  <tr>
@@ -36,8 +36,8 @@
36
36
  <tr>
37
37
  <td>
38
38
  <p style="font-size: 12px;"><%= t :received_in_error, :site_name => Spree::Config[:site_name] %></p>
39
- <p style="font-size: 12px;"><%= t("contact") %>: <b><%= mail_to @email.from, @email.from, :style => "color: #5b8fb1;" %></b></p>
40
- <p style="font-size: 12px;"><%= t("unsubscribe_text", :site_name => Spree::Config[:site_name]) %> <%= link_to t("click_here"), subscriber_url(@subscriber.token), :style => "color: #5b8fb1;" %></p>
39
+ <p style="font-size: 12px;"><%= t('contact') %>: <b><%= mail_to @email.from, @email.from, :style => "color: #5b8fb1;" %></b></p>
40
+ <p style="font-size: 12px;"><%= t('unsubscribe_text', :site_name => Spree::Config[:site_name]) %> <%= link_to t('click_here'), subscriber_url(@subscriber.token), :style => "color: #5b8fb1;" %></p>
41
41
  <h4 style="padding: 10px 0; margin: 0; border-top: 1px solid #e0e0e0;">
42
42
  <%= link_to Spree::Config[:site_name], root_url, :style => "color: #5b8fb1;" %>
43
43
  </h4>
@@ -59,10 +59,10 @@
59
59
  <td align="right">
60
60
  <p style="font-size: 12px">
61
61
  <% if @link_to_browser %>
62
- <%= link_to t("click_here"), @link_to_browser, :style => "color: #5b8fb1;" %>
63
- <%= t("view_in_browser") %>
62
+ <%= link_to t('click_here'), @link_to_browser, :style => "color: #5b8fb1;" %>
63
+ <%= t('view_in_browser') %>
64
64
  <% else %>
65
- <%= t("visit_online") %>
65
+ <%= t('visit_online') %>
66
66
  <%= link_to Spree::Config[:site_url], root_url, :style => "color: #5b8fb1;" %>
67
67
  <% end %>
68
68
  </p>
@@ -71,7 +71,7 @@
71
71
  <tr>
72
72
  <td colspan="2" align="center">
73
73
  <br/>
74
- <p style="font-size: 11px; color: #999;"><%= t(:message_sent_to_from_on,
74
+ <p style="font-size: 11px; color: #999;"><%= t('message_sent_to_from_on',
75
75
  :to => @subscriber.email,
76
76
  :from => @email.from,
77
77
  :on => l(@email.created_at, :format => "%b %d, %Y at %I:%M:%S %p")) %>.</p>
@@ -7,5 +7,5 @@
7
7
  <%= form.text_field :email, :class => 'title required' %>
8
8
  </p>
9
9
  <p class="action">
10
- <%= form.submit t("sign_up") %>
10
+ <%= form.submit t('sign_up') %>
11
11
  </p>
@@ -1,6 +1,6 @@
1
- <h1><%= t("unsubscribe_title") %></h1>
1
+ <h1><%= t('unsubscribe_title') %></h1>
2
2
 
3
- <p><%= t("unsubscribe_mail") %>:</p>
3
+ <p><%= t('unsubscribe_mail') %>:</p>
4
4
 
5
5
  <% token = Digest::SHA1.hexdigest(Time.now.to_s) %>
6
6
  <%= form_for @subscriber, :url => unsubscribe_subscriber_path(@subscriber.token) do |form| %>
@@ -10,7 +10,7 @@
10
10
  <%= form.hidden_field :token, :value => token %>
11
11
  </p>
12
12
  <p>
13
- <%= form.submit t("unsubscribe") %> or
14
- <%= link_to t("cancel"), root_path %>
13
+ <%= form.submit t('unsubscribe') %> or
14
+ <%= link_to t('cancel'), root_path %>
15
15
  </p>
16
16
  <% end %>
@@ -24,7 +24,7 @@ en:
24
24
  show_email: Show Email
25
25
  new_email: New Email
26
26
  editing_email: Editing Email
27
-
27
+ unintened_email_view: This email was not intended for you.
28
28
  emails: Emails
29
29
 
30
30
  to: To
@@ -32,35 +32,32 @@ en:
32
32
  body: Body
33
33
  subject: Subject
34
34
  message_body: Message Body
35
+ contact: Contact
35
36
 
36
37
  delivery_success: Your email was successfully sent!
37
38
  delivery_failed: Sorry, your email could not be sent.
38
39
 
39
- contact: "Contact"
40
-
41
- received_in_error: 'This is a message from the %{site_name} if you believe you have received this in error please let us know.'
42
- unsubscribe_text: "If you would like to Unsubscribe"
43
- click_here: "Click here"
44
- view_in_browser: "to view this email in your browser"
45
- visit_online: "visit us online at"
40
+ unsubscribe_text: If you would like to Unsubscribe
41
+ click_here: Click here
42
+ view_in_browser: to view this email in your browser
43
+ visit_online: visit us online at
44
+
45
+ received_in_error: "This is a message from the %{site_name} if you believe you have received this in error please let us know."
46
46
  message_sent_to_from_on: "This message was sent to %{to} from %{from} on %{on}."
47
47
 
48
+ unsubscribe_title: Unsubscribe from our Mailing List
49
+ unsubscribe_mail: Please enter your email address below
50
+ unsubscribe: Unsubscribe
48
51
 
49
- unsubscribe_title: "Unsubscribe from our Mailing List"
50
- unsubscribe_mail: "Please enter your email address below"
51
- unsubscribe: "Unsubscribe"
52
-
53
- select_subscribers: "Select subscribers"
54
- select_all: "Select All"
55
- deselect_all: "Deselect All"
56
- message_details: "Message Details"
57
-
58
- sign_up_for_our_newsletter: "Sign up for our newsletter"
59
-
60
- newsletter_text_signup: "Lorem Ipsum dolor sit amet..."
52
+ select_subscribers: Select subscribers
53
+ select_all: Select All
54
+ deselect_all: Deselect All
55
+ message_details: Message Details
61
56
 
57
+ sign_up_for_our_newsletter: Sign up for our newsletter
58
+ newsletter_text_signup: Lorem Ipsum dolor sit amet...
62
59
 
63
60
  activerecord:
64
61
  errors:
65
62
  messages:
66
- invalid_email: "appears to be invalid"
63
+ invalid_email: appears to be invalid
@@ -1,6 +1,6 @@
1
1
  Rails.application.routes.draw do
2
2
 
3
- get "/email/:token/:id", :to => "emails#show", :as => :read_email
3
+ get "/email/:subscriber/:email", :to => "emails#show", :as => :read_email
4
4
 
5
5
  resources :subscribers, :except => [:edit,:update] do
6
6
  put :unsubscribe, :on => :member
@@ -1,6 +1,14 @@
1
+ if ENV["RAILS_ENV"] == "test"
2
+ require 'spree_core'
3
+ require 'spree_auth'
4
+ require 'sqlite3'
5
+ end
6
+
1
7
  require 'mail'
2
8
  require 'mustache'
9
+ require 'meta_search'
3
10
  require 'spree_mail/custom_hooks'
11
+ require 'spree_mail/has_token'
4
12
 
5
13
  module SpreeMail
6
14
 
@@ -0,0 +1,27 @@
1
+ module SpreeMail
2
+ module HasToken
3
+
4
+ def self.included(model)
5
+ model.instance_eval do
6
+ attr_readonly :token
7
+ validates :token, :presence => true
8
+ before_validation :set_token, :on => :create
9
+ end
10
+ model.send(:include, InstanceMethods)
11
+ end
12
+
13
+ module InstanceMethods
14
+
15
+ def to_param
16
+ token
17
+ end
18
+
19
+ private
20
+ def set_token
21
+ write_attribute :token, Digest::SHA1.hexdigest((Time.now.to_i * rand).to_s)
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module SpreeMail
2
- VERSION = "0.40.0.3"
2
+ VERSION = "0.40.0.4"
3
3
  end
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_mail
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 40
8
- - 0
9
- - 3
10
- version: 0.40.0.3
4
+ prerelease:
5
+ version: 0.40.0.4
11
6
  platform: ruby
12
7
  authors:
13
8
  - Spencer Steffen
@@ -15,68 +10,86 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-01-29 00:00:00 -08:00
13
+ date: 2011-02-22 00:00:00 -08:00
19
14
  default_executable:
20
15
  dependencies:
21
16
  - !ruby/object:Gem::Dependency
22
17
  name: spree_core
23
- prerelease: false
24
18
  requirement: &id001 !ruby/object:Gem::Requirement
25
19
  none: false
26
20
  requirements:
27
21
  - - ">="
28
22
  - !ruby/object:Gem::Version
29
- segments:
30
- - 0
31
- - 30
32
- - 1
33
23
  version: 0.30.1
34
24
  type: :runtime
25
+ prerelease: false
35
26
  version_requirements: *id001
36
27
  - !ruby/object:Gem::Dependency
37
28
  name: spree_auth
38
- prerelease: false
39
29
  requirement: &id002 !ruby/object:Gem::Requirement
40
30
  none: false
41
31
  requirements:
42
32
  - - ">="
43
33
  - !ruby/object:Gem::Version
44
- segments:
45
- - 0
46
- - 30
47
- - 1
48
34
  version: 0.30.1
49
35
  type: :runtime
36
+ prerelease: false
50
37
  version_requirements: *id002
51
38
  - !ruby/object:Gem::Dependency
52
39
  name: mustache
53
- prerelease: false
54
40
  requirement: &id003 !ruby/object:Gem::Requirement
55
41
  none: false
56
42
  requirements:
57
43
  - - ">="
58
44
  - !ruby/object:Gem::Version
59
- segments:
60
- - 0
61
- - 12
62
- - 0
63
45
  version: 0.12.0
64
46
  type: :runtime
47
+ prerelease: false
65
48
  version_requirements: *id003
66
49
  - !ruby/object:Gem::Dependency
67
50
  name: mail
68
- prerelease: false
69
51
  requirement: &id004 !ruby/object:Gem::Requirement
70
52
  none: false
71
53
  requirements:
72
54
  - - ">="
73
55
  - !ruby/object:Gem::Version
74
- segments:
75
- - 2
76
- - 2
77
- version: "2.2"
56
+ version: 2.2.0
78
57
  type: :runtime
58
+ prerelease: false
79
59
  version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: meta_search
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 1.0.1
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: shoulda
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 2.11.3
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: sqlite3-ruby
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: *id007
80
93
  description: Spree Mail extends Spree by adding a mailing list subscriber model, sign up forms and an admin to send messages.
81
94
  email:
82
95
  - spencer@citrusme.com
@@ -91,6 +104,7 @@ files:
91
104
  - config/locales/en.yml
92
105
  - config/routes.rb
93
106
  - lib/spree_mail/custom_hooks.rb
107
+ - lib/spree_mail/has_token.rb
94
108
  - lib/spree_mail/version.rb
95
109
  - lib/spree_mail.rb
96
110
  - lib/tasks/install.rake
@@ -128,7 +142,7 @@ files:
128
142
  - public/images/mailer/postmark.png
129
143
  - public/stylesheets/admin/spree_mail.css
130
144
  - Rakefile
131
- has_rdoc: false
145
+ has_rdoc: true
132
146
  homepage: http://github.com/citrus/spree_mail
133
147
  licenses: []
134
148
 
@@ -142,6 +156,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - ">="
144
158
  - !ruby/object:Gem::Version
159
+ hash: 104131697701234155
145
160
  segments:
146
161
  - 0
147
162
  version: "0"
@@ -150,13 +165,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
165
  requirements:
151
166
  - - ">="
152
167
  - !ruby/object:Gem::Version
168
+ hash: 104131697701234155
153
169
  segments:
154
170
  - 0
155
171
  version: "0"
156
172
  requirements: []
157
173
 
158
174
  rubyforge_project:
159
- rubygems_version: 1.3.7
175
+ rubygems_version: 1.5.0
160
176
  signing_key:
161
177
  specification_version: 3
162
178
  summary: Spree Mail adds mailing list signup and delivery features.