Skip to content

Commit

Permalink
spree_mail_chimp
Browse files Browse the repository at this point in the history
  • Loading branch information
bzt committed Nov 22, 2010
1 parent e16fa05 commit 6a4708b
Show file tree
Hide file tree
Showing 18 changed files with 322 additions and 124 deletions.
18 changes: 12 additions & 6 deletions README.textile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ The SimpleModal plugin is used in the EJB to pop up a confirmation or error aler
h3. Installation ###

<pre><code>
./script/extension install git://github.com/sbeam/spree-mail-chimp.git
./script/extension install git://github.com/bzt/spree_mail_chimp.git

rake mail_chimp:install

add path to gemfile

bundle install

rake db:migrate
</code> </pre>
Expand All @@ -28,26 +34,26 @@ Look at <code>config/initializers/mail_chimp_settings.rb</code> - copy this to y

h3. Changes ###

Version 1.0 - released 8 Nov 2010
Version 1.0.1 - released 21 Nov 2010

h3. Requirements ###

Spree =~ 0.11.99 (not 0.30, yet)
Spree >= 0.3.0
hominid >= 2.2.0 http://rubygems.org/gems/hominid

Also uses the jQuery SimpleModal plugin, included.

h3. Credits ###

Authored by Sam Beam [email protected]
Authored by bzt [email protected]

Inspired originally by Mailee Spree https://github.com/softa/mailee_spree
Inspired originally by https://github.com/softa/mailee_spree

includes SimpleModal http://www.ericmmartin.com/projects/simplemodal/

h3. TODO ###

* Make Rails 3/Spree 0.30 compat
* make subscribe_to_newsletter_field work
* Export new orders to Mailchimp for full CRM gnarliness
* Utility to export existing users to Mailchimp
* Add admin controller to view lists and subscriptions
Expand Down
54 changes: 22 additions & 32 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,41 +1,31 @@
require File.expand_path('../../config/application', __FILE__)

require 'rubygems'
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/packagetask'
require 'rake/gempackagetask'

desc 'Default: run unit tests.'
task :default => :test
spec = eval(File.read('mail_chimp.gemspec'))

desc 'Test the mail_chimp extension.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
Rake::GemPackageTask.new(spec) do |p|
p.gem_spec = spec
end

namespace :test do
desc 'Functional test the mail_chimp extension.'
Rake::TestTask.new(:functionals) do |t|
t.libs << 'lib'
t.pattern = 'test/functional/*_test.rb'
t.verbose = true
end

desc 'Unit test the mail_chimp extension.'
Rake::TestTask.new(:units) do |t|
t.libs << 'lib'
t.pattern = 'test/unit/*_test.rb'
t.verbose = true
end
desc "Release to gemcutter"
task :release => :package do
require 'rake/gemcutter'
Rake::Gemcutter::Tasks.new(spec).define
Rake::Task['gem:push'].invoke
end

desc 'Generate documentation for the mail_chimp extension.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'MailChimpExtension'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README.markdown')
rdoc.rdoc_files.include('lib/**/*.rb')
end
desc "Default Task"
task :default => [:spec]

require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new

# Load any custom rakefiles for extension
Dir[File.dirname(__FILE__) + '/lib/tasks/*.rake'].sort.each { |f| require f }
# require 'cucumber/rake/task'
# Cucumber::Rake::Task.new do |t|
# t.cucumber_opts = %w{--format pretty}
# end
4 changes: 1 addition & 3 deletions app/helpers/mail_chimp_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
module MailChimpHelper


def subscribe addr
def subscribe addr
end
end
2 changes: 1 addition & 1 deletion app/views/shared/_newsletter_subscribe_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<%= text_field_tag :email, t('enter_your_email'), :class=>'email', :id=>'subscribe_email' %>
</td>
<td>
<%= submit_tag t('submit'), :type=>'image',:src=>'/images/btn.submit1.gif',:id => 'op_subscribe' %>
<%= submit_tag t('submit'), :type=>'image',:src=>'/images/btn.submit1.gif', :id => 'op_subscribe' %>
</td>
</tr>
</table>
Expand Down
5 changes: 5 additions & 0 deletions app/views/shared/_newsletter_subscribe_form_wo_butt.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div id="mailchimp_subscribe_wrap">
<% form_for :user, :url => :subscriptions do |f| %>
<%= text_field_tag :email, t('enter_your_email'), :class=>'email', :id=>'subscribe_email' %>
<% end %>
</div>
3 changes: 2 additions & 1 deletion app/views/users/_subscribe_to_newsletter_field.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<p class="login_newsletter_subscribe">
<%= check_box :user, :is_mail_list_subscriber, :class => 'title', :checked=>'checked' %> <%= label :user, :is_mail_list_subscriber, t(:do_subscribe_to_our_mailing_list) %>
<%= check_box :user, :is_mail_list_subscriber, :class => 'title', :checked=>'checked' %>
<%= label :user, :is_mail_list_subscriber, t(:do_subscribe_to_our_mailing_list) %>
</p>
4 changes: 2 additions & 2 deletions config/initializers/mail_chimp_settings.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
if Spree::Config.instance
Spree::Config.set(:mailchimp_api_key => '29fac3ec027eb71badafce2b1edb72b0-us2')
Spree::Config.set(:mailchimp_list_id => '6ec957aa45')
Spree::Config.set(:mailchimp_api_key => '22c511cd11f94a3a65a542e3fd419aef-us2')
Spree::Config.set(:mailchimp_list_id => 'ece35ed568')
Spree::Config.set(:mailchimp_subscription_opts => {:email_type => 'html', :secure => true, :double_opt_in => true})
end

Expand Down
8 changes: 8 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
Rails.application.routes.draw do

resources :subscriptions, :only => :create
#resources :sync, :only => :create_in_mailchimp
#resources :subscriptions do
# resources :sync, :only => :create_in_mailchimp
#end

end
100 changes: 24 additions & 76 deletions lib/mail_chimp.rb
Original file line number Diff line number Diff line change
@@ -1,84 +1,32 @@
module MailChimp
module Sync

def self.included(target)
target.class_eval do
after_filter :create_in_mailchimp, :only => [:create]
after_filter :update_in_mailchimp, :only => [:update]
destroy.after :remove_from_mailchimp # can use r_c?

def hominid
@hominid ||= Hominid::Base.new({:api_key => Spree::Config.get(:mailchimp_api_key)})
end

def mc_list_id
Spree::Config.get(:mailchimp_list_id)
end
end
end

def create_in_mailchimp
return unless @user.is_mail_list_subscriber

User.benchmark "Adding mailchimp subscriber (list id=#{mc_list_id})" do
hominid.subscribe(mc_list_id, @user.email, Spree::Config.get(:mailchimp_subscription_opts))
end
logger.debug "Fetching new mailchimp subscriber info"
mc_member = hominid.member_info(mc_list_id, @user.email)
logger.debug mc_member.inspect
@user.mailchimp_subscriber_id = mc_member['id']
@user.save # this probably isn't kosher in an after-filter method
rescue
# TODO alert someone there is a problem with mailchimp
logger.warn "MailChimp::Sync: Failed to create contact #{id} in mailchimp: #{$1}"
end

# run before_update, but we don't want to do this everytime
# spree/authlogic update the user's timestamps. So need to detect if
# subscription checkbox is set, that means it was the user editing form.
def update_in_mailchimp

if params && params[:user] && params[:user][:is_mail_list_subscriber] # works if not checked because 0 is true
require 'spree_core'
require 'mail_chimp_hooks'
require 'mail_chimp_sync'
require 'hominid'

if params[:user][:is_mail_list_subscriber].to_i.equal?(1) && !@user.mailchimp_subscriber_id.blank?
User.benchmark "Updating mailchimp subscriber (list id=#{mc_list_id}, member=#{@user.mailchimp_subscriber_id})" do
hominid.update_member(mc_list_id, @user.mailchimp_subscriber_id, {:EMAIL => @user.email})
end
elsif params[:user][:is_mail_list_subscriber].to_i.equal?(1) && @user.mailchimp_subscriber_id.blank?
create_in_mailchimp
elsif params[:user][:is_mail_list_subscriber].to_i.zero? && !@user.mailchimp_subscriber_id.blank?
remove_from_mailchimp
end

end
rescue
logger.warn "MailChimp::Sync: Failed to update mailchimp record for user id=#{@user.id}"
end

def remove_from_mailchimp
module MailChimp
class Engine < Rails::Engine

if @user.mailchimp_subscriber_id
@user.mailchimp_subscriber_id = nil
@user.save
User.benchmark "removing subscriber #{@user.mailchimp_subscriber_id} from mailchimp" do
hominid.unsubscribe(mc_list_id, @user.email)
end
end
rescue
logger.warn "MailChimp::Sync: could not remove user id=#{@user.id} from Mailchimp"
def activate

def self.activate
Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
Rails.env.production? ? require(c) : load(c)
end



Spree::BaseController.class_eval do
helper MailChimpHelper
end
UsersController.send(:include, MailChimpSync::Sync)

User.class_eval do
attr_accessible :is_mail_list_subscriber
end




end
config.autoload_paths += %W(#{config.root}/lib)
config.to_prepare &method(:activate).to_proc
end
end
end


8 changes: 8 additions & 0 deletions lib/mail_chimp_hooks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class MailChimpHooks < Spree::ThemeSupport::HookListener
insert_after :signup_below_password_fields, 'users/subscribe_to_newsletter_field'
#insert_after :inside_head, 'shared/newsletter_subscribe_form'
# Add js for ajaxy subscriptions from footer or wherever
insert_after :inside_head do
"<%= javascript_include_tag 'jquery.simplemodal.1.4.min.js','mailchimp_subscribe' %>"
end
end
73 changes: 73 additions & 0 deletions lib/mail_chimp_sync.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
module MailChimpSync #< Spree::BaseController
module Sync

def self.included(target)
target.class_eval do
after_filter :create_in_mailchimp, :only => [:create]
after_filter :update_in_mailchimp, :only => [:update]
destroy.after :remove_from_mailchimp # can use r_c?

def hominid
@hominid ||= Hominid::Base.new({:api_key => Spree::Config.get(:mailchimp_api_key)})
end

def mc_list_id
Spree::Config.get(:mailchimp_list_id)
end
end
end

def create_in_mailchimp
return unless @user.is_mail_list_subscriber

User.benchmark "Adding mailchimp subscriber (list id=#{mc_list_id})" do
hominid.subscribe(mc_list_id, @user.email, Spree::Config.get(:mailchimp_subscription_opts))
end
logger.debug "Fetching new mailchimp subscriber info"
mc_member = hominid.member_info(mc_list_id, @user.email)
logger.debug mc_member.inspect
@user.mailchimp_subscriber_id = mc_member['id']
@user.save # this probably isn't kosher in an after-filter method
rescue
# TODO alert someone there is a problem with mailchimp
logger.warn "MailChimp::Sync: Failed to create contact #{id} in mailchimp: #{$1}"
end

# run before_update, but we don't want to do this everytime
# spree/authlogic update the user's timestamps. So need to detect if
# subscription checkbox is set, that means it was the user editing form.
def update_in_mailchimp

if params && params[:user] && params[:user][:is_mail_list_subscriber] # works if not checked because 0 is true

if params[:user][:is_mail_list_subscriber].to_i.equal?(1) && !@user.mailchimp_subscriber_id.blank?
User.benchmark "Updating mailchimp subscriber (list id=#{mc_list_id}, member=#{@user.mailchimp_subscriber_id})" do
hominid.update_member(mc_list_id, @user.mailchimp_subscriber_id, {:EMAIL => @user.email})
end
elsif params[:user][:is_mail_list_subscriber].to_i.equal?(1) && @user.mailchimp_subscriber_id.blank?
create_in_mailchimp
elsif params[:user][:is_mail_list_subscriber].to_i.zero? && !@user.mailchimp_subscriber_id.blank?
remove_from_mailchimp
end

end
rescue
logger.warn "MailChimp::Sync: Failed to update mailchimp record for user id=#{@user.id}"
end

def remove_from_mailchimp

if @user.mailchimp_subscriber_id
@user.mailchimp_subscriber_id = nil
@user.save
User.benchmark "removing subscriber #{@user.mailchimp_subscriber_id} from mailchimp" do
hominid.unsubscribe(mc_list_id, @user.email)
end
end
rescue
logger.warn "MailChimp::Sync: could not remove user id=#{@user.id} from Mailchimp"
end


end
end
10 changes: 10 additions & 0 deletions lib/spree/mail-chimp/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Spree::MailChimp
class Config < Spree::Config
class << self
def instance
return nil unless ActiveRecord::Base.connection.tables.include?('configurations')
MailChimpConfiguration.find_or_create_by_name("MailChimp configuration")
end
end
end
end
26 changes: 26 additions & 0 deletions lib/tasks/install.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace :mail_chimp do
desc "Copies all migrations and assets (NOTE: This will be obsolete with Rails 3.1)"
task :install do
Rake::Task['mail_chimp:install:migrations'].invoke
Rake::Task['mail_chimp:install:assets'].invoke
end

namespace :install do
desc "Copies all migrations (NOTE: This will be obsolete with Rails 3.1)"
task :migrations do
source = File.join(File.dirname(__FILE__), '..', '..', 'db')
destination = File.join(Rails.root, 'db')
puts "INFO: Mirroring assets from #{source} to #{destination}"
Spree::FileUtilz.mirror_files(source, destination)
end

desc "Copies all assets (NOTE: This will be obsolete with Rails 3.1)"
task :assets do
source = File.join(File.dirname(__FILE__), '..', '..', 'public')
destination = File.join(Rails.root, 'public')
puts "INFO: Mirroring assets from #{source} to #{destination}"
Spree::FileUtilz.mirror_files(source, destination)
end
end

end
Loading

0 comments on commit 6a4708b

Please sign in to comment.