friendsofvictoire/mailchimpnewsletter-widget
A Laravel package that adds a Mailchimp newsletter subscription widget to your PHP app, making it easy to embed signup forms and manage Mailchimp list subscriptions with minimal configuration.
This is a Victoire DCMS widget bundle, not a general-purpose MailChimp SDK. It exists for one thing: letting a content editor drop a newsletter sign-up form into a page from the Victoire page builder, then wire that form to a MailChimp list. If you are not running Victoire on Symfony 2.x, stop here — there is nothing to reuse.
Minimal steps:
composer require friendsofvictoire/mailchimpnewsletter-widget
Pin it (:dev-master#<sha> or an explicit tag) — the last release is from August 2016 and the dependency constraints will not resolve cleanly against anything modern.
app/AppKernel.php alongside VictoireCmsBundle and the other *WidgetBundle entries:
new FriendsOfVictoire\WidgetMailchimpNewsletterBundle\WidgetMailchimpNewsletterBundle(),
Widget/MailchimpNewsletterWidget.php (the Doctrine-backed widget model and its persisted settings)Form/Widget/MailchimpNewsletterWidgetType.php (what the editor can configure)Resources/views/Widget/MailchimpNewsletterWidget.html.twig (what the visitor sees)First use case: create a page slot, insert the widget, fill in the MailChimp API key and list ID in the widget's settings panel, publish, and submit the front-end form against a MailChimp test list. If that round-trip works you have exercised every part of the package.
Understand the three-artifact pattern. Every Victoire widget is a triad: a Widget entity subclass (persisted, holds settings), a Symfony form type (edits those settings in the backend), and a Twig template (renders the front end). Any customization you make will touch all three. Do not try to work around this — it is how Victoire serializes widget configuration into its page revision model.
Configuration placement. There are two plausible places the MailChimp credentials live in a bundle of this vintage:
parameters.yml / bundle config values.Check the form type to see which. If it's per-widget, migrate the key out immediately — see Gotchas. The reliable pattern is to define the key once in parameters.yml (or config.yml under your bundle's mailchimp: node), keep the list ID as a widget field so editors can target different lists per page, and have the template/controller read the global key.
Submission handling. Two shapes are common and you should pick deliberately:
For anything beyond a toy, do the second. Add a route in the bundle (or in your app, overriding the widget template's action), a small NewsletterController::subscribeAction, and a form type with csrf_protection on.
Override, don't fork. Everything is overridable through standard Symfony bundle inheritance:
app/Resources/WidgetMailchimpNewsletterBundle/views/Widget/MailchimpNewsletterWidget.html.twigIf you need real behavioural change (extra fields, consent checkbox, honeypot), the cleanest path is a new widget bundle that extends this one's widget class, adds properties, and overrides the template. Victoire's page revisions will keep both widgets side by side, so you can migrate pages gradually.
Extend the entity for the fields you actually need. A 2016 newsletter widget has email only. GDPR-era forms need: an explicit consent checkbox with the policy version recorded, a hidden source/page field for attribution, and a honeypot or timing check. Add these as nullable columns on the widget entity (or better, on a separate subscription-request entity) and surface them in the form type. Remember the Doctrine migration — Victoire stores widgets as serialized/related records, so schema changes need a migration plus a cache clear.
Decorate the MailChimp client. Rather than calling the API from the template or controller directly, register the underlying client (drewm/mailchimp-api or whatever the bundle pulls in) as a service and decorate it. That gives you a single seam for logging, retry, and stubbing in tests. If the bundle hardcodes new MailChimp(...) inside the widget, that is a sign to reimplement the call in your own service and leave the bundle as a rendering shell.
Testing. Functional-test the rendered form (assert the widget appears on a page and the form posts), and unit-test your subscribe service against a mocked client. Do not attempt to hit the real MailChimp API in CI — the v2/v3 churn will burn you.
This package is effectively abandoned. Last release 2016, 2 stars, zero dependents on Packagist. Treat it as reference code, not a dependency you can count on. Before adopting, verify it installs at all against your PHP/Symfony versions — the constraints almost certainly cap at Symfony 2.7/2.8 and PHP 5.x/7.0.
MailChimp API v2 is dead. MailChimp shut down API v2 in 2016. If this bundle depends on a v2 client or posts to usX.api.mailchimp.com/1.3/, it will not work against any live account. Check composer.lock after install and grep the source for api.mailchimp.com. Migrating to v3 means changing the endpoint, the auth scheme (basic auth with anystring:APIKEY), and the payload shape (members array with email_address and status: subscribed|pending). Budget for a rewrite of the submission path even if the widget rendering is fine.
Never store the API key in the widget record. Widget settings are persisted in the CMS database and rendered into page revisions — a leaked DB dump or an editor with page-preview access can expose the key. Move it to parameters.yml/env and, if the form type still has the field, remove it or make it read-only. Rotate any key that has been entered into a widget.
Caching vs. CSRF tokens. Victoire caches rendered widgets aggressively. A cached form embeds a stale CSRF token, and every subsequent submission fails with "The CSRF token is invalid." Either disable caching for the widget template ({% cache %}-style annotations depending on your Victoire version), or set csrf_protection => false on the form and rely on other anti-spam measures. Do not disable CSRF globally.
Double opt-in is not the default. MailChimp's v3 API creates pending members only if you send status: pending. Sending subscribed bypasses confirmation email — which is a compliance problem in the EU and a deliverability problem everywhere. Set the status explicitly and tell editors which mode they are in.
Widget discovery failures are silent. If the widget does not appear in the picker, the usual causes are: bundle not registered in AppKernel, services.yml not loaded from DependencyInjection/, or a missing Resources/config/widget.yml/translation key. Check the Symfony profiler's container for the widget service, and check Victoire's own widget registry command/logs. Clear cache twice — Victoire caches the widget list separately from the container.
Translations. Widget labels almost certainly ship only in French (Resources/translations/*.fr.yml) — FriendsOfVictoire is a French project. Provide your own *.en.yml overrides or the editor UI will show raw keys.
Extension points to prefer over edits. If you must keep the bundle in place, hook via: template override (safe), form type extension (safe), service decoration of the MailChimp client (safe), and a custom widget subclass (moderate). Avoid patching vendor files — there is no maintenance upstream, so your patches will be the only copy that exists.
Debugging checklist for a silent "form submits but nothing happens": log the actual HTTP response from MailChimp (it returns JSON with title/detail on errors, even on 200-level oddities), verify the list ID belongs to the same datacenter as the API key suffix (usX), and confirm the form is not being swallowed by Victoire's page-preview JS, which intercepts submit events on some versions.
How can I help you explore Laravel packages today?