refinerycms-mailchimp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,80 @@
1
+ class Admin::CampaignsController < Admin::BaseController
2
+
3
+ crudify :campaign, :order => "updated_at desc", :sortable => false, :title_attribute => :subject
4
+
5
+ rescue_from Refinery::Mailchimp::API::BadAPIKeyError, :with => :need_api_key
6
+ rescue_from Hominid::APIError, :with => :need_api_key
7
+
8
+ before_filter :get_mailchimp_assets, :except => :index
9
+ before_filter :find_campaign, :except => [:index, :new, :create]
10
+
11
+ def new
12
+ @campaign = Campaign.new :to_name => RefinerySetting.get_or_set(Refinery::Mailchimp::API::DefaultToNameSetting[:name], Refinery::Mailchimp::API::DefaultToNameSetting[:default]),
13
+ :from_name => RefinerySetting.get_or_set(Refinery::Mailchimp::API::DefaultFromNameSetting[:name], Refinery::Mailchimp::API::DefaultFromNameSetting[:default]),
14
+ :from_email => RefinerySetting.get_or_set(Refinery::Mailchimp::API::DefaultFromEmailSetting[:name], Refinery::Mailchimp::API::DefaultFromEmailSetting[:default])
15
+ end
16
+
17
+ def send_options
18
+ end
19
+
20
+ def send_test
21
+ if @campaign.send_test_to params[:email]
22
+ flash[:notice] = t('admin.campaigns.campaign.send_test_success', :email => params[:email])
23
+ else
24
+ flash[:alert] = t('admin.campaigns.campaign.send_test_failure', :email => params[:email])
25
+ end
26
+ sending_redirect_to admin_campaigns_path
27
+ end
28
+
29
+ def send_now
30
+ if @campaign.send_now
31
+ flash[:notice] = t('admin.campaigns.campaign.send_now_success')
32
+ else
33
+ flash[:alert] = t('admin.campaigns.campaign.send_now_failure')
34
+ end
35
+ sending_redirect_to admin_campaigns_path
36
+ end
37
+
38
+ def schedule
39
+ if @campaign.schedule_for DateTime.new(*params['date'].values_at('year','month','day','hour','minute').map{|x|x.to_i})
40
+ flash[:notice] = t('admin.campaigns.campaign.schedule_success')
41
+ else
42
+ flash[:alert] = t('admin.campaigns.campaign.schedule_failure')
43
+ end
44
+ sending_redirect_to admin_campaigns_path
45
+ end
46
+
47
+ def unschedule
48
+ if @campaign.unschedule
49
+ flash[:notice] = t('admin.campaigns.campaign.unschedule_success')
50
+ else
51
+ flash[:alert] = t('admin.campaigns.campaign.unschedule_failure')
52
+ end
53
+ sending_redirect_to admin_campaigns_path
54
+ end
55
+
56
+ protected
57
+ def sending_redirect_to(path)
58
+ if from_dialog?
59
+ render :text => "<script>parent.window.location = '#{path}';</script>"
60
+ else
61
+ redirect_to path
62
+ end
63
+ end
64
+
65
+ def need_api_key
66
+ msg = t('admin.campaigns.index.set_api_key')
67
+ msg += " <a href=\"#{edit_admin_refinery_setting_path(RefinerySetting.find_by_name(Refinery::Mailchimp::API::KeySetting[:name]))}\" style=\"display:inline\">#{t('admin.campaigns.index.set_api_link')}</a>"
68
+ flash[:alert] = msg.html_safe
69
+ redirect_to admin_campaigns_path
70
+ end
71
+
72
+ def get_mailchimp_assets
73
+ @lists = client.lists['data']
74
+ @templates = client.templates['user']
75
+ end
76
+
77
+ def client
78
+ @client ||= Refinery::Mailchimp::API.new
79
+ end
80
+ end
@@ -0,0 +1,105 @@
1
+ class Campaign < ActiveRecord::Base
2
+
3
+ acts_as_indexed :fields => [:subject, :body]
4
+
5
+ validates_presence_of :subject, :body, :mailchimp_list_id, :from_email, :from_name, :to_name
6
+
7
+ before_save :update_mailchimp_campaign
8
+ before_create :create_mailchimp_campaign
9
+ before_destroy :delete_mailchimp_campaign
10
+
11
+ def sent?
12
+ !!sent_at || !!scheduled_at && scheduled_at <= Time.now
13
+ end
14
+
15
+ def scheduled?
16
+ !!scheduled_at && scheduled_at > Time.now
17
+ end
18
+
19
+ def sent
20
+ sent_at || scheduled_at
21
+ end
22
+
23
+ def send_test_to(*emails)
24
+ Refinery::Mailchimp::API.new.campaign_send_test mailchimp_campaign_id, emails
25
+ rescue Hominid::APIError
26
+ false
27
+ end
28
+
29
+ def send_now
30
+ success = Refinery::Mailchimp::API.new.campaign_send_now mailchimp_campaign_id
31
+ self.update_attribute :sent_at, Time.now if success
32
+ success
33
+ rescue Hominid::APIError
34
+ false
35
+ end
36
+
37
+ def schedule_for(datetime)
38
+ success = Refinery::Mailchimp::API.new.campaign_schedule mailchimp_campaign_id, datetime.utc.strftime("%Y-%m-%d %H:%M:%S")
39
+ self.update_attribute :scheduled_at, datetime if success
40
+ success
41
+ rescue Hominid::APIError
42
+ false
43
+ end
44
+
45
+ def unschedule
46
+ success = Refinery::Mailchimp::API.new.campaign_unschedule mailchimp_campaign_id
47
+ self.update_attribute :scheduled_at, nil if success
48
+ success
49
+ rescue Hominid::APIError
50
+ false
51
+ end
52
+
53
+ def google_analytics
54
+ RefinerySetting.find_or_set Refinery::Mailchimp::API::GoogleAnalyticsSetting[:name], Refinery::Mailchimp::API::GoogleAnalyticsSetting[:default]
55
+ end
56
+
57
+ protected
58
+
59
+ def create_mailchimp_campaign
60
+ options = { :subject => subject, :from_email => from_email, :from_name => from_name, :to_name => to_name, :list_id => mailchimp_list_id, :auto_tweet => auto_tweet }
61
+ options[:template_id] = mailchimp_template_id unless mailchimp_template_id.blank?
62
+ # options[:analytics] = { :google => google_analytics } unless google_analytics.blank?
63
+
64
+ self.mailchimp_campaign_id = begin
65
+ Refinery::Mailchimp::API.new.campaign_create 'regular', options, { content_key => body }
66
+ rescue Hominid::APIError
67
+ nil
68
+ end
69
+
70
+ return halt_with_mailchimp_error if self.mailchimp_campaign_id.blank?
71
+ end
72
+
73
+ def update_mailchimp_campaign
74
+ return if new_record?
75
+
76
+ client = Refinery::Mailchimp::API.new
77
+
78
+ options = {:title => :subject, :from_email => :from_email, :from_name => :from_name, :to_name => :to_name, :list_id => :mailchimp_list_id, :template_id => :mailchimp_template_id, :content => :body, :auto_tweet => :auto_tweet }
79
+ options.each_pair do |option_name, attribute|
80
+ if changed.include?(attribute.to_s)
81
+ success = client.campaign_update mailchimp_campaign_id, option_name, (option_name == :content ? { content_key => body } : self.send(attribute))
82
+ return halt_with_mailchimp_error unless success
83
+ end
84
+ end
85
+ end
86
+
87
+ def delete_mailchimp_campaign
88
+ success = begin
89
+ Refinery::Mailchimp::API.new.campaign_delete mailchimp_campaign_id
90
+ rescue Hominid::APIError
91
+ nil
92
+ end
93
+
94
+ return halt_with_mailchimp_error unless success
95
+ end
96
+
97
+ def halt_with_mailchimp_error
98
+ self.errors.add :base, I18n.t('admin.campaigns.campaign.mailchimp_error')
99
+ return false
100
+ end
101
+
102
+ def content_key
103
+ mailchimp_template_id.blank? ? :html : :html_MAIN
104
+ end
105
+ end
@@ -0,0 +1,22 @@
1
+ <li class='clearfix record <%= cycle("on", "on-hover") %>' id="<%= dom_id(campaign) -%>">
2
+ <span class='subject'>
3
+ <%= campaign.subject %>
4
+
5
+ <% if campaign.sent? %>
6
+ <span class="preview" title="<%= campaign.sent %>">sent <%= distance_of_time_in_words_to_now(campaign.sent) %> ago</span>
7
+ <% elsif campaign.scheduled? %>
8
+ <span class="preview" title="<%= campaign.scheduled_at %>">sending in <%= distance_of_time_in_words_to_now(campaign.scheduled_at) %></span>
9
+ <% end %>
10
+ </span>
11
+ <span class='actions'>
12
+ <%= link_to refinery_icon_tag("application_edit.png"), edit_admin_campaign_path(campaign),
13
+ :subject => t('.edit') %>
14
+ <%= link_to refinery_icon_tag("email_go.png"), send_options_admin_campaign_path(campaign, :dialog => true, :width => 725, :height => 525),
15
+ :title => t('send_dialog', :scope => 'admin.campaigns.campaign') %>
16
+ <%= link_to refinery_icon_tag("delete.png"), admin_campaign_path(campaign),
17
+ :class => "cancel confirm-delete",
18
+ :subject => t('.delete'),
19
+ :'data-confirm' => t('admin.campaigns.campaign.delete_confirmation', :subject => campaign.subject),
20
+ :'data-method' => :delete %>
21
+ </span>
22
+ </li>
@@ -0,0 +1,85 @@
1
+ <% form_for [:admin, @campaign] do |f| -%>
2
+ <%= render :partial => "/shared/admin/error_messages", :locals => {
3
+ :object => @campaign,
4
+ :include_object_name => true
5
+ } %>
6
+
7
+ <div class='field'>
8
+ <span class='label_with_help'>
9
+ <%= f.label :subject -%>
10
+ <%= refinery_help_tag t('.subject_help') %>
11
+ </span>
12
+ <%= f.text_field :subject, :class => 'larger widest' -%>
13
+ </div>
14
+
15
+ <div class='field'>
16
+ <%= f.label :body -%>
17
+ <%= f.text_area :body, :rows => 20, :class => 'wymeditor widest' -%>
18
+ </div>
19
+
20
+ <div class="hemisquare">
21
+ <h2><%= t('.to_and_from') %></h2>
22
+
23
+ <div class='field'>
24
+ <span class='label_with_help'>
25
+ <%= f.label :to_name, t('.to_name') -%>
26
+ <%= refinery_help_tag t('.to_name_help') %>
27
+ </span>
28
+ <%= f.text_field :to_name %>
29
+ </div>
30
+
31
+ <div class='field'>
32
+ <span class='label_with_help'>
33
+ <%= f.label :from_name, t('.from_name') -%>
34
+ <%= refinery_help_tag t('.from_name_help') %>
35
+ </span>
36
+ <%= f.text_field :from_name %>
37
+ </div>
38
+
39
+ <div class='field'>
40
+ <span class='label_with_help'>
41
+ <%= f.label :from_email, t('.from_email') -%>
42
+ <%= refinery_help_tag t('.from_email_help') %>
43
+ </span>
44
+ <%= f.text_field :from_email %>
45
+ </div>
46
+ </div>
47
+
48
+ <div class="hemisquare right_side">
49
+ <h2><%= t('.settings') %></h2>
50
+
51
+ <div class='field'>
52
+ <span class='label_with_help'>
53
+ <%= f.label :mailchimp_list_id, t('.mailchimp_list_id') -%>
54
+ <%= refinery_help_tag t('.mailchimp_list_id_help') %>
55
+ </span>
56
+ <%= f.select :mailchimp_list_id, @lists.collect{ |list| [list['name'], list['id']] } %>
57
+ </div>
58
+
59
+ <div class='field'>
60
+ <span class='label_with_help'>
61
+ <%= f.label :mailchimp_template_id, t('.mailchimp_template_id') -%>
62
+ <%= refinery_help_tag t('.mailchimp_template_id_help') %>
63
+ </span>
64
+ <%= f.select :mailchimp_template_id, @templates.collect{ |template| [template['name'], template['id']] }, :include_blank => true %>
65
+ </div>
66
+
67
+ <div class='field'>
68
+ <span class='label_with_help'>
69
+ <%= f.label :auto_tweet, t('.auto_tweet') -%>
70
+ <%= refinery_help_tag t('.auto_tweet_help') %>
71
+ </span>
72
+ <%= f.check_box :auto_tweet %>
73
+ </div>
74
+ </div>
75
+
76
+ <div class="clearfix"></div>
77
+
78
+ <%= render :partial => "/shared/admin/form_actions",
79
+ :locals => {
80
+ :f => f,
81
+ :continue_editing => false,
82
+ :delete_subject => t('admin.campaigns.campaign.delete'),
83
+ :delete_confirmation => t('admin.campaigns.campaign.delete_confirmation', :subject => @campaign.subject)
84
+ } %>
85
+ <% end -%>
@@ -0,0 +1,4 @@
1
+ <% if from_dialog? %>
2
+ <input type='hidden' name='modal' value='true' />
3
+ <input type='hidden' name='dialog' value='true' />
4
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <ul id='sortable_list'>
2
+ <%= render :partial => 'campaign', :collection => @campaigns %>
3
+ </ul>
4
+ <%= render :partial => "/shared/admin/sortable_list", :locals => {:continue_reordering => (defined?(continue_reordering) ? continue_reordering : true)} %>
@@ -0,0 +1 @@
1
+ <%= render :partial => "form" %>
@@ -0,0 +1,49 @@
1
+ <div id='actions'>
2
+ <ul>
3
+ <% if Admin::CampaignsController.searchable? %>
4
+ <li>
5
+ <%= render :partial => "/shared/admin/search",
6
+ :locals => {
7
+ :url => admin_campaigns_url
8
+ } %>
9
+ </li>
10
+ <% end %>
11
+ <li>
12
+ <%= link_to t('.create_new'), new_admin_campaign_url,
13
+ :class => "add_icon" %>
14
+ </li>
15
+ </ul>
16
+ </div>
17
+ <div id='records'>
18
+ <% if searching? %>
19
+ <h2><%= t('shared.admin.search.results_for', :query => params[:search]) %></h2>
20
+ <% if @campaigns.any? %>
21
+ <%= will_paginate @campaigns, :previous_label => '&laquo;', :next_label => '&raquo;' %>
22
+ <ul>
23
+ <%= render :partial => "campaign",
24
+ :collection => @campaigns %>
25
+ </ul>
26
+ <%= will_paginate @campaigns, :previous_label => '&laquo;', :next_label => '&raquo;' %>
27
+ <% else %>
28
+ <p><%= t('shared.admin.search.no_results') %></p>
29
+ <% end %>
30
+ <% else %>
31
+ <% if @campaigns.any? %>
32
+ <%= will_paginate @campaigns,
33
+ :previous_label => '&laquo;',
34
+ :next_label => '&raquo;' %>
35
+
36
+ <%= render :partial => "sortable_list" %>
37
+
38
+ <%= will_paginate @campaigns,
39
+ :previous_label => '&laquo;',
40
+ :next_label => '&raquo;' %>
41
+ <% else %>
42
+ <p>
43
+ <strong>
44
+ <%= t('.no_items_yet') %>
45
+ </strong>
46
+ </p>
47
+ <% end %>
48
+ <% end %>
49
+ </div>
@@ -0,0 +1 @@
1
+ <%= render :partial => "form" %>
@@ -0,0 +1,40 @@
1
+ <% if @campaign.sent? %>
2
+ <h2>Sent</h2>
3
+ <p>
4
+ This campaign was sent <strong title="<%= @campaign.sent_at %>"><%= distance_of_time_in_words_to_now(@campaign.sent_at) %> ago</strong>.
5
+ </p>
6
+ <% elsif @campaign.scheduled? %>
7
+ <h2>Scheduled</h2>
8
+ <p>
9
+ This campaign is scheduled to be sent in <strong title="<%= @campaign.scheduled_at %>"><%= distance_of_time_in_words_to_now(@campaign.scheduled_at) %></strong>.
10
+ </p>
11
+ <%= form_tag unschedule_admin_campaign_path(@campaign) do -%>
12
+ <%= render :partial => "modal_fields" %>
13
+ <%= submit_tag "Unschedule Campaign"%>
14
+ <% end %>
15
+ <% else %>
16
+ <h2>Send Test Email</h2>
17
+ <p>This will send a test email to the email address you enter below.</p>
18
+ <%= form_tag send_test_admin_campaign_path(@campaign) do -%>
19
+ <%= render :partial => "modal_fields" %>
20
+ <%= label_tag :email %>
21
+ <%= text_field_tag :email, current_user.email %>
22
+ <%= submit_tag "Send Test" %>
23
+ <% end %>
24
+
25
+ <h2>Send Campaign Now</h2>
26
+ <p>This will send the campaign.</p>
27
+ <%= form_tag send_now_admin_campaign_path(@campaign) do -%>
28
+ <%= render :partial => "modal_fields" %>
29
+ <%= submit_tag "Send Now"%>
30
+ <% end %>
31
+
32
+ <h2>Schedule Campaign for Later</h2>
33
+ <p>This will schedule the campaign to be sent automatically at a future date.</p>
34
+ <%= form_tag schedule_admin_campaign_path(@campaign) do -%>
35
+ <%= render :partial => "modal_fields" %>
36
+ <%= label_tag :send_at %>
37
+ <%= select_datetime %>
38
+ <%= submit_tag "Schedule Campaign"%>
39
+ <% end %>
40
+ <% end %>
@@ -0,0 +1,60 @@
1
+ en:
2
+ shared:
3
+ admin:
4
+ image_picker:
5
+ image: image
6
+ plugins:
7
+ campaigns:
8
+ title: Campaigns
9
+ admin:
10
+ refinery_settings:
11
+ form:
12
+ help:
13
+ mailchimp_api_key: "Get your API key from your Mailchimp dashboard by choosing 'Account' and then 'API Keys & Info.'"
14
+ mailchimp_default_to_name: "The default To: name recipients will see (not email address). This can be changed for each campaign."
15
+ mailchimp_default_from_name: "The default From: name for your campaign message (not an email address). This can be changed for each campaign."
16
+ mailchimp_default_from_email: "The default From: email address for your campaign message. This can be changed for each campaign."
17
+ mailchimp_admin_base_url: The base URL of your Mailchimp admin area. This is used to generate links to your campaigns for convenience. Only change it if you know what you're doing.
18
+ campaigns:
19
+ index:
20
+ create_new: Create a new Campaign
21
+ reorder: Reorder Campaigns
22
+ reorder_done: Done Reordering Campaigns
23
+ sorry_no_results: Sorry! There are no results found.
24
+ no_items_yet: There are no Campaigns yet. Click "Create a new Campaign" to add your first campaign.
25
+ set_api_key: You must set a valid Mailchimp API key.
26
+ set_api_link: Click here to update your key.
27
+ campaign:
28
+ view_live: View this campaign live <br/><em>(opens in a new window)</em>
29
+ edit: Edit this campaign
30
+ delete: Remove this campaign forever
31
+ delete_confirmation: "Are you sure you want to remove '%{subject}'?"
32
+ mailchimp_error: "Could not save to Mailchimp! Please make sure your API key is right and that you are using a good 'From' email address."
33
+ send_dialog: "Send, schedule, or test this campaign"
34
+ send_test_success: Test email successfully sent to %{email}.
35
+ send_test_failure: Test email could not be sent to %{email}. Please check the email address.
36
+ send_now_success: The campaign was successfully sent!
37
+ send_now_failure: The campaign could not be sent. Please check in Mailchimp to make sure everything is ok.
38
+ schedule_success: The campaign was successfully scheduled.
39
+ schedule_failure: The campaign could not be scheduled. Please check in Mailchimp to make sure everything is ok.
40
+ unschedule_success: The campaign was successfully unscheduled.
41
+ unschedule_failure: The campaign could not be unscheduled. Please check in Mailchimp to make sure everything is ok.
42
+ form:
43
+ to_and_from: To and From
44
+ settings: Settings
45
+ subject_help: The subject line that will be used for the campaign emails.
46
+ mailchimp_list_id: Mailing List
47
+ mailchimp_list_id_help: The mailing list to send this campaign to. These are managed in Mailchimp.
48
+ mailchimp_template_id: Template
49
+ mailchimp_template_id_help: The HTML template to use for this campaign. These are managed in Mailchimp.
50
+ to_name: To Name
51
+ to_name_help: "The To: name recipients will see (not email address). You can change the default in Settings."
52
+ from_name: From Name
53
+ from_name_help: "The From: name for your campaign message (not an email address). You can change the default in Settings."
54
+ from_email: From Email
55
+ from_email_help: "The From: email address for your campaign message. You can change the default in Settings."
56
+ auto_tweet: Auto Tweet
57
+ auto_tweet_help: Automatically tweet about this campaign when sent. Requires setting up Twitter from Mailchimp.
58
+ campaigns:
59
+ show:
60
+ other: Other Campaigns
@@ -0,0 +1,19 @@
1
+ nb:
2
+ plugins:
3
+ refinerycms_mailchimp:
4
+ title: Campaigns
5
+ admin:
6
+ campaigns:
7
+ index:
8
+ create_new: Lag en ny Campaign
9
+ reorder: Endre rekkefølgen på Campaigns
10
+ reorder_done: Ferdig å endre rekkefølgen Campaigns
11
+ sorry_no_results: Beklager! Vi fant ikke noen resultater.
12
+ no_items_yet: Det er ingen Campaigns enda. Klikk på "Lag en ny Campaign" for å legge til din første campaign.
13
+ campaign:
14
+ view_live: Vis hvordan denne campaign ser ut offentlig <br/><em>(åpner i et nytt vindu)</em>
15
+ edit: Rediger denne campaign
16
+ delete: Fjern denne campaign permanent
17
+ campaigns:
18
+ show:
19
+ other: Andre Campaigns
@@ -0,0 +1,19 @@
1
+ nl:
2
+ plugins:
3
+ refinerycms_mailchimp:
4
+ title: Campaigns
5
+ admin:
6
+ campaigns:
7
+ index:
8
+ create_new: Maak een nieuwe Campaign
9
+ reorder: Wijzig de volgorde van de Campaigns
10
+ reorder_done: Klaar met het wijzingen van de volgorde van de Campaigns
11
+ sorry_no_results: Helaas! Er zijn geen resultaten gevonden.
12
+ no_items_yet: Er zijn nog geen Campaigns. Druk op 'Maak een nieuwe Campaign' om de eerste aan te maken.
13
+ campaign:
14
+ view_live: Bekijk deze campaign op de website <br/><em>(opent een nieuw venster)</em>
15
+ edit: Bewerk deze campaign
16
+ delete: Verwijder deze campaign voor eeuwig
17
+ campaigns:
18
+ show:
19
+ other: Andere Campaigns
data/config/routes.rb ADDED
@@ -0,0 +1,13 @@
1
+ Refinery::Application.routes.draw do
2
+ scope(:path => 'refinery', :as => 'admin', :module => 'admin') do
3
+ resources :campaigns do
4
+ member do
5
+ get :send_options
6
+ post :send_test
7
+ post :send_now
8
+ post :schedule
9
+ post :unschedule
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ class CreateCampaigns < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ create_table :campaigns do |t|
5
+ t.string :subject, :mailchimp_campaign_id, :mailchimp_list_id, :mailchimp_template_id, :from_email, :from_name, :to_name
6
+ t.text :body
7
+ t.datetime :sent_at, :scheduled_at
8
+ t.boolean :auto_tweet, :default => false
9
+ t.timestamps
10
+ end
11
+
12
+ add_index :campaigns, :id
13
+
14
+ load(Rails.root.join('db', 'seeds', 'campaigns.rb'))
15
+ end
16
+
17
+ def self.down
18
+ UserPlugin.destroy_all({:name => "Campaigns"})
19
+
20
+ Page.delete_all({:link_url => "/campaigns"})
21
+
22
+ drop_table :campaigns
23
+ end
24
+
25
+ end
@@ -0,0 +1,10 @@
1
+ User.find(:all).each do |user|
2
+ user.plugins.create(:name => "campaigns",
3
+ :position => (user.plugins.maximum(:position) || -1) +1)
4
+ end
5
+
6
+ RefinerySetting.create :name => Refinery::Mailchimp::API::KeySetting[:name], :value => Refinery::Mailchimp::API::KeySetting[:default], :restricted => true
7
+ RefinerySetting.create :name => Refinery::Mailchimp::API::DefaultFromNameSetting[:name], :value => Refinery::Mailchimp::API::DefaultFromNameSetting[:default], :restricted => true
8
+ RefinerySetting.create :name => Refinery::Mailchimp::API::DefaultFromEmailSetting[:name], :value => Refinery::Mailchimp::API::DefaultFromEmailSetting[:default], :restricted => true
9
+ RefinerySetting.create :name => Refinery::Mailchimp::API::DefaultToNameSetting[:name], :value => Refinery::Mailchimp::API::DefaultToNameSetting[:default], :restricted => true
10
+
@@ -0,0 +1,15 @@
1
+ @campaign
2
+ Feature: Campaigns
3
+ Campaigns can be created through the given user model
4
+ current_user is assumed through admin screens
5
+
6
+ Scenario: Saving a campaign is successful
7
+ Given I am a logged in refinery user
8
+
9
+ When I am on the new campaign form
10
+ And I fill in "Subject" with "This is my campaign"
11
+ And I fill in "Body" with "And I love it"
12
+ And I press "Save"
13
+
14
+ Then there should be 1 campaign
15
+ And the campaign should belong to me
@@ -0,0 +1,8 @@
1
+ Factory.define(:campaign) do |f|
2
+ f.sequence(:subject) { |n| "See our #{n} newest site additions!" }
3
+ f.body "Here's a campaign body!"
4
+ f.to_name "Jimmy"
5
+ f.from_name "Johnny"
6
+ f.from_email "Johnson"
7
+ f.mailchimp_list_id "ah23jxj"
8
+ end
@@ -0,0 +1,24 @@
1
+ module NavigationHelpers
2
+ module Refinery
3
+ module Mailchimp
4
+ def path_to(page_name)
5
+ case page_name
6
+ when /the list of campaigns/
7
+ admin_campaigns_path
8
+ when /the new campaigns? form/
9
+ new_admin_campaign_path
10
+ else
11
+ begin
12
+ if page_name =~ /the campaign subjectd "?([^\"]*)"?/ and (page = Campaign.find_by_subject($1)).present?
13
+ self.url_for(page.url)
14
+ else
15
+ nil
16
+ end
17
+ rescue
18
+ nil
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ require 'refinery/generators'
2
+
3
+ class RefinerycmsMailchimp < Refinery::Generators::EngineInstaller
4
+
5
+ source_root File.expand_path('../../../', __FILE__)
6
+ engine_name "refinerycms-mailchimp"
7
+
8
+ end
@@ -0,0 +1,39 @@
1
+ require 'refinery'
2
+ require 'hominid'
3
+
4
+ module Refinery
5
+ module Mailchimp
6
+ class Engine < Rails::Engine
7
+ initializer "static assets" do |app|
8
+ app.middleware.insert_after ::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public"
9
+ end
10
+
11
+ config.after_initialize do
12
+ Refinery::Plugin.register do |plugin|
13
+ plugin.name = "campaigns"
14
+ plugin.activity = {:class => Campaign,}
15
+ end
16
+ end
17
+ end
18
+
19
+ class API < Hominid::API
20
+ KeySetting = { :name => "mailchimp_api_key", :default => "Set me!" }
21
+ DefaultFromNameSetting = { :name => "mailchimp_default_from_name", :default => "" }
22
+ DefaultFromEmailSetting = { :name => "mailchimp_default_from_email", :default => "" }
23
+ DefaultToNameSetting = { :name => "mailchimp_default_to_name", :default => "" }
24
+
25
+ class BadAPIKeyError < StandardError; end
26
+
27
+ def initialize
28
+ api_key = RefinerySetting.get_or_set KeySetting[:name], KeySetting[:default]
29
+ raise BadAPIKeyError if api_key.blank? || api_key == KeySetting[:default]
30
+
31
+ begin
32
+ super api_key
33
+ rescue ArgumentError
34
+ raise BadAPIKeyError
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ namespace :refinery do
2
+
3
+ namespace :mailchimp do
4
+
5
+ # call this task my running: rake refinery:campaigns:my_task
6
+ # desc "Description of my task below"
7
+ # task :my_task => :environment do
8
+ # # add your logic here
9
+ # end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ Dir[File.expand_path('../../../../features/support/factories/*.rb', __FILE__)].each{|factory| require factory}
3
+
4
+ describe Admin::CampaignsController do
5
+ describe "getting lists and templates" do
6
+ it "should get lists and templates on new"
7
+ it "should get lists and templates on create"
8
+ end
9
+
10
+ describe "creating a campaign" do
11
+ it "should redirect to index with flash message if API is not set up"
12
+ end
13
+
14
+ describe "sending the campaign" do
15
+ it "should send a test email"
16
+ it "should send the campaign now"
17
+ it "should schedule the campaign to send in the future"
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'hominid'
3
+
4
+ Dir[File.expand_path('../../../features/support/factories/*.rb', __FILE__)].each{|factory| require factory}
5
+
6
+ describe Refinery::Mailchimp::API do
7
+ describe "the client" do
8
+ before do
9
+ RefinerySetting.find_by_name(Refinery::Mailchimp::API::KeySetting[:name]).try :destroy
10
+ RefinerySetting.rewrite_cache
11
+ end
12
+
13
+ it "should give a properly setup client if the API key is set" do
14
+ RefinerySetting.set Refinery::Mailchimp::API::KeySetting[:name], 'abcdefg-us1'
15
+ Refinery::Mailchimp::API.new
16
+ end
17
+
18
+ it "should raise an error if the API key is not set" do
19
+ begin
20
+ client = Refinery::Mailchimp::API.new
21
+ fail
22
+ rescue Refinery::Mailchimp::API::BadAPIKeyError
23
+ end
24
+ end
25
+
26
+ it "should raise an error if the API key is malformed" do
27
+ begin
28
+ RefinerySetting.set Refinery::Mailchimp::API::KeySetting[:name], 'abcdefg'
29
+ client = Refinery::Mailchimp::API.new
30
+ fail
31
+ rescue Refinery::Mailchimp::API::BadAPIKeyError
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ Dir[File.expand_path('../../../features/support/factories/*.rb', __FILE__)].each{|factory| require factory}
3
+
4
+ describe Campaign do
5
+ describe "validations" do
6
+ it "should be valid with valid attributes" do
7
+ Factory.build(:campaign).should be_valid
8
+ end
9
+
10
+ it "requires subject" do
11
+ Factory.build(:campaign, :subject => "").should_not be_valid
12
+ end
13
+
14
+ it "requires a body" do
15
+ Factory.build(:campaign, :body => "").should_not be_valid
16
+ end
17
+ end
18
+
19
+ describe "integrating with Mailchimp" do
20
+ it "should save to mailchimp before create" do
21
+ campaign = Factory.build(:campaign)
22
+ campaign.mailchimp_campaign_id.should be_nil
23
+
24
+ Refinery::Mailchimp::API.should_receive(:new).and_return(mock('api', :campaign_create => 'abcdef'))
25
+ campaign.save
26
+ campaign.reload.mailchimp_campaign_id.should == 'abcdef'
27
+ end
28
+
29
+ it "should not create and add error if mailchimp create fails" do
30
+ campaign = Factory.build(:campaign)
31
+ mock_api = mock('api')
32
+ mock_api.stub(:campaign_create) { |*args| raise Hominid::APIError.new(mock('xmlerror', :faultCode => -32602, :message => "server error. invalid method parameters")) }
33
+ Refinery::Mailchimp::API.should_receive(:new).and_return(mock_api)
34
+ campaign.save.should be_false
35
+ campaign.errors[:base].should include(I18n.t('admin.campaigns.campaign.mailchimp_error'))
36
+ end
37
+
38
+ it "should update mailchimp before save"
39
+ it "should not save if mailchimp update fails"
40
+ it "should know if it's been sent or scheduled"
41
+ it "should know where it was sent to"
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: refinerycms-mailchimp
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ian Terrell
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-04 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: hominid
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 3
32
+ - 0
33
+ version: "3.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description: Ruby on Rails Mailchimp engine for Refinery CMS. Manage your campaigns right from the admin!
37
+ email: ian.terrell@gmail.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - lib/generators/refinerycms_mailchimp_generator.rb
46
+ - lib/refinerycms-mailchimp.rb
47
+ - lib/tasks/mailchimp.rake
48
+ - config/locales/en.yml
49
+ - config/locales/nb.yml
50
+ - config/locales/nl.yml
51
+ - config/routes.rb
52
+ - app/controllers/admin/campaigns_controller.rb
53
+ - app/models/campaign.rb
54
+ - app/views/admin/campaigns/_campaign.html.erb
55
+ - app/views/admin/campaigns/_form.html.erb
56
+ - app/views/admin/campaigns/_modal_fields.html.erb
57
+ - app/views/admin/campaigns/_sortable_list.html.erb
58
+ - app/views/admin/campaigns/edit.html.erb
59
+ - app/views/admin/campaigns/index.html.erb
60
+ - app/views/admin/campaigns/new.html.erb
61
+ - app/views/admin/campaigns/send_options.html.erb
62
+ - spec/controllers/admin/campaigns_controller_spec.rb
63
+ - spec/models/api_spec.rb
64
+ - spec/models/campaign_spec.rb
65
+ - features/campaigns.feature_brainstorm
66
+ - features/support/factories/campaigns.rb
67
+ - features/support/paths.rb
68
+ - db/migrate/1_create_campaigns.rb
69
+ - db/seeds/campaigns.rb
70
+ has_rdoc: true
71
+ homepage: https://github.com/ianterrell/refinerycms-mailchimp
72
+ licenses: []
73
+
74
+ post_install_message:
75
+ rdoc_options: []
76
+
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 1.5.2
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Ruby on Rails Mailchimp engine for Refinery CMS
104
+ test_files: []
105
+