alchemy_crm 2.0.0
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.
- data/.gitignore +22 -0
- data/.travis.yml +12 -0
- data/Gemfile +21 -0
- data/Guardfile +13 -0
- data/LICENSE +24 -0
- data/README.md +82 -0
- data/Rakefile +27 -0
- data/alchemy_crm.gemspec +31 -0
- data/app/assets/images/.DS_Store +0 -0
- data/app/assets/images/alchemy_crm/.DS_Store +0 -0
- data/app/assets/images/alchemy_crm/contact-icons.png +0 -0
- data/app/assets/images/alchemy_crm/fill_content.gif +0 -0
- data/app/assets/images/alchemy_crm/group-icons.png +0 -0
- data/app/assets/images/alchemy_crm/mailing-icons.png +0 -0
- data/app/assets/images/alchemy_crm/module_icon.png +0 -0
- data/app/assets/images/alchemy_crm/newsletter-icons.png +0 -0
- data/app/assets/images/alchemy_crm/statistic.png +0 -0
- data/app/assets/images/alchemy_crm/tag-icons.png +0 -0
- data/app/assets/javascripts/alchemy_crm/alchemy_crm.base.js +65 -0
- data/app/assets/javascripts/alchemy_crm/scripts.js +2 -0
- data/app/assets/stylesheets/alchemy_crm/base.css.scss +473 -0
- data/app/assets/stylesheets/alchemy_crm/styles.css +3 -0
- data/app/controllers/alchemy_crm/admin/base_controller.rb +7 -0
- data/app/controllers/alchemy_crm/admin/contact_groups_controller.rb +23 -0
- data/app/controllers/alchemy_crm/admin/contacts_controller.rb +112 -0
- data/app/controllers/alchemy_crm/admin/deliveries_controller.rb +80 -0
- data/app/controllers/alchemy_crm/admin/elements_controller_extension.rb +32 -0
- data/app/controllers/alchemy_crm/admin/mailings_controller.rb +47 -0
- data/app/controllers/alchemy_crm/admin/newsletters_controller.rb +24 -0
- data/app/controllers/alchemy_crm/admin/tags_controller.rb +62 -0
- data/app/controllers/alchemy_crm/base_controller.rb +5 -0
- data/app/controllers/alchemy_crm/contacts_controller.rb +103 -0
- data/app/controllers/alchemy_crm/mailings_controller.rb +20 -0
- data/app/controllers/alchemy_crm/recipients_controller.rb +35 -0
- data/app/controllers/alchemy_crm/subscriptions_controller.rb +57 -0
- data/app/helpers/alchemy/pages_helper_extension.rb +18 -0
- data/app/helpers/alchemy_crm/admin/base_helper.rb +12 -0
- data/app/helpers/alchemy_crm/mailings_helper.rb +190 -0
- data/app/mailers/alchemy_crm/bounce_receiver.rb +13 -0
- data/app/mailers/alchemy_crm/contacts_mailer.rb +26 -0
- data/app/mailers/alchemy_crm/mailings_mailer.rb +48 -0
- data/app/mailers/alchemy_crm/subscriptions_mailer.rb +17 -0
- data/app/models/alchemy/essence_element_teaser.rb +19 -0
- data/app/models/alchemy_crm/contact.rb +264 -0
- data/app/models/alchemy_crm/contact_group.rb +26 -0
- data/app/models/alchemy_crm/contact_group_filter.rb +26 -0
- data/app/models/alchemy_crm/delivery.rb +57 -0
- data/app/models/alchemy_crm/element_extension.rb +28 -0
- data/app/models/alchemy_crm/mailing.rb +93 -0
- data/app/models/alchemy_crm/newsletter.rb +48 -0
- data/app/models/alchemy_crm/reaction.rb +9 -0
- data/app/models/alchemy_crm/recipient.rb +48 -0
- data/app/models/alchemy_crm/subscription.rb +8 -0
- data/app/views/alchemy/admin/elements/_view_not_found.text.erb +0 -0
- data/app/views/alchemy/admin/elements/fill.js.erb +13 -0
- data/app/views/alchemy/admin/elements/link.js.erb +1 -0
- data/app/views/alchemy/elements/_newsletter_article_editor.html.erb +4 -0
- data/app/views/alchemy/elements/_newsletter_article_view.html.erb +16 -0
- data/app/views/alchemy/elements/_newsletter_article_view.text.erb +5 -0
- data/app/views/alchemy/elements/_newsletter_greeting_editor.html.erb +3 -0
- data/app/views/alchemy/elements/_newsletter_greeting_view.html.erb +11 -0
- data/app/views/alchemy/elements/_newsletter_greeting_view.text.erb +6 -0
- data/app/views/alchemy/elements/_newsletter_signout_form_editor.html.erb +3 -0
- data/app/views/alchemy/elements/_newsletter_signout_form_view.html.erb +32 -0
- data/app/views/alchemy/elements/_newsletter_signout_mail_editor.html.erb +4 -0
- data/app/views/alchemy/elements/_newsletter_signup_form_editor.html.erb +6 -0
- data/app/views/alchemy/elements/_newsletter_signup_form_view.html.erb +78 -0
- data/app/views/alchemy/elements/_newsletter_signup_mail_editor.html.erb +4 -0
- data/app/views/alchemy/essences/_essence_date_view.text.erb +3 -0
- data/app/views/alchemy/essences/_essence_element_teaser_editor.html.erb +31 -0
- data/app/views/alchemy/essences/_essence_element_teaser_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_element_teaser_view.text.erb +3 -0
- data/app/views/alchemy/essences/_essence_richtext_view.text.erb +1 -0
- data/app/views/alchemy/essences/_essence_text_view.text.erb +1 -0
- data/app/views/alchemy/newsletter_layouts/_standard.html.erb +39 -0
- data/app/views/alchemy/newsletter_layouts/_standard.text.erb +5 -0
- data/app/views/alchemy_crm/admin/contact_groups/_contact_group.html.erb +32 -0
- data/app/views/alchemy_crm/admin/contact_groups/_filter.html.erb +30 -0
- data/app/views/alchemy_crm/admin/contact_groups/_form.html.erb +47 -0
- data/app/views/alchemy_crm/admin/contact_groups/_tag.html.erb +6 -0
- data/app/views/alchemy_crm/admin/contact_groups/add_filter.js.erb +9 -0
- data/app/views/alchemy_crm/admin/contact_groups/destroy.rjs +1 -0
- data/app/views/alchemy_crm/admin/contact_groups/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contact_groups/index.html.erb +41 -0
- data/app/views/alchemy_crm/admin/contact_groups/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contacts/_contact.html.erb +44 -0
- data/app/views/alchemy_crm/admin/contacts/_form.html.erb +86 -0
- data/app/views/alchemy_crm/admin/contacts/destroy.rjs +1 -0
- data/app/views/alchemy_crm/admin/contacts/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contacts/import.html.erb +33 -0
- data/app/views/alchemy_crm/admin/contacts/import.js.erb +2 -0
- data/app/views/alchemy_crm/admin/contacts/index.html.erb +51 -0
- data/app/views/alchemy_crm/admin/contacts/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/contacts/vcf_import_result.html.erb +49 -0
- data/app/views/alchemy_crm/admin/deliveries/_delivery.html.erb +41 -0
- data/app/views/alchemy_crm/admin/deliveries/_form.html.erb +65 -0
- data/app/views/alchemy_crm/admin/deliveries/_recipient.html.erb +40 -0
- data/app/views/alchemy_crm/admin/deliveries/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/deliveries/index.html.erb +29 -0
- data/app/views/alchemy_crm/admin/deliveries/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/deliveries/show.html.erb +66 -0
- data/app/views/alchemy_crm/admin/elements/link.rjs +4 -0
- data/app/views/alchemy_crm/admin/elements/teasables.html.erb +57 -0
- data/app/views/alchemy_crm/admin/mailings/_form.html.erb +43 -0
- data/app/views/alchemy_crm/admin/mailings/_mailing.html.erb +75 -0
- data/app/views/alchemy_crm/admin/mailings/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/mailings/edit_content.html.erb +194 -0
- data/app/views/alchemy_crm/admin/mailings/import_result.html.erb +37 -0
- data/app/views/alchemy_crm/admin/mailings/index.html.erb +39 -0
- data/app/views/alchemy_crm/admin/mailings/new.html.erb +1 -0
- data/app/views/alchemy_crm/admin/mailings/show.html.erb +1 -0
- data/app/views/alchemy_crm/admin/mailings/show.text.erb +1 -0
- data/app/views/alchemy_crm/admin/newsletters/_form.html.erb +54 -0
- data/app/views/alchemy_crm/admin/newsletters/_newsletter.html.erb +42 -0
- data/app/views/alchemy_crm/admin/newsletters/_tag_with_radiobutton.html.erb +7 -0
- data/app/views/alchemy_crm/admin/newsletters/destroy.rjs +1 -0
- data/app/views/alchemy_crm/admin/newsletters/edit.html.erb +1 -0
- data/app/views/alchemy_crm/admin/newsletters/index.html.erb +42 -0
- data/app/views/alchemy_crm/admin/newsletters/new.html.erb +10 -0
- data/app/views/alchemy_crm/admin/tags/_radio_tag.html.erb +6 -0
- data/app/views/alchemy_crm/admin/tags/_tag.html.erb +32 -0
- data/app/views/alchemy_crm/admin/tags/edit.html.erb +40 -0
- data/app/views/alchemy_crm/admin/tags/index.html.erb +35 -0
- data/app/views/alchemy_crm/admin/tags/new.html.erb +16 -0
- data/app/views/alchemy_crm/contacts_mailer/signout_mail.html.erb +8 -0
- data/app/views/alchemy_crm/contacts_mailer/signout_mail.text.erb +4 -0
- data/app/views/alchemy_crm/contacts_mailer/signup_mail.html.erb +11 -0
- data/app/views/alchemy_crm/contacts_mailer/signup_mail.text.erb +4 -0
- data/app/views/alchemy_crm/mailings/show.html.erb +1 -0
- data/app/views/alchemy_crm/mailings_mailer/verification_mail.html.erb +11 -0
- data/app/views/alchemy_crm/subscriptions/index.html.erb +23 -0
- data/app/views/alchemy_crm/subscriptions_mailer/overview_mail.html.erb +27 -0
- data/app/views/alchemy_crm/subscriptions_mailer/overview_mail.text.erb +19 -0
- data/app/views/csv_magic/import_errors.html.erb +44 -0
- data/app/views/csv_magic/mapper.html.erb +62 -0
- data/app/views/layouts/alchemy_crm/mailings.html.erb +212 -0
- data/app/views/layouts/alchemy_crm/mailings.text.erb +3 -0
- data/config/alchemy_crm.config.yml +21 -0
- data/config/authorization_rules.rb +37 -0
- data/config/initializers/assets.rb +4 -0
- data/config/initializers/delayed_job.rb +6 -0
- data/config/locales/alchemy.de.yml +55 -0
- data/config/locales/alchemy.en.yml +52 -0
- data/config/locales/alchemy_crm.de.yml +196 -0
- data/config/locales/alchemy_crm.en.yml +53 -0
- data/config/locales/localized_country_select.de.rb +268 -0
- data/config/locales/localized_country_select.en.rb +282 -0
- data/config/module_definition.yml +30 -0
- data/config/routes.rb +71 -0
- data/db/migrate/20100708220434_create_mailings.rb +19 -0
- data/db/migrate/20100708220534_create_contacts.rb +27 -0
- data/db/migrate/20100708220812_create_contact_groups.rb +13 -0
- data/db/migrate/20100708221009_create_newsletters.rb +15 -0
- data/db/migrate/20100708221319_create_sent_mailings.rb +15 -0
- data/db/migrate/20100708221529_create_recipients.rb +21 -0
- data/db/migrate/20100708222620_acts_as_taggable_migration.rb +28 -0
- data/db/migrate/20100708223324_create_contact_group_filters.rb +17 -0
- data/db/migrate/20100708223727_create_newsletter_subscriptions.rb +14 -0
- data/db/migrate/20100708223922_create_essence_element_teasers.rb +15 -0
- data/db/migrate/20100714172207_create_contact_groups_newsletters.rb +12 -0
- data/db/migrate/20100927152601_create_reactions.rb +14 -0
- data/db/migrate/20111028091722_acts_as_taggable_on_migration.rb +15 -0
- data/db/migrate/20111028200710_add_counter_cache_columns_for_tags.rb +11 -0
- data/db/migrate/20111030204931_create_delayed_jobs.rb +21 -0
- data/db/migrate/20111104105854_add_deliver_at_to_sent_mailings.rb +9 -0
- data/db/migrate/20111104125306_remove_sent_mailing_pdf_id_from_sent_mailings.rb +9 -0
- data/db/migrate/20111104131912_add_delivered_at_to_sent_mailings.rb +9 -0
- data/db/migrate/20111124145923_namespace_alchemy_crm_models.rb +17 -0
- data/db/migrate/20120306115555_add_disabled_to_alchemy_crm_contacts.rb +5 -0
- data/db/migrate/20120307160721_rename_alchemy_crm_recipients_sent_mailing_id.rb +5 -0
- data/db/migrate/20120315113522_add_url_to_alchemy_crm_reactions.rb +5 -0
- data/db/migrate/20120316161333_add_sha1_and_salt_to_alchemy_crm_recipients.rb +6 -0
- data/db/migrate/20120320103412_add_indexes_to_alchemy_crm_sha1_columns.rb +7 -0
- data/db/migrate/20120321105455_add_queue_to_delayed_jobs.rb +9 -0
- data/db/migrate/20120327174301_add_more_indexes_to_alchemy_crm_tables.rb +12 -0
- data/lib/alchemy_crm.rb +18 -0
- data/lib/alchemy_crm/bounced_delivery.rb +46 -0
- data/lib/alchemy_crm/config.rb +28 -0
- data/lib/alchemy_crm/engine.rb +40 -0
- data/lib/alchemy_crm/i18n_helpers.rb +35 -0
- data/lib/alchemy_crm/newsletter_layout.rb +40 -0
- data/lib/alchemy_crm/seeder.rb +30 -0
- data/lib/alchemy_crm/version.rb +3 -0
- data/lib/generators/alchemy_crm/scaffold/files/_standard.html.erb +1 -0
- data/lib/generators/alchemy_crm/scaffold/files/_standard.text.erb +1 -0
- data/lib/generators/alchemy_crm/scaffold/files/elements.yml +51 -0
- data/lib/generators/alchemy_crm/scaffold/files/newsletter_layouts.yml +3 -0
- data/lib/generators/alchemy_crm/scaffold/files/newsletters.html.erb +22 -0
- data/lib/generators/alchemy_crm/scaffold/files/newsletters.text.erb +4 -0
- data/lib/generators/alchemy_crm/scaffold/files/page_layouts.yml +19 -0
- data/lib/generators/alchemy_crm/scaffold/scaffold_generator.rb +26 -0
- data/lib/tasks/alchemy_crm.rake +28 -0
- data/lib/tasks/routes.rake +29 -0
- data/rails/init.rb +1 -0
- data/recipes/alchemy-mailings-capistrano-tasks.rb +12 -0
- data/spec/alchemy_mailings_spec.rb +7 -0
- data/spec/config_spec.rb +28 -0
- data/spec/controllers/alchemy_crm/contacts_controller_spec.rb +210 -0
- data/spec/controllers/alchemy_crm/mailings_controller_spec.rb +89 -0
- data/spec/controllers/alchemy_crm/recipients_controller_spec.rb +155 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/alchemy/config.yml +142 -0
- data/spec/dummy/config/alchemy/elements.yml +79 -0
- data/spec/dummy/config/alchemy/newsletter_layouts.yml +4 -0
- data/spec/dummy/config/alchemy/page_layouts.yml +55 -0
- data/spec/dummy/config/application.rb +43 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/db/schema.rb +452 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/helpers/alchemy_crm/mailings_helper_spec.rb +169 -0
- data/spec/mailers/alchemy_crm/contacts_mailer_spec.rb +88 -0
- data/spec/mailers/alchemy_crm/mailings_mailer_spec.rb +42 -0
- data/spec/models/alchemy_crm/contact_group_spec.rb +41 -0
- data/spec/models/alchemy_crm/contact_spec.rb +108 -0
- data/spec/models/alchemy_crm/delivery_spec.rb +55 -0
- data/spec/models/alchemy_crm/mailing_spec.rb +63 -0
- data/spec/models/alchemy_crm/newsletter_spec.rb +45 -0
- data/spec/spec_helper.rb +58 -0
- data/vendor/assets/javascripts/autocomplete-rails.js +16 -0
- metadata +438 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module AlchemyCrm
|
|
2
|
+
class MailingsController < AlchemyCrm::BaseController
|
|
3
|
+
|
|
4
|
+
def show
|
|
5
|
+
@mailing = Mailing.find_by_sha1(params[:m])
|
|
6
|
+
if @mailing.nil? && !params[:id].blank?
|
|
7
|
+
@mailing = Mailing.find(params[:id])
|
|
8
|
+
end
|
|
9
|
+
@page = @mailing.page
|
|
10
|
+
if params[:r].present?
|
|
11
|
+
@recipient = @mailing.recipients.find_by_sha1(params[:r])
|
|
12
|
+
@contact = @recipient.contact || Contact.new_from_recipient(@recipient)
|
|
13
|
+
else
|
|
14
|
+
@contact = Contact.fake
|
|
15
|
+
@recipient = Recipient.new_from_contact(@contact)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module AlchemyCrm
|
|
2
|
+
class RecipientsController < AlchemyCrm::BaseController
|
|
3
|
+
|
|
4
|
+
def reads
|
|
5
|
+
recipient = Recipient.find_by_sha1(params[:h])
|
|
6
|
+
if recipient && !recipient.read?
|
|
7
|
+
recipient.reads!
|
|
8
|
+
end
|
|
9
|
+
render :nothing => true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def reacts
|
|
13
|
+
recipient = Recipient.find_by_sha1(params[:h])
|
|
14
|
+
if recipient
|
|
15
|
+
recipient.reacts!({
|
|
16
|
+
:page_id => params[:page_id],
|
|
17
|
+
:element_id => params[:element_id],
|
|
18
|
+
:url => params[:r]
|
|
19
|
+
})
|
|
20
|
+
end
|
|
21
|
+
if params[:r].present?
|
|
22
|
+
redirect_to params[:r]
|
|
23
|
+
else
|
|
24
|
+
page = Alchemy::Page.includes(:elements).find(params[:page_id])
|
|
25
|
+
element = page.elements.find_by_id(params[:element_id])
|
|
26
|
+
redirect_to alchemy.show_page_url(
|
|
27
|
+
:urlname => page.urlname,
|
|
28
|
+
:lang => multi_language? ? page.language_code : nil,
|
|
29
|
+
:anchor => element ? element.dom_id : nil
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Caution: Not yet implemmented!
|
|
2
|
+
module AlchemyCrm
|
|
3
|
+
class SubscriptionsController < AlchemyCrm::BaseController
|
|
4
|
+
|
|
5
|
+
before_filter :load_contact, :except => :deliver_subscriptions_overview
|
|
6
|
+
|
|
7
|
+
def index
|
|
8
|
+
@page = Alchemy::Page.find_by_page_layout('newsletter_views')
|
|
9
|
+
@root_page = @page.get_language_root
|
|
10
|
+
render :template => 'alchemy/pages/show', :layout => layout_for_page
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def new
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def edit
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def update
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def destroy
|
|
30
|
+
@subscription = @contact.subscriptions.find(params[:subscription_id])
|
|
31
|
+
@subscription.destroy
|
|
32
|
+
flash[:notice] = t(:subscription_destroyed)
|
|
33
|
+
@page = Alchemy::Page.find_by_page_layout('newsletter_views')
|
|
34
|
+
@root_page = @page.get_language_root
|
|
35
|
+
render :template => 'alchemy/pages/show', :layout => layout_for_page
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def overview
|
|
39
|
+
@contact = Contact.find_by_email(params[:email])
|
|
40
|
+
if @contact
|
|
41
|
+
SubscriptionsMailer.overview_mail.deliver(@contact, @element)
|
|
42
|
+
flash[:notice] = t(:send_subscriptions_overview_via_email)
|
|
43
|
+
redirect_to :index
|
|
44
|
+
else
|
|
45
|
+
flash[:error] = t(:no_subscriber_found)
|
|
46
|
+
render :index
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def load_contact
|
|
53
|
+
@contact = Contact.find_by_email_sha1(params[:token])
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Alchemy::PagesHelper.module_eval do
|
|
2
|
+
|
|
3
|
+
def render_page_layout(options={})
|
|
4
|
+
default_options = {
|
|
5
|
+
:render_format => "html"
|
|
6
|
+
}
|
|
7
|
+
options = default_options.merge(options)
|
|
8
|
+
if @page.layout_description['newsletter']
|
|
9
|
+
render :partial => "alchemy/newsletter_layouts/#{@page.page_layout.downcase}.#{options[:render_format]}.erb"
|
|
10
|
+
else
|
|
11
|
+
render :partial => "alchemy/page_layouts/#{@page.page_layout.downcase}.#{options[:render_format]}.erb"
|
|
12
|
+
end
|
|
13
|
+
rescue ActionView::MissingTemplate
|
|
14
|
+
warning("PageLayout: '#{@page.page_layout}' not found. Rendering standard page_layout.")
|
|
15
|
+
render :partial => "alchemy/page_layouts/standard"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
module AlchemyCrm
|
|
2
|
+
module MailingsHelper
|
|
3
|
+
|
|
4
|
+
include Alchemy::PagesHelper
|
|
5
|
+
|
|
6
|
+
# Renders the newsletter layout for +@mailing.page+
|
|
7
|
+
#
|
|
8
|
+
# The +@mailing.page.page_layout+ must have a +newsletter_layout+ prefix.
|
|
9
|
+
# The partial itself is named without the +newsletter_layout+ prefix.
|
|
10
|
+
# The partial resists in +/app/views/newsletter_layouts/+
|
|
11
|
+
#
|
|
12
|
+
# === Example:
|
|
13
|
+
#
|
|
14
|
+
# Given a mailing page with a +standard+ layout has partials named +_standard.html.erb+ and +_standard.text.erb+
|
|
15
|
+
# But the page page_layout attribute is +newsletter_layout_standard+
|
|
16
|
+
#
|
|
17
|
+
def render_newsletter_layout(options={})
|
|
18
|
+
options = {:format => 'html'}.update(options)
|
|
19
|
+
render "alchemy/newsletter_layouts/#{@page.page_layout.downcase.gsub(Regexp.new(Mailing::MAILING_PAGE_LAYOUT_PREFIX), '')}.#{options[:format]}.erb"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Renders the tracking image that records the receivement of the mailing inside the mail client.
|
|
23
|
+
def render_tracking_image
|
|
24
|
+
return "" if @preview_mode || @recipient.nil?
|
|
25
|
+
image_tag(
|
|
26
|
+
alchemy_crm.recipient_reads_url(:h => @recipient.sha1, :host => current_host),
|
|
27
|
+
:style => "width: 0; height: 0; display: none",
|
|
28
|
+
:width => 0,
|
|
29
|
+
:height => 0,
|
|
30
|
+
:alt => ''
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Renders a link to the unsubscribe page.
|
|
35
|
+
#
|
|
36
|
+
# Please notice that you have to create a page with a +newsletter_signout+ page layout and this page has to be public.
|
|
37
|
+
#
|
|
38
|
+
# The text inside the link is translated.
|
|
39
|
+
#
|
|
40
|
+
# === Example translation:
|
|
41
|
+
#
|
|
42
|
+
# de:
|
|
43
|
+
# alchemy_crm:
|
|
44
|
+
# unsubscribe: 'abmelden'
|
|
45
|
+
#
|
|
46
|
+
# === Options:
|
|
47
|
+
#
|
|
48
|
+
# html_options [Hash] # Passed to the link. Useful for styling the link with inline css.
|
|
49
|
+
#
|
|
50
|
+
# You can pass an optional block thats gets passed to +link_to+
|
|
51
|
+
#
|
|
52
|
+
def link_to_unsubscribe_page(html_options={})
|
|
53
|
+
text = ::I18n.t(:unsubscribe, :scope => :alchemy_crm)
|
|
54
|
+
if block_given?
|
|
55
|
+
link_to(url_for_unsubscribe_page, html_options) do
|
|
56
|
+
yield
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
link_to(text, url_for_unsubscribe_page, html_options)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Returns the url for the unsubscribe page.
|
|
64
|
+
# Used by +link_to_unsubscribe_page+ helper and inside of plain text views of mailings.
|
|
65
|
+
def url_for_unsubscribe_page
|
|
66
|
+
unsubscribe_page = Alchemy::Page.find_by_page_layout('newsletter_signout')
|
|
67
|
+
if unsubscribe_page.nil?
|
|
68
|
+
raise('Newsletter Signout Page Could Not Be Found. Please create one!')
|
|
69
|
+
else
|
|
70
|
+
alchemy.show_page_url(
|
|
71
|
+
:urlname => unsubscribe_page.urlname,
|
|
72
|
+
:lang => multi_language? ? unsubscribe_page.language_code : nil,
|
|
73
|
+
:email => @contact ? @contact.email : nil,
|
|
74
|
+
:host => current_host
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Renders a notice to open the mailing inside a browser, if it does not displays correctly.
|
|
80
|
+
#
|
|
81
|
+
# The notice and the link inside are translated via I18n.
|
|
82
|
+
#
|
|
83
|
+
# === Example translation:
|
|
84
|
+
#
|
|
85
|
+
# de:
|
|
86
|
+
# alchemy_crm:
|
|
87
|
+
# here: 'hier'
|
|
88
|
+
# read_in_browser_notice: "Falls der Newsletter nicht richtig dargestellt wird, klicken Sie bitte %{link}."
|
|
89
|
+
#
|
|
90
|
+
# === Options:
|
|
91
|
+
#
|
|
92
|
+
# html_options [Hash] # Passed to the link. Useful for styling the link with inline css.
|
|
93
|
+
#
|
|
94
|
+
def read_in_browser_notice(html_options = {})
|
|
95
|
+
return "" if @recipient.nil?
|
|
96
|
+
::I18n.t(
|
|
97
|
+
:read_in_browser_notice,
|
|
98
|
+
:link => link_to(
|
|
99
|
+
::I18n.t(:here, :scope => :alchemy_crm),
|
|
100
|
+
alchemy_crm.show_mailing_url(
|
|
101
|
+
:m => @mailing.sha1,
|
|
102
|
+
:r => @recipient.sha1,
|
|
103
|
+
:host => current_host
|
|
104
|
+
),
|
|
105
|
+
html_options,
|
|
106
|
+
:host => current_host
|
|
107
|
+
),
|
|
108
|
+
:scope => :alchemy_crm
|
|
109
|
+
).html_safe
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Use this helper to render an image from your server.
|
|
113
|
+
#
|
|
114
|
+
# The notice and the link inside are translated via I18n.
|
|
115
|
+
#
|
|
116
|
+
# === Example:
|
|
117
|
+
#
|
|
118
|
+
# <%= image_from_server_tag('logo.png', :alt => 'Logo', :width => 230, :height => 116, :style => 'outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;') %>
|
|
119
|
+
# => <img src="http://example.com/assets/logo.png"
|
|
120
|
+
#
|
|
121
|
+
# === Options:
|
|
122
|
+
#
|
|
123
|
+
# html_options [Hash] # Passed to the image_tag helper.
|
|
124
|
+
#
|
|
125
|
+
def image_from_server_tag(image, html_options={})
|
|
126
|
+
image_tag([current_server, Rails.application.config.assets.prefix, image].join('/'), html_options)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Renders a link that tracks the reaction of a recipient.
|
|
130
|
+
#
|
|
131
|
+
# After getting tracked the controller redirects to the url passed in.
|
|
132
|
+
#
|
|
133
|
+
# It has the same arguments that the Rails +link_to+ helper has.
|
|
134
|
+
#
|
|
135
|
+
# === Example:
|
|
136
|
+
#
|
|
137
|
+
# <%= tracked_link_tag('read more', :r => 'http://example.com/my-article', :style => 'color: black') %>
|
|
138
|
+
# => <a href="http://example.com/recipient/s3cr3tSh41/reacts?r=http%3A%2F%2Fexample.com%2Fmy-article" style="color: black">
|
|
139
|
+
#
|
|
140
|
+
# *NOTE:* You can even pass a block like you could for +link_to+ helper from Rails.
|
|
141
|
+
#
|
|
142
|
+
def tracked_link_tag(*args)
|
|
143
|
+
if block_given?
|
|
144
|
+
link_to(tracked_url_for(args.first), args.last) do
|
|
145
|
+
yield
|
|
146
|
+
end
|
|
147
|
+
else
|
|
148
|
+
link_to(args.first, tracked_url_for(args[1]), args.last)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Returns the url for tracking a link that's clicked inside a mailing.
|
|
153
|
+
# Used by +tracked_link_tag+ helper and plain text mailing views.
|
|
154
|
+
def tracked_url_for(redirect_url)
|
|
155
|
+
alchemy_crm.recipient_reacts_url(:h => @recipient.sha1, :r => redirect_url, :host => current_host)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def current_host
|
|
159
|
+
(defined?(request)).nil? || request.nil? ? @options[:host] : request.host
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def current_server
|
|
163
|
+
if (defined?(request)).nil? || request.nil?
|
|
164
|
+
protocol = @options.nil? || @options[:protocol].blank? ? 'http://' : @options[:protocol]
|
|
165
|
+
else
|
|
166
|
+
protocol = request.protocol
|
|
167
|
+
end
|
|
168
|
+
if (defined?(request)).nil? || request.nil?
|
|
169
|
+
if @options
|
|
170
|
+
port = @options[:port] && @options[:port] != 80 ? @options[:port] : nil
|
|
171
|
+
else
|
|
172
|
+
port = nil
|
|
173
|
+
end
|
|
174
|
+
else
|
|
175
|
+
port = request.port != 80 ? request.port : nil
|
|
176
|
+
end
|
|
177
|
+
[protocol, current_host, port ? ":#{port}" : nil].join
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def current_language
|
|
181
|
+
return @language if @language
|
|
182
|
+
if @options && @options[:language_id]
|
|
183
|
+
@language = Alchemy::Language.find(@options[:language_id])
|
|
184
|
+
else
|
|
185
|
+
@language = Alchemy::Language.get_default
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module AlchemyCrm
|
|
2
|
+
class BounceReceiver < ActionMailer::Base
|
|
3
|
+
|
|
4
|
+
def receive(email)
|
|
5
|
+
return unless email.content_type == "multipart/report"
|
|
6
|
+
bounce = BouncedDelivery.from_email(email)
|
|
7
|
+
recipient = Recipient.find_by_message_id(bounce.original_message_id)
|
|
8
|
+
recipient.bounced = (bounce.status == "Failure")
|
|
9
|
+
recipient.save!
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module AlchemyCrm
|
|
2
|
+
class ContactsMailer < ActionMailer::Base
|
|
3
|
+
|
|
4
|
+
def signup_mail(contact, page)
|
|
5
|
+
@contact = contact
|
|
6
|
+
@newsletter_ids = @contact.subscriptions.collect(&:newsletter_id)
|
|
7
|
+
@element = page.elements.where(:name => 'newsletter_signup_mail').first
|
|
8
|
+
mail(
|
|
9
|
+
:from => @element.ingredient('mail_from'),
|
|
10
|
+
:to => contact.email,
|
|
11
|
+
:subject => @element.ingredient('subject')
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def signout_mail(contact, page)
|
|
16
|
+
@element = page.elements.where(:name => 'newsletter_signout_mail').first
|
|
17
|
+
@contact = contact
|
|
18
|
+
mail(
|
|
19
|
+
:from => @element.ingredient("mail_from"),
|
|
20
|
+
:to => contact.email,
|
|
21
|
+
:subject => @element.ingredient('subject')
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module AlchemyCrm
|
|
2
|
+
class MailingsMailer < ActionMailer::Base
|
|
3
|
+
|
|
4
|
+
default :from => AlchemyCrm::Config.get(:mail_from)
|
|
5
|
+
|
|
6
|
+
helper "AlchemyCrm::Mailings"
|
|
7
|
+
helper_method :logged_in?, :configuration
|
|
8
|
+
|
|
9
|
+
# Renders the email sent to the mailing recipient
|
|
10
|
+
# It takes the layout from +layouts/alchemy_crm/mailings.erb+ and renders a html and a text part from it.
|
|
11
|
+
def build(mailing, recipient, options = {})
|
|
12
|
+
@options = options
|
|
13
|
+
::I18n.locale = @options[:locale]
|
|
14
|
+
@mailing = mailing
|
|
15
|
+
@page = @mailing.page
|
|
16
|
+
@recipient = recipient
|
|
17
|
+
@contact = @recipient.contact || Contact.new_from_recipient(@recipient)
|
|
18
|
+
|
|
19
|
+
mail(:to => @recipient.mail_to, :subject => mailing.subject) do |format|
|
|
20
|
+
format.html { render("layouts/alchemy_crm/mailings.html") }
|
|
21
|
+
format.text { render("layouts/alchemy_crm/mailings.text") }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Faking that we are not logged in
|
|
26
|
+
def logged_in?
|
|
27
|
+
false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Proxy to Alchemy config for view helpers
|
|
31
|
+
def configuration(name)
|
|
32
|
+
Alchemy::Config.get(name)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Simple session object that contains the language id for view helpers.
|
|
36
|
+
def session
|
|
37
|
+
{
|
|
38
|
+
:language_id => @options[:language_id]
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Setting default url options for rails url_for helpers.
|
|
43
|
+
def default_url_options
|
|
44
|
+
{:host => @options[:host], :port => @options[:port]}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module AlchemyCrm
|
|
3
|
+
class SubscriptionsMailer < ActionMailer::Base
|
|
4
|
+
|
|
5
|
+
def overview_mail(contact, element)
|
|
6
|
+
@contact = contact
|
|
7
|
+
@subscriptions = contact.subscriptions
|
|
8
|
+
@element = element
|
|
9
|
+
mail(
|
|
10
|
+
:from => element.ingredient("mail_from"),
|
|
11
|
+
:to => contact.email,
|
|
12
|
+
:subject => element.ingredient("mail_subject")
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|