refinerycms-mailchimp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+