=== M+M Mailing ===
Contributors: net360
Tags: email marketing, newsletter, mailing, smtp, campaigns
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.3.3
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Email marketing tools for WordPress with contacts, lists, campaign queues, scheduled delivery and campaign statistics.

== Changelog ==

= 1.3.3 =
* CORRECCIÓN: actualización de numeración de versión para la publicación de WordPress.org.
* PRESERVADO: todas las funcionalidades y correcciones de la versión estable 1.2.62, sin cambios funcionales.


== 1.2.62 =
* CORRECCIÓN: el Constructor de campañas queda registrado como página administrativa real y ya no se elimina del árbol de submenús, evitando el mensaje de WordPress "Sorry, you are not allowed to access this page." al abrir admin.php?page=mm-campaign-builder.
* MEJORA: añadido un control de permisos explícito dentro del callback del Constructor de campañas.
* MANTENIMIENTO: sincronizada la versión del esquema interno con la versión 1.2.62.

== 1.2.61 =
* CORRECCIÓN: añadido uninstall.php para eliminar todas las tablas propias de M+M Mailing al desinstalar el plugin.
* CORRECCIÓN: también se eliminan opciones, previsualizaciones temporales, transients y eventos WP-Cron propios del plugin.
* CORRECCIÓN: inicialización temprana de los filtros de Suscriptores para evitar warnings de variables indefinidas en PHP 8.x.
* CORRECCIÓN: optimizada la bandera de plantillas predeterminadas para evitar consultas repetidas en cada carga.
* MEJORA: el diagnóstico del sistema verifica todas las tablas utilizadas por el plugin.

== 1.2.60 =
* CORRECCIÓN: el Builder de campañas se registra con un parent válido y se oculta del menú después del registro, evitando valores NULL en get_admin_page_title() de WordPress/PHP 8.2+.
* CORRECCIÓN: eliminada la sobrecarga de admin_title que no podía prevenir el warning de strip_tags() porque ocurría antes del filtro.
* CORRECCIÓN: sincronizados todos los argumentos de la consulta preparada de Estadísticas con sus 58 placeholders.
* PRESERVADO: corrección de campos personalizados de suscriptores al editar contactos.


= 1.2.59 =
* CORRECCIÓN: ajustados los argumentos de la consulta preparada de Estadísticas para que coincidan exactamente con sus placeholders.
* CORRECCIÓN: sincronizada la versión del plugin con Stable tag.
* PRESERVADO: corrección de campos personalizados de suscriptores al editar contactos.

= 1.2.58 =
* CORRECCIÓN: mejoras de diagnóstico y compatibilidad del administrador.

= 1.3.1 =
* MEJORA: administración bilingüe Español / English según el idioma de WordPress.
* AGREGADO: infraestructura i18n, Text Domain y catálogos de idioma.
* MEJORA: navegación principal traducible y traducción automática de etiquetas administrativas heredadas.

= 1.2.56 =
* Plugin Check: corrected remaining dynamic ORDER BY warnings in Segments, Logs and Statistics using fully prepared static SQL ordering conditions.
* Preserved existing sorting ASC/DESC, search, filters and pagination.
* No campaign selection or statistics functionality was removed.

= 1.2.52 =
* Plugin Check: resolved the remaining PreparedSQL.NotPrepared report in the selected-list CSV export query.
* The dynamically sized IN() placeholder list is generated only from validated integer list IDs and prepared immediately before execution.
* Synchronized plugin header, version constant and stable tag to 1.2.52.

= 1.2.51 =
* Corrected remaining dynamic ORDER BY queries reported by Plugin Check.
* Preserved campaign selection, pagination, search and existing functionality.

= 1.2.50 =
* Sanitized dynamic ORDER BY handling in campaigns, templates, lists, custom fields and subscribers.
* Reworked campaign-list relationship queries to use identifier and value placeholders.
* Hardened subscriber CSV export queries and synchronized plugin metadata.


= 1.2.39 =
* Fixed the two remaining PreparedSQL.NotPrepared errors in the campaign builder list queries.
* Sanitized campaign list IDs as integers before constructing IN() clauses.
* Kept dynamic table identifiers and contact status handling inside prepared queries.
* Updated the in-plugin changelog shown at admin.php?page=mm-changelog.

= 1.2.38 =
* Improved nonce validation and input handling in AJAX/contact search and campaign builder.
* Hardened dynamic table identifiers and queue update queries.
* Improved prepared SQL handling for campaign list queries.
* Added lightweight caching to the import screen data lookups.
* Improved database safety checks during table verification.

== 1.2.36 ==

* Hardened admin request handling with explicit input checks, unslashing and sanitization in fields, lists, segments, campaigns, templates and shortcodes.
* Removed dead dynamic SQL filter construction from the queue screen and kept queue queries on prepared statements.
* Improved prepared SQL handling for plugin-controlled table identifiers and pagination values.
* Added nonce protection to custom-field management actions.
* Improved tracking and unsubscribe/spam request input handling without changing mailing behavior.


== 1.2.33 ==

* Hardened admin input handling with explicit unslash and sanitization for settings, lists, segments, subscribers, templates and queue actions.
* Reworked dynamic queue/list queries to use prepared statements and identifier placeholders.
* Added proper segment edit/update handling and nonce protection.
* Fixed pagination queries in campaigns and templates.
* Improved queue action nonce handling and search/filter sanitization.
* Improved campaign/list/template bulk-action database safety.


== 1.2.31 ==

* Fixed the Stable tag mismatch so the readme version matches the plugin header.
* Hardened database checks and dynamic queries used by the admin system, statistics and template screens.
* Improved Plugin Check compatibility for database parameter handling.
* Continued cleanup of database query patterns to reduce false-positive security warnings.

== 1.2.26 ==

* Added three starter email templates: Welcome, Special Promotion and Monthly Newsletter.
* Added safe one-time template seeding for new and existing installations without overwriting user-created templates.
* Improved the CSV import example with neutral sample contact data.

== 1.2.25 ==

* Fixed bulk list deletion by removing contact and campaign relationships before deleting lists.
* Deleting a list no longer deletes subscribers; it only removes their relationship with that list.
* Added CSV import recommendations covering file format, UTF-8 encoding, headers, required email field, separators and file-size limits.
* Added import-file validation guidance with a 10 MB recommended size and a 25 MB screen limit.

== 1.2.24 ==

* Fixed list selection for Duplicate and Delete actions.
* Improved the visual presentation of CSV import mode options.
* The list subscriber view now shows all available standard and custom fields.

== Description ==

M+M Mailing is a WordPress email marketing plugin for managing contacts, mailing lists, campaigns, templates, delivery queues and campaign performance.

Features include:

* Contact and list management.
* CSV contact import with field mapping.
* Campaign builder and HTML email editor.
* Scheduled campaigns.
* Background delivery through WordPress Cron.
* Configurable SMTP delivery through WordPress PHPMailer.
* Sending queue with retries and error logging.
* Open and click tracking.
* Unsubscribe and spam-report tracking links.
* Campaign statistics and delivery KPIs.
* Test email delivery.
* Custom contact fields.
* Campaign attachments.

M+M Mailing uses WordPress APIs and does not require external JavaScript CDNs.

== Installation ==

1. Upload the `mm-mailing` folder to `/wp-content/plugins/` or install the ZIP from the WordPress admin.
2. Activate M+M Mailing from Plugins.
3. Open M+M Mailing in the WordPress admin.
4. Configure the sender and, if required, SMTP settings.
5. Create a list and import or add contacts.
6. Create a campaign and send it immediately or schedule it.

== Frequently Asked Questions ==

= Why are emails not being sent? =

Check the sender settings, SMTP configuration and the WordPress Cron status. The Queue page also shows pending and failed messages.

= Can I schedule a campaign? =

Yes. A scheduled campaign creates its queue immediately and waits until the configured date and time before delivery.

= How are opens tracked? =

The plugin adds a first-party tracking pixel to sent HTML emails. Open tracking depends on the recipient's email client loading images.

= How are clicks tracked? =

Links in HTML campaigns are routed through the site's tracking endpoint before the visitor is redirected to the original destination.

== 1.2.22 ==
* Unsubscribe changes the contact to Unsubscribed and excludes it from future sends.
* Spam reporting records the complaint and blocks the contact from future mailings.
* Added subscriber states for unsubscribe and spam.
* Added friendly URLs and secure tokens for unsubscribe and spam reporting.
* Added List-Unsubscribe and List-Unsubscribe-Post headers.

== 1.2.21 ==
* Version visible across all plugin views.
* New Cambios y mejoras tab with version history.
* 🚀 Cola de Envío label and per-campaign processing controls.

= 1.2.14 =
* Hardened dynamic SQL filters in subscriber exports, logs, segments and campaign queue generation.
* Reworked campaign-builder list selection to use prepared placeholders.
* Improved subscriber filtering and ordering query construction.
* Reduced Plugin Check database-query findings without changing campaign delivery behavior.


= 1.2.7 =
* Reworked queue, delivery tracking and test-email handling.
* Added reliable WYSIWYG template editing and campaign template loading.
* Hardened database queries, scheduled-date handling and tracking pixel delivery.
* Added manual queue processing safeguards and improved campaign completion states.

= 1.2.3 =
* Improved WordPress output escaping across admin screens.
* Improved campaign builder attachment output escaping.
* Improved system diagnostics output escaping.
* Updated WYSIWYG campaign editor compatibility.


= 1.2.2 =
* Hardened campaign admin output escaping and safe admin URLs.
* Replaced nonce field echoing with direct WordPress nonce output.
* Improved campaign pagination and metric output escaping.
* Replaced JavaScript redirects with safe WordPress redirects.

= 1.2.1 =
* Reworked queue processing with stale-job recovery and real delivery error capture.
* Fixed scheduled campaign queue generation.
* Corrected campaign statistics to use sent queue messages as the delivery denominator.
* Added a native WordPress WYSIWYG/HTML editor for campaign and template content.
* Added template preview and safer template editing.
* Improved queue and campaign completion handling.

= 1.1.0 =
* Fixed campaign queue creation and background processing.
* Fixed tracking schema required by open and click statistics.
* Added queue retry handling and email delivery logs.
* Fixed scheduled campaign queue creation.
* Corrected campaign KPI denominators to use successfully sent messages.
* Added database migrations for existing installations.
* Removed external JavaScript CDN dependencies from the admin.
* Added GPL license metadata and WordPress.org readme information.
