[buddypress-trac] [BuddyPress Trac] #9329: Enhancement Request: Add filter hook to `bp_email_get_type_schema()`
buddypress-trac
noreply at wordpress.org
Sun Feb 8 11:58:37 UTC 2026
#9329: Enhancement Request: Add filter hook to `bp_email_get_type_schema()`
-------------------------+-----------------------------
Reporter: indigetal | Owner: (none)
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Emails | Version:
Severity: normal | Keywords:
-------------------------+-----------------------------
== The Gap
BuddyPress's email system has two schema functions that work in tandem:
1. `bp_email_get_schema()` — returns email content (subject, HTML body,
plain text). '''Has a filter:''' `bp_email_get_schema` (applied at line
4109 of `bp-core-functions.php`). Plugins CAN extend this.
2. `bp_email_get_type_schema( $field )` — returns email type metadata
(description, `named_salutation`, unsubscribe config). '''No filter.'''
Returns a hardcoded `$types` array directly (lines 4310–4518 of `bp-core-
functions.php`).
The content schema is filterable; the type schema is not. This creates a
gap: plugins can register new email types into the content schema, but
cannot register the corresponding type metadata.
The install function `bp_core_install_emails()` in `bp-core-admin-
schema.php` (lines 504–544) consumes both:
{{{#!php
$emails = bp_email_get_schema(); // ← filtered,
plugin types included
$descriptions = bp_email_get_type_schema( 'description' ); // ← NOT
filtered, plugin types missing
}}}
Then for each email it sets the taxonomy term description from
`$descriptions[$id]` (line 540). For plugin-registered email types,
`$descriptions[$id]` is undefined — the email post IS created (because the
content schema filter works), but the taxonomy term description is empty.
The only filtered code path that touches type schema data is
`bp_email_get_unsubscribe_type_schema()` (lines 4718–4730), which filters
the return of `bp_email_get_type_schema('all')` via the
`bp_email_get_unsubscribe_type_schema` hook. However, this filter is NOT
consumed by `bp_core_install_emails()` — it's only used by the unsubscribe
handler.
This means:
1. **Inconsistent schema extensibility** — `bp_email_get_schema()` is
filterable, `bp_email_get_type_schema()` is not. Plugin developers who
follow the documented pattern of filtering `bp_email_get_schema` to
register custom emails find that their type metadata has no equivalent
entry point.
2. **Empty term descriptions after "Reinstall Emails"** — Email posts are
created successfully, but their taxonomy term descriptions are blank
because `$descriptions[$id]` is undefined for plugin types.
3. **Incomplete enumeration** — Any admin UI or utility code that calls
`bp_email_get_type_schema('description')` or
`bp_email_get_type_schema('all')` directly will miss plugin-registered
types entirely.
== Proposed Change
Add `apply_filters( 'bp_email_get_type_schema', $types )` before the
return in `bp_email_get_type_schema()`, matching the pattern established
by `bp_email_get_schema()`.
In `bp-core-functions.php`, before the field check at line 4513:
{{{#!php
/**
* Filters the email type schema, allowing anyone to add/update email type
metadata.
*
* @since {next_version}
*
* @param array $types The array of email type metadata.
*/
$types = apply_filters( 'bp_email_get_type_schema', $types );
if ( $field !== 'all' ) {
return wp_list_pluck( $types, $field );
} else {
return $types;
}
}}}
== Scope
* ~1 line of functional code added to one function in `bp-core-
functions.php`
* Zero behavioral change — the filter passes through existing values by
default
* Brings `bp_email_get_type_schema()` into parity with
`bp_email_get_schema()`
* The existing `bp_email_get_unsubscribe_type_schema` filter continues to
work as-is
[[br]]
== What This Enables for Addons
With this hook, addon plugins can register their custom email type
metadata (description, `named_salutation`, unsubscribe config) alongside
their email content schema. This means:
* '''Complete email registration''' — Plugins that filter
`bp_email_get_schema` to add email content can also filter
`bp_email_get_type_schema` to add the corresponding metadata, keeping both
schemas in sync.
* '''Correct "Reinstall Emails" behavior''' — `bp_core_install_emails()`
will pick up plugin type descriptions, so taxonomy terms are populated
correctly.
* '''Full enumeration support''' — Admin tools, settings pages, or any
code that calls `bp_email_get_type_schema()` will include plugin-
registered types.
== Prior Art
BuddyBoss Platform independently added exactly this filter to their fork.
In `bp-core-functions.php` (line 4047 in BuddyBoss 2.19.0):
{{{#!php
/**
* Filters Email type schema
*
* @param array $types Types array.
*
* @since BuddyBoss 1.5.4
*/
$types = apply_filters( 'bp_email_get_type_schema', $types );
}}}
Their notification abstract class (`BP_Core_Notification_Abstract`) hooks
both schema filters at priority 999 in its `start()` method:
{{{#!php
add_filter( 'bp_email_get_schema', array( $this, 'email_schema' ), 999 );
add_filter( 'bp_email_get_type_schema', array( $this, 'email_type_schema'
), 999 );
}}}
The fact that BuddyBoss independently arrived at the same 1-line solution
(and has shipped it since version 1.5.4) validates the need. If this
filter had existed in BuddyPress core, plugins could register complete
email type metadata without relying on platform-specific workarounds.
I'm happy to submit a patch for this change.
--
Ticket URL: <https://buddypress.trac.wordpress.org/ticket/9329>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac
More information about the buddypress-trac
mailing list