@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/?post_type=lh-portfolio-doc&#038;p=147702>
  a sioc:Post ;
  dc:title "Hooks and filters" ;
  dcterms:identifier 147702 ;
  dc:modified "2026-09-18T18:23:04Z"^^xsd:dateTime ;
  dc:created "2026-09-17T23:25:02Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-crm/hooks-and-filters/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded """<ul class="lh_portfolio-meta"><li><strong>Part of:</strong> <a href="https://lhero.org/portfolio/lh-crm/">LH Customer Relationship Management</a></li></ul>
<p class="wp-block-paragraph">All names below are as they appear in the code. The namespace is <code>lh_crm</code>. The four form HTML filters mix a hyphen into the name; they are documented as they are, since renaming a public hook needs a back-compat step.</p>



<h2 class="wp-block-heading">Actions fired</h2>



<figure class="wp-block-table"><table><thead><tr><th>Hook</th><th>Arguments</th><th>When</th></tr></thead><tbody><tr><td><code>lh_crm_http_post_after_user</code></td><td><code>$user</code></td><td>After a submission&#8217;s user has been resolved (the logged-in user, or matched or created from the email), before anything else is saved. Plugins whose profile fields save themselves, such as LH User Experience Taxonomy, save here.</td></tr><tr><td><code>lh_crm_enquiry_created</code></td><td><code>$post_id, $form_id, $user</code></td><td>After an enquiry post is created. Only fires when the form was submitted from a singular page, since no enquiry is created otherwise. Nothing inside LH CRM listens to it since 1.5.8, when the relationships sync was removed; it is there for other plugins.</td></tr><tr><td><code>lh_post_ip_tax_insert_post</code></td><td><code>$post_id</code></td><td>Asks the bundled IP library to record the submitter&#8217;s IP on a new enquiry</td></tr><tr><td><code>lh_post_user_agent_insert_post</code></td><td><code>$post_id</code></td><td>Asks the bundled User Agent library to record the browser string</td></tr><tr><td><code>lh_as_queue_runner_enqueue_runner</code></td><td>none</td><td>After the auto-reply email is queued, to nudge the mail queue runner</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Profile field saves also fire BuddyPress&#8217;s own <code>xprofile_profile_field_data_updated</code> and <code>xprofile_updated_profile</code>.</p>



<h2 class="wp-block-heading">Filters</h2>



<figure class="wp-block-table"><table><thead><tr><th>Hook</th><th>Arguments</th><th>Effect</th></tr></thead><tbody><tr><td><code>lh_crm_init_plugin</code></td><td><code>true</code></td><td>Return false to skip the main bootstrap (frontend script, block, notices). The other component classes still load.</td></tr><tr><td><code>lh_crm_return_plugin_debugging_status</code></td><td><code>true</code></td><td>Whether to write debug log lines when <code>WP_DEBUG</code> is on</td></tr><tr><td><code>lh_crm_enquiry_action</code></td><td><code>$action, $page_id, $user_id</code></td><td>The &#8220;X enquired via Page on Site&#8221; string, which becomes the enquiry title</td></tr><tr><td><code>lh_crm_message_title</code></td><td><code>$title, $user</code></td><td>Receives the submitted subject. The result is currently not used anywhere.</td></tr><tr><td><code>lh_crm_message_content</code></td><td><code>$content, $user</code></td><td>Receives the submitted message. The result is only passed to the auto-reply as the default user summary; the enquiry itself stores the unfiltered message.</td></tr><tr><td><code>lh_crm_user_summary</code></td><td><code>$summary, $user</code></td><td>Value of the <code>recipient.user_summary</code> token in the auto-reply and the response template</td></tr><tr><td><code>lh_crm_send_notification_tokens</code></td><td><code>$tokens, $user</code></td><td>The full token array for the auto-reply email</td></tr><tr><td><code>lh_crm_format_notification</code></td><td><code>$html</code>, or <code>$array, $link, $total, $text</code></td><td>BuddyPress notification output for enquiry notifications (string or array format)</td></tr><tr><td><code>lh_crm_frontend_always_editable_field_types</code></td><td><code>$field_types</code></td><td>xProfile field type keys that stay editable on the logged-in form even when they already have a value. Defaults to <code>lh_uet-tax</code> and <code>lh_uet-text</code> (User Experience). These field types must save their own input, since they are left out of the submitted <code>field_ids</code>. Since 1.5.19.</td></tr><tr><td><code>lh_crm_frontend_field_display_value</code></td><td><code>$value, $field_id, $user_id</code></td><td>Plain-text value shown in the greyed box for a filled profile field on the logged-in form, for field types whose value is not returned by <code>bp_get_the_profile_field_value()</code>. If still empty, the box reads On your profile. Since 1.5.18.</td></tr><tr><td><code>lh_crm-form-after_full_name</code></td><td><code>$html, $atts</code></td><td>Form HTML after the name field or fields (runs for logged-in and logged-out forms)</td></tr><tr><td><code>lh_crm-form-after_frontend_email</code></td><td><code>$html, $atts</code></td><td>Form HTML after the email and profile fields</td></tr><tr><td><code>lh_crm-form-after_frontend_subject</code></td><td><code>$html, $atts</code></td><td>Form HTML after the subject field. Always fires, since the subject field is always output, either visible or as a hidden input.</td></tr><tr><td><code>lh_crm-form-after_frontend_submit</code></td><td><code>$html, $atts</code></td><td>Form HTML after the submit button</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">In the four form HTML filters, <code>$atts</code> holds the Contact Form block&#8217;s settings. The <code>lh_crm_gmt_offset</code> filter was removed in 1.5.9, when the hourly cron switched to comparing GMT dates directly.</p>



<h2 class="wp-block-heading">Bundled library filters</h2>



<ul class="wp-block-list"><li>IP address library: <code>lh_post_ip_tax_get_applicable_post_types</code>, <code>lh_post_ip_tax_get_taxonomy_ip_args</code>, <code>lh_post_ip_tax_show_column_content_ip_address</code>, <code>lh_post_ip_tax_return_plugin_debugging_status</code>.</li><li>User agent library: <code>lh_post_user_agent_get_applicable_post_types</code>, <code>lh_post_user_agent_get_current_user_ua</code>, <code>lh_post_user_agent_show_column_content_user_agent</code>, <code>lh_post_user_agent_show_column_content</code>, <code>lh_post_user_agent_the_metabox_content</code>, <code>lh_post_user_agent_return_plugin_debugging_status</code>.</li></ul>



<h2 class="wp-block-heading">Hooks from other plugins that LH CRM uses</h2>



<ul class="wp-block-list"><li>Opts the enquiry post type in through <code>lh_post_ip_tax_get_applicable_post_types</code>, <code>lh_post_user_agent_get_applicable_post_types</code> and <code>lh_comps_get_applicable_season_post_types_filter</code>.</li><li>Opts it out through <code>lh_archive_post_status_get_applicable_post_types_filter</code>, <code>lh_logged_in_post_status_get_applicable_post_types_filter</code>, <code>lh_r_post_status_get_applicable_post_types</code>, <code>lh_rejected_post_status_get_applicable_post_types</code>, <code>lh_bp_cpp_a_get_applicable_publish_post_types_filter</code>, <code>lh_ogp_meta_tags_get_applicable_post_types_filter</code>, <code>lh_html_sitemap_get_non_hierarchical_post_types</code>, <code>wp_sitemaps_post_types</code>, <code>lh_seo_meta_tags_get_applicable_post_types</code>, <code>lh_anon_comments_get_applicable_post_types</code>, <code>lh_attribution_get_applicable_post_types</code>, <code>lh_ui_pt_extender_get_applicable_post_types</code> and <code>lh_emoji_taxonomy_get_applicable_post_types</code>.</li><li>Adds its five statuses to <code>lh_membership_private_content_class_return_applicable_post_statuses</code> for logged-in users.</li><li>Adds five per-user enquiry fields (count, last date, last ID, last title, last content of New enquiries) to Users Insights through <code>usin_fields</code>, <code>usin_db_map</code> and <code>usin_query_join_table</code>.</li><li>Removes the contact form post type from Co-Authors Plus (<code>coauthors_supported_post_types</code>).</li><li>Uses <code>wp_statuses_registered</code> to remove the core statuses from enquiries. Note that its own <code>init</code> priority 1000 status registration must be added before the wp-statuses library&#8217;s own callback at the same priority; see Architecture notes, Load order.</li><li>Adjusts bbPress: moves its menus under CRM, adds thumbnail support to forums, and replaces <code>bbp_get_total_users</code> with the site&#8217;s real user count.</li><li>Passes <code>suppress_if_populated</code> in the properties given to an xProfile field type&#8217;s <code>edit_field_html()</code> on the logged-in form. The extended field types in LH Profile Page and LH User Experience Taxonomy honour it by printing nothing when their stored value is already set, which is how LH CRM detects values kept outside BuddyPress&#8217;s own profile data.</li></ul>
"""^^rdf:XMLLiteral ;
  sioc:content """Part of: LH Customer Relationship Management
All names below are as they appear in the code. The namespace is lh_crm. The four form HTML filters mix a hyphen into the name; they are documented as they are, since renaming a public hook needs a back-compat step.



Actions fired



HookArgumentsWhenlh_crm_http_post_after_user$userAfter a submission&#8217;s user has been resolved (the logged-in user, or matched or created from the email), before anything else is saved. Plugins whose profile fields save themselves, such as LH User Experience Taxonomy, save here.lh_crm_enquiry_created$post_id, $form_id, $userAfter an enquiry post is created. Only fires when the form was submitted from a singular page, since no enquiry is created otherwise. Nothing inside LH CRM listens to it since 1.5.8, when the relationships sync was removed; it is there for other plugins.lh_post_ip_tax_insert_post$post_idAsks the bundled IP library to record the submitter&#8217;s IP on a new enquirylh_post_user_agent_insert_post$post_idAsks the bundled User Agent library to record the browser stringlh_as_queue_runner_enqueue_runnernoneAfter the auto-reply email is queued, to nudge the mail queue runner



Profile field saves also fire BuddyPress&#8217;s own xprofile_profile_field_data_updated and xprofile_updated_profile.



Filters



HookArgumentsEffectlh_crm_init_plugintrueReturn false to skip the main bootstrap (frontend script, block, notices). The other component classes still load.lh_crm_return_plugin_debugging_statustrueWhether to write debug log lines when WP_DEBUG is onlh_crm_enquiry_action$action, $page_id, $user_idThe &#8220;X enquired via Page on Site&#8221; string, which becomes the enquiry titlelh_crm_message_title$title, $userReceives the submitted subject. The result is currently not used anywhere.lh_crm_message_content$content, $userReceives the submitted message. The result is only passed to the auto-reply as the default user summary; the enquiry itself stores the unfiltered message.lh_crm_user_summary$summary, $userValue of the recipient.user_summary token in the auto-reply and the response templatelh_crm_send_notification_tokens$tokens, $userThe full token array for the auto-reply emaillh_crm_format_notification$html, or $array, $link, $total, $textBuddyPress notification output for enquiry notifications (string or array format)lh_crm_frontend_always_editable_field_types$field_typesxProfile field type keys that stay editable on the logged-in form even when they already have a value. Defaults to lh_uet-tax and lh_uet-text (User Experience). These field types must save their own input, since they are left out of the submitted field_ids. Since 1.5.19.lh_crm_frontend_field_display_value$value, $field_id, $user_idPlain-text value shown in the greyed box for a filled profile field on the logged-in form, for field types whose value is not returned by bp_get_the_profile_field_value(). If still empty, the box reads On your profile. Since 1.5.18.lh_crm-form-after_full_name$html, $attsForm HTML after the name field or fields (runs for logged-in and logged-out forms)lh_crm-form-after_frontend_email$html, $attsForm HTML after the email and profile fieldslh_crm-form-after_frontend_subject$html, $attsForm HTML after the subject field. Always fires, since the subject field is always output, either visible or as a hidden input.lh_crm-form-after_frontend_submit$html, $attsForm HTML after the submit button



In the four form HTML filters, $atts holds the Contact Form block&#8217;s settings. The lh_crm_gmt_offset filter was removed in 1.5.9, when the hourly cron switched to comparing GMT dates directly.



Bundled library filters



IP address library: lh_post_ip_tax_get_applicable_post_types, lh_post_ip_tax_get_taxonomy_ip_args, lh_post_ip_tax_show_column_content_ip_address, lh_post_ip_tax_return_plugin_debugging_status.User agent library: lh_post_user_agent_get_applicable_post_types, lh_post_user_agent_get_current_user_ua, lh_post_user_agent_show_column_content_user_agent, lh_post_user_agent_show_column_content, lh_post_user_agent_the_metabox_content, lh_post_user_agent_return_plugin_debugging_status.



Hooks from other plugins that LH CRM uses



Opts the enquiry post type in through lh_post_ip_tax_get_applicable_post_types, lh_post_user_agent_get_applicable_post_types and lh_comps_get_applicable_season_post_types_filter.Opts it out through lh_archive_post_status_get_applicable_post_types_filter, lh_logged_in_post_status_get_applicable_post_types_filter, lh_r_post_status_get_applicable_post_types, lh_rejected_post_status_get_applicable_post_types, lh_bp_cpp_a_get_applicable_publish_post_types_filter, lh_ogp_meta_tags_get_applicable_post_types_filter, lh_html_sitemap_get_non_hierarchical_post_types, wp_sitemaps_post_types, lh_seo_meta_tags_get_applicable_post_types, lh_anon_comments_get_applicable_post_types, lh_attribution_get_applicable_post_types, lh_ui_pt_extender_get_applicable_post_types and lh_emoji_taxonomy_get_applicable_post_types.Adds its five statuses to lh_membership_private_content_class_return_applicable_post_statuses for logged-in users.Adds five per-user enquiry fields (count, last date, last ID, last title, last content of New enquiries) to Users Insights through usin_fields, usin_db_map and usin_query_join_table.Removes the contact form post type from Co-Authors Plus (coauthors_supported_post_types).Uses wp_statuses_registered to remove the core statuses from enquiries. Note that its own init priority 1000 status registration must be added before the wp-statuses library&#8217;s own callback at the same priority; see Architecture notes, Load order.Adjusts bbPress: moves its menus under CRM, adds thumbnail support to forums, and replaces bbp_get_total_users with the site&#8217;s real user count.Passes suppress_if_populated in the properties given to an xProfile field type&#8217;s edit_field_html() on the logged-in form. The extended field types in LH Profile Page and LH User Experience Taxonomy honour it by printing nothing when their stored value is already set, which is how LH CRM detects values kept outside BuddyPress&#8217;s own profile data.
""" ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
