- Rename core migration 20260627000000_PluginMigrationsTableCreate to
20261026000000_PluginConfigTableCreate, merging plugin_migrations
table creation into the same SQL script as plugin_config and adding
a startup log message; down() now drops both tables.
- Consolidate the plugin_migrations CREATE TABLE statement into
3.5.0_PluginConfigTableCreate.sql and remove the now-redundant
3.5.1_PluginMigrationsTableCreate.sql script.
- Update app/Plugins/README.md reference to the renamed migration
class.
- Add WhatsAppPlugin migration CreateWhatsAppMessagesTable to create
the whatsapp_messages conversation log table (utf8mb4, unique
wa_message_id to dedupe webhook redelivery); dropped explicitly by
WhatsAppPlugin::uninstall() instead of a down() method.
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
Add three missing plugin hook points for sale documents so plugins can
inject buttons into invoice, quote, and work order views alongside the
existing receipt hook. All four pass ['saleId' => $sale_id_num] and
follow the same naming pattern (view:sales_{type}_buttons).
Exempt plugins/*/webhook from CSRF filtering to support server-to-server
provider callbacks. Also convert the CSRF except list from a string to an
array — the previous 'login|migrate' string produced a single unanchored
pattern, making login/anything CSRF-exempt. Separate array entries anchor
each one individually. Plugin webhook handlers are responsible for their
own authentication.
Add WhatsApp Business Cloud API plugin (app/Plugins/WhatsAppPlugin/):
- Free-form messaging page registered as the 'whatsapp' office module
with its own permission, plus per-customer modal and thread view
- "Send via WhatsApp" button on all four sale document types via the new
hooks; renders only when the customer has a phone number
- PDF delivery using the same sales/{type}_email view core uses for email
- Inbound webhook at plugins/whatsapp/webhook authenticated by
X-Hub-Signature-256 HMAC; fails closed on missing/bad signature;
always returns 200 to suppress Meta retries
- Out-of-order status callbacks cannot downgrade sent → delivered → read
- Conversation log table via plugin migration; dropped on uninstall with
version reset so re-install recreates it cleanly
- Access token and app secret encrypted at rest in plugin_config; no
writes to app_config or initial_schema.sql
- utf8mb4_unicode_520_ci collation throughout (MySQL and MariaDB compat)
- Language file stubs for all existing locales; English strings complete
- README covering credentials, install, webhook setup, and uninstall
- Add column to indicate control setting (installed, enabled).
- Add column to indicate plugin.
- Rework business logic to read the status properly.
- Renamed the migration to properly reflect which version it's released in.
Signed-off-by: objec <objecttothis@gmail.com>